{"_id":"@edgefirst-dev/crud-routes","_rev":"3-69c80bca0080c76f738107be349f6ac3","name":"@edgefirst-dev/crud-routes","dist-tags":{"latest":"1.0.0"},"versions":{"0.0.2":{"name":"@edgefirst-dev/crud-routes","version":"0.0.2","author":{"url":"https://sergiodxa.com","name":"Sergio Xalambrí","email":"hello+oss@sergiodxa.com"},"license":"MIT","_id":"@edgefirst-dev/crud-routes@0.0.2","maintainers":[{"name":"sergiodxa","email":"hello@sergiodxa.com"}],"homepage":"https://edgefirst-dev.github.io/crud-routes","bugs":{"url":"https://github.com/edgefirst-dev/crud-routes/issues"},"dist":{"shasum":"aa98683ccd739a90c77cb4daa125a505f288b976","tarball":"https://registry.npmjs.org/@edgefirst-dev/crud-routes/-/crud-routes-0.0.2.tgz","fileCount":9,"integrity":"sha512-JRsh9isy5Wv6pg/Eu17fHL8b+5TrQeVVd/Bmtz+CFbPs2FOwLn9EXXqxjvBQS3gsjdraH6TXz9r7JFtIMvabQg==","signatures":[{"sig":"MEQCIAg2arMIU22o4ZOrw4J2zxaC3mzcRDi8a4Xh2GaXWotyAiAwBvp8gMliX0b9AOHBQOOFGGHisNBCFPCmh1d36aZ2Fw==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":22064},"type":"module","engines":{"node":">=20.0.0"},"exports":{".":"./build/index.js","./package.json":"./package.json"},"funding":["https://github.com/sponsors/sergiodxa"],"gitHead":"0fbd3d9bb218af30a1b4359ac125823aacdf47b9","scripts":{"build":"tsc","exports":"bun run ./scripts/exports.ts","quality":"biome check .","typecheck":"tsc --noEmit","quality:fix":"biome check . --write --unsafe"},"_npmUser":{"name":"sergiodxa","email":"hello@sergiodxa.com"},"repository":{"url":"git+https://github.com/edgefirst-dev/crud-routes.git","type":"git"},"_npmVersion":"10.9.2","description":"A helper to define CRUD routes in a React Router application using `routes.ts`.","directories":{},"sideEffects":false,"_nodeVersion":"22.14.0","dependencies":{"inflected":"^2.1.0","@react-router/dev":"^7.3.0","@ryanflorence/async-provider":"^0.0.1"},"_hasShrinkwrap":false,"devDependencies":{"consola":"^3.4.0","typedoc":"^0.27.9","@types/bun":"^1.2.5","typescript":"^5.8.2","@biomejs/biome":"^1.9.4","@types/inflected":"^2.1.3","@arethetypeswrong/cli":"^0.17.4","typedoc-plugin-mdn-links":"^5.0.1","@total-typescript/tsconfig":"^1.0.4"},"peerDependencies":{},"_npmOperationalInternal":{"tmp":"tmp/crud-routes_0.0.2_1742020212700_0.5166789817826043","host":"s3://npm-registry-packages-npm-production"}},"0.0.3":{"name":"@edgefirst-dev/crud-routes","version":"0.0.3","author":{"url":"https://sergiodxa.com","name":"Sergio Xalambrí","email":"hello+oss@sergiodxa.com"},"license":"MIT","_id":"@edgefirst-dev/crud-routes@0.0.3","maintainers":[{"name":"sergiodxa","email":"hello@sergiodxa.com"}],"homepage":"https://edgefirst-dev.github.io/crud-routes","bugs":{"url":"https://github.com/edgefirst-dev/crud-routes/issues"},"dist":{"shasum":"e300bf73ea0be8c49a6c08adde9ed35509ee2380","tarball":"https://registry.npmjs.org/@edgefirst-dev/crud-routes/-/crud-routes-0.0.3.tgz","fileCount":9,"integrity":"sha512-0lZORC3qr8IkU/jGcud9Mq7XUWiImjKPapxJozpwg5DHPvGHMZY1VrYClM2klhDOZPOW6CUE7ifn9fBVw8qGdQ==","signatures":[{"sig":"MEUCIHLOdwTYJEpKzBC0fPMZkimozhK4eL2mnzrGXxd7Ub10AiEA1iknfwJNObxuDX/BNhOAipdFdLoYJ4+LHtXMjv/u5wA=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":22136},"type":"module","engines":{"node":">=20.0.0"},"exports":{".":"./build/index.js","./package.json":"./package.json"},"funding":["https://github.com/sponsors/sergiodxa"],"gitHead":"6c5a7cb23a3deb28fbba93e163d4716248450683","scripts":{"build":"tsc","exports":"bun run ./scripts/exports.ts","quality":"biome check .","typecheck":"tsc --noEmit","quality:fix":"biome check . --write --unsafe"},"_npmUser":{"name":"sergiodxa","email":"hello@sergiodxa.com"},"repository":{"url":"git+https://github.com/edgefirst-dev/crud-routes.git","type":"git"},"_npmVersion":"10.9.2","description":"A helper to define CRUD routes in a React Router application using `routes.ts`.","directories":{},"sideEffects":false,"_nodeVersion":"22.14.0","dependencies":{"inflected":"^2.1.0","@react-router/dev":"^7.3.0","@ryanflorence/async-provider":"^0.0.1"},"_hasShrinkwrap":false,"devDependencies":{"consola":"^3.4.0","typedoc":"^0.27.9","@types/bun":"^1.2.5","typescript":"^5.8.2","@biomejs/biome":"^1.9.4","@types/inflected":"^2.1.3","@arethetypeswrong/cli":"^0.17.4","typedoc-plugin-mdn-links":"^5.0.1","@total-typescript/tsconfig":"^1.0.4"},"peerDependencies":{},"_npmOperationalInternal":{"tmp":"tmp/crud-routes_0.0.3_1742055132565_0.15514333234989852","host":"s3://npm-registry-packages-npm-production"}},"1.0.0":{"name":"@edgefirst-dev/crud-routes","version":"1.0.0","description":"A helper to define CRUD routes in a React Router application using `routes.ts`.","license":"MIT","funding":["https://github.com/sponsors/sergiodxa"],"author":{"name":"Sergio Xalambrí","email":"hello+oss@sergiodxa.com","url":"https://sergiodxa.com"},"repository":{"type":"git","url":"git+https://github.com/edgefirst-dev/crud-routes.git"},"homepage":"https://edgefirst-dev.github.io/crud-routes","bugs":{"url":"https://github.com/edgefirst-dev/crud-routes/issues"},"scripts":{"build":"tsc","typecheck":"tsc --noEmit","quality":"biome check .","quality:fix":"biome check . --write --unsafe","exports":"bun run ./scripts/exports.ts"},"sideEffects":false,"type":"module","engines":{"node":">=20.0.0"},"exports":{".":"./build/index.js","./package.json":"./package.json"},"dependencies":{"@react-router/dev":"^7.3.0","inflected":"^2.1.0"},"peerDependencies":{},"devDependencies":{"@arethetypeswrong/cli":"^0.17.4","@biomejs/biome":"^1.9.4","@total-typescript/tsconfig":"^1.0.4","@types/bun":"^1.2.5","@types/inflected":"^2.1.3","consola":"^3.4.0","typedoc":"^0.27.9","typedoc-plugin-mdn-links":"^5.0.1","typescript":"^5.8.2"},"_id":"@edgefirst-dev/crud-routes@1.0.0","gitHead":"fa4eec6330e0689339b389a74b5883ac4a689919","_nodeVersion":"22.14.0","_npmVersion":"10.9.2","dist":{"integrity":"sha512-9KhqLDfGDgo2Y+ccmytOBnAJeJJVZz4TS5Qncr4+SkIaiPLztTksMk1R4kkuLyrt/ju19tQIn5Q3R3GTvK+Stg==","shasum":"38d4826bfc0fac37bc6885d51034431f76026721","tarball":"https://registry.npmjs.org/@edgefirst-dev/crud-routes/-/crud-routes-1.0.0.tgz","fileCount":9,"unpackedSize":28151,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIQCZXdcYrJT8KLti3gDgziGnx5B4Ae9N1fE/lGPSsHwwfAIgaZUqqUuC/2xA/ArAMlS/tgSzBeYcqEjNdhwI+SnX3L8="}]},"_npmUser":{"name":"sergiodxa","email":"hello@sergiodxa.com"},"directories":{},"maintainers":[{"name":"sergiodxa","email":"hello@sergiodxa.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/crud-routes_1.0.0_1742105099345_0.7358999245397781"},"_hasShrinkwrap":false}},"time":{"created":"2025-03-15T06:30:12.634Z","modified":"2025-03-16T06:04:59.727Z","0.0.2":"2025-03-15T06:30:12.897Z","0.0.3":"2025-03-15T16:12:12.755Z","1.0.0":"2025-03-16T06:04:59.530Z"},"bugs":{"url":"https://github.com/edgefirst-dev/crud-routes/issues"},"author":{"name":"Sergio Xalambrí","email":"hello+oss@sergiodxa.com","url":"https://sergiodxa.com"},"license":"MIT","homepage":"https://edgefirst-dev.github.io/crud-routes","repository":{"type":"git","url":"git+https://github.com/edgefirst-dev/crud-routes.git"},"description":"A helper to define CRUD routes in a React Router application using `routes.ts`.","maintainers":[{"name":"sergiodxa","email":"hello@sergiodxa.com"}],"readme":"# React Router CRUD Helper\n\nA helper to define CRUD routes in a React Router application using `routes.ts`.\n\nInspired by [Rails](https://guides.rubyonrails.org/routing.html#resource-routing-the-rails-default) resource routing.\n\n## Installation\n\n```bash\nbun add @edgefirst-dev/crud-routes\n```\n\n## Usage\n\nImport the `crud` helper in your `app/routes.ts` file.\n\n```ts\nimport { crud } from \"@edgefirst-dev/crud-routes\";\n```\n\nThen you can use to to define routes in the exported array.\n\n```ts\nexport default [...crud(\"users\")] satisfies RouteConfig;\n```\n\nThis will generate the following routes:\n\n| Path                   | File                        | ID            | Used to                       |\n| ---------------------- | --------------------------- | ------------- | ----------------------------- |\n| -                      | `./views/users/_layout.tsx` | users.layout  | Layout of every users route   |\n| /users                 | `./views/users/index.tsx`   | users.index   | Display a list of all users   |\n| /users/new             | `./views/users/new.tsx`     | users.new     | Form to create a new user     |\n| /users/:userId         | `./views/users/show.tsx`    | users.show    | Display the details of a user |\n| /users/:userId/edit    | `./views/users/edit.tsx`    | users.edit    | Form to edit a user           |\n| /users/:userId/destroy | `./views/users/destroy.tsx` | users.destroy | Action to delete a user       |\n\n### Custom ID Prefix\n\nYou can also define a custom ID prefix for the generated routes.\n\n```ts\nexport default [...crud(\"users\", { idPrefix: \"admin\" })] satisfies RouteConfig;\n```\n\nThis will generate the following routes:\n\n| Path                   | File                        | ID            | Used to                       |\n| ---------------------- | --------------------------- | ------------- | ----------------------------- |\n| -                      | `./views/users/_layout.tsx` | admin.layout  | Layout of every users route   |\n| /users                 | `./views/users/index.tsx`   | admin.index   | Display a list of all users   |\n| /users/new             | `./views/users/new.tsx`     | admin.new     | Form to create a new user     |\n| /users/:userId         | `./views/users/show.tsx`    | admin.show    | Display the details of a user |\n| /users/:userId/edit    | `./views/users/edit.tsx`    | admin.edit    | Form to edit a user           |\n| /users/:userId/destroy | `./views/users/destroy.tsx` | admin.destroy | Action to delete a user       |\n\n### Nested Routes\n\nYou can also define nested routes using the React Router built-in helpers.\n\n```ts\nimport { crud } from \"@edgefirst-dev/crud-routes\";\nimport { route } from \"@react-router/dev/routes\";\n\nexport default [\n  ...crud(\"users\", () => [\n    // /users/profile\n    route(\"profile\", \"./views/users/profile.tsx\", { id: \"users.profile\" }),\n  ]),\n] satisfies RouteConfig;\n```\n\nThis will generate the following routes:\n\n| Path                   | File                        | ID            | Used to                       |\n| ---------------------- | --------------------------- | ------------- | ----------------------------- |\n| -                      | `./views/users/_layout.tsx` | users.layout  | Layout of every users route   |\n| /users                 | `./views/users/index.tsx`   | users.index   | Display a list of all users   |\n| /users/new             | `./views/users/new.tsx`     | users.new     | Form to create a new user     |\n| /users/:userId         | `./views/users/show.tsx`    | users.show    | Display the details of a user |\n| /users/:userId/edit    | `./views/users/edit.tsx`    | users.edit    | Form to edit a user           |\n| /users/:userId/destroy | `./views/users/destroy.tsx` | users.destroy | Action to delete a user       |\n| /users/profile         | `./views/users/profile.tsx` | users.profile | Display the profile of a user |\n\nThe nested route will be added to the layout of the CRUD.\n\n#### Member Routes\n\nA member route is a route attached to a specific resource. For example, in the resource `users` a member can be nested inside `/users/:userId`.\n\n```ts\nimport { crud, route } from \"@edgefirst-dev/crud-routes\";\n\nexport default [\n  ...crud(\"users\", () => [\n    route(\"profile\", \"./views/users/profile.tsx\", {\n      id: \"users.profile\",\n      on: \"member\",\n    }),\n  ]),\n] satisfies RouteConfig;\n```\n\nHere we're using the `route` helper exported by this package to define a new route. The `on` option is used to define the type of route. In this case, it's a `member` route.\n\nA member route could also be another CRUD\n\n```ts\nimport { crud } from \"@edgefirst-dev/crud-routes\";\n\nexport default [\n  ...crud(\"users\", () => [\n    ...crud(\"posts\", { on: \"member\" }), // /users/:userId/posts and other CRUD routes\n  ]),\n] satisfies RouteConfig;\n```\n\n#### Collection Routes\n\nA collection route is a route attached to a specific resource. For example, in the resource `users` a collection can be nested inside `/users`.\n\n```ts\nimport { crud, route } from \"@edgefirst-dev/crud-routes\";\n\nexport default [\n  ...crud(\"users\", () => [\n    route(\"profile\", \"./views/users/profile.tsx\", {\n      id: \"users.profile\",\n      on: \"member\",\n    }),\n  ]),\n] satisfies RouteConfig;\n```\n\nHere we're using the `route` helper exported by this package to define a new route. The `on` option is used to define the type of route. In this case, it's a `collection` route.\n\nA collection route could also be another CRUD\n\n```ts\nimport { crud } from \"@edgefirst-dev/crud-routes\";\n\nexport default [\n  ...crud(\"users\", () => [\n    ...crud(\"posts\", { on: \"collection\" }), // /users/posts and other CRUD routes\n  ]),\n] satisfies RouteConfig;\n```\n\n#### Shallow Routes\n\nShallow routes allows you to nest a resource inside another resource, but limiting it to only the `index` and `new` routes. While the `show`, `edit`, and `destroy` routes are not nested, and with the same layout for both nested and non-nested routes.\n\n```ts\nimport { crud } from \"@edgefirst-dev/crud-routes\";\n\nexport default [\n  ...crud(\"users\", () => [...crud(\"posts\", { on: \"shallow\" })]),\n] satisfies RouteConfig;\n```\n\nThis will generate the following routes:\n\n| Path                     | File                        | ID              | Used to                       |\n| ------------------------ | --------------------------- | --------------- | ----------------------------- |\n| -                        | `./views/users/_layout.tsx` | users.layout    | Layout of every users route   |\n| /users                   | `./views/users/index.tsx`   | users.index     | Display a list of all users   |\n| /users/new               | `./views/users/new.tsx`     | users.new       | Form to create a new user     |\n| /users/:userId           | `./views/users/show.tsx`    | users.show      | Display the details of a user |\n| /users/:userId/edit      | `./views/users/edit.tsx`    | users.edit      | Form to edit a user           |\n| /users/:userId/destroy   | `./views/users/destroy.tsx` | users.destroy   | Action to delete a user       |\n| /users/:userId/posts     | `./views/posts/index.tsx`   | users.posts     | Display a list of all posts   |\n| /users/:userId/posts/new | `./views/posts/new.tsx`     | users.posts.new | Form to create a new post     |\n| /posts/:postId           | `./views/posts/show.tsx`    | posts.show      | Display the details of a post |\n| /posts/:postId/edit      | `./views/posts/edit.tsx`    | posts.edit      | Form to edit a post           |\n| /posts/:postId/destroy   | `./views/posts/destroy.tsx` | posts.destroy   | Action to delete a post       |\n\nNote that shallow routes will not include a layout for the nested resource. This is because the layout is shared with the parent resource.\n\n## Author\n\n- [Sergio Xalambrí](https://sergiodxa.com)\n","readmeFilename":"README.md"}