{"_id":"@antislop/zero-lucid-generator","_rev":"4-4b819ab7a7121ab9ae07f015c210b104","name":"@antislop/zero-lucid-generator","dist-tags":{"latest":"1.1.1"},"versions":{"1.0.0":{"name":"@antislop/zero-lucid-generator","version":"1.0.0","keywords":["zero","lucid","adonisjs","schema","generator","rocicorp"],"author":{"name":"antislop"},"license":"ISC","_id":"@antislop/zero-lucid-generator@1.0.0","maintainers":[{"name":"udeshya-dhungana","email":"eddie@codecrafters.io"},{"name":"rohitpaulk","email":"rohitpaulk@gmail.com"}],"bin":{"lucid-zero":"dist/index.js"},"dist":{"shasum":"62a61cb4f8b60f30736c290e21c92cb47fd8134d","tarball":"https://registry.npmjs.org/@antislop/zero-lucid-generator/-/zero-lucid-generator-1.0.0.tgz","fileCount":4,"integrity":"sha512-th94zqS3sTifvKkCJvM8HNJsLG1ni0njOu51Ub71UfC/AlnF3McoUh13fQatbc8ZVtGALdHQEg9L6VqWXGZxJQ==","signatures":[{"sig":"MEQCIGbPfUZgGF4aVRsTbHBSpITthla1tn3CkiPo9v+aeafJAiBBZN9dIVXUEImJ+MY8FmiK3G39KnOzcP2xPILYapc+mQ==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":26969},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"}},"gitHead":"b38411a4662f34e6bef252f726235e2812e24681","scripts":{"lint":"eslint src tests","test":"vitest run --typecheck --coverage","build":"rm -rf dist && npx tsx build.ts && chmod +x dist/index.js","format":"prettier --write \"src/**/*.ts\" \"tests/**/*.ts\"","lint:fix":"eslint src tests --fix","check-types":"tsc --noEmit","format:check":"prettier --check \"src/**/*.ts\" \"tests/**/*.ts\""},"_npmUser":{"name":"udeshya-dhungana","email":"eddie@codecrafters.io"},"_npmVersion":"11.13.0","description":"Generate Zero schemas from Lucid ORM models","directories":{},"_nodeVersion":"24.16.0","dependencies":{"tsx":"^4.22.4","ts-morph":"^28.0.0","commander":"^15.0.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"packageManager":"npm@11.12.1","devDependencies":{"tsx":"^4.22.4","tsup":"^8.5.1","eslint":"^10.4.1","vitest":"^4.1.8","prettier":"^3.8.4","typescript":"^6.0.3","@types/node":"^25.9.2","@adonisjs/lucid":"^22.4.2","@vitest/coverage-v8":"^4.1.8","eslint-config-prettier":"^10.1.8","@typescript-eslint/parser":"^8.61.0","@typescript-eslint/eslint-plugin":"^8.61.0"},"peerDependencies":{"@adonisjs/lucid":">=21.0.0"},"_npmOperationalInternal":{"tmp":"tmp/zero-lucid-generator_1.0.0_1781084228685_0.37313330371580333","host":"s3://npm-registry-packages-npm-production"}},"1.1.0":{"name":"@antislop/zero-lucid-generator","version":"1.1.0","keywords":["zero","lucid","adonisjs","schema","generator","rocicorp"],"author":{"name":"antislop"},"license":"ISC","_id":"@antislop/zero-lucid-generator@1.1.0","maintainers":[{"name":"udeshya-dhungana","email":"eddie@codecrafters.io"},{"name":"rohitpaulk","email":"rohitpaulk@gmail.com"}],"bin":{"lucid-zero":"dist/index.js"},"dist":{"shasum":"13dff255dd7590aba5ed16a970a603ce965fbd1c","tarball":"https://registry.npmjs.org/@antislop/zero-lucid-generator/-/zero-lucid-generator-1.1.0.tgz","fileCount":4,"integrity":"sha512-mHxWWdl6azVnlzcvQtsCBKzO5ApZthTuMyMKvB2Sg7SDbMYVCNk6Z+F7UdKlOSOWZbDNU/nb8+bB5dPOEZZEtw==","signatures":[{"sig":"MEQCICnm8lgYcOdcYSCMmOURikc7lC1z3S8QBg1rkcu+aty6AiBw/gfg5FrKqEorwYrIIUAgKViIYHpvdvDeMVEvdNgPbw==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":27688},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"}},"gitHead":"b2cd147a0633db67f618e4fc5d9d7b30f628b8fd","scripts":{"lint":"eslint src tests","test":"vitest run --typecheck --coverage","build":"rm -rf dist && npx tsx build.ts && chmod +x dist/index.js","format":"oxfmt \"src/**/*.ts\" \"tests/**/*.ts\"","lint:fix":"eslint src tests --fix","check-types":"tsc --noEmit","format:check":"oxfmt --check \"src/**/*.ts\" \"tests/**/*.ts\""},"_npmUser":{"name":"udeshya-dhungana","email":"eddie@codecrafters.io"},"_npmVersion":"11.13.0","description":"Generate Zero schemas from Lucid ORM models","directories":{},"_nodeVersion":"24.16.0","dependencies":{"tsx":"^4.22.4","ts-morph":"^28.0.0","commander":"^15.0.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"packageManager":"npm@11.12.1","devDependencies":{"tsx":"^4.22.4","tsup":"^8.5.1","oxfmt":"^0.54.0","eslint":"^10.4.1","vitest":"^4.1.8","typescript":"^6.0.3","@types/node":"^25.9.2","@adonisjs/lucid":"^22.4.2","@vitest/coverage-v8":"^4.1.8","@typescript-eslint/parser":"^8.61.0","@typescript-eslint/eslint-plugin":"^8.61.0"},"peerDependencies":{"@adonisjs/lucid":">=21.0.0"},"_npmOperationalInternal":{"tmp":"tmp/zero-lucid-generator_1.1.0_1781086612181_0.004124100269024433","host":"s3://npm-registry-packages-npm-production"}},"1.1.1":{"_id":"@antislop/zero-lucid-generator@1.1.1","bin":{"lucid-zero":"dist/index.js"},"dist":{"shasum":"d33bb37f7582e52575b04d1509f6175d25c4536b","tarball":"https://registry.npmjs.org/@antislop/zero-lucid-generator/-/zero-lucid-generator-1.1.1.tgz","fileCount":4,"integrity":"sha512-hAbiCL875B8OmYd19FMe5wUIqpV2a/g8c2hqtItLbiZQXanOX+ZG2COqUvAAx5rmNzR+Si6nFerU5a/Ff8DZqQ==","signatures":[{"sig":"MEUCIBiWsylcw2dca+d02zIJNQUNJ/+ezJJl6r1P0wqC99S7AiEA2rf6E8E2VZqKjmxk7NStt4YEzsLx9QJ4SP0waJhOcdk=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"},{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEQCIGIls0ySR+Zuep1t/+d6tvzAYzAr9MAe5O0REIH61PEGAiAPTt7gcE6jo3CZnTOEomR6OfUr4SQYNtRgqyNS9O+IpQ=="}],"unpackedSize":26514},"main":"./dist/index.js","name":"@antislop/zero-lucid-generator","type":"module","types":"./dist/index.d.ts","author":{"name":"antislop"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"}},"gitHead":"b50fba369e338bae19e0a51ffbedf0493beeb046","license":"ISC","scripts":{"lint":"eslint src tests","test":"vitest run --typecheck --coverage","build":"rm -rf dist && npx tsx build.ts && chmod +x dist/index.js","format":"oxfmt \"src/**/*.ts\" \"tests/**/*.ts\"","lint:fix":"eslint src tests --fix","check-types":"tsc --noEmit","format:check":"oxfmt --check \"src/**/*.ts\" \"tests/**/*.ts\""},"version":"1.1.1","_npmUser":{"name":"rohitpaulk","email":"rohitpaulk@gmail.com"},"keywords":["zero","lucid","adonisjs","schema","generator","rocicorp"],"_npmVersion":"11.12.1","description":"Generate Zero schemas from Lucid ORM models","directories":{},"maintainers":[{"name":"udeshya-dhungana","email":"eddie@codecrafters.io"},{"name":"andyli-antislop","email":"andy@codecrafters.io"},{"name":"rohitpaulk","email":"rohitpaulk@gmail.com"}],"_nodeVersion":"24.15.0","dependencies":{"tsx":"^4.22.4","ts-morph":"^28.0.0","commander":"^15.0.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"packageManager":"npm@11.12.1","devDependencies":{"tsx":"^4.22.4","tsup":"^8.5.1","oxfmt":"^0.54.0","eslint":"^10.4.1","vitest":"^4.1.8","typescript":"^6.0.3","@types/node":"^25.9.2","@adonisjs/lucid":"^22.4.2","@vitest/coverage-v8":"^4.1.8","@typescript-eslint/parser":"^8.61.0","@typescript-eslint/eslint-plugin":"^8.61.0"},"peerDependencies":{"@adonisjs/lucid":">=21.0.0"},"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/zero-lucid-generator_1.1.1_1790416745495_0.8643854702612244"}}},"time":{"created":"2026-06-10T09:37:08.520Z","modified":"2026-09-26T09:59:05.771Z","1.0.0":"2026-06-10T09:37:08.816Z","1.1.0":"2026-06-10T10:16:52.343Z","1.1.1":"2026-09-26T09:59:05.590Z"},"author":{"name":"antislop"},"license":"ISC","keywords":["zero","lucid","adonisjs","schema","generator","rocicorp"],"description":"Generate Zero schemas from Lucid ORM models","maintainers":[{"name":"udeshya-dhungana","email":"eddie@codecrafters.io"},{"name":"andyli-antislop","email":"andy@codecrafters.io"},{"name":"rohitpaulk","email":"rohitpaulk@gmail.com"}],"readme":"# @antislop/zero-lucid-generator\n\nGenerate [Zero](https://zero.rocicorp.dev) schemas directly from your [Lucid ORM](https://lucid.adonisjs.com) models — no manual schema duplication.\n\nInspired by [`drizzle-zero`](https://github.com/rocicorp/drizzle-zero) and [`prisma-zero`](https://github.com/rocicorp/prisma-zero).\n\n---\n\n## How it works\n\n`@antislop/zero-lucid-generator` scans your Lucid model files, introspects their column and relation definitions at runtime, infers TypeScript types via [ts-morph](https://ts-morph.com), and writes a typed Zero schema file you can import directly into your app.\n\n---\n\n## Installation\n\n```sh\nnpm add -D @antislop/zero-lucid-generator\n```\n\n`@antislop/zero-lucid-generator` is a dev-time generator. You only need it during development to regenerate the schema when models change.\n\n---\n\n## Setup\n\n### 1. Create a config file\n\nCreate `config/lucid_zero.ts`:\n\n```ts\nimport type { Config } from '@antislop/zero-lucid-generator'\n\nconst config: Config = {\n  modelsDirectory: './app/models', // Optional; this is the default\n}\n\nexport default config\n```\n\n### 2. Run the generator\n\n```sh\nnpx lucid-zero generate\n```\n\nRun this from your project root. This writes `zero-schema.gen.ts` in the current working directory.\n\n### 3. Import the schema\n\n```ts\nimport { schema, zql } from './zero-schema.gen.js'\n```\n\n---\n\n## Config options\n\n| Option                | Type                                     | Default              | Description                                                              |\n| --------------------- | ---------------------------------------- | -------------------- | ------------------------------------------------------------------------ |\n| `modelsDirectory`     | `string`                                 | `./app/models`       | Path to your models directory, relative to the current working directory |\n| `outputPath`          | `string`                                 | `zero-schema.gen.ts` | Output file path, relative to the current working directory              |\n| `excludeModels`       | `LucidModel[]`                           | `[]`                 | Models to exclude from the generated schema                              |\n| `columnTypeOverrides` | `Record<string, Record<string, string>>` | `{}`                 | Override the inferred Zero type for specific columns                     |\n\n---\n\n## CLI options\n\n```\nlucid-zero generate [options]\n\nOptions:\n  -c, --config <path>     Path to config file     (default: config/lucid_zero.ts)\n  -t, --tsconfig <path>   Path to tsconfig.json   (default: tsconfig.json in cwd)\n```\n\n---\n\n## Column type inference\n\n`@antislop/zero-lucid-generator` maps TypeScript types to Zero types automatically:\n\n| TypeScript type                 | Zero type            |\n| ------------------------------- | -------------------- |\n| `string`                        | `string()`           |\n| `number`                        | `number()`           |\n| `boolean`                       | `boolean()`          |\n| `DateTime` / `Date`             | `number()` (Unix ms) |\n| `object` / `unknown` / `any`    | `json()`             |\n| `T \\| null` or `T \\| undefined` | `.optional()`        |\n\nWhen inference isn't accurate — for example a JSON column with a known shape — use `columnTypeOverrides`:\n\n```ts\nimport type { Config } from '@antislop/zero-lucid-generator'\nimport Session from '#models/session'\n\nconst config: Config = {\n  modelsDirectory: './app/models',\n  columnTypeOverrides: {\n    Issue: {\n      // metadata is typed as `unknown` but has a known shape\n      metadata: 'json<{ priority: number; labels: string[] }>()',\n    },\n    User: {\n      // role is stored as a string enum\n      role: 'enumeration<\"admin\" | \"member\" | \"viewer\">()',\n    },\n  },\n  excludeModels: [Session],\n}\n\nexport default config\n```\n\nValid Zero base types: `string`, `number`, `boolean`, `json`, `enumeration`.\n\n---\n\n## Example output\n\n```ts\n// zero-schema.gen.ts (auto-generated — do not edit)\n\nimport { createBuilder, createSchema, number, relationships, string, table } from '@rocicorp/zero'\n\nexport const users = table('users')\n  .columns({\n    id: number(),\n    name: string(),\n    email: string(),\n  })\n  .primaryKey('id')\n\nexport const posts = table('posts')\n  .columns({\n    id: number(),\n    userId: number().from('user_id'),\n    title: string(),\n    body: string().optional(),\n  })\n  .primaryKey('id')\n\nexport const usersRelationships = relationships(users, ({ many }) => ({\n  posts: many({\n    sourceField: ['id'],\n    destField: ['userId'],\n    destSchema: posts,\n  }),\n}))\n\nexport const schema = createSchema({\n  tables: [users, posts],\n  relationships: [usersRelationships],\n})\n\nexport type Schema = typeof schema\n\nexport const zql = createBuilder(schema)\n```\n\n## Supported relation types\n\n| Lucid relation   | Zero mapping                       |\n| ---------------- | ---------------------------------- |\n| `hasOne`         | `one(...)`                         |\n| `hasMany`        | `many(...)`                        |\n| `belongsTo`      | `one(...)`                         |\n| `manyToMany`     | `many([...chain])` via pivot table |\n| `hasManyThrough` | `many([...chain])`                 |\n\nRelations pointing to a model not found in `modelsDirectory` are skipped with a warning.\n\n---\n\n## Automating regeneration\n\nAdd a script to `package.json` to regenerate whenever models change:\n\n```json\n{\n  \"scripts\": {\n    \"zero:generate\": \"lucid-zero generate\",\n    \"postinstall\": \"npm run zero:generate\"\n  }\n}\n```\n","readmeFilename":"README.md"}