@drzl/cli 4.24.1 → 4.24.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -865,6 +865,11 @@ function finalize(raw, file, onWarn) {
865
865
  );
866
866
  }
867
867
  for (const w of unknownKeyWarnings(raw, configShapeForReading())) onWarn(w);
868
+ if (raw && typeof raw === "object" && !("generators" in raw)) {
869
+ onWarn(
870
+ `drzl config: no "generators" key, so this run uses the default, [{ kind: 'orpc' }], and writes an oRPC router tree. Name the key to choose: "zod", "valibot", "arktype", "typebox", "effect" and "json-schema" emit validation schemas, "orpc", "trpc", "hono", "express", "fastify", "nestjs" and "graphql" emit an API surface, and "service" emits typed data-access stubs.`
871
+ );
872
+ }
868
873
  const { config, warnings } = resolveConfig(parsed.data);
869
874
  for (const w of warnings) onWarn(w);
870
875
  return config;
@@ -1027,4 +1032,4 @@ export {
1027
1032
  tableFilterWarnings,
1028
1033
  computeWatchTargets
1029
1034
  };
1030
- //# sourceMappingURL=chunk-54E2IO7N.js.map
1035
+ //# sourceMappingURL=chunk-QNYJFUVS.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/config.ts","../src/config-errors.ts","../src/patterns.ts"],"sourcesContent":["import type { AffixOptions } from '@drzl/validation-core';\nimport {\n AFFIX_PREFIX_PATTERN,\n AFFIX_PROBE_TABLE,\n AFFIX_SUFFIX_PATTERN,\n DEFAULT_IMPORT_EXTENSION,\n IMPORT_EXTENSIONS,\n NAME_MODES,\n resolveAffix,\n schemaName,\n validateAffix,\n} from '@drzl/validation-core';\nimport * as fs from 'node:fs';\nimport { createRequire } from 'node:module';\nimport * as path from 'node:path';\nimport { z } from 'zod';\nimport {\n ConfigValidationError,\n formatConfigProblems,\n unknownKeyWarnings,\n} from './config-errors.js';\nimport { ambiguousPatternWarnings, matchesTable } from './patterns.js';\n\nexport const NamingSchema = z\n .object({\n routerSuffix: z.string().default('Router'),\n procedureCase: z.enum(['camel', 'kebab', 'snake']).default('camel'),\n })\n .partial();\n\n/**\n * One affix for every mode, or a per-mode map. Keys match drzl's internal mode names.\n *\n * `pattern` is annotation only: it changes nothing about how this parses, and exists so the\n * generated `drzl.config.schema.json` carries the character half of the affix rule that\n * `z.toJSONSchema` drops along with the `.superRefine` that states it. `validateAffix` remains\n * the enforcing copy, and its message is the one a user sees.\n */\nconst affixValueSchema = (pattern: string) =>\n z.union(\n [\n z.string().meta({ pattern }),\n z\n .object({\n insert: z.string().meta({ pattern }).optional(),\n update: z.string().meta({ pattern }).optional(),\n select: z.string().meta({ pattern }).optional(),\n })\n .strict(),\n ],\n {\n error:\n 'Expected a string to use for every mode, or an object with any of the keys \"insert\", ' +\n '\"update\" and \"select\". Those keys are lowercase, matching the mode names drzl uses ' +\n 'everywhere else.',\n }\n );\n\nconst AffixPartSchema = z\n .object({\n prefix: affixValueSchema(AFFIX_PREFIX_PATTERN).optional(),\n suffix: affixValueSchema(AFFIX_SUFFIX_PATTERN).optional(),\n })\n .strict();\n\nexport const AffixSchema = z\n .object({\n /**\n * `preserve` (default) keeps today's output: the Drizzle export name goes into the\n * identifier verbatim, so `export const users` yields `InsertusersSchema`. `pascal`\n * upper-camels it first, yielding `InsertUsersSchema`.\n */\n tableCase: z.enum(['preserve', 'pascal']).optional(),\n schema: AffixPartSchema.optional(),\n type: AffixPartSchema.optional(),\n })\n .strict();\n\n/**\n * How every relative specifier drzl invents spells its extension.\n *\n * The generated files land in the consumer's own source tree, so the consumer's\n * `moduleResolution` decides which forms resolve. `js` is the only one that resolves under\n * all of `bundler`, `node10`, `node16` and `nodenext` with no compiler flag, so it is the\n * default. See the `ImportExtension` docs in `@drzl/validation-core` for the measured grid.\n */\nexport const ImportExtensionSchema = z.enum(IMPORT_EXTENSIONS);\n\n/**\n * Every generator DRZL can run, named once.\n *\n * Extracted from `GeneratorSchema.kind` rather than restated beside it, because three surfaces\n * have to agree about this list and two of them used to spell it themselves: the config parser,\n * the JSON Schema editors validate a `drzl.config.json` against, and the CLI's `--only`. A kind\n * added here is accepted by all three at once, which is the property `--only` needs to be able to\n * refuse an unknown value by name instead of matching nothing in silence.\n */\nexport const GeneratorKindSchema = z.enum([\n 'orpc',\n 'trpc',\n 'hono',\n 'express',\n 'fastify',\n 'nestjs',\n 'graphql',\n 'service',\n 'zod',\n 'valibot',\n 'arktype',\n 'typebox',\n 'effect',\n 'json-schema',\n]);\n\n/** One generator kind, as the config spells it. */\nexport type GeneratorKind = z.infer<typeof GeneratorKindSchema>;\n\n/** The kinds in declaration order, for a message that has to list them. */\nexport const GENERATOR_KINDS: readonly GeneratorKind[] = GeneratorKindSchema.options;\n\nexport const GeneratorSchema = z.object({\n kind: GeneratorKindSchema,\n /**\n * Which of Hono's two official validator middlewares the emitted routes carry, and therefore\n * which package they import. `hono` only.\n *\n * `standard` is `sValidator` from `@hono/standard-validator`, which takes any Standard Schema\n * and so works with every library `validation.library` can name. `zod` is `zValidator` from\n * `@hono/zod-validator`, which is zod-specific.\n */\n validator: z.enum(['standard', 'zod']).optional(),\n /**\n * Overrides the top-level `importExtension` for this generator alone, for a project whose\n * generated directories are compiled by different tsconfigs.\n */\n importExtension: ImportExtensionSchema.optional(),\n template: z.string().optional(),\n includeRelations: z.boolean().optional(),\n /**\n * Write an enum used by two or more columns once under `$defs` in the `json-schema` per-table\n * modules, and `$ref` it at each use.\n *\n * Off by default, and the reason is a consumer pattern rather than a doubt about the keyword. A\n * per-table schema is used whole and one property at a time, and a `$ref` cannot survive being\n * pulled out with its property: `properties[col]` compiled on its own is a dangling reference\n * that ajv refuses outright. The OpenAPI document shares regardless, because a document is only\n * ever read whole.\n */\n sharedEnums: z.boolean().optional(),\n /**\n * Type `json` and `jsonb` columns from the schema rather than leaving them wide.\n *\n * `.$type<T>()` is a compile-time cast, so no runtime-derived validator can see it and\n * `drizzle-orm/zod` types every json column as its generic `Json`. A generator can reference\n * `typeof <table>.$inferSelect['<column>']` instead, which is the declared type resolved by\n * TypeScript itself, so generics, unions and imported interfaces all work.\n *\n * Off by default because it makes the generated file import your schema module, as a\n * type-only import that disappears at build time.\n */\n // What a date column accepts. Documented on the zod generator and, until now, accepted by the\n // config parser and then dropped on the floor: the generators default it to 'input' themselves,\n // so setting it here changed nothing.\n coerceDates: z.enum(['input', 'all', 'none']).optional(),\n typedJson: z.boolean().optional(),\n // The wider form: every column's static type comes from Drizzle, not just the untyped ones.\n typedColumns: z.boolean().optional(),\n // Reproduce literal column defaults in the insert schema, so parsing fills them in.\n applyDefaults: z.boolean().optional(),\n /**\n * Emit `findDuplicate<Table>` beside the schemas: the rows in a batch that collide with an\n * earlier row on a unique constraint.\n *\n * Uniqueness is the one constraint a per-row validator structurally cannot see, since it is a\n * fact about the table rather than the row. This checks the half that needs no database.\n */\n duplicateFinder: z.boolean().optional(),\n /**\n * zod and valibot. Also emit `constraints.ts`: every CHECK, unique constraint, primary and\n * foreign key on each table as plain data, plus `constraintForIssue`, which maps a validation\n * issue back to the constraint that caused it.\n *\n * For building forms. A schema states what a value must look like and never says which\n * constraint said so, so a failed parse hands a form a message and no way to attribute it; and\n * uniqueness and foreign keys, the two constraints no per-row schema can check, are absent from\n * the emitted schemas in every form.\n *\n * Not `meta` written to a second file. `meta` describes a *field* and travels with the schema\n * into `z.toJSONSchema`; this describes the table's *constraints*, carries their names, states\n * each operand as data rather than inside a sentence, and is read without holding a schema.\n *\n * `true` is the shorthand for `{ enabled: true }`. `{ errorMap: false }` emits the data alone,\n * without the matcher.\n */\n constraints: z\n .union([\n z.boolean(),\n z.object({ enabled: z.boolean().optional(), errorMap: z.boolean().optional() }).strict(),\n ])\n .optional(),\n /**\n * zod only. Attach the facts the analyzer knows and a zod schema cannot state, as `.meta()` on\n * every field and every table schema: the declared SQL type, the primary key, the unique\n * constraints, whether the database generates or defaults the value, and the CHECK constraints,\n * including the ones DRZL declined to enforce.\n *\n * `z.toJSONSchema` copies these through, so they are also how an OpenAPI document built from the\n * emitted schemas gets the declared width back: DRZL enforces one as a `.refine()`, and\n * `toJSONSchema` drops every refinement in silence.\n *\n * `true` is the shorthand for `{ enabled: true }`. `{ description: true }` additionally writes a\n * `description`, which is what an OpenAPI viewer renders to a human.\n */\n meta: z\n .union([\n z.boolean(),\n z.object({ enabled: z.boolean().optional(), description: z.boolean().optional() }).strict(),\n ])\n .optional(),\n /**\n * TypeBox only. Give every emitted schema a `~standard` key, so it can be handed to a tRPC or\n * oRPC route.\n *\n * TypeBox is the one validator DRZL emits that carries none of its own: measured on 0.34.52, a\n * bare `Type.Object()` has no `~standard` and the package exports nothing matching\n * `/standard/i`. zod, valibot and arktype all put one on every schema they build, so the option\n * does nothing for them and is not passed through.\n *\n * The property is non-enumerable, so the schema stays a TypeBox schema in every respect that was\n * already observable, including the JSON Schema `JSON.stringify` produces.\n */\n standardSchema: z.boolean().optional(),\n /**\n * Emit `NestedInsert<Table>` and `NestedSelect<Table>` beside the flat schemas: the table plus\n * one key per relation, so `{ ...user, posts: [...] }` can be validated whole.\n *\n * Nothing in the Drizzle validator ecosystem describes that payload, and `db.insert` drops the\n * relation key silently rather than refusing it, so the children are never written and nothing\n * says so.\n */\n nestedSchemas: z.boolean().optional(),\n /**\n * How many levels of children a nested schema describes. Defaults to 1, capped at 3.\n *\n * Nesting is expanded inline rather than by reference, so this multiplies the emitted size, and\n * it is also what terminates a cycle: `users -> posts -> users` stops here.\n */\n nestedDepth: z.number().int().optional(),\n /**\n * Give every primary key, and every foreign key pointing at one, a nominal type, so a\n * `users.id` cannot be passed where a `posts.id` is wanted.\n *\n * Type level only, in all five validators. Measured on zod 4.4.3, `.brand()` returns the same\n * schema object it was called on and the parsed value of `1` is `1`, so nothing about what a\n * schema accepts changes and no bytes are added to the bundle. TypeBox has no brand of its own\n * and gets a `TUnsafe` cast, which leaves the schema object identical.\n *\n * Off by default: it changes the inferred type of every consumer of the select schemas, which\n * is the point, but it is a change to existing call sites rather than an addition.\n *\n * `true` is the shorthand for `{ enabled: true }`. `{ foreignKeys: false }` brands only the\n * keys themselves, and `{ aliases: false }` stops the `export type UsersId = ...` lines.\n */\n branded: z\n .union([\n z.boolean(),\n z\n .object({\n enabled: z.boolean().optional(),\n foreignKeys: z.boolean().optional(),\n aliases: z.boolean().optional(),\n })\n .strict(),\n ])\n .optional(),\n naming: NamingSchema.optional(),\n outputHeader: z\n .object({\n enabled: z.boolean().default(true).optional(),\n text: z.string().optional(),\n })\n .optional(),\n format: z\n .object({\n enabled: z.boolean().default(true).optional(),\n engine: z.enum(['auto', 'prettier', 'biome']).default('auto').optional(),\n configPath: z.string().optional(),\n })\n .optional(),\n /**\n * Which spelling of JSON Schema the `json-schema` generator emits.\n *\n * OpenAPI 3.0 is not an older superset of the 2020-12 draft, it is a different dialect: a\n * nullable type is `nullable: true` rather than a type array, and an exclusive bound is a\n * boolean flag beside the bound rather than its own keyword. An unknown keyword is not an error\n * in JSON Schema, it is ignored, so emitting the wrong dialect produces a document that\n * validates and then accepts the values the constraints exist to reject.\n */\n target: z.enum(['draft-2020-12', 'openapi-3.1', 'openapi-3.0']).optional(),\n /** Also emit `components.ts` for the `json-schema` generator, ready for an OpenAPI document. */\n components: z.boolean().optional(),\n /**\n * Also emit the whole OpenAPI document for the `json-schema` generator: paths, verbs, request and\n * response bodies per table, with `components.schemas` embedded so the file stands alone.\n *\n * `true` is the short form. The object form carries the three things a Drizzle schema genuinely\n * cannot say: what the API is called, where it is served, and which status code that particular\n * server answers a request that fails its schema with.\n */\n document: z\n .union([\n z.boolean(),\n z\n .object({\n enabled: z.boolean().optional(),\n /** `ts` (default) writes a module, `json` the file OpenAPI tooling reads directly. */\n format: z.enum(['ts', 'json', 'both']).optional(),\n info: z\n .object({\n title: z.string().optional(),\n version: z.string().optional(),\n description: z.string().optional(),\n })\n .strict()\n .optional(),\n /**\n * Omitted by default, which the specification reads as a single server at `/`: the\n * document describes whatever is serving it. A placeholder host would be a fabrication\n * that tooling then follows.\n */\n servers: z\n .array(z.object({ url: z.string(), description: z.string().optional() }).strict())\n .optional(),\n /** 400 by default. 422 is the other defensible reading; exactly one is emitted. */\n validationStatus: z.union([z.literal(400), z.literal(422)]).optional(),\n })\n .strict(),\n ])\n .optional(),\n // service generator specific options\n path: z.string().optional(),\n dataAccess: z.enum(['stub', 'drizzle']).default('stub').optional(),\n dbImportPath: z.string().optional(),\n schemaImportPath: z.string().optional(),\n // zod/valibot/arktype generator specific options\n schemaSuffix: z.string().optional(),\n fileSuffix: z.string().optional(),\n /**\n * Prefixes, suffixes and table casing for generated identifiers (zod/valibot/arktype).\n * Omitting it reproduces the output of every previous release exactly.\n */\n affix: AffixSchema.optional(),\n /**\n * How the router generators reach a database handle: through the request context, rather than\n * through a module-level import in the service layer.\n *\n * Documented on the oRPC generator since it was added and, until now, absent from this schema\n * entirely. `GeneratorSchema` is not strict, so zod stripped the key without a word and the\n * option did nothing at all when set from a config file. It was only ever reachable by calling\n * the generator's API directly.\n */\n databaseInjection: z\n .object({\n enabled: z.boolean().optional(),\n /** The type annotation for the injected handle, e.g. `DrizzleD1Database`. */\n databaseType: z.string().optional(),\n databaseTypeImport: z.object({ name: z.string(), from: z.string() }).optional(),\n })\n .optional(),\n // router validation sharing (orpc, trpc)\n validation: z\n .object({\n useShared: z.boolean().default(false).optional(),\n library: z.enum(['zod', 'valibot', 'arktype']).default('zod').optional(),\n importPath: z.string().optional(),\n schemaSuffix: z.string().optional(),\n /**\n * How the validation generator named its exports. Usually left unset: the CLI copies\n * it from the sibling generator whose `kind` matches `library`.\n */\n affix: AffixSchema.optional(),\n })\n .optional(),\n // template options\n templateOptions: z.record(z.string(), z.any()).optional(),\n});\n\n/**\n * One table's column rules. Strict, so `ommit` is refused by the parser rather than dropped.\n *\n * The whole option exists to remove a column, and a key zod strips in silence is a config that\n * looks like it removed one and did not. `GeneratorSchema` is deliberately not strict and has\n * already cost this repo two options that parsed and then did nothing.\n */\nexport const ColumnRulesSchema = z\n .object({\n omit: z.array(z.string()).optional(),\n pick: z.array(z.string()).optional(),\n })\n .strict();\n\nexport const AnalyzerSchema = z.object({\n includeRelations: z.boolean().default(true),\n validateConstraints: z.boolean().default(true),\n includeHeuristicRelations: z.boolean().default(false),\n});\n\nexport const ConfigSchema = z\n .object({\n /**\n * Path to the Drizzle schema module. Optional since drizzle-kit interop: a project that\n * already names its schema in `drizzle.config.ts` should not have to say it twice, so an\n * omitted `schema` falls back to reading the drizzle-kit config (see `drizzleKit`). The\n * \"neither file names a schema\" error is raised at resolution time, where it can name both\n * files, rather than here, where \"Required\" could name only this one.\n */\n schema: z.string().optional(),\n /**\n * Read the schema path from drizzle-kit's own config instead of `schema`.\n *\n * `true` reads `drizzle.config.ts`, then `.js`, then `.json`, the same candidates in the\n * same order drizzle-kit's CLI uses (measured on drizzle-kit 0.31.10). A string reads that\n * file, wherever it is, like kit's own `--config` flag. `false` disables the fallback, so\n * an omitted `schema` is an error even beside a drizzle.config. Unset behaves like `true`\n * whenever `schema` is omitted, and does nothing when `schema` is set: `schema` always\n * wins, with a warning when both are stated.\n *\n * Only kit's `schema` (string or array, entries may be globs) and `dialect` (cross-checked\n * against what the analyzer detects) are read. Everything else in that file describes\n * migrations and database credentials, which DRZL has no use for.\n */\n drizzleKit: z\n .union([z.boolean(), z.string()], {\n error:\n 'Expected true (read drizzle.config.ts/.js/.json, the same candidates drizzle-kit ' +\n 'uses), false (never read one), or a path to the drizzle-kit config file.',\n })\n .optional(),\n outDir: z.string().default('src/api'),\n /**\n * Which tables to generate for, matched against the database table name.\n *\n * There was no way to say this, and every generator loops over every table it finds, so\n * DRZL emitted unauthenticated CRUD over whatever shared the schema file. That is noise for\n * a migrations table and a genuine leak for an auth one: Better Auth puts `user`, `session`,\n * `account` and `verification` alongside your own tables, and `account` holds\n * `accessToken`, `refreshToken`, `idToken` and `password`.\n *\n * Deliberately name-based and explicit rather than detecting any particular library. Auth\n * table names are all renameable, so a built-in list would miss renamed tables and, worse,\n * silently skip an ordinary table that happened to be called `user`, which is usually the\n * application's main entity.\n *\n * `exclude` wins over `include`. Patterns support `*`, matching within a name.\n */\n include: z.array(z.string()).optional(),\n exclude: z.array(z.string()).optional(),\n /**\n * Which columns of those tables to generate for, keyed by table.\n *\n * `include`/`exclude` is all or nothing per table, and the column that should not be in a\n * generated schema is usually sitting in a table you do want: `passwordHash` on `users`, an\n * internal note beside the public fields, a `tenantId` the server sets from the session and a\n * request body must not carry. Editing the emitted file is not an answer, because the next\n * `drzl generate` overwrites it.\n *\n * ```ts\n * columns: {\n * users: { omit: ['passwordHash'] },\n * 'app_*': { omit: ['deleted_at'] },\n * }\n * ```\n *\n * The key is a table pattern in the same language `include`/`exclude` uses: the database table\n * name, anchored, with `*` as the only metacharacter. Column patterns are the same language\n * again. Every matching entry applies, in the order written; within one entry `pick` narrows\n * first and `omit` then removes, so `omit` wins, exactly as `exclude` wins over `include`.\n *\n * Applies to every mode and every generator at once, because it narrows the analysis rather\n * than any one generator's output. A column cannot be kept in `select` and dropped from\n * `insert`: see the docs for why that form was not taken on.\n *\n * A pattern that matches nothing is an error rather than a no-op, because a typo in `omit`\n * that silently does nothing leaves the column exactly where it was while reading like a fix.\n * Dropping a primary key column is an error too; dropping a NOT NULL column with no default is\n * a warning.\n */\n columns: z.record(z.string(), ColumnRulesSchema).optional(),\n /**\n * How every relative specifier drzl invents spells its extension, for every generator.\n * A generator may override it. Defaults to `js`, which is the only form that resolves\n * under every `moduleResolution` without a compiler flag.\n */\n importExtension: ImportExtensionSchema.default(DEFAULT_IMPORT_EXTENSION),\n analyzer: AnalyzerSchema.default({\n includeRelations: true,\n validateConstraints: true,\n includeHeuristicRelations: false,\n }),\n generators: z\n .array(GeneratorSchema)\n .min(1)\n .default([{ kind: 'orpc' } as any]),\n })\n // Reject an affix before anything is written, rather than emitting a file that cannot\n // compile. Only `affix` is inspected; the legacy flat `schemaSuffix` is left alone so\n // configs that parse today keep parsing.\n .superRefine((cfg, ctx) => {\n cfg.generators.forEach((g, i) => {\n const report = (base: (string | number)[], affix?: AffixOptions, schemaSuffix?: string) => {\n for (const issue of validateAffix(affix, schemaSuffix)) {\n ctx.addIssue({\n code: 'custom',\n path: ['generators', i, ...base, ...issue.path],\n message: issue.message,\n });\n }\n };\n report(['affix'], g.affix as AffixOptions | undefined, g.schemaSuffix);\n report(\n ['validation', 'affix'],\n g.validation?.affix as AffixOptions | undefined,\n g.validation?.schemaSuffix\n );\n });\n });\n\n// ✨ Separate input vs output types\nexport type DrzlConfigInput = z.input<typeof ConfigSchema>;\nexport type DrzlConfig = z.output<typeof ConfigSchema>;\n\nexport function defineConfig<T extends DrzlConfigInput>(cfg: T): T {\n return cfg;\n}\n\n/**\n * Every filename `drzl` will load a config from, in the order it tries them.\n *\n * One list because there were two. `computeWatchTargets` carried its own copy of four of these\n * names, and the copy was missing `drzl.config.json`: a JSON config loaded fine, and then\n * `drzl watch` never noticed an edit to it, because nothing was watching the file. The watcher's\n * test spelled the same four names a third time, so it agreed with the bug.\n */\nexport const CONFIG_FILE_NAMES = [\n 'drzl.config.ts',\n 'drzl.config.mjs',\n 'drzl.config.js',\n 'drzl.config.cjs',\n 'drzl.config.json',\n] as const;\n\n/** Where the published schema answers from, and what `$schema` in a config should point at. */\nexport const CONFIG_SCHEMA_ID = 'https://use-drzl.github.io/drzl/drzl.config.schema.json';\n\n/**\n * `ConfigSchema` as a JSON Schema, for editors pointed at a `drzl.config.json`.\n *\n * Two things about `z.toJSONSchema` decide the arguments here, both measured rather than assumed:\n *\n * - `io` defaults to `'output'`, which marks every key carrying a `.default()` as `required`.\n * That is four of the nine top-level keys, so the default would produce a schema that flags\n * all 32 configs in the docs and every minimal config a reader writes. `'input'` describes\n * what a user writes, which is what a config file is.\n * - refinements are dropped silently. The only one here is the affix `.superRefine`; its\n * character half is carried by the `pattern` annotations on `affixValueSchema`, and its\n * collision half cannot be stated in JSON Schema at all and stays a CLI-only error.\n *\n * draft-07 rather than 2020-12 because that is the dialect every editor implements fully, and\n * this schema uses nothing newer.\n */\nexport function buildConfigJsonSchema(): Record<string, unknown> {\n const generated = z.toJSONSchema(ConfigSchema, {\n io: 'input',\n target: 'draft-7',\n }) as Record<string, unknown>;\n\n const properties = {\n // Declared so an editor suggests it and does not report the pointer a reader was told to\n // add as an unknown key. `ConfigSchema` is not strict, so the CLI strips it and never sees it.\n $schema: {\n type: 'string',\n description: 'Path or URL of this schema, for editor completion. Ignored by drzl.',\n },\n ...(generated.properties as Record<string, unknown>),\n };\n\n // Rebuilt rather than mutated so the key order of the written file is deliberate and stable:\n // a diff of this artefact should show what changed in the config, not a reshuffle.\n const { $schema, properties: _dropped, ...rest } = generated;\n return {\n $schema,\n $id: CONFIG_SCHEMA_ID,\n title: 'DRZL configuration',\n description:\n 'Configuration for the drzl CLI. Also describes drzl.config.ts, which gets the same ' +\n 'shape from the defineConfig export of @drzl/cli/config.',\n ...rest,\n properties,\n };\n}\n\ntype GeneratorConfig = DrzlConfig['generators'][number];\n\n/** The generators that emit an RPC router, and so share `outDir` and `validation`. */\n/** The generators that import the validation generators' exports by name. */\nconst ROUTER_KINDS = new Set(['orpc', 'trpc', 'hono', 'express']);\n\n/**\n * The routers that can reach a database through the request context.\n *\n * `hono` and `express` are deliberately absent. `databaseInjection` is a contract between a\n * router and `@drzl/generator-service`, and neither generator emits service delegation at all:\n * their handlers are stubs a consumer fills in, and neither has a template that would call one.\n * Letting the option through would push `databaseInjection` onto the service generator on behalf\n * of a router that never uses it, which is the shape of dead option this config has already\n * shipped twice.\n */\nconst INJECTION_KINDS = new Set(['orpc', 'trpc']);\n\n/**\n * Where the tRPC generator writes.\n *\n * `outDir` by default, exactly like oRPC, so a config that names one router generator puts its\n * output where the top-level setting says. `path` is the escape hatch, and a config that runs\n * *both* router generators needs it: they would otherwise write two different `index.ts` files to\n * the same directory and the second would win.\n *\n * Exported because `computeGeneratorOutputDirs` has to agree with the dispatch in cli.ts about\n * this, and the watcher ignoring the wrong directory is an infinite regeneration loop.\n */\nexport function trpcOutDir(g: { path?: string }, cfg: { outDir: string }): string {\n return g.path ?? cfg.outDir;\n}\n\n/**\n * Where the Hono generator writes.\n *\n * The same rule as the other two routers, and for the same reason: it writes an `index.ts` of its\n * own, so a config running two router generators has to give at least one of them a `path`.\n *\n * Its own function rather than a call to `trpcOutDir`, because these are three separate decisions\n * that happen to agree today, and a reader following `computeGeneratorOutputDirs` should not have\n * to work out whether a function named for tRPC is authoritative for Hono.\n */\nexport function honoOutDir(g: { path?: string }, cfg: { outDir: string }): string {\n return g.path ?? cfg.outDir;\n}\n\n/**\n * Where the Express generator writes.\n *\n * The same rule as the other three routers, and for the same reason: it writes an `index.ts` of\n * its own, so a config running two router generators has to give at least one of them a `path`.\n *\n * Its own function rather than a call to one of the others, for the reason `honoOutDir` records:\n * these are separate decisions that happen to agree today, and a reader following\n * `computeGeneratorOutputDirs` should not have to work out which router's function is\n * authoritative for which kind.\n */\nexport function expressOutDir(g: { path?: string }, cfg: { outDir: string }): string {\n return g.path ?? cfg.outDir;\n}\n\n/**\n * Where the Fastify generator writes.\n *\n * The same rule as the other four routers, and for the same reason: it writes an `index.ts` of\n * its own, so a config running two router generators has to give at least one of them a `path`.\n *\n * Its own function rather than a call to one of the others, for the reason `honoOutDir` records:\n * these are separate decisions that happen to agree today, and a reader following\n * `computeGeneratorOutputDirs` should not have to work out which router's function is\n * authoritative for which kind.\n */\nexport function fastifyOutDir(g: { path?: string }, cfg: { outDir: string }): string {\n return g.path ?? cfg.outDir;\n}\n\n/**\n * Where the NestJS generator writes.\n *\n * The same rule as the five routers, though this one emits DTO modules rather than routes: it\n * still writes an `index.ts` barrel and a `validation.ts` of its own, so a config that runs it\n * beside a router generator has to give at least one of them a `path`.\n *\n * Its own function rather than a call to one of the others, for the reason `honoOutDir` records:\n * these are separate decisions that happen to agree today, and a reader following\n * `computeGeneratorOutputDirs` should not have to work out which kind's function is\n * authoritative for which.\n */\nexport function nestjsOutDir(g: { path?: string }, cfg: { outDir: string }): string {\n return g.path ?? cfg.outDir;\n}\n\n/**\n * Where the GraphQL generator writes.\n *\n * The same rule as the routers and the NestJS kind, though this one emits SDL modules rather\n * than routes: it still writes an `index.ts` barrel and a `scalars.ts` of its own, so a config\n * that runs it beside a router generator has to give at least one of them a `path`.\n *\n * Its own function rather than a call to one of the others, for the reason `honoOutDir`\n * records: these are separate decisions that happen to agree today, and a reader following\n * `computeGeneratorOutputDirs` should not have to work out which kind's function is\n * authoritative for which.\n */\nexport function graphqlOutDir(g: { path?: string }, cfg: { outDir: string }): string {\n return g.path ?? cfg.outDir;\n}\n\nfunction sharedSchemaNames(opts: { affix?: AffixOptions; schemaSuffix?: string }): string[] {\n const resolved = resolveAffix(opts);\n return NAME_MODES.map((mode) => schemaName(mode, AFFIX_PROBE_TABLE, resolved));\n}\n\n/**\n * Fill in cross-generator defaults and refuse configs whose generators would disagree.\n *\n * An oRPC router that imports shared schemas has to spell the exact names the validation\n * generator exported. Both sides used to be configured independently, so they could silently\n * drift into a router that does not compile. When an oRPC generator uses shared validation\n * and exactly one sibling generator produces that library, its `affix` is copied across.\n *\n * Deliberately conservative about the pre-existing flat `schemaSuffix`: a disagreement there\n * is only reported, never repaired, because repairing it would change the bytes an existing\n * config emits.\n *\n * `importExtension` is pushed down here too. A consumer compiles the whole generated tree\n * with one tsconfig, so the setting that has to hold is the same for every generator, and\n * every call site downstream can then read it off the generator without knowing about the\n * top-level default.\n */\nexport function resolveConfig(cfg: DrzlConfig): { config: DrzlConfig; warnings: string[] } {\n const warnings: string[] = [];\n const generators: GeneratorConfig[] = cfg.generators.map((g) => ({\n ...g,\n importExtension: g.importExtension ?? cfg.importExtension,\n }));\n\n for (const g of generators) {\n /**\n * The Fastify generator is a router that belongs to neither set below. Its schemas are JSON\n * Schema built by the same code as the `json-schema` generator and inlined at generation\n * time, so there is no validation library to choose and no shared schema module to import,\n * and its handlers are stubs that never call a service. Both options would otherwise parse\n * and then do nothing, which is the shape of dead option this config has already shipped\n * twice, so each is refused with a warning here instead.\n */\n if (g.kind === 'fastify') {\n if (g.databaseInjection?.enabled) {\n warnings.push(\n `drzl config: the \"fastify\" generator sets databaseInjection.enabled, which it does ` +\n `not support. Its handlers are stubs and never call a service, so nothing reads ` +\n `the injected handle. Reach your database from inside the handler bodies you fill ` +\n `in, or use the \"trpc\" or \"orpc\" generator, which do delegate to ` +\n `@drzl/generator-service.`\n );\n }\n if (g.validation) {\n warnings.push(\n `drzl config: the \"fastify\" generator sets \"validation\", which it does not read. Its ` +\n `route schemas are JSON Schema produced by the same builder as the \"json-schema\" ` +\n `generator and inlined into the routes, so there is no library to choose and no ` +\n `shared schema module to import. Remove the block.`\n );\n }\n continue;\n }\n\n /**\n * The NestJS generator emits DTO classes, not routes, so it belongs to neither set below.\n * It does read `validation.library` (which library the emitted schemas are spelled in), but\n * every other key of that block describes schema *sharing*, and its DTO modules are\n * self-contained on purpose: the class fields are generated from the same columns as the\n * schema, so importing a schema another generator wrote would let the two drift. Each unread\n * option is refused with a warning rather than parsed and dropped, which is the shape of\n * dead option this config has already shipped twice.\n */\n if (g.kind === 'nestjs') {\n if (g.databaseInjection?.enabled) {\n warnings.push(\n `drzl config: the \"nestjs\" generator sets databaseInjection.enabled, which it does ` +\n `not support. It emits DTO classes with no handlers at all, so nothing reads the ` +\n `injected handle. Reach your database from the controllers you write around these ` +\n `DTOs, or use the \"trpc\" or \"orpc\" generator, which do delegate to ` +\n `@drzl/generator-service.`\n );\n }\n if (g.includeRelations) {\n warnings.push(\n `drzl config: the \"nestjs\" generator sets includeRelations, which it does not read. ` +\n `Relation lookups are routes, and this generator emits DTO classes for your own ` +\n `controllers rather than routes. Remove the flag.`\n );\n }\n if (g.validation?.useShared || g.validation?.importPath) {\n warnings.push(\n `drzl config: the \"nestjs\" generator sets validation.useShared or ` +\n `validation.importPath, which it does not read. Its DTO modules are ` +\n `self-contained: the class fields and the schema are generated from the same ` +\n `columns, and wrapping a schema another generator wrote would let the two drift. ` +\n `Only validation.library is read on this kind.`\n );\n }\n if (g.validation?.schemaSuffix || g.validation?.affix) {\n warnings.push(\n `drzl config: the \"nestjs\" generator sets validation.schemaSuffix or ` +\n `validation.affix, which it does not read. Those options spell the names of shared ` +\n `schema modules, and this generator imports none. Only validation.library is read ` +\n `on this kind.`\n );\n }\n continue;\n }\n\n /**\n * The GraphQL generator emits SDL and resolver stubs, so it belongs to neither set below,\n * and unlike the NestJS kind it reads no `validation` key at all: its schema is GraphQL\n * SDL, GraphQL's own type language, so there is no library to choose and no shared schema\n * module to import. Each unread option is refused with a warning rather than parsed and\n * dropped, which is the shape of dead option this config has already shipped twice.\n */\n if (g.kind === 'graphql') {\n if (g.databaseInjection?.enabled) {\n warnings.push(\n `drzl config: the \"graphql\" generator sets databaseInjection.enabled, which it does ` +\n `not support. It emits SDL and resolver stubs with no handlers at all, so nothing ` +\n `reads the injected handle. Reach your database from the resolvers you write in ` +\n `place of the stubs, or use the \"trpc\" or \"orpc\" generator, which do delegate to ` +\n `@drzl/generator-service.`\n );\n }\n if (g.includeRelations) {\n warnings.push(\n `drzl config: the \"graphql\" generator sets includeRelations, which it does not ` +\n `read. Relation lookups are routes on the router generators, and relation fields ` +\n `on a GraphQL type are resolvers you write against your own data layer. Remove ` +\n `the flag.`\n );\n }\n if (g.validation) {\n warnings.push(\n `drzl config: the \"graphql\" generator sets \"validation\", which it does not read. ` +\n `Its schema is GraphQL SDL, GraphQL's own type language, so there is no library ` +\n `to choose and no shared schema module to import. Remove the block.`\n );\n }\n continue;\n }\n\n // Both router generators import the validation generators' exports by name, so both have to\n // spell them the way the sibling generator wrote them.\n if (!ROUTER_KINDS.has(g.kind)) continue;\n\n /**\n * `databaseInjection` describes a contract between two generators, not a setting of one.\n *\n * A router in injection mode emits `Service.getById(ctx.db, id)`, and only a service\n * generated in the same mode has a `db` parameter to receive it. Declared once on the router\n * and pushed onto the service generator here, exactly as `validation.affix` is pulled the\n * other way, because the alternative is writing the same block twice and a project that\n * compiles in halves and not as a whole.\n *\n * `@drzl/generator-service` honours the flag only while emitting real Drizzle queries: its\n * stub bodies take no database whatever they are told. That combination cannot be repaired\n * from here without changing what an existing config emits, so it is reported instead.\n */\n if (g.databaseInjection?.enabled && !INJECTION_KINDS.has(g.kind)) {\n warnings.push(\n `drzl config: the \"${g.kind}\" generator sets databaseInjection.enabled, which it does ` +\n `not support. Its handlers are stubs and never call a service, so nothing reads the ` +\n `injected handle. Reach your database from inside the handler bodies you fill in, or ` +\n `use the \"trpc\" or \"orpc\" generator, which do delegate to @drzl/generator-service.`\n );\n } else if (g.databaseInjection?.enabled) {\n for (const s of generators.filter((x) => x.kind === 'service')) {\n if (!s.databaseInjection) {\n s.databaseInjection = g.databaseInjection;\n } else if (!s.databaseInjection.enabled) {\n warnings.push(\n `drzl config: the \"${g.kind}\" generator sets databaseInjection.enabled while the ` +\n `\"service\" generator sets it to false. The router will call ` +\n `Service.method(ctx.db, ...) against services that take no database parameter, so ` +\n `the generated project will not compile. Set both, or neither.`\n );\n }\n if ((s.dataAccess ?? 'stub') === 'stub') {\n warnings.push(\n `drzl config: the \"${g.kind}\" generator sets databaseInjection.enabled, so its ` +\n `handlers call Service.method(ctx.db, ...). The \"service\" generator emits stub ` +\n `bodies, which take no database parameter whatever this option says, so those ` +\n `calls will not compile. Set dataAccess: 'drizzle' on the \"service\" generator, or ` +\n `drop databaseInjection.`\n );\n }\n }\n }\n\n const v = g.validation;\n if (!v?.useShared) continue;\n\n const library = v.library ?? 'zod';\n const siblings = generators.filter((s) => s.kind === library);\n // Zero siblings means the user points at a barrel drzl does not generate; more than one\n // means there is no single source of truth. Either way, leave the config alone.\n if (siblings.length !== 1) continue;\n const sibling = siblings[0];\n\n const theirs = sharedSchemaNames({\n affix: sibling.affix as AffixOptions | undefined,\n schemaSuffix: sibling.schemaSuffix,\n });\n\n if (!v.affix) {\n if (sibling.affix) {\n // Bake the sibling's fully resolved naming in, so its own schemaSuffix fallback\n // travels with it and cannot be re-interpreted on the oRPC side.\n g.validation = {\n ...v,\n affix: resolveAffix({\n affix: sibling.affix as AffixOptions,\n schemaSuffix: sibling.schemaSuffix,\n }),\n };\n continue;\n }\n const mine = sharedSchemaNames({ schemaSuffix: v.schemaSuffix });\n if (mine.join(',') !== theirs.join(',')) {\n warnings.push(\n `drzl config: the \"${g.kind}\" generator's validation.schemaSuffix ` +\n `(${JSON.stringify(v.schemaSuffix ?? 'Schema')}) does not match the \"${library}\" ` +\n `generator's schemaSuffix (${JSON.stringify(sibling.schemaSuffix ?? 'Schema')}). ` +\n `The router will import ${mine.join(', ')} but the \"${library}\" generator exports ` +\n `${theirs.join(', ')}, so the generated router will not compile. Set both to the ` +\n `same value, or move to \"affix\", which is inherited automatically.`\n );\n }\n continue;\n }\n\n const mine = sharedSchemaNames({\n affix: v.affix as AffixOptions,\n schemaSuffix: v.schemaSuffix,\n });\n if (mine.join(',') !== theirs.join(',')) {\n throw new Error(\n `drzl config: the \"${g.kind}\" generator imports shared ${library} schemas, but its ` +\n `validation.affix disagrees with the \"${library}\" generator's own naming. The router ` +\n `would import ${mine.join(', ')} while the \"${library}\" generator exports ` +\n `${theirs.join(', ')}. Make them match, or drop validation.affix and let it be ` +\n `inherited from the \"${library}\" generator.`\n );\n }\n }\n\n return { config: { ...cfg, generators }, warnings };\n}\n\n/**\n * `ConfigSchema` as a JSON Schema, once, for the two things that read it back.\n *\n * Rebuilt on every call it would cost about 0.7ms, which is nothing for `generate` and is paid on\n * every rebuild of a `watch` that may run for a day. Held apart from `buildConfigJsonSchema`\n * itself so the exported function keeps handing every caller a fresh object it may write to; this\n * one is only ever read.\n */\nlet configShape: Record<string, unknown> | null = null;\nfunction configShapeForReading(): Record<string, unknown> {\n return (configShape ??= buildConfigJsonSchema());\n}\n\n/**\n * How the config file is named in a message: relative to where the command was run, unless that\n * would be a walk back up out of it, which says less than the path itself.\n */\nfunction displayConfigPath(file: string, cwd = process.cwd()): string {\n const relative = path.relative(cwd, file);\n return relative && !relative.startsWith('..') ? relative : file;\n}\n\n/**\n * Parse, report, then resolve cross-generator defaults. Both `generate` and `watch` go through\n * loadConfig, so putting the resolution here is what keeps the two duplicated generator\n * dispatch blocks in cli.ts from needing the logic twice.\n *\n * `safeParse` rather than `parse`, because the thrown `ZodError`'s message is a formatted JSON\n * array of issue objects and that array is what the CLI used to print (item 78). The issues\n * themselves carry the key path; only the rendering was missing.\n *\n * Unknown keys are reported after the parse succeeds and not before (item 79). A config that does\n * not parse has a failure to fix first, and listing the keys that would have been dropped from a\n * config nobody can load yet is noise under an error.\n */\nfunction finalize(raw: unknown, file: string, onWarn: (warning: string) => void): DrzlConfig {\n const parsed = ConfigSchema.safeParse(raw);\n if (!parsed.success) {\n throw new ConfigValidationError(\n formatConfigProblems(\n displayConfigPath(file),\n parsed.error.issues,\n raw,\n configShapeForReading()\n )\n );\n }\n for (const w of unknownKeyWarnings(raw, configShapeForReading())) onWarn(w);\n // A config with no `generators` key gets oRPC routers, which is a whole API surface arriving\n // from a default nobody typed. Someone who came for validators and wrote the smallest config\n // that parses gets a router tree and no hint of where it came from.\n //\n // Said rather than changed. Both ways of removing the surprise, requiring the key or defaulting\n // to zod, change what an existing config does, and that belongs with a major rather than with a\n // patch. What does not have to wait is the silence: the default is now named where it applies,\n // with the choices beside it. Read off `raw`, because the parsed config cannot tell a key that\n // was absent from one that was written out.\n if (raw && typeof raw === 'object' && !('generators' in (raw as Record<string, unknown>))) {\n onWarn(\n `drzl config: no \"generators\" key, so this run uses the default, [{ kind: 'orpc' }], and ` +\n `writes an oRPC router tree. Name the key to choose: \"zod\", \"valibot\", \"arktype\", ` +\n `\"typebox\", \"effect\" and \"json-schema\" emit validation schemas, \"orpc\", \"trpc\", \"hono\", ` +\n `\"express\", \"fastify\", \"nestjs\" and \"graphql\" emit an API surface, and \"service\" emits ` +\n `typed data-access stubs.`\n );\n }\n const { config, warnings } = resolveConfig(parsed.data);\n for (const w of warnings) onWarn(w);\n return config;\n}\n\n/**\n * Load a config module fresh from disk: JSON parsed directly, everything else through jiti\n * with cache-busting, exactly as `loadConfig` always has.\n *\n * Extracted so the drizzle-kit interop reads `drizzle.config.ts` through the same loader that\n * reads `drzl.config.ts`, rather than through a second dependency or a second set of jiti\n * options that could drift from this one.\n */\nexport async function importFreshConfigModule(p: string): Promise<unknown> {\n const fsp = await import('node:fs/promises');\n const ext = path.extname(p).toLowerCase();\n\n // JSON: read directly\n if (ext === '.json') {\n return JSON.parse(await fsp.readFile(p, 'utf8'));\n }\n\n // Everything else (TS/JS/MJS/CJS) -> Jiti with cache-busting\n const { createJiti } = await import('jiti');\n const stat = await fsp.stat(p);\n\n // Passing __filename is safe in CJS; fallback to cwd if not defined.\n const base =\n typeof __filename !== 'undefined' ? __filename : path.join(process.cwd(), 'index.js');\n\n const jiti = createJiti(base, {\n moduleCache: false, // re-evaluate each time\n fsCache: true, // keep transform cache\n cacheVersion: String(stat.mtimeMs), // bump on edit\n interopDefault: true,\n tryNative: false, // <-- prevent native import of .ts\n // debug: true,\n }) as any;\n\n const mod = await jiti.import(p);\n return mod?.default ?? mod;\n}\n\n/**\n * The config, or `null` when there is none.\n *\n * `onWarn` exists so the config's warnings reach the output layer rather than the process. They\n * went to `console.warn` until now, which is stderr with no route through `--quiet` or `--json`:\n * `drzl generate --json` printed them beside the document it promises is the only thing on\n * stdout's channel, and `--quiet` could not remove them. Item 79 adds a warning to exactly this\n * path, so the path is fixed here rather than gaining a second writer that bypasses `Output`.\n *\n * The default keeps the old behaviour for any caller that has no output layer to hand.\n */\nexport async function loadConfig(\n customPath?: string,\n onWarn: (warning: string) => void = (warning) => console.warn(warning)\n): Promise<DrzlConfig | null> {\n const fsp = await import('node:fs/promises');\n\n const candidates = customPath ? [customPath] : [...CONFIG_FILE_NAMES];\n\n for (const c of candidates) {\n const p = path.resolve(process.cwd(), c);\n try {\n await fsp.access(p);\n } catch {\n continue;\n }\n return finalize(await importFreshConfigModule(p), p, onWarn);\n }\n\n return null;\n}\n\n/**\n * A config nobody wrote to a file, built from what the command line said.\n *\n * `drzl generate --schema src/db/schema.ts --only orpc` is the config route with the config\n * inlined, and it is what replaces the two per-kind commands: those took a schema path and a kind\n * and could reach none of the config's features, because they had no config at all. This produces\n * a real one, so everything downstream, the filters, the naming, the write plan, `--check`, is the\n * same code reading the same shape whether the config came from disk or from two flags.\n *\n * Through `ConfigSchema` and `resolveConfig` rather than by hand, and that is the whole point: the\n * defaults a config file gets are applied here too, `importExtension` is pushed down onto each\n * generator exactly as it is for a file, and a hand-built object that skipped either would emit\n * different bytes from the equivalent config for no reason a user could see.\n *\n * `schema` may be omitted, in which case the drizzle-kit config answers for it, exactly as it does\n * for a `drzl.config.ts` with no `schema` key.\n */\nexport function configFromKinds(\n kinds: readonly GeneratorKind[],\n schema?: string,\n onWarn: (warning: string) => void = () => {}\n): DrzlConfig {\n const parsed = ConfigSchema.parse({\n ...(schema ? { schema } : {}),\n generators: kinds.map((kind) => ({ kind })),\n });\n const { config, warnings } = resolveConfig(parsed);\n for (const w of warnings) onWarn(w);\n return config;\n}\n\n/** Absolute output dirs for all generators (to ignore in watcher). */\nexport function computeGeneratorOutputDirs(cfg: DrzlConfig, cwd = process.cwd()): string[] {\n const abs = (p: string) => path.resolve(cwd, p);\n const dirs = new Set<string>();\n dirs.add(abs(cfg.outDir)); // orpc\n for (const g of cfg.generators) {\n if (g.kind === 'trpc') dirs.add(abs(trpcOutDir(g, cfg)));\n if (g.kind === 'hono') dirs.add(abs(honoOutDir(g, cfg)));\n if (g.kind === 'express') dirs.add(abs(expressOutDir(g, cfg)));\n if (g.kind === 'fastify') dirs.add(abs(fastifyOutDir(g, cfg)));\n if (g.kind === 'nestjs') dirs.add(abs(nestjsOutDir(g, cfg)));\n if (g.kind === 'graphql') dirs.add(abs(graphqlOutDir(g, cfg)));\n if (g.kind === 'service') dirs.add(abs(g.path ?? 'src/services'));\n if (g.kind === 'zod') dirs.add(abs(g.path ?? 'src/validators/zod'));\n if (g.kind === 'valibot') dirs.add(abs(g.path ?? 'src/validators/valibot'));\n if (g.kind === 'arktype') dirs.add(abs(g.path ?? 'src/validators/arktype'));\n if (g.kind === 'typebox') dirs.add(abs(g.path ?? 'src/validators/typebox'));\n if (g.kind === 'effect') dirs.add(abs(g.path ?? 'src/validators/effect'));\n if (g.kind === 'json-schema') dirs.add(abs(g.path ?? 'src/validators/json-schema'));\n }\n return [...dirs];\n}\n\n/** Resolve custom template directories (local path or installed package). */\nexport function resolveTemplateDirsSync(cfg: DrzlConfig, cwd = process.cwd()): string[] {\n const results: string[] = [];\n const req = createRequire(\n typeof __filename !== 'undefined' ? __filename : path.join(process.cwd(), 'index.js')\n );\n\n for (const g of cfg.generators) {\n const t = g.template;\n // Built-in template names, not packages. `service` is the tRPC generator's, and without it\n // here every run would try to resolve a package called \"service\" and then watch a directory\n // of that name, neither of which exists.\n if (!t || t === 'standard' || t === 'minimal' || t === 'service') continue;\n\n // Try package resolution relative to cwd\n let pkgDir: string | null = null;\n try {\n const pkg = req.resolve(`${t}/package.json`, { paths: [cwd] as any });\n pkgDir = path.dirname(pkg);\n } catch {}\n\n if (pkgDir) {\n results.push(pkgDir);\n continue;\n }\n\n // Local path-like template\n if (/[./\\\\]/.test(t)) {\n const abs = path.resolve(cwd, t);\n if (fs.existsSync(abs)) results.push(abs);\n }\n }\n\n return Array.from(new Set(results));\n}\n\n/** Build watch targets (exclude output dirs; watcher will ignore those). */\n/**\n * Narrow an analysis's tables to the ones the config asked for.\n *\n * Matching is on the database table name, anchored, with `*` as the only metacharacter. Anchored\n * matters: `user` must not also drop `users`, and a substring match would. `exclude` is applied\n * after `include`, so the safer direction wins when both name the same table.\n *\n * A table also answers to its schema-qualified name, so `reporting.users` addresses one of two\n * same-named tables and `reporting.*` addresses a whole schema. See `tableAliases`.\n */\nexport function filterTables<T extends { name: string; schema?: string }>(\n tables: T[],\n opts: { include?: string[]; exclude?: string[] }\n): T[] {\n let out = tables;\n if (opts.include?.length) out = out.filter((t) => matchesTable(opts.include!, t));\n if (opts.exclude?.length) out = out.filter((t) => !matchesTable(opts.exclude!, t));\n return out;\n}\n\n/**\n * What to warn about the table filter, before it is applied.\n *\n * Separate from `filterTables` so that returns a plain array, as every caller and every test\n * already expects it to.\n */\nexport function tableFilterWarnings(\n tables: readonly { name: string; schema?: string }[],\n opts: { include?: string[]; exclude?: string[] }\n): string[] {\n return [\n ...ambiguousPatternWarnings(opts.include ?? [], tables, 'include'),\n ...ambiguousPatternWarnings(opts.exclude ?? [], tables, 'exclude'),\n ];\n}\n\nexport function computeWatchTargets(\n cfg: DrzlConfig,\n cwd = process.cwd(),\n source?: import('./drizzle-kit.js').ResolvedSchemaSource\n): string[] {\n const abs = (p: string) => path.resolve(cwd, p);\n // Directories and files only, never globs. Chokidar removed glob support in v4 and treats\n // `<dir>/**/*.{ts,tsx,js}` as a literal path, so it watched a directory named `**` that does\n // not exist: no event ever fired and `drzl watch` did its initial build and then sat inert.\n // A directory is watched recursively by chokidar itself, and the extension filtering that the\n // glob was doing now happens on the event instead.\n const targets = new Set<string>(CONFIG_FILE_NAMES.map(abs));\n if (source) {\n // The resolved source's directories cover both shapes: the drzl `schema` file's directory,\n // or every directory the drizzle-kit config's entries live in (glob bases included, so a\n // file created later that matches the glob still raises an event). The drizzle-kit config\n // file itself is watched too: editing it changes which files are the schema, and a watcher\n // not watching it would keep generating from the old set forever.\n for (const d of source.watchDirs) targets.add(abs(d));\n if (source.drizzleKitConfigPath) targets.add(abs(source.drizzleKitConfigPath));\n } else if (cfg.schema) {\n targets.add(path.dirname(abs(cfg.schema)));\n }\n for (const t of resolveTemplateDirsSync(cfg, cwd)) targets.add(t);\n return [...targets];\n}\n","/**\n * What a bad `drzl.config` says, and what a silently-dropped key says instead of nothing.\n *\n * Two plan items, one file, because they are the same question asked at two levels of the config\n * schema. Both were measured on the built 4.22.0 CLI before anything here existed.\n *\n * **A validation failure printed the zod dump (item 78).** `ConfigSchema.parse` throws a\n * `ZodError` whose `.message` is a formatted JSON array of issue objects, and the CLI printed it\n * verbatim. A config that set `outDir: 123` produced eleven lines of JSON in which the word\n * `outDir` appeared once, inside a `path` array, three levels down. zod already knows which key\n * it was talking about; it was thrown away at the point of printing.\n *\n * **An unknown key produced no output at all (item 79).** `ConfigSchema` and `GeneratorSchema`\n * are both permissive, so zod strips a key it does not recognise and says nothing. Measured:\n * `outDirr: 'src/api'` at the root, `typedJsn: true` in a generator entry and\n * `validation: { librari: 'zod' }` in a nested object all generated normally and exited 0. This\n * repository has already shipped that failure twice from the other direction, as a documented\n * option the config schema did not declare (`databaseInjection`, `coerceDates`), and the user\n * side of it is identical: a setting that is written down, has no effect, and is never mentioned.\n *\n * The known keys at every level come from the JSON Schema `buildConfigJsonSchema()` derives from\n * `ConfigSchema` (item 64), rather than from a list maintained here. That matters for more than\n * duplication: `additionalProperties: false` appears in it exactly where the zod object is\n * `.strict()`, so the same walk distinguishes the levels zod refuses a key at from the levels it\n * drops one at, and neither can drift from the schema as the config grows.\n */\n\n/** A JSON Schema node, read rather than validated against, so nothing here needs a resolver. */\ntype SchemaNode = Record<string, unknown>;\n\n/**\n * An own property, without `Object.hasOwn`, which needs the ES2022 lib this repository does not\n * target, and without a bare `in`, which walks the prototype chain and would answer yes to\n * `constructor` and `toString` on every object walked here.\n */\nfunction hasOwn(object: object, key: string): boolean {\n return Object.prototype.hasOwnProperty.call(object, key);\n}\n\n/** The code a config that does not parse reports, on stderr and in the `--json` document. */\nexport const CONFIG_INVALID_CODE = 'DRZL_CFG_002';\n\n/**\n * A config that could not be parsed, carrying the code the failure document needs.\n *\n * A class rather than a `code` property on a plain `Error`, because the `generate` catch has to\n * tell this apart from every other throw, and `e.code` is a convention Node already uses:\n * `ENOENT` from a filesystem call would otherwise land in the `--json` document as though it\n * were one of ours.\n */\nexport class ConfigValidationError extends Error {\n readonly code = CONFIG_INVALID_CODE;\n constructor(message: string) {\n super(message);\n this.name = 'ConfigValidationError';\n }\n}\n\n/** The subset of a zod issue this file reads. Structural, so it is not tied to a zod version. */\nexport interface ConfigIssue {\n code?: string;\n path?: readonly PropertyKey[];\n message?: string;\n /** Present on `unrecognized_keys`, which is what a `.strict()` object produces. */\n keys?: readonly string[];\n}\n\n/** How many problems are listed before the rest are counted instead. */\nconst MAX_LISTED_PROBLEMS = 8;\n\n/** How long a value may be before showing it costs more than it explains. */\nconst MAX_VALUE_CHARS = 60;\n\n/**\n * A key path as a reader would write it: `generators[1].validation.library`.\n *\n * Not `generators.1.validation.library` and not the flattened blob zod prints. A path a user can\n * paste back into their own config file is the whole of item 78; anything else makes them count\n * array entries by hand.\n *\n * A key that is not an identifier is bracketed and quoted, because `columns` is keyed by table\n * pattern and `columns.app_*` reads as though `*` were part of the path language.\n */\nexport function renderConfigPath(segments: readonly PropertyKey[]): string {\n if (!segments.length) return '(root)';\n let out = '';\n for (const segment of segments) {\n if (typeof segment === 'number') {\n out += `[${segment}]`;\n continue;\n }\n const key = String(segment);\n if (/^[A-Za-z_$][A-Za-z0-9_$]*$/.test(key)) out += out ? `.${key}` : key;\n else out += `[${JSON.stringify(key)}]`;\n }\n return out;\n}\n\n/**\n * What the config actually said at that key, short enough to sit on the line.\n *\n * Numbers go through `String`, never `JSON.stringify`. `JSON.stringify(NaN)` is the four\n * characters `null`, and so is `JSON.stringify(Infinity)`, so a config written `nestedDepth: NaN`\n * would be reported as having said `null`: a different mistake, with a different fix, stated with\n * total confidence. That exact substitution has already turned one real defect in this repository\n * into a reasoned-through false conclusion.\n *\n * Returns `null` when there is nothing worth showing, which is what keeps a whole generator entry\n * out of a message about one of its keys.\n */\nexport function describeValue(value: unknown): string | null {\n if (value === undefined) return 'undefined';\n if (value === null) return 'null';\n switch (typeof value) {\n case 'boolean':\n return String(value);\n case 'number':\n return String(value);\n case 'bigint':\n return `${value}n`;\n case 'function':\n return '[function]';\n case 'symbol':\n return String(value);\n case 'string':\n return value.length <= MAX_VALUE_CHARS\n ? JSON.stringify(value)\n : `${JSON.stringify(value.slice(0, MAX_VALUE_CHARS))} ... (${value.length} characters)`;\n }\n let json: string;\n try {\n json = JSON.stringify(value) as string;\n } catch {\n return null;\n }\n if (typeof json !== 'string') return null;\n return json.length <= MAX_VALUE_CHARS ? json : null;\n}\n\n/** The value the config really holds at a path, and whether the path leads anywhere at all. */\nfunction valueAt(\n raw: unknown,\n segments: readonly PropertyKey[]\n): { found: boolean; value: unknown } {\n let current: unknown = raw;\n for (const segment of segments) {\n if (current === null || typeof current !== 'object') return { found: false, value: undefined };\n // `hasOwn` rather than `in`, which walks the prototype chain: a path segment of `constructor`\n // or `toString` would otherwise be reported as a value the config states.\n if (!hasOwn(current, String(segment))) return { found: false, value: undefined };\n current = (current as Record<PropertyKey, unknown>)[segment as never];\n }\n return { found: true, value: current };\n}\n\n/**\n * Levenshtein distance, iteratively over two rows.\n *\n * Written here rather than installed. Config keys are a handful of characters and there are under\n * forty of them, so this costs nothing worth measuring, and a dependency added to suggest a\n * spelling is a dependency on every install of the CLI for ever.\n */\nexport function editDistance(a: string, b: string): number {\n if (a === b) return 0;\n if (!a.length) return b.length;\n if (!b.length) return a.length;\n let previous = Array.from({ length: b.length + 1 }, (_, i) => i);\n for (let i = 1; i <= a.length; i++) {\n const current = new Array<number>(b.length + 1);\n current[0] = i;\n for (let j = 1; j <= b.length; j++) {\n const substitution = previous[j - 1] + (a[i - 1] === b[j - 1] ? 0 : 1);\n current[j] = Math.min(current[j - 1] + 1, previous[j] + 1, substitution);\n }\n previous = current;\n }\n return previous[b.length];\n}\n\n/**\n * The key the writer probably meant, or nothing.\n *\n * A typo, not a different word. One edit for a short key and two for anything from five\n * characters up: `librari` to `library` is one, `typedJsn` to `typedJson` is one, `outDirr` to\n * `outDir` is one, and `abc` to `kind` is three, which is somebody meaning something else. A\n * wrong suggestion is worse than none, because it sends a reader to change a line that was right.\n *\n * Ties go to the earliest known key, which is schema declaration order, so the suggestion for a\n * given typo is the same on every run.\n */\nexport function nearestKey(key: string, known: readonly string[]): string | undefined {\n const budget = key.length >= 5 ? 2 : 1;\n let best: string | undefined;\n let bestDistance = Number.POSITIVE_INFINITY;\n for (const candidate of known) {\n if (candidate === key) return undefined;\n const distance = editDistance(key, candidate);\n if (distance <= budget && distance < bestDistance) {\n best = candidate;\n bestDistance = distance;\n }\n }\n return best;\n}\n\n/**\n * The object description at a node, seeing through a `anyOf`.\n *\n * A union is only followed when exactly one of its branches describes an object. Two would mean\n * guessing which one the value was written against, and a wrong guess reports keys that are\n * perfectly valid, which is the one outcome item 79 must not produce.\n */\nfunction objectNodeFor(node: unknown): SchemaNode | undefined {\n if (!node || typeof node !== 'object') return undefined;\n const record = node as SchemaNode;\n const anyOf = record.anyOf;\n if (Array.isArray(anyOf)) {\n const branches = anyOf.filter(\n (branch) =>\n branch &&\n typeof branch === 'object' &&\n ((branch as SchemaNode).properties !== undefined ||\n typeof (branch as SchemaNode).additionalProperties === 'object')\n ) as SchemaNode[];\n return branches.length === 1 ? branches[0] : undefined;\n }\n if (record.properties !== undefined || record.additionalProperties !== undefined) return record;\n return undefined;\n}\n\n/** One key the config states and the schema does not declare. */\nexport interface UnknownConfigKey {\n /** Where the object holding it lives, as instance-path segments. */\n path: readonly PropertyKey[];\n key: string;\n suggestion?: string;\n}\n\n/**\n * Every key a permissive level of the config schema would drop in silence.\n *\n * Strict levels are skipped deliberately: zod refuses those outright, so nothing reaches this\n * walk with one set, and `formatConfigProblems` gives that refusal the same key path and the same\n * suggestion this produces. Record levels are skipped too, and for the opposite reason: the keys\n * of `columns` are table patterns and the keys of `templateOptions` are a template's own options,\n * so there is no such thing as an unknown one there.\n */\nexport function unknownConfigKeys(raw: unknown, schema: SchemaNode): UnknownConfigKey[] {\n const found: UnknownConfigKey[] = [];\n walkForUnknownKeys(raw, schema, [], found);\n return found;\n}\n\nfunction walkForUnknownKeys(\n value: unknown,\n node: unknown,\n segments: PropertyKey[],\n found: UnknownConfigKey[]\n): void {\n if (value === null || typeof value !== 'object') return;\n\n if (Array.isArray(value)) {\n const items = (node as SchemaNode | undefined)?.items;\n if (!items) return;\n value.forEach((entry, index) => walkForUnknownKeys(entry, items, [...segments, index], found));\n return;\n }\n\n const object = objectNodeFor(node);\n if (!object) return;\n\n const properties = object.properties as Record<string, unknown> | undefined;\n const additional = object.additionalProperties;\n\n if (!properties) {\n // A record. Only the values are described by the schema, so the keys are the user's data and\n // every one of them is legitimate.\n if (additional && typeof additional === 'object') {\n for (const [key, entry] of Object.entries(value as Record<string, unknown>)) {\n walkForUnknownKeys(entry, additional, [...segments, key], found);\n }\n }\n return;\n }\n\n const known = Object.keys(properties);\n for (const [key, entry] of Object.entries(value as Record<string, unknown>)) {\n if (hasOwn(properties, key)) {\n walkForUnknownKeys(entry, properties[key], [...segments, key], found);\n continue;\n }\n if (additional === false) continue;\n found.push({ path: [...segments], key, suggestion: nearestKey(key, known) });\n }\n}\n\n/** The warning lines for every key the config states and the schema drops. */\nexport function unknownKeyWarnings(raw: unknown, schema: SchemaNode): string[] {\n return unknownConfigKeys(raw, schema).map((unknown) => {\n const where = unknown.path.length ? `in ${renderConfigPath(unknown.path)}` : 'at the top level';\n const suggestion = unknown.suggestion ? ` Did you mean \"${unknown.suggestion}\"?` : '';\n return `drzl config: unknown key \"${unknown.key}\" ${where}; it is ignored.${suggestion}`;\n });\n}\n\n/** The schema node an instance path leads to, for reading the known keys off a strict object. */\nfunction nodeAt(schema: SchemaNode, segments: readonly PropertyKey[]): SchemaNode | undefined {\n let node: unknown = schema;\n for (const segment of segments) {\n if (typeof segment === 'number') {\n node = (node as SchemaNode | undefined)?.items;\n continue;\n }\n const object = objectNodeFor(node);\n if (!object) return undefined;\n const properties = object.properties as Record<string, unknown> | undefined;\n if (properties && hasOwn(properties, String(segment))) {\n node = properties[String(segment)];\n continue;\n }\n const additional = object.additionalProperties;\n if (additional && typeof additional === 'object') {\n node = additional;\n continue;\n }\n return undefined;\n }\n return objectNodeFor(node);\n}\n\n/** The keys declared at a path, so a strict object's refusal can carry a suggestion too. */\nfunction knownKeysAt(schema: SchemaNode, segments: readonly PropertyKey[]): string[] {\n const node = nodeAt(schema, segments);\n const properties = node?.properties as Record<string, unknown> | undefined;\n return properties ? Object.keys(properties) : [];\n}\n\n/** One issue, as one line: where it is, what is wrong, and what the file actually says. */\nfunction renderIssue(issue: ConfigIssue, raw: unknown, schema: SchemaNode): string[] {\n const segments = issue.path ?? [];\n const where = renderConfigPath(segments);\n\n if (issue.code === 'unrecognized_keys' && issue.keys?.length) {\n const known = knownKeysAt(schema, segments);\n return issue.keys.map((key) => {\n const suggestion = nearestKey(key, known);\n return `${where}: unrecognized key \"${key}\".${suggestion ? ` Did you mean \"${suggestion}\"?` : ''}`;\n });\n }\n\n // zod prefixes every type failure with \"Invalid input: \", which restates the header this line\n // already sits under.\n const what = String(issue.message ?? 'is not valid').replace(/^Invalid input:\\s*/, '');\n const { found, value } = valueAt(raw, segments);\n const shown = found ? describeValue(value) : null;\n return [`${where}: ${what}${shown === null ? '' : ` (found ${shown})`}`];\n}\n\n/**\n * Every problem in a config that would not parse, one per line, each naming its key.\n *\n * All of them rather than the first, because a config written from an old example usually has\n * three or four problems of the same kind, and reporting one per run makes the user run the CLI\n * once per typo. Capped, because a config whose top-level shape is wrong can produce an issue per\n * key and a screen of them says less than eight and a count.\n *\n * The order is zod's, which is declaration order of the schema rather than of the file, and it is\n * stable across runs.\n */\nexport function formatConfigProblems(\n file: string,\n issues: readonly ConfigIssue[],\n raw: unknown,\n schema: SchemaNode\n): string {\n const lines = issues.flatMap((issue) => renderIssue(issue, raw, schema));\n const shown = lines.slice(0, MAX_LISTED_PROBLEMS);\n const rest = lines.length - shown.length;\n const header = `${file} is not valid (${CONFIG_INVALID_CODE}). ${lines.length} problem${\n lines.length === 1 ? '' : 's'\n }:`;\n const body = shown.map((line) => ` - ${line}`);\n if (rest > 0) body.push(` ... and ${rest} more`);\n return [header, ...body].join('\\n');\n}\n","/**\n * The one name-matching language every filter in a DRZL config speaks.\n *\n * Anchored, with `*` as the only metacharacter. Anchored is the whole point: `user` must not also\n * match `users`, and a substring match would, which for the table filter means silently dropping\n * the application's main entity while trying to drop an auth table.\n *\n * Shared rather than reimplemented. `include`/`exclude` and the per-table `columns` filter both\n * take patterns, and a reader who has learned one has learned the other only while there is one\n * implementation of \"learned\". Two copies of an anchored glob agree on the easy cases and drift on\n * exactly the corners that made this explicit in the first place.\n */\nexport function patternToRegExp(pattern: string): RegExp {\n return new RegExp(\n '^' +\n pattern\n .split('*')\n .map((part) => part.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&'))\n .join('.*') +\n '$'\n );\n}\n\n/** Whether any of `patterns` matches `name` outright. */\nexport function matchesAny(patterns: string[], name: string): boolean {\n return patterns.some((p) => patternToRegExp(p).test(name));\n}\n\n/** The least a filter needs to know about a table. */\nexport interface NamedTable {\n name: string;\n schema?: string;\n}\n\n/** How the default SQL schema is spelled in a config, since a table in it carries no name for it. */\nexport const DEFAULT_SCHEMA_ALIAS = 'public';\n\n/**\n * Every name a table answers to in a config pattern.\n *\n * A table states one name and lives in one schema, and Postgres lets two schemas hold the same\n * name, so `users` alone stopped identifying a table the moment `pgSchema` entered the picture.\n * Each table therefore answers to two:\n *\n * - its bare database name, unchanged and listed first, so every pattern that matched before\n * matches now. That is not a compatibility gesture: `exclude: ['users']` written before a\n * `reporting` schema existed means \"the users tables\", and quietly narrowing it to one of them\n * would start generating an endpoint the config had already turned off.\n * - its qualified name, `reporting.users`, which is what addresses exactly one of them.\n *\n * A table with no schema answers to `public.users` rather than to a bare-schema form, because\n * Drizzle refuses `pgSchema('public')` outright: there is no other way to write a table in the\n * default schema, so there is no other name for it to have. That makes `public.` an alias this\n * file defines rather than something read back off the analysis, which is why it is only ever\n * offered to a table that names no schema.\n *\n * Order is the order they are tried, and the bare name being first is what keeps a table whose own\n * name contains a dot reachable by a pattern that spells it.\n */\nexport function tableAliases(table: NamedTable): string[] {\n return [table.name, `${table.schema ?? DEFAULT_SCHEMA_ALIAS}.${table.name}`];\n}\n\n/** Whether any of `patterns` matches the table under any of the names it answers to. */\nexport function matchesTable(patterns: string[], table: NamedTable): boolean {\n return tableAliases(table).some((alias) => matchesAny(patterns, alias));\n}\n\n/**\n * How a message names one table.\n *\n * Qualified only where the table names a schema, so every message in a project that uses none is\n * word for word what it was, and a project that uses several never has two of them reading alike.\n */\nexport function displayTableName(table: NamedTable): string {\n return table.schema ? `${table.schema}.${table.name}` : table.name;\n}\n\n/**\n * The spelling that addresses exactly this table and no other, `public.users` included.\n *\n * For a message whose job is to hand the reader something to paste into a config. Elsewhere\n * `displayTableName` is the one to use: spelling `public.` at someone who has only ever had one\n * schema names a concept their schema file does not contain.\n */\nexport function addressableName(table: NamedTable): string {\n return `${table.schema ?? DEFAULT_SCHEMA_ALIAS}.${table.name}`;\n}\n\n/** Whether an analysis has any table outside the default schema at all. */\nexport function hasNamedSchemas(tables: readonly NamedTable[]): boolean {\n return tables.some((t) => t.schema);\n}\n\n/**\n * Patterns that reach more than one SQL schema, which is nearly always a pattern written before\n * the second schema existed.\n *\n * Reported rather than refused. Matching every schema is what an unqualified pattern has always\n * done and is the reading that keeps an existing `exclude` doing its job, so it cannot be an\n * error. It is still worth a sentence, because the two tables are different tables: `columns: {\n * users: { pick: ['id', 'email'] } }` narrows both, and the table that has no `email` silently\n * loses every column that is not `id`, while the typo check stays quiet because the pattern did\n * match a column somewhere.\n *\n * Silent on a schema that uses no `pgSchema`, which is the shape of nearly every one: with one\n * schema in play no pattern can span two.\n */\nexport function ambiguousPatternWarnings(\n patterns: string[],\n tables: readonly NamedTable[],\n option: string\n): string[] {\n const out: string[] = [];\n for (const pattern of patterns) {\n // A pattern that already names a schema said which one it meant.\n if (pattern.includes('.')) continue;\n const matched = tables.filter((t) => matchesTable([pattern], t));\n const schemas = new Set(matched.map((t) => t.schema ?? DEFAULT_SCHEMA_ALIAS));\n if (schemas.size < 2) continue;\n out.push(\n `drzl config: ${option} pattern ${JSON.stringify(pattern)} matches tables in more than one ` +\n `schema, and every one of them is affected: ` +\n `${matched.map(addressableName).sort().join(', ')}. ` +\n `Write the schema to mean one of them, for example ${JSON.stringify(addressableName(matched[0]))}.`\n );\n }\n return out;\n}\n"],"mappings":"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","names":["mine","relative"]}
package/dist/cli.cjs CHANGED
@@ -1064,6 +1064,11 @@ function finalize(raw, file, onWarn) {
1064
1064
  );
1065
1065
  }
1066
1066
  for (const w of unknownKeyWarnings(raw, configShapeForReading())) onWarn(w);
1067
+ if (raw && typeof raw === "object" && !("generators" in raw)) {
1068
+ onWarn(
1069
+ `drzl config: no "generators" key, so this run uses the default, [{ kind: 'orpc' }], and writes an oRPC router tree. Name the key to choose: "zod", "valibot", "arktype", "typebox", "effect" and "json-schema" emit validation schemas, "orpc", "trpc", "hono", "express", "fastify", "nestjs" and "graphql" emit an API surface, and "service" emits typed data-access stubs.`
1070
+ );
1071
+ }
1067
1072
  const { config, warnings } = resolveConfig(parsed.data);
1068
1073
  for (const w of warnings) onWarn(w);
1069
1074
  return config;
@@ -1769,7 +1774,7 @@ function checkFindings(table) {
1769
1774
  const label = k.name ? `"${k.name}"` : "an unnamed constraint";
1770
1775
  const raw = k.expression ?? "";
1771
1776
  const expr = raw.trim() ? raw : "(empty)";
1772
- const parsed = (0, import_validation_core2.parseCheck)(raw, k.name);
1777
+ const parsed = (0, import_validation_core2.parseCheck)(raw, k.name, table.dialect);
1773
1778
  if (!parsed.ok) {
1774
1779
  out.push({
1775
1780
  kind: "check-declined",