{"_id":"@bunlyfans/rest","_rev":"2-a0489dbb5d930e62ca8883e31e5353c2","name":"@bunlyfans/rest","dist-tags":{"latest":"0.1.2"},"versions":{"0.1.0":{"name":"@bunlyfans/rest","description":"Simple server for you to REST, powered by Bun","type":"module","version":"0.1.0","keywords":["bun","bunlyfans"],"bugs":{"url":"https://github.com/bunlyfans/bunlyfans/issues"},"license":"ISC","author":{"name":"bunlyfans"},"repository":{"type":"git","url":"git+https://github.com/bunlyfans/bunlyfans.git","directory":"packages/rest"},"homepage":"https://github.com/bunlyfans/bunlyfans/blob/main/packages/rest/README.md","scripts":{"dev":"bun run --watch example/index.ts","test:watch":"bun test --watch --coverage"},"exports":{"./index":"./index.ts"},"devDependencies":{"bun-types":"latest"},"peerDependencies":{"typescript":"^5.0.0"},"engines":{"bun":"^1.0.0"},"gitHead":"3bc4cd8067f1ba2788afe515782199da1b2ca3ba","_id":"@bunlyfans/rest@0.1.0","_nodeVersion":"18.17.1","_npmVersion":"9.6.7","dist":{"integrity":"sha512-YjB3i3DSheEAvMyJruYCQgm11pKW1PSIVNmcW/rRx2hiTPFOAV+nz5FqcDnfXFfxScuJ4eD+zkVKSAo0+oULKg==","shasum":"100159f97d3edcc86178a4eaa095aacaceec7e04","tarball":"https://registry.npmjs.org/@bunlyfans/rest/-/rest-0.1.0.tgz","fileCount":12,"unpackedSize":21183,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCICYQ7nYOjBK0JgrPUuf16BcBVIwUHjPdoD9ptsgR3mLpAiAYEfx3XWhWsl8xDcRRD6HZHRO4hk29DQoW40OENdMq4Q=="}]},"_npmUser":{"name":"apastuhov","email":"aleksey.pastuhov@gmail.com"},"directories":{},"maintainers":[{"name":"apastuhov","email":"aleksey.pastuhov@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/rest_0.1.0_1694809763317_0.008726762844326164"},"_hasShrinkwrap":false},"0.1.1":{"name":"@bunlyfans/rest","description":"Simple server for you to REST, powered by Bun","type":"module","version":"0.1.1","keywords":["bun","bunlyfans"],"bugs":{"url":"https://github.com/bunlyfans/bunlyfans/issues"},"license":"ISC","author":{"name":"bunlyfans"},"repository":{"type":"git","url":"git+https://github.com/bunlyfans/bunlyfans.git","directory":"packages/rest"},"homepage":"https://github.com/bunlyfans/bunlyfans/blob/main/packages/rest/README.md","scripts":{"dev":"bun run --watch example/index.ts","test:watch":"bun test --watch --coverage"},"exports":{".":"./index.ts"},"devDependencies":{"bun-types":"latest"},"peerDependencies":{"typescript":"^5.0.0","@bunlyfans/log":"^0.1.0"},"engines":{"bun":"^1.0.0"},"gitHead":"3bc4cd8067f1ba2788afe515782199da1b2ca3ba","_id":"@bunlyfans/rest@0.1.1","_nodeVersion":"18.17.1","_npmVersion":"9.6.7","dist":{"integrity":"sha512-H4e29HnqkQ8ehzFumo6z7Pm6hkYGLOuuLaj77wMLpKq5KYtnxiGTfMy3QJRPkg+OSLyM2sQV1xZQiJnnu5wzJw==","shasum":"a50c5252fca9bf83f42367648dd115d2d9d66144","tarball":"https://registry.npmjs.org/@bunlyfans/rest/-/rest-0.1.1.tgz","fileCount":12,"unpackedSize":21209,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIHRp7AsPUjf2SS5EE42UszoZxZ32J3eu05jVG4qrzI4sAiEAsacE4CzRljShAN0gXmJLFVj/7tqmw+oCDyeWxCF5j2s="}]},"_npmUser":{"name":"apastuhov","email":"aleksey.pastuhov@gmail.com"},"directories":{},"maintainers":[{"name":"apastuhov","email":"aleksey.pastuhov@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/rest_0.1.1_1694811019082_0.9935454317877621"},"_hasShrinkwrap":false},"0.1.2":{"name":"@bunlyfans/rest","description":"Simple server for you to REST, powered by Bun","type":"module","version":"0.1.2","keywords":["bun","bunlyfans"],"bugs":{"url":"https://github.com/bunlyfans/bunlyfans/issues"},"license":"ISC","author":{"name":"bunlyfans"},"repository":{"type":"git","url":"git+https://github.com/bunlyfans/bunlyfans.git","directory":"packages/rest"},"homepage":"https://github.com/bunlyfans/bunlyfans/blob/main/packages/rest/README.md","scripts":{"dev":"bun run --watch example/index.ts","test:watch":"bun test --watch --coverage"},"exports":{".":"./index.ts"},"devDependencies":{"bun-types":"latest"},"peerDependencies":{"typescript":"^5.0.0"},"dependencies":{"@bunlyfans/log":"^0.1.0"},"engines":{"bun":"^1.0.0"},"gitHead":"3bc4cd8067f1ba2788afe515782199da1b2ca3ba","_id":"@bunlyfans/rest@0.1.2","_nodeVersion":"18.17.1","_npmVersion":"9.6.7","dist":{"integrity":"sha512-hhL611HIzcQEJ8JpnXnk+uBwnuKwrtSnVwZRyTyxZbaBwir0jTZfSdFFY7x173bGbH6pXa1phCeXFAP/Fvl8rQ==","shasum":"46de7f83907487e4c49ba484ee8caa2e14d1b83c","tarball":"https://registry.npmjs.org/@bunlyfans/rest/-/rest-0.1.2.tgz","fileCount":12,"unpackedSize":21234,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCLMOMA7zpeUnVGKCYE+M9ug5MLiPVGU4tEY50dEeIW8AIgDHPxrlNP8pbanlzPElpW2B5cz4zMwIO3HoWaCYMD00w="}]},"_npmUser":{"name":"apastuhov","email":"aleksey.pastuhov@gmail.com"},"directories":{},"maintainers":[{"name":"apastuhov","email":"aleksey.pastuhov@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/rest_0.1.2_1694811157667_0.5391151091059592"},"_hasShrinkwrap":false}},"time":{"created":"2023-09-15T20:29:23.187Z","0.1.0":"2023-09-15T20:29:23.488Z","modified":"2023-09-15T20:52:38.065Z","0.1.1":"2023-09-15T20:50:19.270Z","0.1.2":"2023-09-15T20:52:37.833Z"},"maintainers":[{"name":"apastuhov","email":"aleksey.pastuhov@gmail.com"}],"description":"Simple server for you to REST, powered by Bun","homepage":"https://github.com/bunlyfans/bunlyfans/blob/main/packages/rest/README.md","keywords":["bun","bunlyfans"],"repository":{"type":"git","url":"git+https://github.com/bunlyfans/bunlyfans.git","directory":"packages/rest"},"author":{"name":"bunlyfans"},"bugs":{"url":"https://github.com/bunlyfans/bunlyfans/issues"},"license":"ISC","readme":"# @bunlyfans/rest\n\n![Bun Version](https://img.shields.io/badge/bun-v1.0.0-blue)\n![Version](https://img.shields.io/npm/v/@bunlyfans/rest.svg)\n![Build Status](https://img.shields.io/badge/build-passed-success)\n![Test Coverage](https://img.shields.io/badge/coverage-60-orange)\n\nUse Bun so you can REST. 😴\n\n- 🐰 100% Bun\n- ⚡️ 100% TypeScript\n- 🪄 100% magic\n- 🛫 0 dependencies\n- 💩🚫 0 bullshit\n\n## Contribution appreciated! 🙏\n\nIf you have any ideas / thougts / feature requests or want to contribute - feel free to create an issue or pull request!\n\n## Usage\n\nSee example directory for more details.\n\n```bash\nbun add @bunlyfans/rest\n```\n\nCreate folder directory:\n\n```sh\n- src/\n  - routes/\n    - users/\n      - [id].routes.ts\n  - index.ts\n```\n\nAdd next content to `index.ts`:\n\n```ts\nimport { Router, DebugMiddleware } from \"@bundlyfans/rest\";\n\nconst router = new Router({\n  dir: \"/routes/\",\n  debug: true, // to preview identified routes on app start/restart\n});\n\nrouter.register(new DebugMiddleware());\n\nBun.serve({\n  fetch: router.handle,\n  port: process.env.PORT || 3000,\n});\n```\n\nAdd next content to `routes/users/[id].routes.ts`:\n\n```ts\nimport { JSON, Param } from \"@bunlyfans/rest\";\n\nexport const middlewares = [new MyCustomMiddleware()];\n\nGET.middlewares = [new UserExistsMiddleware()];\n// This function will handle `GET /users/[id]` request\nexport function GET(id: Param<number>) { \n  // ..\n  return Response.json(user);\n}\n\nDELETE.middlewares = [new AllowFor([USER_ROLES.ADMIN])];\nexport async function DELETE(id: Param<number>, user: JSON<unknown>) {\n  // ..\n  return new Response('User deleted');\n}\n\nexport async function POST(user: JSON<User>) {\n  // ..\n  return Response.json(user, { status: 201 });\n}\n```\n\n## Router\n\nMain concept about router is that each entity is located in its own folder/file. Each folder can contain multiple files that will be used as endpoints. So File System path represents URL path.\n\nRoute handlers can be described **only** as Functions Declarations! So you can't use arrow functions or anonymous functions.\n\nUsage of methods as names may be found as a bit weird, but it's done on purpose, so it will force you to split your routes according to REST principles.\n\nIf you want to create custom endpoint - create file `/routes/users/[id]/reset-password.routes.ts` and it will be available as `/users/[id]/reset-password`. Now create a handle with function in this file:\n\n```ts\n// Replace POST with GET, PUT, DELETE, etc. to use another method\nexport async function POST(id: Param<number>) { // Id will be automatically parsed\n  // That is it! Just write your logic to reset password\n}\n```\n\nSometimes you may need index route, if folder for entity was already created and you do not want any params, then just use `routes.ts` filename.\n**Note:** In future such routes may become deprecated or renamed.\n\n### Supported argument sources\n\nAs you may noticed - arguments are parsed automatically by generic types. For now only fixed types are supported, but in future it will be possible to use custom types.\n\n| Type | Description |\n| --- | --- |\n| `arg1 JSON<T>` | Body of request. Will be parsed to JSON. |\n| `arg2 Param<T>` | Parameter extracted from request. Will be parsed to specified type, but default - fallback to `string`. **NOTE**: `arg2` is a name of the route param, so your path should look like `/entity/[arg2].routes.ts` or `/entity/[arg2]/custom.routes.ts`. |\n| `arg3 Query<T>` | Argument will extract `arg3` from request query. |\n\nIf `T` is `number`, example `Param<number>` - it will be parsed as a number automatically.\n\nIf `T` is `boolean`, example `Query<boolean>` - it will be parsed as a number automatically.\n\n## Response\n\nJust use `Response.json(body)` to return JSON object, or `new Response('text')`. See Bun documentation for more details.\n\n## Middleware\n\nCreate middleware by implementing `PreMiddleware` or `PostMiddleware` interface, or both.\n\n```ts\nexport class DebugMiddleware implements PreMiddleware, PostMiddleware {\n  preProcess(context: RequestContext): void | Promise<void> {\n    // Context provides access to request, logger, matched route\n  }\n\n  postProcess(context: RequestContext, response: Response): void | Promise<void> | Response | Promise<Response> {\n    // ...\n    // You can modify or create new response, if nothing is returned - default response will be used\n  }\n}\n```\n\n### Global\n\nIt will be applied to all routes in the app/router.\n\n```ts\nrouter.register(new DebugMiddleware());\n```\n\n### Module\n\nIt will be applied to all methods in the router file from which it is exported.\n\n```ts\nexport const middlewares = [new MyCustomMiddleware()];\n```\n\n### Local\n\nIt will be applied to specific method in the router file.\n\n```ts\nDELETE.middlewares = [new AllowFor([USER_ROLES.ADMIN])];\nexport async function DELETE(id: Param<number>, user: JSON<unknown>) {\n```\n","readmeFilename":"README.md"}