{"_id":"@bishop-and-co/dmvc","_rev":"7-e1803a440edbe4f430d2808ef8f10370","name":"@bishop-and-co/dmvc","dist-tags":{"latest":"0.1.6"},"versions":{"0.1.0":{"name":"@bishop-and-co/dmvc","version":"0.1.0","keywords":["hono","crud","dynamodb","electrodb"],"author":{"name":"Michael Bishop","email":"michael@bishopand.com"},"license":"ISC","_id":"@bishop-and-co/dmvc@0.1.0","maintainers":[{"name":"michaelbishop","email":"michael.bishop.stl@icloud.com"}],"homepage":"https://github.com/bishopandco/dmvc#readme","bugs":{"url":"https://github.com/bishopandco/dmvc/issues"},"dist":{"shasum":"c145fa37775655d5622f055f668ec869d1205fab","tarball":"https://registry.npmjs.org/@bishop-and-co/dmvc/-/dmvc-0.1.0.tgz","fileCount":12,"integrity":"sha512-xatD2ONPv6ELwEql/2GfuyYQueawPpZN9nLlfjNgTTCFu3UwoSEhJJS7h3z6c433fmLvNQUJ+75t45V8eLV6uQ==","signatures":[{"sig":"MEUCIQCPho5tMmyL09xju0Yf73PV+c34iKcCVZIkpR7FLXRIfwIgH6KEbjXBRQkI6W5jQZDZ+HKqoON0IFicuk//zmRBfFU=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":32018},"main":"dist/index.js","types":"dist/index.d.ts","gitHead":"7828008eb1911192270fbf68537f7a05e0235ceb","scripts":{"build":"tsc -p tsconfig.json","prepare":"npm run build"},"_npmUser":{"name":"michaelbishop","email":"michael.bishop.stl@icloud.com"},"repository":{"url":"git+https://github.com/bishopandco/dmvc.git","type":"git"},"_npmVersion":"10.5.0","description":"Minimal model/controller utilities for Hono-based REST APIs","directories":{"example":"examples"},"_nodeVersion":"21.7.1","dependencies":{"zod":"^3.24.2","electrodb":"^3.4.3","typescript":"^5.5.3","@types/node":"^20.14.2","@aws-sdk/lib-dynamodb":"^3.750.0","@aws-sdk/client-dynamodb":"^3.750.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"@types/node":"^20.14.2"},"peerDependencies":{"hono":"^4.8.12"},"_npmOperationalInternal":{"tmp":"tmp/dmvc_0.1.0_1755972367921_0.837378068655338","host":"s3://npm-registry-packages-npm-production"}},"0.1.1":{"name":"@bishop-and-co/dmvc","version":"0.1.1","keywords":["hono","crud","dynamodb","electrodb"],"author":{"name":"Michael Bishop","email":"michael@bishopand.com"},"license":"ISC","_id":"@bishop-and-co/dmvc@0.1.1","maintainers":[{"name":"michaelbishop","email":"michael.bishop.stl@icloud.com"}],"homepage":"https://github.com/bishopandco/dmvc#readme","bugs":{"url":"https://github.com/bishopandco/dmvc/issues"},"dist":{"shasum":"1bd7fa192dd294a8816dea2f9ccf23af468c02e2","tarball":"https://registry.npmjs.org/@bishop-and-co/dmvc/-/dmvc-0.1.1.tgz","fileCount":12,"integrity":"sha512-2p0+l/KWX2sHGvrbDRIIzEo73tpsqIWvCA7cZtqbh8x7LvRO+MlNHInvWf9k47odHpcuNUb/sXHC+s6DaUTAMg==","signatures":[{"sig":"MEYCIQD4O83w0MRLEtlqatY23+RpmKIKfREIznb3nx1dfEP1LAIhAP8alm6x29fAkY2c53z9Q98e2SLcTTxKGaPpe1noFw9i","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":32345},"main":"dist/index.js","types":"dist/index.d.ts","gitHead":"26688feaa9e5b558a64872182f80f0ee73964727","scripts":{"test":"vitest run --coverage","build":"tsc -p tsconfig.json","prepare":"npm run build"},"_npmUser":{"name":"michaelbishop","email":"michael.bishop.stl@icloud.com"},"repository":{"url":"git+https://github.com/bishopandco/dmvc.git","type":"git"},"_npmVersion":"10.8.2","description":"Minimal model/controller utilities for Hono-based REST APIs","directories":{"example":"examples"},"_nodeVersion":"20.19.4","dependencies":{"zod":"^3.24.2","electrodb":"^3.4.3","typescript":"^5.5.3","@types/node":"^20.14.2","@aws-sdk/lib-dynamodb":"^3.750.0","@aws-sdk/client-dynamodb":"^3.750.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"hono":"^4.8.12","vitest":"^1.6.0","@types/node":"^20.14.2","@vitest/coverage-v8":"^1.6.0"},"peerDependencies":{"hono":"^4.8.12"},"_npmOperationalInternal":{"tmp":"tmp/dmvc_0.1.1_1755978200695_0.385079542109789","host":"s3://npm-registry-packages-npm-production"}},"0.1.2":{"name":"@bishop-and-co/dmvc","version":"0.1.2","keywords":["hono","crud","dynamodb","electrodb"],"author":{"name":"Michael Bishop","email":"michael@bishopand.com"},"license":"ISC","_id":"@bishop-and-co/dmvc@0.1.2","maintainers":[{"name":"michaelbishop","email":"michael.bishop.stl@icloud.com"}],"homepage":"https://github.com/bishopandco/dmvc#readme","bugs":{"url":"https://github.com/bishopandco/dmvc/issues"},"bin":{"dmvc":"dist/generator.js"},"dist":{"shasum":"f68669af1f4d5786c13c73f3aa552a8a9c8a6c38","tarball":"https://registry.npmjs.org/@bishop-and-co/dmvc/-/dmvc-0.1.2.tgz","fileCount":14,"integrity":"sha512-3on5R49XrimWNWQQHwgqd7SmvMyJJmXJu2WlqFpXoAsdf4fQ7gdNUyloHMQ6m2OGW0DTXTPNP5F3xlU8UlCN0A==","signatures":[{"sig":"MEUCIQDVSQuSjsiTqoCkQ3LJ8XJOU6BNJhxmfvTctDDXfNmprwIgUDKFe7lGQ3/R9s6ECGZSt8Yxb76lW9ggNmpdNCKUpZQ=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":36464},"main":"dist/index.js","types":"dist/index.d.ts","gitHead":"72f1dd08b97c2e5a3a15c7abd6c249bbbe50230f","scripts":{"test":"vitest run --coverage","build":"tsc -p tsconfig.json","prepare":"npm run build"},"_npmUser":{"name":"michaelbishop","email":"michael.bishop.stl@icloud.com"},"repository":{"url":"git+https://github.com/bishopandco/dmvc.git","type":"git"},"_npmVersion":"10.8.2","description":"Minimal model/controller utilities for Hono-based REST APIs","directories":{"example":"examples"},"_nodeVersion":"20.19.4","dependencies":{"zod":"^3.24.2","electrodb":"^3.4.3","typescript":"^5.5.3","@types/node":"^20.14.2","@aws-sdk/lib-dynamodb":"^3.750.0","@aws-sdk/client-dynamodb":"^3.750.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"hono":"^4.8.12","vitest":"^1.6.0","@types/node":"^20.14.2","@vitest/coverage-v8":"^1.6.0"},"peerDependencies":{"hono":"^4.8.12"},"_npmOperationalInternal":{"tmp":"tmp/dmvc_0.1.2_1755980736555_0.10188031558275679","host":"s3://npm-registry-packages-npm-production"}},"0.1.3":{"name":"@bishop-and-co/dmvc","version":"0.1.3","keywords":["hono","crud","dynamodb","electrodb"],"author":{"name":"Michael Bishop","email":"michael@bishopand.com"},"license":"ISC","_id":"@bishop-and-co/dmvc@0.1.3","maintainers":[{"name":"michaelbishop","email":"michael.bishop.stl@icloud.com"}],"homepage":"https://github.com/bishopandco/dmvc#readme","bugs":{"url":"https://github.com/bishopandco/dmvc/issues"},"bin":{"dmvc":"dist/generator.js"},"dist":{"shasum":"b80d615b5a7d9d541b8d23271f149d93fdb8ddc6","tarball":"https://registry.npmjs.org/@bishop-and-co/dmvc/-/dmvc-0.1.3.tgz","fileCount":14,"integrity":"sha512-tfN/kvyh1Ha7CotGqpiZoZa6QzpNk72vXepG/wytwAWLQgIk7Sh7JPVBbORy0IO5d98giTtW4OetefYa2lilgQ==","signatures":[{"sig":"MEYCIQCZL/Mui2AoiyKaM4RjhSTOBmL9pM7lkw+nmiivwG+CIgIhAKi6rHCTkHDSwQlrK1S0HjvMEykjErs/UNfK/tcU1JK4","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":39060},"main":"dist/index.js","types":"dist/index.d.ts","gitHead":"9c14a7fecc236cba7d72c3f2ca58ef7c44d0059b","scripts":{"test":"vitest run --coverage","build":"tsc -p tsconfig.json","prepare":"npm run build"},"_npmUser":{"name":"michaelbishop","email":"michael.bishop.stl@icloud.com"},"repository":{"url":"git+https://github.com/bishopandco/dmvc.git","type":"git"},"_npmVersion":"10.8.2","description":"Minimal model/controller utilities for Hono-based REST APIs","directories":{"example":"examples"},"_nodeVersion":"20.19.4","dependencies":{"zod":"^3.24.2","electrodb":"^3.4.3","typescript":"^5.5.3","@types/node":"^20.14.2","readline-sync":"^1.4.10","@aws-sdk/lib-dynamodb":"^3.750.0","@aws-sdk/client-dynamodb":"^3.750.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"hono":"^4.8.12","vitest":"^1.6.0","@types/node":"^20.14.2","@vitest/coverage-v8":"^1.6.0"},"peerDependencies":{"hono":"^4.8.12"},"_npmOperationalInternal":{"tmp":"tmp/dmvc_0.1.3_1755988516007_0.9002978030385622","host":"s3://npm-registry-packages-npm-production"}},"0.1.4":{"name":"@bishop-and-co/dmvc","version":"0.1.4","keywords":["hono","crud","dynamodb","electrodb"],"author":{"name":"Michael Bishop","email":"michael@bishopand.com"},"license":"ISC","_id":"@bishop-and-co/dmvc@0.1.4","maintainers":[{"name":"michaelbishop","email":"michael.bishop.stl@icloud.com"}],"homepage":"https://github.com/bishopandco/dmvc#readme","bugs":{"url":"https://github.com/bishopandco/dmvc/issues"},"bin":{"dmvc":"dist/generator.js"},"dist":{"shasum":"ac7f61f4206cc19571711f8af8b7a939a74ea767","tarball":"https://registry.npmjs.org/@bishop-and-co/dmvc/-/dmvc-0.1.4.tgz","fileCount":14,"integrity":"sha512-EVU58aQNkPhDsBng/ZsfXdhxFI9oLjbPd85+nvLSMwhsYigch0uUH6+3/Y6nK4+LpaM97KWZsHeXUtyeCTmTOw==","signatures":[{"sig":"MEUCIDLra3+qrCy570I7GO8orcczJJPJMXOxeIPyfl+G1dbiAiEAsru3NlhHdsRSHggL2qMQw3ttgPW39QRc3yMhp7kQWqA=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":39503},"main":"dist/index.js","types":"dist/index.d.ts","gitHead":"bc7f4413e81a97dfbc4af8897a46d0edb4fa910d","scripts":{"test":"vitest run --coverage","build":"tsc -p tsconfig.json","prepare":"npm run build"},"_npmUser":{"name":"michaelbishop","email":"michael.bishop.stl@icloud.com"},"repository":{"url":"git+https://github.com/bishopandco/dmvc.git","type":"git"},"_npmVersion":"10.8.2","description":"Minimal model/controller utilities for Hono-based REST APIs","directories":{"example":"examples"},"_nodeVersion":"20.19.4","dependencies":{"zod":"^3.24.2","electrodb":"^3.4.3","typescript":"^5.5.3","@types/node":"^20.14.2","readline-sync":"^1.4.10","@aws-sdk/lib-dynamodb":"^3.750.0","@aws-sdk/client-dynamodb":"^3.750.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"hono":"^4.8.12","vitest":"^1.6.0","@types/node":"^20.14.2","@vitest/coverage-v8":"^1.6.0"},"peerDependencies":{"hono":"^4.8.12"},"_npmOperationalInternal":{"tmp":"tmp/dmvc_0.1.4_1755992144319_0.6211228487413014","host":"s3://npm-registry-packages-npm-production"}},"0.1.5":{"name":"@bishop-and-co/dmvc","version":"0.1.5","keywords":["hono","crud","dynamodb","electrodb"],"author":{"name":"Michael Bishop","email":"michael@bishopand.com"},"license":"ISC","_id":"@bishop-and-co/dmvc@0.1.5","maintainers":[{"name":"michaelbishop","email":"michael.bishop.stl@icloud.com"}],"homepage":"https://github.com/bishopandco/dmvc#readme","bugs":{"url":"https://github.com/bishopandco/dmvc/issues"},"bin":{"dmvc":"dist/generator.js"},"dist":{"shasum":"3b4fabded433002cee7beb6a62eaf2fb44b59846","tarball":"https://registry.npmjs.org/@bishop-and-co/dmvc/-/dmvc-0.1.5.tgz","fileCount":14,"integrity":"sha512-Q+yQ2amzQdwEmoJXoEvqROhSQMsqBla45Nsgx35RYRo360MKaPX7pmqDlZkoyI66d6LqObIH6NCUexG6xGkpdw==","signatures":[{"sig":"MEQCIALhbxpk7L3O7VDpZdrT1xkxW227ZKmKZz12ExcYjT87AiBLgj+01huSeLgk1rFyy/ydeDpMAmVwwoxYD8olCPb1Hg==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":39629},"main":"dist/index.js","types":"dist/index.d.ts","gitHead":"c8ad4761c7b92a67b29975511f79595780f4227a","scripts":{"test":"vitest run --coverage","build":"tsc -p tsconfig.json","prepare":"npm run build"},"_npmUser":{"name":"michaelbishop","email":"michael.bishop.stl@icloud.com"},"repository":{"url":"git+https://github.com/bishopandco/dmvc.git","type":"git"},"_npmVersion":"10.8.2","description":"Minimal model/controller utilities for Hono-based REST APIs","directories":{"example":"examples"},"_nodeVersion":"20.19.4","dependencies":{"zod":"^3.24.2","electrodb":"^3.4.3","typescript":"^5.5.3","@types/node":"^20.14.2","readline-sync":"^1.4.10","@aws-sdk/lib-dynamodb":"^3.750.0","@aws-sdk/client-dynamodb":"^3.750.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"hono":"^4.8.12","vitest":"^1.6.0","@types/node":"^20.14.2","@vitest/coverage-v8":"^1.6.0"},"peerDependencies":{"hono":"^4.8.12"},"_npmOperationalInternal":{"tmp":"tmp/dmvc_0.1.5_1756176975636_0.3594423447387296","host":"s3://npm-registry-packages-npm-production"}},"0.1.6":{"name":"@bishop-and-co/dmvc","version":"0.1.6","description":"Minimal model/controller utilities for Hono-based REST APIs","license":"ISC","main":"dist/index.js","types":"dist/index.d.ts","scripts":{"build":"tsc -p tsconfig.json","prepare":"npm run build","test":"vitest run --coverage"},"publishConfig":{"access":"public"},"peerDependencies":{"fastify":"^4.28.1","hono":"^4.8.12"},"peerDependenciesMeta":{"fastify":{"optional":true},"hono":{"optional":true}},"devDependencies":{"@types/node":"^20.14.2","@types/readline-sync":"^1.4.8","@vitest/coverage-v8":"^3.2.4","fastify":"^4.28.1","hono":"^4.8.12","vitest":"^3.2.4"},"dependencies":{"@aws-sdk/client-dynamodb":"^3.980.0","@aws-sdk/lib-dynamodb":"^3.980.0","@types/node":"^20.14.2","electrodb":"^3.4.3","readline-sync":"^1.4.10","typescript":"^5.5.3","zod":"^3.24.2"},"overrides":{"fast-xml-parser":"^5.3.4"},"directories":{"example":"examples"},"repository":{"type":"git","url":"git+https://github.com/bishopandco/dmvc.git"},"keywords":["hono","crud","dynamodb","electrodb"],"author":{"name":"Michael Bishop","email":"michael@bishopand.com"},"bugs":{"url":"https://github.com/bishopandco/dmvc/issues"},"homepage":"https://github.com/bishopandco/dmvc#readme","bin":{"dmvc":"dist/generator.js"},"_id":"@bishop-and-co/dmvc@0.1.6","gitHead":"0fe8e88fd354fcca552903e070991a7ebf9e9500","_nodeVersion":"20.20.0","_npmVersion":"10.8.2","dist":{"integrity":"sha512-Nkn93OXqEzYfnKuEOpgZCcSZhMrlxq4wrX45Asff0SSzuekK+P7jB32h5Frb7ApVMts8XAxxAKJWJP+2GKCO5g==","shasum":"df2d7cf272422e569866ef0e78a0184da4920c3a","tarball":"https://registry.npmjs.org/@bishop-and-co/dmvc/-/dmvc-0.1.6.tgz","fileCount":14,"unpackedSize":47971,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIGYXBXZ7LR8DI413goPqF1LtjEb3Bipd+KTIapkxQqyoAiEAyY/gj7IZ/SkMZKHASq67a0O2wZHgVKlqfq0r2Q5wdNY="}]},"_npmUser":{"name":"michaelbishop","email":"michael.bishop.stl@icloud.com"},"maintainers":[{"name":"michaelbishop","email":"michael.bishop.stl@icloud.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/dmvc_0.1.6_1769897049733_0.5979560985185755"},"_hasShrinkwrap":false}},"time":{"created":"2025-08-23T18:06:07.408Z","modified":"2026-01-31T22:04:10.008Z","0.1.0":"2025-08-23T18:06:08.193Z","0.1.1":"2025-08-23T19:43:20.859Z","0.1.2":"2025-08-23T20:25:36.787Z","0.1.3":"2025-08-23T22:35:16.245Z","0.1.4":"2025-08-23T23:35:44.503Z","0.1.5":"2025-08-26T02:56:15.804Z","0.1.6":"2026-01-31T22:04:09.886Z"},"bugs":{"url":"https://github.com/bishopandco/dmvc/issues"},"author":{"name":"Michael Bishop","email":"michael@bishopand.com"},"license":"ISC","homepage":"https://github.com/bishopandco/dmvc#readme","keywords":["hono","crud","dynamodb","electrodb"],"repository":{"type":"git","url":"git+https://github.com/bishopandco/dmvc.git"},"description":"Minimal model/controller utilities for Hono-based REST APIs","maintainers":[{"name":"michaelbishop","email":"michael.bishop.stl@icloud.com"}],"readme":"```terminaloutput\n██████╗   ███╗   ███╗ ██╗     ██╗  ██████╗ \n██╔══██╗  ████╗ ████║ ██║     ██║ ██╔════╝ \n██║  ██║  ██╔████╔██║ ██║     ██║ ██║           \n██║  ██║  ██║╚██╔╝██║ ╚██╗   ██╔╝ ██║           \n██████╔╝  ██║ ╚═╝ ██║  ╚██████╔╝  ╚██████╗ \n╚═════╝   ╚═╝     ╚═╝   ╚═════╝    ╚═════╝ \n```\n\n# dmvc\n\n[![Tests](https://github.com/bishopandco/dmvc/actions/workflows/tests.yml/badge.svg)](https://github.com/bishopandco/dmvc/actions/workflows/tests.yml)\n\ndmvc provides a minimal model/controller layer for building REST APIs on top of [Hono](https://hono.dev). It pairs [ElectroDB](https://github.com/tywalch/electrodb) for DynamoDB access with [Zod](https://zod.dev) schemas and exposes helpers to quickly register CRUD routes.\n\nInstall via `npm i @bishop-and-co/dmvc`. Source code is available on [GitHub](https://github.com/bishopandco/dmvc).\n\n## Installation\n\n`hono` is a peer dependency and must be installed in your application along with DMVC's runtime dependencies:\n\n```bash\nnpm install @bishop-and-co/dmvc hono zod electrodb @aws-sdk/client-dynamodb @aws-sdk/lib-dynamodb\n```\n\n## Defining a model\n\nCreate a model by extending `BaseModel`. ElectroDB conventions use the model name itself as the identifier attribute, so avoid generic `id` or `modelId` fields. The model wires up a Zod schema and ElectroDB entity:\n\n```ts\nimport { BaseModel } from \"@bishop-and-co/dmvc\";\nimport { Entity } from \"electrodb\";\nimport { z } from \"zod\";\n\nconst UserSchema = z.object({\n  user: z.string(), // model id\n  name: z.string().optional(),\n});\n\nexport class UserModel extends BaseModel<typeof UserSchema> {\n  constructor(client: any, table: string) {\n    super(client, table);\n    this.schema = UserSchema;\n    this.keySchema = UserSchema.pick({ user: true });\n    this.entity = new Entity(\n      {\n        model: { entity: \"User\", version: \"1\", service: \"app\" },\n        attributes: { user: { type: \"string\", required: true }, name: { type: \"string\" } },\n        indexes: { primary: { pk: { field: \"pk\", composite: [\"user\"] } } },\n      },\n      { client, table }\n    );\n  }\n}\n```\n\nConfigure the DynamoDB connection once during startup:\n\n```ts\nimport { DynamoDBClient } from \"@aws-sdk/client-dynamodb\";\nimport { DynamoDBDocumentClient } from \"@aws-sdk/lib-dynamodb\";\nimport { BaseModel } from \"@bishop-and-co/dmvc\";\n\nconst raw = new DynamoDBClient({ region: \"us-east-1\" });\nconst client = DynamoDBDocumentClient.from(raw);\nBaseModel.configure({ client, table: process.env.DYNAMODB_TABLE_NAME! });\n```\n\n## Registering routes\n\nUse `BaseController.register` to expose CRUD endpoints for the model:\n\n```ts\nimport { Hono } from \"hono\";\nimport { BaseController, requireAuth } from \"@bishop-and-co/dmvc\";\nimport { UserModel } from \"./UserModel\";\n\nconst app = new Hono();\n\nBaseController.register(app, {\n  model: UserModel,\n  basePath: \"/users\",\n});\n\nexport default app;\n```\n\nYou can optionally supply per-operation `roles`, a custom `authCheckFn`, or `pageSize` in the options.\n\n## Authentication\n\n`dmvc` expects an authenticated user to be attached to the `Hono` context as `c.set(\"user\", ...)`.  \nRoutes registered through `BaseController` automatically use the `requireAuth` middleware which checks the user's role, supports a custom checker, and honours the `SKIP_AUTH` environment flag and the special `anonymous` role.\n\n```ts\nimport { Hono } from \"hono\";\nimport { BaseController, requireAuth } from \"@bishop-and-co/dmvc\";\nimport { UserModel } from \"./UserModel\";\n\nconst app = new Hono();\n\n// attach a user from your auth system (JWT, session, etc.)\napp.use(\"*\", async (c, next) => {\n  const token = c.req.header(\"Authorization\");\n  if (token) {\n    // decode token and set the user on the context\n    c.set(\"user\", { user: \"u123\", role: \"admin\" });\n  }\n  await next();\n});\n\n// optional custom authorization function\nconst authCheckFn = async (user: any, allowed: string[]) => {\n  if (user.role === \"admin\") return true; // admins always allowed\n  return allowed.includes(user.role);\n};\n\nBaseController.register(app, {\n  model: UserModel,\n  basePath: \"/users\",\n  roles: {\n    list: [\"anonymous\"],   // public route\n    get: [\"user\", \"admin\"],\n    create: [\"admin\"],\n    update: [\"admin\"],\n    delete: [\"admin\"],\n  },\n  authCheckFn,\n});\n\napp.get(\n  \"/reports\",\n  requireAuth([\"admin\"], authCheckFn),\n  (c) => c.text(\"secret\")\n);\n```\n\nSet `SKIP_AUTH=true` in the environment to bypass all checks during local development.\n\n## Hooks\n\n`BaseModel` supports lifecycle hooks via decorators:\n\n```ts\nimport { BeforeCreate, AfterDelete } from \"@bishop-and-co/dmvc\";\n\nclass UserModel extends BaseModel<typeof UserSchema> {\n  @BeforeCreate\n  async setDefaults(data: any) {\n    data.createdAt = new Date().toISOString();\n  }\n\n  @AfterDelete\n  async logDeletion(deleted: any) {\n    console.log(\"deleted\", deleted);\n  }\n}\n```\n\nThese hooks run automatically around the respective operations.\n\n## Generator\n\ndmvc ships with a tiny CLI that scaffolds boilerplate models and controllers for you.\n\n```bash\nnpx dmvc generate model widget\n# => creates src/models/Widget.ts\n\nnpx dmvc generate controller widget\n# => creates src/controllers/WidgetController.ts\n```\n\nThe generator creates the `src/models` and `src/controllers` directories if they do not exist and refuses to overwrite existing files.\nEdit the generated files to flesh out schemas, attributes, and any custom logic for your application.\n\nOn first run, the generator asks where to place models and controllers and writes a `dmvc.config.ts` file with your answers. You can adjust this file later:\n\n```ts\nexport default {\n  modelFolder: 'app/models',\n  controllerFolder: 'app/controllers',\n};\n```\n\nThe generator will respect these paths when creating new files.\n\n## Example\n\nA minimal todo application built with dmvc lives in [examples/todo](./examples/todo). It defines a todo model and registers CRUD routes with Hono. The example's `package.json` also exposes scripts to create, read, update, and destroy todos, and includes a `docker-compose.yml` for spinning up a local DynamoDB instance. See its [README](examples/todo/README.md) for setup instructions.\n\n---\n\ndmvc aims to stay minimal. See the source for additional helpers like `requireAuth` and `QueryService`.\n","readmeFilename":"README.md"}