cvx-kit 0.1.14 → 0.1.16

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.
Files changed (51) hide show
  1. package/README.md +64 -45
  2. package/dist/querying/cursors.d.mts +5 -0
  3. package/dist/querying/cursors.mjs +1 -1
  4. package/dist/querying/cursors.mjs.map +1 -1
  5. package/dist/querying.d.mts +20 -6
  6. package/dist/querying.mjs +1 -1
  7. package/dist/querying.mjs.map +1 -1
  8. package/dist/relations.mjs +1 -1
  9. package/dist/relations.mjs.map +1 -1
  10. package/dist/zod-table.d.mts +59 -2
  11. package/dist/zod-table.mjs +1 -1
  12. package/dist/zod-table.mjs.map +1 -1
  13. package/package.json +10 -3
  14. package/AGENTS.md +0 -47
  15. package/CHANGELOG.md +0 -324
  16. package/ROADMAP.md +0 -126
  17. package/docs/agent-tools.md +0 -41
  18. package/docs/approvals.md +0 -201
  19. package/docs/architecture.md +0 -124
  20. package/docs/auth.md +0 -443
  21. package/docs/command-context.md +0 -150
  22. package/docs/commands-legacy.md +0 -513
  23. package/docs/commands.md +0 -173
  24. package/docs/conventions.md +0 -345
  25. package/docs/crud.md +0 -66
  26. package/docs/domain-contracts.md +0 -148
  27. package/docs/domain-operations.md +0 -615
  28. package/docs/effect.md +0 -403
  29. package/docs/llms.md +0 -324
  30. package/docs/maintainability.md +0 -124
  31. package/docs/migration.md +0 -351
  32. package/docs/oxlint.md +0 -254
  33. package/docs/querying.md +0 -293
  34. package/docs/tenancy.md +0 -176
  35. package/docs/triggers.md +0 -77
  36. package/docs/upgrading.md +0 -287
  37. package/docs/webhooks.md +0 -58
  38. package/docs/zod-table.md +0 -278
  39. package/scripts/convex-config-bridge.mjs +0 -44
  40. package/scripts/convex-smoke-env.mjs +0 -33
  41. package/scripts/extract-changelog.mjs +0 -29
  42. package/scripts/owned-process.mjs +0 -140
  43. package/scripts/owned-process.test.mjs +0 -107
  44. package/scripts/smoke-packed-components.mjs +0 -341
  45. package/scripts/smoke-packed-effect.mjs +0 -439
  46. package/scripts/smoke-packed-querying.mjs +0 -296
  47. package/scripts/test-packed-auth.mjs +0 -72
  48. package/scripts/test-packed-effect.mjs +0 -482
  49. package/scripts/test-packed-ids.mjs +0 -150
  50. package/scripts/test-packed-oxlint.mjs +0 -167
  51. package/scripts/test-packed-querying.mjs +0 -185
@@ -1 +1 @@
1
- {"version":3,"file":"zod-table.mjs","names":["zid","convexToZod","convexToZod$1","zid$1","timestampFields","z","TIMESTAMP_FIELDS","zodTable","declared","fields","assertOwnedFields","columns","assertFieldLists","options","storage","schema","documentSchema","tableName","omittedKeys","commandKeys","publicKeys","insertSchema","omitFields","updateSchema","commandInput","pickFields","publicDto","reservedDtoFields","dto","deriveDto","normalized","extension","key","assertDtoValidationSchema","resultSchema","toPublicDto","projected","row","result","insert","omit","update","nativeStorage","zodToConvex","table","defineTable","paginationOpts","scalarPaginationSchema","selection","jsonSafeZid","tenantFields","tenantTable","id","createModule","maps","combined","map","definition","paginated","paginationOptsValidator","zodVariantTable","value","keys","omitted","seen","def","reject","visit","child","check","reserved","server","command","managed","convexToZod","zid"],"sources":["../src/zod-table.ts"],"sourcesContent":["import { convexToZod, zid, type ConvexValidatorFromZod, type Zid } from 'convex-helpers/server/zod4'\nimport { defineTable, paginationOptsValidator, type TableDefinition } from 'convex/server'\nimport type { GenericId } from 'convex/values'\nimport { z } from 'zod'\n\nimport { zodToConvex } from './zod-convex'\n\nimport {\n\tscalarPaginationSchema,\n\ttype ScalarPaginationSchema,\n\ttype ScalarSelection,\n\ttype ExactScalarSelection,\n} from './querying/filters'\n\n// Use this entry point when deriving validators from kit-owned schemas so\n// the producer and converter consult the same convex-helpers ID registry.\nexport { zid, convexToZod } from 'convex-helpers/server/zod4'\nexport { zodToConvex } from './zod-convex'\n\ntype FieldSchemas = Record<string, z.ZodType>\ntype FieldKey<Fields extends FieldSchemas> = Extract<keyof Fields, string>\n\n/**\n * Opinionated lifecycle timestamps — every table has them, server-owned,\n * always excluded from insert/command boundaries. Maintained by the\n * `timestamps` trigger helper (see cvx-kit/triggers).\n */\nconst timestampFields = {\n\tcreatedAt: z.number().optional(),\n\tupdatedAt: z.number().optional(),\n\tarchivedAt: z.number().optional(),\n} satisfies FieldSchemas\n\ntype TimestampFields = typeof timestampFields\ntype ReservedStorageField = '_id' | '_creationTime' | keyof TimestampFields\ntype OwnedFields<Fields> = {\n\t[Key in keyof Fields]: Key extends ReservedStorageField ? never : Fields[Key]\n}\ntype SystemFields<Table extends string> = { _id: Zid<Table>; _creationTime: z.ZodNumber }\n\nexport const TIMESTAMP_FIELDS = ['createdAt', 'updatedAt', 'archivedAt'] as const\n\nexport type TableBoundaryOptions<\n\tFields extends FieldSchemas,\n\tServerFields extends readonly FieldKey<Fields>[],\n\tCommandFields extends readonly FieldKey<Fields>[],\n\tPublicFields extends readonly FieldKey<Fields & TimestampFields>[],\n> = {\n\tserverFields?: ServerFields\n\tcommandFields?: CommandFields &\n\t\treadonly Exclude<FieldKey<Fields>, ServerFields[number] | keyof TimestampFields>[]\n\tpublicFields?: PublicFields\n}\n\ntype StrictObject<Fields extends FieldSchemas> = z.ZodObject<Fields, z.core.$strict>\ntype WriteFields<\n\tFields extends FieldSchemas,\n\tServerFields extends readonly FieldKey<Fields>[],\n> = Omit<Fields & TimestampFields, ServerFields[number] | (typeof TIMESTAMP_FIELDS)[number]>\ntype PartialFields<Fields extends FieldSchemas> = {\n\t[Key in keyof Fields]: z.ZodOptional<Fields[Key]>\n}\n\n/** Options shared by the DTO return schema and row projector.\n * Promised contributions must be present, including in reusable options.\n * New extension schemas support validation only: no transforms, pipes,\n * coercion, preprocess, defaults, catches, or overwrites, even when nested.\n * Refinements must validate without mutating their input.\n */\nexport type DtoOptions<IncludeId extends boolean = false, Extension extends FieldSchemas = {}> = ([\n\tIncludeId,\n] extends [true]\n\t? { _id: IncludeId }\n\t: { _id?: IncludeId }) &\n\t(keyof Extension extends never ? { extend?: Extension } : { extend: Extension })\n\ntype DtoProjectionOptions<IncludeId extends boolean> = DtoOptions<IncludeId> & {\n\textend?: Record<string, never>\n\tvalues?: never\n}\n\ntype ReservedDtoField =\n\t| '_id'\n\t| '_creationTime'\n\t| 'tenant'\n\t| '__proto__'\n\t| (typeof TIMESTAMP_FIELDS)[number]\ntype DtoExtension<Public extends FieldSchemas, Extension extends FieldSchemas> = {\n\t[Key in keyof Extension]: Key extends keyof Public | ReservedDtoField\n\t\t? never\n\t\t: Extension[Key] extends z.ZodPipe | z.ZodTransform\n\t\t\t? never\n\t\t\t: unknown\n}\n// Broad dictionaries cannot promise any particular extension field.\ntype KnownExtension<Extension> = string extends keyof Extension ? {} : Extension\n\ntype DtoSchema<\n\tTable extends string,\n\tPublic extends FieldSchemas,\n\tIncludeId extends boolean,\n\tExtension extends FieldSchemas = {},\n> = IncludeId extends true\n\t? StrictObject<Public & { _id: Zid<Table> } & KnownExtension<Extension>>\n\t: StrictObject<Public & KnownExtension<Extension>>\ntype DtoRow<Row, IncludeId extends boolean> = Row & (true extends IncludeId ? { _id: string } : {})\ntype DtoValues<Extension extends FieldSchemas> = keyof Extension extends never\n\t? { values?: never }\n\t: { values: z.input<StrictObject<NoInfer<Extension>>> }\n\ntype DtoBoundary<Table extends string, Fields extends FieldSchemas, Public extends FieldSchemas> = {\n\tdto(): StrictObject<Public>\n\tdto<const IncludeId extends boolean>(includeId: IncludeId): DtoSchema<Table, Public, IncludeId>\n\tdto<const IncludeId extends boolean = false>(\n\t\toptions: DtoProjectionOptions<IncludeId>,\n\t): DtoSchema<Table, Public, IncludeId>\n\tdto<const IncludeId extends boolean = false, const Extension extends FieldSchemas = {}>(\n\t\toptions: DtoOptions<IncludeId, Extension> & { extend?: DtoExtension<Public, Extension> },\n\t): DtoSchema<Table, Public, IncludeId, Extension>\n\ttoPublicDto(row: z.input<StrictObject<Fields>>): z.output<StrictObject<Public>>\n\ttoPublicDto<const IncludeId extends boolean>(\n\t\trow: DtoRow<z.input<StrictObject<Fields>>, IncludeId>,\n\t\tincludeId: IncludeId,\n\t): z.output<DtoSchema<Table, Public, IncludeId>>\n\ttoPublicDto<const IncludeId extends boolean = false>(\n\t\trow: DtoRow<z.input<StrictObject<Fields>>, IncludeId>,\n\t\toptions: DtoProjectionOptions<IncludeId>,\n\t): z.output<DtoSchema<Table, Public, IncludeId>>\n\ttoPublicDto<const IncludeId extends boolean = false, const Extension extends FieldSchemas = {}>(\n\t\trow: DtoRow<z.input<StrictObject<Fields>>, IncludeId>,\n\t\toptions: DtoOptions<IncludeId, Extension> & {\n\t\t\textend?: DtoExtension<Public, Extension>\n\t\t} & DtoValues<Extension>,\n\t): z.output<DtoSchema<Table, Public, IncludeId, Extension>>\n}\n\n/** Named schema relationships keep generated declarations bounded and consumers fully typed. */\nexport type TableBoundary<\n\tTable extends string,\n\tFields extends FieldSchemas,\n\tServerFields extends readonly FieldKey<Fields>[],\n\tCommandFields extends readonly FieldKey<Fields>[],\n\tPublicFields extends readonly FieldKey<Fields & TimestampFields>[],\n> = DtoBoundary<\n\tTable,\n\tFields & TimestampFields,\n\tPick<Fields & TimestampFields, PublicFields[number]>\n> & {\n\tpaginationOpts<\n\t\tconst Selection extends ScalarSelection<Fields & TimestampFields & SystemFields<Table>>,\n\t>(\n\t\tselection: ExactScalarSelection<Fields & TimestampFields & SystemFields<Table>, Selection>,\n\t): ScalarPaginationSchema<Fields & TimestampFields & SystemFields<Table>, Selection>\n\ttableName: Table\n\tstorage: StrictObject<Fields & TimestampFields>\n\tschema: ReturnType<typeof documentSchema<Fields & TimestampFields, Table>>\n\tinsertSchema: StrictObject<WriteFields<Fields, ServerFields>>\n\tupdateSchema: StrictObject<PartialFields<WriteFields<Fields, ServerFields>>>\n\tcommandInput: StrictObject<Pick<Fields & TimestampFields, CommandFields[number]>>\n\tpublicDto: StrictObject<Pick<Fields & TimestampFields, PublicFields[number]>>\n\ttable: TableDefinition<ConvexValidatorFromZod<StrictObject<Fields & TimestampFields>, 'required'>>\n\tinsert(): StrictObject<WriteFields<Fields, ServerFields>>\n\tinsert<Mask extends z.util.Mask<keyof WriteFields<Fields, ServerFields>>>(\n\t\tomit: Mask,\n\t): ZodObjectOmit<StrictObject<WriteFields<Fields, ServerFields>>, Mask>\n\tupdate(): StrictObject<PartialFields<WriteFields<Fields, ServerFields>>>\n\tupdate<Mask extends z.util.Mask<keyof WriteFields<Fields, ServerFields>>>(\n\t\tomit: Mask,\n\t): ZodObjectOmit<StrictObject<PartialFields<WriteFields<Fields, ServerFields>>>, Mask>\n\ttools: {\n\t\tinsert: StrictObject<Pick<Fields & TimestampFields, CommandFields[number]>>\n\t\tupdate: StrictObject<{\n\t\t\tdata: StrictObject<PartialFields<Pick<Fields & TimestampFields, CommandFields[number]>>>\n\t\t\tid: z.ZodType<GenericId<Table>, string>\n\t\t}>\n\t\tid: StrictObject<{ id: z.ZodType<GenericId<Table>, string> }>\n\t}\n}\n\n/** Defines one table and derives its storage, document, write, and DTO boundaries. */\nexport function zodTable<\n\tTable extends string,\n\tFields extends FieldSchemas,\n\tconst ServerFields extends readonly FieldKey<Fields>[] = readonly [],\n\tconst CommandFields extends readonly FieldKey<Fields>[] = readonly [],\n\tconst PublicFields extends readonly FieldKey<Fields & TimestampFields>[] = readonly [],\n>(\n\ttableName: Table,\n\tfields: (id: typeof zid) => Fields & OwnedFields<Fields>,\n\toptions: TableBoundaryOptions<Fields, ServerFields, CommandFields, PublicFields> = {},\n): TableBoundary<Table, Fields, ServerFields, CommandFields, PublicFields> {\n\tconst declared = fields(zid)\n\tassertOwnedFields(declared, ['_id', '_creationTime', ...TIMESTAMP_FIELDS])\n\tconst columns: Fields & TimestampFields = { ...declared, ...timestampFields }\n\tassertFieldLists(\n\t\tcolumns,\n\t\toptions.serverFields ?? [],\n\t\toptions.commandFields ?? [],\n\t\toptions.publicFields ?? [],\n\t)\n\tconst storage: z.ZodObject<Fields & TimestampFields, z.core.$strict> = z.object(columns).strict()\n\tconst schema = documentSchema(storage, tableName)\n\tconst omittedKeys: readonly (ServerFields[number] | (typeof TIMESTAMP_FIELDS)[number])[] = [\n\t\t...TIMESTAMP_FIELDS,\n\t\t...(options.serverFields ?? []),\n\t]\n\tconst commandKeys: readonly CommandFields[number][] = options.commandFields ?? []\n\tconst publicKeys: readonly PublicFields[number][] = options.publicFields ?? []\n\tconst insertSchema: z.ZodObject<WriteFields<Fields, ServerFields>, z.core.$strict> = z\n\t\t.object(omitFields(columns, omittedKeys))\n\t\t.strict()\n\tconst updateSchema = insertSchema.partial()\n\tconst commandInput: z.ZodObject<\n\t\tPick<Fields & TimestampFields, CommandFields[number]>,\n\t\tz.core.$strict\n\t> = z.object(pickFields(columns, commandKeys)).strict()\n\tconst publicDto: z.ZodObject<\n\t\tPick<Fields & TimestampFields, PublicFields[number]>,\n\t\tz.core.$strict\n\t> = z.object(pickFields(columns, publicKeys)).strict()\n\ttype Public = Pick<Fields & TimestampFields, PublicFields[number]>\n\ttype Row = z.input<typeof storage>\n\ttype RuntimeDtoFields = Public & FieldSchemas\n\ttype RuntimeDto = z.output<StrictObject<RuntimeDtoFields>> & { _id?: GenericId<Table> }\n\ttype RuntimeOptions = { _id?: boolean; extend?: FieldSchemas; values?: unknown }\n\tconst reservedDtoFields = new Set<string>([\n\t\t'_id',\n\t\t'_creationTime',\n\t\t'tenant',\n\t\t'__proto__',\n\t\t...TIMESTAMP_FIELDS,\n\t])\n\n\tfunction dto(): typeof publicDto\n\tfunction dto<const IncludeId extends boolean>(\n\t\tincludeId: IncludeId,\n\t): DtoSchema<Table, Public, IncludeId>\n\tfunction dto<const IncludeId extends boolean = false>(\n\t\toptions: DtoProjectionOptions<IncludeId>,\n\t): DtoSchema<Table, Public, IncludeId>\n\tfunction dto<const IncludeId extends boolean = false, const Extension extends FieldSchemas = {}>(\n\t\toptions: DtoOptions<IncludeId, Extension> & { extend?: DtoExtension<Public, Extension> },\n\t): DtoSchema<Table, Public, IncludeId, Extension>\n\tfunction dto(options?: boolean | RuntimeOptions) {\n\t\treturn deriveDto(options)\n\t}\n\n\tfunction deriveDto(options?: boolean | RuntimeOptions) {\n\t\tconst normalized = options === true || options === false ? { _id: options } : options\n\t\tconst extension = normalized?.extend ?? {}\n\t\tfor (const key of Object.keys(extension)) {\n\t\t\tif (reservedDtoFields.has(key) || Object.hasOwn(publicDto.shape, key)) {\n\t\t\t\tthrow new Error(`DTO extension collision for field \"${key}\" on table \"${tableName}\"`)\n\t\t\t}\n\t\t\tassertDtoValidationSchema(extension[key])\n\t\t}\n\t\tif (!normalized?._id && Object.keys(extension).length === 0) return publicDto\n\t\tconst resultSchema = z.object({ ...publicDto.shape, ...extension }).strict()\n\t\treturn normalized?._id ? resultSchema.extend({ _id: schema.shape._id }) : resultSchema\n\t}\n\n\tfunction toPublicDto(row: Row): z.output<typeof publicDto>\n\tfunction toPublicDto<const IncludeId extends boolean>(\n\t\trow: DtoRow<Row, IncludeId>,\n\t\tincludeId: IncludeId,\n\t): z.output<DtoSchema<Table, Public, IncludeId>>\n\tfunction toPublicDto<const IncludeId extends boolean = false>(\n\t\trow: DtoRow<Row, IncludeId>,\n\t\toptions: DtoProjectionOptions<IncludeId>,\n\t): z.output<DtoSchema<Table, Public, IncludeId>>\n\tfunction toPublicDto<\n\t\tconst IncludeId extends boolean = false,\n\t\tconst Extension extends FieldSchemas = {},\n\t>(\n\t\trow: DtoRow<Row, IncludeId>,\n\t\toptions: DtoOptions<IncludeId, Extension> & {\n\t\t\textend?: DtoExtension<Public, Extension>\n\t\t} & DtoValues<Extension>,\n\t): z.output<DtoSchema<Table, Public, IncludeId, Extension>>\n\tfunction toPublicDto(row: Row, options?: boolean | RuntimeOptions): RuntimeDto {\n\t\tconst normalized = options === true || options === false ? { _id: options } : options\n\t\t// Enforce extension collisions and validation-only schemas before parsing values.\n\t\tderiveDto(options)\n\t\tconst projected = publicDto.parse(\n\t\t\tObject.fromEntries(\n\t\t\t\tObject.keys(publicDto.shape).map((key) => {\n\t\t\t\t\t// SAFETY: publicDto contains only keys selected from the storage fields.\n\t\t\t\t\treturn [key, row[key as keyof typeof row]]\n\t\t\t\t}),\n\t\t\t),\n\t\t)\n\t\tconst extension = z\n\t\t\t.object(normalized?.extend ?? {})\n\t\t\t.strict()\n\t\t\t.parse(normalized?.values ?? {})\n\t\tconst result: RuntimeDto = { ...projected, ...extension }\n\t\tif (normalized?._id) {\n\t\t\tresult._id = schema.shape._id.parse('_id' in row ? row._id : undefined)\n\t\t}\n\t\treturn result\n\t}\n\n\ttype InsertSchema = typeof insertSchema\n\ttype UpdateSchema = typeof updateSchema\n\ttype InsertMask = z.util.Mask<keyof InsertSchema['shape']>\n\ttype UpdateMask = z.util.Mask<keyof UpdateSchema['shape']>\n\n\tfunction insert(): InsertSchema\n\tfunction insert<OmitMask extends InsertMask>(\n\t\tomit: OmitMask,\n\t): ZodObjectOmit<InsertSchema, OmitMask>\n\tfunction insert(omit?: InsertMask) {\n\t\t// SAFETY: InsertMask contains only insertSchema keys; the overload retains Zod's exact mask relationship.\n\t\treturn omit ? insertSchema.omit(omit as never) : insertSchema\n\t}\n\n\tfunction update(): UpdateSchema\n\tfunction update<OmitMask extends UpdateMask>(\n\t\tomit: OmitMask,\n\t): ZodObjectOmit<UpdateSchema, OmitMask>\n\tfunction update(omit?: UpdateMask) {\n\t\t// SAFETY: UpdateMask contains only updateSchema keys; the overload retains Zod's exact mask relationship.\n\t\treturn omit ? updateSchema.omit(omit as never) : updateSchema\n\t}\n\n\tconst nativeStorage = zodToConvex(storage)\n\tconst table: TableDefinition<ConvexValidatorFromZod<typeof storage, 'required'>> =\n\t\tdefineTable(nativeStorage)\n\ttype EntityFields = Fields & TimestampFields & SystemFields<Table>\n\tfunction paginationOpts<const Selection extends ScalarSelection<EntityFields>>(\n\t\tselection: ExactScalarSelection<EntityFields, Selection>,\n\t): ScalarPaginationSchema<EntityFields, Selection> {\n\t\treturn scalarPaginationSchema<EntityFields, Selection>(zodToConvex(schema).fields, selection)\n\t}\n\treturn {\n\t\ttableName,\n\t\tschema,\n\t\tstorage,\n\t\tinsertSchema,\n\t\tupdateSchema,\n\t\tcommandInput,\n\t\tpublicDto,\n\t\tdto,\n\t\ttoPublicDto,\n\t\tpaginationOpts,\n\t\ttable,\n\t\tinsert,\n\t\tupdate,\n\t\ttools: {\n\t\t\t// jsonSafeZid (not zid): tool masks feed generated JSON schemas, so\n\t\t\t// ids must present as plain strings while keeping the Id<...> type.\n\t\t\tinsert: commandInput,\n\t\t\tupdate: z.object({ data: commandInput.partial(), id: jsonSafeZid(tableName) }).strict(),\n\t\t\tid: z.object({ id: jsonSafeZid(tableName) }).strict(),\n\t\t},\n\t}\n}\n\nconst tenantFields = {\n\ttenant: z.string().min(1),\n} satisfies FieldSchemas\n\ntype TenantFields = typeof tenantFields\n\n/**\n * A zodTable whose rows are tenant-owned: injects the server-owned `tenant`\n * field (the tenancy boundary — see cvx-kit/tenancy). Like timestamps, it is\n * excluded from insert/update/command boundaries; handlers stamp it from\n * ctx.tenant, row-level security matches on it, and the tenantOwnership\n * trigger forbids reassigning it. Expose it via publicFields only when a DTO\n * genuinely needs it.\n */\nexport function tenantTable<\n\tTable extends string,\n\tFields extends FieldSchemas,\n\tconst ServerFields extends readonly FieldKey<Fields>[] = readonly [],\n\tconst CommandFields extends readonly FieldKey<Fields>[] = readonly [],\n\tconst PublicFields extends readonly FieldKey<Fields & TenantFields & TimestampFields>[] =\n\t\treadonly [],\n>(\n\ttableName: Table,\n\tfields: (\n\t\tid: typeof zid,\n\t) => Fields &\n\t\tOwnedFields<Fields> & { [Key in keyof Fields]: Key extends 'tenant' ? never : Fields[Key] },\n\toptions: TableBoundaryOptions<\n\t\tFields & TenantFields,\n\t\treadonly (ServerFields[number] | 'tenant')[],\n\t\tCommandFields,\n\t\tPublicFields\n\t> = {},\n) {\n\treturn zodTable<\n\t\tTable,\n\t\tFields & TenantFields,\n\t\treadonly (ServerFields[number] | 'tenant')[],\n\t\tCommandFields,\n\t\tPublicFields\n\t>(\n\t\ttableName,\n\t\t(id) => {\n\t\t\tconst declared = fields(id)\n\t\t\tassertOwnedFields(declared, ['tenant', '_id', '_creationTime', ...TIMESTAMP_FIELDS])\n\t\t\t// SAFETY: reserved keys were rejected before injecting tenant; the generic\n\t\t\t// wrapper forwards the same checked fields to the ordinary table constructor.\n\t\t\treturn { ...declared, ...tenantFields } as Fields &\n\t\t\t\tTenantFields &\n\t\t\t\tOwnedFields<Fields & TenantFields>\n\t\t},\n\t\t{\n\t\t\t...options,\n\t\t\tserverFields: [...(options.serverFields ?? []), 'tenant'],\n\t\t},\n\t)\n}\n\n/**\n * Merges per-module table maps into the application schema map, rejecting\n * duplicate table names across modules — the module-registry combinator for\n * domain/table.ts: `defineSchema(createModule(catalogTables, salesTables))`.\n */\nexport function createModule<const Maps extends readonly Record<string, TableDefinition<any>>[]>(\n\t...maps: Maps\n): UnionToIntersection<Maps[number]> {\n\tconst combined: Record<string, TableDefinition<any>> = {}\n\tfor (const map of maps) {\n\t\tfor (const [tableName, definition] of Object.entries(map)) {\n\t\t\tif (tableName in combined) {\n\t\t\t\tthrow new Error(`Table \"${tableName}\" is declared by more than one module`)\n\t\t\t}\n\t\t\tcombined[tableName] = definition\n\t\t}\n\t}\n\t// SAFETY: every input entry is copied, and duplicate keys are rejected above.\n\treturn combined as UnionToIntersection<Maps[number]>\n}\n\ntype UnionToIntersection<Union> = (\n\tUnion extends unknown ? (member: Union) => void : never\n) extends (member: infer Intersection) => void\n\t? Intersection\n\t: never\n\n/**\n * Cursor-pagination boundary schemas bridged from Convex's own validators:\n * `args.paginationOpts` for function args, `result` for the page shape.\n * Pair with `include(...).paginate(opts)` (cvx-kit/auth). The result object\n * is deliberately non-strict — Convex may attach engine fields (splitCursor,\n * pageStatus); the page items themselves are validated against the dto.\n * Note: under row-level security, pages may be SHORTER than numItems when\n * rules reject rows mid-page; cursors remain correct.\n */\nexport function paginated<Dto extends z.ZodType>(dto: Dto) {\n\treturn {\n\t\targs: { paginationOpts: convexToZod(paginationOptsValidator) },\n\t\tresult: z.object({\n\t\t\tpage: z.array(dto),\n\t\t\tisDone: z.boolean(),\n\t\t\tcontinueCursor: z.string(),\n\t\t\tsplitCursor: z.string().nullable().optional(),\n\t\t\tpageStatus: z.enum(['SplitRecommended', 'SplitRequired']).nullable().optional(),\n\t\t}),\n\t}\n}\n\n/** Preserves discriminated-union storage while retaining the same table owner. */\nexport function zodVariantTable<Table extends string, Schema extends z.ZodType>(\n\ttableName: Table,\n\tstorage: Schema,\n) {\n\treturn {\n\t\ttableName,\n\t\tstorage,\n\t\tinsertSchema: storage,\n\t\ttable: defineTable(zodToConvex(storage)),\n\t}\n}\n\n/**\n * A zid that presents as a plain string in generated JSON schemas so\n * LLM-tool inputs stay primitive, while keeping the Id type at compile time.\n */\nexport function jsonSafeZid<Table extends string>(\n\ttableName: Table,\n): z.ZodType<GenericId<Table>, string> {\n\tconst id = zid(tableName)\n\treturn z\n\t\t.string()\n\t\t.refine((value): value is GenericId<Table> => id.safeParse(value).success)\n\t\t.describe(`Convex document id for table \"${tableName}\"; validated against the table by Convex`)\n}\n\ntype ZodObjectOmit<\n\tSchema extends z.ZodObject<any, any>,\n\tOmitMask extends z.util.Mask<keyof Schema['shape']>,\n> =\n\tSchema extends z.ZodObject<infer ObjectFields, infer Config>\n\t\t? z.ZodObject<\n\t\t\t\tz.util.Flatten<Omit<ObjectFields, Extract<keyof ObjectFields, keyof OmitMask>>>,\n\t\t\t\tConfig\n\t\t\t>\n\t\t: never\n\nfunction documentSchema<Fields extends FieldSchemas, Table extends string>(\n\tstorage: StrictObject<Fields>,\n\ttableName: Table,\n) {\n\treturn storage.extend({ _id: zid(tableName), _creationTime: z.number() })\n}\n\nfunction pickFields<Fields extends FieldSchemas, const Keys extends readonly FieldKey<Fields>[]>(\n\tfields: Fields,\n\tkeys: Keys,\n) {\n\t// SAFETY: each entry uses a requested key and its original validator, preserving Pick.\n\treturn Object.fromEntries(keys.map((key) => [key, fields[key]])) as Pick<Fields, Keys[number]>\n}\n\nfunction omitFields<Fields extends FieldSchemas, const Keys extends readonly FieldKey<Fields>[]>(\n\tfields: Fields,\n\tkeys: Keys,\n) {\n\tconst omitted = new Set<string>(keys)\n\t// SAFETY: filtering removes exactly the supplied keys and keeps every remaining validator.\n\treturn Object.fromEntries(Object.entries(fields).filter(([key]) => !omitted.has(key))) as Omit<\n\t\tFields,\n\t\tKeys[number]\n\t>\n}\n\ntype DtoPropertiesCheck = z.core.$ZodCheck & {\n\treadonly _zod: {\n\t\treadonly def: { readonly check: 'properties' } & Record<\n\t\t\t'shape',\n\t\t\tRecord<string, z.core.$ZodType>\n\t\t>\n\t}\n}\n\n/** Inspect Zod 4's discriminated definitions, failing closed for unsupported nodes.\n * This restriction applies only to new DTO extensions; storage/publicDto are unchanged.\n */\nfunction assertDtoValidationSchema(\n\tschema: z.core.$ZodType,\n\tseen = new Set<z.core.$ZodType>(),\n): void {\n\tif (seen.has(schema)) return\n\tseen.add(schema)\n\t// SAFETY: Zod 4 exposes its built-in schema definitions as this discriminated union.\n\tconst def = (schema as z.core.$ZodTypes)._zod.def\n\tconst reject = () => {\n\t\tthrow new Error('DTO extensions require supported value-preserving validation schemas')\n\t}\n\tif ('coerce' in def && def.coerce) reject()\n\tif ('normalize' in def && def.normalize) reject()\n\tconst visit = (child: z.core.$ZodType) => assertDtoValidationSchema(child, seen)\n\tfor (const check of def.checks ?? []) {\n\t\tif (check._zod.def.check === 'overwrite') reject()\n\t\tif ('normalize' in check._zod.def && check._zod.def.normalize) reject()\n\t\tif (check._zod.def.check === 'property') {\n\t\t\t// SAFETY: the property discriminator owns this embedded schema in Zod 4.\n\t\t\tvisit((check as z.core.$ZodCheckProperty)._zod.def.schema)\n\t\t}\n\t\tif (check._zod.def.check === 'properties') {\n\t\t\t// SAFETY: the properties discriminator owns this schema shape in Zod 4.\n\t\t\tfor (const child of Object.values((check as DtoPropertiesCheck)._zod.def.shape)) {\n\t\t\t\tvisit(child)\n\t\t\t}\n\t\t}\n\t}\n\tswitch (def.type) {\n\t\tcase 'string':\n\t\tcase 'number':\n\t\tcase 'boolean':\n\t\tcase 'bigint':\n\t\tcase 'date':\n\t\tcase 'symbol':\n\t\tcase 'null':\n\t\tcase 'undefined':\n\t\tcase 'void':\n\t\tcase 'never':\n\t\tcase 'literal':\n\t\tcase 'enum':\n\t\t\treturn\n\t\tcase 'object':\n\t\t\tfor (const child of Object.values(def.shape)) visit(child)\n\t\t\tif (def.catchall) visit(def.catchall)\n\t\t\treturn\n\t\tcase 'array':\n\t\t\tvisit(def.element)\n\t\t\treturn\n\t\tcase 'optional':\n\t\tcase 'nullable':\n\t\tcase 'nonoptional':\n\t\t\tvisit(def.innerType)\n\t\t\treturn\n\t\tcase 'union':\n\t\t\tfor (const child of def.options) visit(child)\n\t\t\treturn\n\t\tcase 'intersection':\n\t\t\tvisit(def.left)\n\t\t\tvisit(def.right)\n\t\t\treturn\n\t\tcase 'tuple':\n\t\t\tfor (const child of def.items) visit(child)\n\t\t\tif (def.rest) visit(def.rest)\n\t\t\treturn\n\t\tcase 'record':\n\t\t\tvisit(def.keyType)\n\t\t\tvisit(def.valueType)\n\t\t\treturn\n\t\tdefault:\n\t\t\treject()\n\t}\n}\n\nfunction assertOwnedFields(fields: FieldSchemas, reserved: readonly string[]): void {\n\tfor (const key of reserved) {\n\t\tif (Object.hasOwn(fields, key))\n\t\t\tthrow new Error(`Reserved table field \"${key}\" cannot be declared`)\n\t}\n}\n\nfunction assertFieldLists(\n\tfields: FieldSchemas,\n\tserver: readonly string[],\n\tcommand: readonly string[],\n\tpublicKeys: readonly string[],\n): void {\n\tfor (const key of [...server, ...command, ...publicKeys]) {\n\t\tif (!Object.hasOwn(fields, key)) throw new Error(`Unknown table field \"${key}\"`)\n\t}\n\tconst managed = new Set<string>([...TIMESTAMP_FIELDS, ...server])\n\tfor (const key of command) {\n\t\tif (managed.has(key)) throw new Error(`Server-owned field \"${key}\" cannot be a command input`)\n\t}\n}\n"],"mappings":"4SA2BA,MAAMI,EAAkB,CACvB,UAAWC,EAAE,OAAO,CAAC,CAAC,SAAS,EAC/B,UAAWA,EAAE,OAAO,CAAC,CAAC,SAAS,EAC/B,WAAYA,EAAE,OAAO,CAAC,CAAC,SAAS,CACjC,EASaC,EAAmB,CAAC,YAAa,YAAa,YAAY,EA4IvE,SAAgBC,EAOf,EACA,EACA,EAAmF,CAAC,EACV,CAC1E,IAAMC,EAAWC,EAAOT,CAAG,EAC3BU,EAAkBF,EAAU,CAAC,MAAO,gBAAiB,GAAGF,CAAgB,CAAC,EACzE,IAAMK,EAAoC,CAAE,GAAGH,EAAU,GAAGJ,CAAgB,EAC5EQ,EACCD,EACAE,EAAQ,cAAgB,CAAC,EACzBA,EAAQ,eAAiB,CAAC,EAC1BA,EAAQ,cAAgB,CAAC,CAC1B,EACA,IAAMC,EAAiET,EAAE,OAAOM,CAAO,CAAC,CAAC,OAAO,EAC1FI,EAASC,EAAeF,EAASG,CAAS,EAC1CC,EAAqF,CAC1F,GAAGZ,EACH,GAAIO,EAAQ,cAAgB,CAAC,CAC9B,EACMM,EAAgDN,EAAQ,eAAiB,CAAC,EAC1EO,EAA8CP,EAAQ,cAAgB,CAAC,EACvEQ,EAA+EhB,EACnF,OAAOiB,EAAWX,EAASO,CAAW,CAAC,CAAC,CACxC,OAAO,EACHK,EAAeF,EAAa,QAAQ,EACpCG,EAGFnB,EAAE,OAAOoB,EAAWd,EAASQ,CAAW,CAAC,CAAC,CAAC,OAAO,EAChDO,EAGFrB,EAAE,OAAOoB,EAAWd,EAASS,CAAU,CAAC,CAAC,CAAC,OAAO,EAM/CO,kBAAoB,IAAI,IAAY,CACzC,MACA,gBACA,SACA,YACA,GAAGrB,CACJ,CAAC,EAYD,SAASsB,EAAI,EAAoC,CAChD,OAAOC,EAAUhB,CAAO,CACzB,CAEA,SAASgB,EAAU,EAAoC,CACtD,IAAMC,EAAajB,IAAY,IAAQA,IAAY,GAAQ,CAAE,IAAKA,CAAQ,EAAIA,EACxEkB,EAAYD,GAAY,QAAU,CAAC,EACzC,IAAK,IAAME,KAAO,OAAO,KAAKD,CAAS,EAAG,CACzC,GAAIJ,EAAkB,IAAIK,CAAG,GAAK,OAAO,OAAON,EAAU,MAAOM,CAAG,EACnE,MAAU,MAAM,sCAAsCA,EAAI,cAAcf,EAAU,EAAE,EAErFgB,EAA0BF,EAAUC,EAAI,CACzC,CACA,GAAI,CAACF,GAAY,KAAO,OAAO,KAAKC,CAAS,CAAC,CAAC,SAAW,EAAG,OAAOL,EACpE,IAAMQ,EAAe7B,EAAE,OAAO,CAAE,GAAGqB,EAAU,MAAO,GAAGK,CAAU,CAAC,CAAC,CAAC,OAAO,EAC3E,OAAOD,GAAY,IAAMI,EAAa,OAAO,CAAE,IAAKnB,EAAO,MAAM,GAAI,CAAC,EAAImB,CAC3E,CAoBA,SAASC,EAAY,EAAU,EAAgD,CAC9E,IAAML,EAAajB,IAAY,IAAQA,IAAY,GAAQ,CAAE,IAAKA,CAAQ,EAAIA,EAE9EgB,EAAUhB,CAAO,EACjB,IAAMuB,EAAYV,EAAU,MAC3B,OAAO,YACN,OAAO,KAAKA,EAAU,KAAK,CAAC,CAAC,IAAK,GAE1B,CAACM,EAAKK,EAAIL,EAAwB,CACzC,CACF,CACD,EACMD,EAAY1B,EAChB,OAAOyB,GAAY,QAAU,CAAC,CAAC,CAAC,CAChC,OAAO,CAAC,CACR,MAAMA,GAAY,QAAU,CAAC,CAAC,EAC1BQ,EAAqB,CAAE,GAAGF,EAAW,GAAGL,CAAU,EAIxD,OAHID,GAAY,MACf,EAAO,IAAMf,EAAO,MAAM,IAAI,MAAM,QAASsB,EAAMA,EAAI,IAAM,IAAA,EAAS,GAEhEC,CACR,CAWA,SAASC,EAAO,EAAmB,CAElC,OAAOC,EAAOnB,EAAa,KAAKmB,CAAa,EAAInB,CAClD,CAMA,SAASoB,EAAO,EAAmB,CAElC,OAAOD,EAAOjB,EAAa,KAAKiB,CAAa,EAAIjB,CAClD,CAEA,IAAMmB,EAAgBC,EAAY7B,CAAO,EACnC8B,EACLC,EAAYH,CAAa,EAE1B,SAASI,EACR,EACkD,CAClD,OAAOC,EAAgDJ,EAAY5B,CAAM,CAAC,CAAC,OAAQiC,CAAS,CAC7F,CACA,MAAO,CACN,YACA,SACA,UACA,eACA,eACA,eACA,YACA,MACA,cACA,iBACA,QACA,SACA,SACA,MAAO,CAGN,OAAQxB,EACR,OAAQnB,EAAE,OAAO,CAAE,KAAMmB,EAAa,QAAQ,EAAG,GAAIyB,EAAYhC,CAAS,CAAE,CAAC,CAAC,CAAC,OAAO,EACtF,GAAIZ,EAAE,OAAO,CAAE,GAAI4C,EAAYhC,CAAS,CAAE,CAAC,CAAC,CAAC,OAAO,CACrD,CACD,CACD,CAEA,MAAMiC,EAAe,CACpB,OAAQ7C,EAAE,OAAO,CAAC,CAAC,IAAI,CAAC,CACzB,EAYA,SAAgB8C,EAQf,EACA,EAIA,EAKI,CAAC,EACJ,CACD,OAAO5C,EAONU,EACC,GAAO,CACP,IAAMT,EAAWC,EAAO2C,CAAE,EAI1B,OAHA1C,EAAkBF,EAAU,CAAC,SAAU,MAAO,gBAAiB,GAAGF,CAAgB,CAAC,EAG5E,CAAE,GAAGE,EAAU,GAAG0C,CAAa,CAGvC,EACA,CACC,GAAGrC,EACH,aAAc,CAAC,GAAIA,EAAQ,cAAgB,CAAC,EAAI,QAAQ,CACzD,CACD,CACD,CAOA,SAAgBwC,EACf,GAAGC,EACiC,CACpC,IAAMC,EAAiD,CAAC,EACxD,IAAK,IAAMC,KAAOF,EACjB,IAAK,GAAM,CAACrC,EAAWwC,KAAe,OAAO,QAAQD,CAAG,EAAG,CAC1D,GAAIvC,KAAasC,EAChB,MAAU,MAAM,UAAUtC,EAAU,sCAAsC,EAE3E,EAASA,GAAawC,CACvB,CAGD,OAAOF,CACR,CAiBA,SAAgBG,EAAiC,EAAU,CAC1D,MAAO,CACN,KAAM,CAAE,eAAgBzD,EAAY0D,CAAuB,CAAE,EAC7D,OAAQtD,EAAE,OAAO,CAChB,KAAMA,EAAE,MAAMuB,CAAG,EACjB,OAAQvB,EAAE,QAAQ,EAClB,eAAgBA,EAAE,OAAO,EACzB,YAAaA,EAAE,OAAO,CAAC,CAAC,SAAS,CAAC,CAAC,SAAS,EAC5C,WAAYA,EAAE,KAAK,CAAC,mBAAoB,eAAe,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,SAAS,CAC/E,CAAC,CACF,CACD,CAGA,SAAgBuD,EACf,EACA,EACC,CACD,MAAO,CACN,YACA,UACA,aAAc9C,EACd,MAAO+B,EAAYF,EAAY7B,CAAO,CAAC,CACxC,CACD,CAMA,SAAgBmC,EACf,EACsC,CACtC,IAAMG,EAAKpD,EAAIiB,CAAS,EACxB,OAAOZ,EACL,OAAO,CAAC,CACR,OAAQ,GAAqC+C,EAAG,UAAUS,CAAK,CAAC,CAAC,OAAO,CAAC,CACzE,SAAS,iCAAiC5C,EAAU,yCAAyC,CAChG,CAaA,SAASD,EACR,EACA,EACC,CACD,OAAOF,EAAQ,OAAO,CAAE,IAAKd,EAAIiB,CAAS,EAAG,cAAeZ,EAAE,OAAO,CAAE,CAAC,CACzE,CAEA,SAASoB,EACR,EACA,EACC,CAED,OAAO,OAAO,YAAYqC,EAAK,IAAK,GAAQ,CAAC9B,EAAKvB,EAAOuB,EAAI,CAAC,CAAC,CAChE,CAEA,SAASV,EACR,EACA,EACC,CACD,IAAMyC,EAAU,IAAI,IAAYD,CAAI,EAEpC,OAAO,OAAO,YAAY,OAAO,QAAQrD,CAAM,CAAC,CAAC,QAAQ,CAACuB,KAAS,CAAC+B,EAAQ,IAAI/B,CAAG,CAAC,CAAC,CAItF,CAcA,SAASC,EACR,EACA,kBAAO,IAAI,IACJ,CACP,GAAI+B,EAAK,IAAIjD,CAAM,EAAG,OACtBiD,EAAK,IAAIjD,CAAM,EAEf,IAAMkD,EAAOlD,EAA4B,KAAK,IACxCmD,MAAe,CACpB,MAAU,MAAM,sEAAsE,CACvF,EACI,WAAYD,GAAOA,EAAI,QAAQC,EAAO,EACtC,cAAeD,GAAOA,EAAI,WAAWC,EAAO,EAChD,IAAMC,EAAS,GAA2BlC,EAA0BmC,EAAOJ,CAAI,EAC/E,IAAK,IAAMK,KAASJ,EAAI,QAAU,CAAC,EAOlC,GANII,EAAM,KAAK,IAAI,QAAU,aAAaH,EAAO,EAC7C,cAAeG,EAAM,KAAK,KAAOA,EAAM,KAAK,IAAI,WAAWH,EAAO,EAClEG,EAAM,KAAK,IAAI,QAAU,YAE5BF,EAAOE,EAAmC,KAAK,IAAI,MAAM,EAEtDA,EAAM,KAAK,IAAI,QAAU,aAE5B,IAAK,IAAMD,KAAS,OAAO,OAAQC,EAA6B,KAAK,IAAI,KAAK,EAC7EF,EAAMC,CAAK,EAId,OAAQH,EAAI,KAAZ,CACC,IAAK,SACL,IAAK,SACL,IAAK,UACL,IAAK,SACL,IAAK,OACL,IAAK,SACL,IAAK,OACL,IAAK,YACL,IAAK,OACL,IAAK,QACL,IAAK,UACL,IAAK,OACJ,OACD,IAAK,SACJ,IAAK,IAAMG,KAAS,OAAO,OAAOH,EAAI,KAAK,EAAGE,EAAMC,CAAK,EACrDH,EAAI,UAAUE,EAAMF,EAAI,QAAQ,EACpC,OACD,IAAK,QACJE,EAAMF,EAAI,OAAO,EACjB,OACD,IAAK,WACL,IAAK,WACL,IAAK,cACJE,EAAMF,EAAI,SAAS,EACnB,OACD,IAAK,QACJ,IAAK,IAAMG,KAASH,EAAI,QAASE,EAAMC,CAAK,EAC5C,OACD,IAAK,eACJD,EAAMF,EAAI,IAAI,EACdE,EAAMF,EAAI,KAAK,EACf,OACD,IAAK,QACJ,IAAK,IAAMG,KAASH,EAAI,MAAOE,EAAMC,CAAK,EACtCH,EAAI,MAAME,EAAMF,EAAI,IAAI,EAC5B,OACD,IAAK,SACJE,EAAMF,EAAI,OAAO,EACjBE,EAAMF,EAAI,SAAS,EACnB,OACD,QACCC,EAAO,CACT,CACD,CAEA,SAASxD,EAAkB,EAAsB,EAAmC,CACnF,IAAK,IAAMsB,KAAOsC,EACjB,GAAI,OAAO,OAAO7D,EAAQuB,CAAG,EAC5B,MAAU,MAAM,yBAAyBA,EAAI,qBAAqB,CAErE,CAEA,SAASpB,EACR,EACA,EACA,EACA,EACO,CACP,IAAK,IAAMoB,IAAO,CAAC,GAAGuC,EAAQ,GAAGC,EAAS,GAAGpD,CAAU,EACtD,GAAI,CAAC,OAAO,OAAOX,EAAQuB,CAAG,EAAG,MAAU,MAAM,wBAAwBA,EAAI,EAAE,EAEhF,IAAMyC,kBAAU,IAAI,IAAY,CAAC,GAAGnE,EAAkB,GAAGiE,CAAM,CAAC,EAChE,IAAK,IAAMvC,KAAOwC,EACjB,GAAIC,EAAQ,IAAIzC,CAAG,EAAG,MAAU,MAAM,uBAAuBA,EAAI,4BAA4B,CAE/F"}
1
+ {"version":3,"file":"zod-table.mjs","names":["zid","convexToZod","convexToZod$1","zid$1","timestampFields","z","TIMESTAMP_FIELDS","zodTable","declared","fields","assertOwnedFields","columns","assertFieldLists","options","storage","schema","documentSchema","tableName","omittedKeys","commandKeys","publicKeys","insertSchema","omitFields","updateSchema","commandInput","pickFields","publicDto","reservedDtoFields","dto","deriveDto","normalized","extension","key","assertDtoValidationSchema","resultSchema","toPublicDto","projected","row","result","insert","omit","update","nativeStorage","zodToConvex","table","defineTable","paginationOpts","scalarPaginationSchema","selection","jsonSafeZid","tenantFields","tenantTable","id","createModule","maps","combined","map","definition","paginated","paginationOptsValidator","zodVariantTable","deriveVariantTable","value","discriminator","branches","branch","cause","tagSchema","tag","tagValue","config","mask","stored","command","partial","union","schemas","mode","tool","field","variantToolField","includeId","projection","native","child","\"shape\"","keys","omitted","seen","def","reject","visit","allowNativeIds","check","reserved","server","managed","convexToZod","zid"],"sources":["../src/zod-table.ts"],"sourcesContent":["import { convexToZod, zid, type ConvexValidatorFromZod, type Zid } from 'convex-helpers/server/zod4'\nimport { defineTable, paginationOptsValidator, type TableDefinition } from 'convex/server'\nimport type { GenericId } from 'convex/values'\nimport { z } from 'zod'\n\nimport { zodToConvex } from './zod-convex'\n\nimport {\n\tscalarPaginationSchema,\n\ttype ScalarPaginationSchema,\n\ttype ScalarSelection,\n\ttype ExactScalarSelection,\n} from './querying/filters'\n\n// Use this entry point when deriving validators from kit-owned schemas so\n// the producer and converter consult the same convex-helpers ID registry.\nexport { zid, convexToZod } from 'convex-helpers/server/zod4'\nexport { zodToConvex } from './zod-convex'\n\ntype FieldSchemas = Record<string, z.ZodType>\ntype FieldKey<Fields extends FieldSchemas> = Extract<keyof Fields, string>\n\n/**\n * Opinionated lifecycle timestamps — every table has them, server-owned,\n * always excluded from insert/command boundaries. Maintained by the\n * `timestamps` trigger helper (see cvx-kit/triggers).\n */\nconst timestampFields = {\n\tcreatedAt: z.number().optional(),\n\tupdatedAt: z.number().optional(),\n\tarchivedAt: z.number().optional(),\n} satisfies FieldSchemas\n\ntype TimestampFields = typeof timestampFields\ntype ReservedStorageField = '_id' | '_creationTime' | keyof TimestampFields\ntype OwnedFields<Fields> = {\n\t[Key in keyof Fields]: Key extends ReservedStorageField ? never : Fields[Key]\n}\ntype SystemFields<Table extends string> = { _id: Zid<Table>; _creationTime: z.ZodNumber }\n\nexport const TIMESTAMP_FIELDS = ['createdAt', 'updatedAt', 'archivedAt'] as const\n\nexport type TableBoundaryOptions<\n\tFields extends FieldSchemas,\n\tServerFields extends readonly FieldKey<Fields>[],\n\tCommandFields extends readonly FieldKey<Fields>[],\n\tPublicFields extends readonly FieldKey<Fields & TimestampFields>[],\n> = {\n\tserverFields?: ServerFields\n\tcommandFields?: CommandFields &\n\t\treadonly Exclude<FieldKey<Fields>, ServerFields[number] | keyof TimestampFields>[]\n\tpublicFields?: PublicFields\n}\n\ntype StrictObject<Fields extends FieldSchemas> = z.ZodObject<Fields, z.core.$strict>\ntype WriteFields<\n\tFields extends FieldSchemas,\n\tServerFields extends readonly FieldKey<Fields>[],\n> = Omit<Fields & TimestampFields, ServerFields[number] | (typeof TIMESTAMP_FIELDS)[number]>\ntype PartialFields<Fields extends FieldSchemas> = {\n\t[Key in keyof Fields]: z.ZodOptional<Fields[Key]>\n}\n\n/** Options shared by the DTO return schema and row projector.\n * Promised contributions must be present, including in reusable options.\n * New extension schemas support validation only: no transforms, pipes,\n * coercion, preprocess, defaults, catches, or overwrites, even when nested.\n * Refinements must validate without mutating their input.\n */\nexport type DtoOptions<IncludeId extends boolean = false, Extension extends FieldSchemas = {}> = ([\n\tIncludeId,\n] extends [true]\n\t? { _id: IncludeId }\n\t: { _id?: IncludeId }) &\n\t(keyof Extension extends never ? { extend?: Extension } : { extend: Extension })\n\ntype DtoProjectionOptions<IncludeId extends boolean> = DtoOptions<IncludeId> & {\n\textend?: Record<string, never>\n\tvalues?: never\n}\n\ntype ReservedDtoField =\n\t| '_id'\n\t| '_creationTime'\n\t| 'tenant'\n\t| '__proto__'\n\t| (typeof TIMESTAMP_FIELDS)[number]\ntype DtoExtension<Public extends FieldSchemas, Extension extends FieldSchemas> = {\n\t[Key in keyof Extension]: Key extends keyof Public | ReservedDtoField\n\t\t? never\n\t\t: Extension[Key] extends z.ZodPipe | z.ZodTransform\n\t\t\t? never\n\t\t\t: unknown\n}\n// Broad dictionaries cannot promise any particular extension field.\ntype KnownExtension<Extension> = string extends keyof Extension ? {} : Extension\n\ntype DtoSchema<\n\tTable extends string,\n\tPublic extends FieldSchemas,\n\tIncludeId extends boolean,\n\tExtension extends FieldSchemas = {},\n> = IncludeId extends true\n\t? StrictObject<Public & { _id: Zid<Table> } & KnownExtension<Extension>>\n\t: StrictObject<Public & KnownExtension<Extension>>\ntype DtoRow<Row, IncludeId extends boolean> = Row & (true extends IncludeId ? { _id: string } : {})\ntype DtoValues<Extension extends FieldSchemas> = keyof Extension extends never\n\t? { values?: never }\n\t: { values: z.input<StrictObject<NoInfer<Extension>>> }\n\ntype DtoBoundary<Table extends string, Fields extends FieldSchemas, Public extends FieldSchemas> = {\n\tdto(): StrictObject<Public>\n\tdto<const IncludeId extends boolean>(includeId: IncludeId): DtoSchema<Table, Public, IncludeId>\n\tdto<const IncludeId extends boolean = false>(\n\t\toptions: DtoProjectionOptions<IncludeId>,\n\t): DtoSchema<Table, Public, IncludeId>\n\tdto<const IncludeId extends boolean = false, const Extension extends FieldSchemas = {}>(\n\t\toptions: DtoOptions<IncludeId, Extension> & { extend?: DtoExtension<Public, Extension> },\n\t): DtoSchema<Table, Public, IncludeId, Extension>\n\ttoPublicDto(row: z.input<StrictObject<Fields>>): z.output<StrictObject<Public>>\n\ttoPublicDto<const IncludeId extends boolean>(\n\t\trow: DtoRow<z.input<StrictObject<Fields>>, IncludeId>,\n\t\tincludeId: IncludeId,\n\t): z.output<DtoSchema<Table, Public, IncludeId>>\n\ttoPublicDto<const IncludeId extends boolean = false>(\n\t\trow: DtoRow<z.input<StrictObject<Fields>>, IncludeId>,\n\t\toptions: DtoProjectionOptions<IncludeId>,\n\t): z.output<DtoSchema<Table, Public, IncludeId>>\n\ttoPublicDto<const IncludeId extends boolean = false, const Extension extends FieldSchemas = {}>(\n\t\trow: DtoRow<z.input<StrictObject<Fields>>, IncludeId>,\n\t\toptions: DtoOptions<IncludeId, Extension> & {\n\t\t\textend?: DtoExtension<Public, Extension>\n\t\t} & DtoValues<Extension>,\n\t): z.output<DtoSchema<Table, Public, IncludeId, Extension>>\n}\n\n/** Named schema relationships keep generated declarations bounded and consumers fully typed. */\nexport type TableBoundary<\n\tTable extends string,\n\tFields extends FieldSchemas,\n\tServerFields extends readonly FieldKey<Fields>[],\n\tCommandFields extends readonly FieldKey<Fields>[],\n\tPublicFields extends readonly FieldKey<Fields & TimestampFields>[],\n> = DtoBoundary<\n\tTable,\n\tFields & TimestampFields,\n\tPick<Fields & TimestampFields, PublicFields[number]>\n> & {\n\tpaginationOpts<\n\t\tconst Selection extends ScalarSelection<Fields & TimestampFields & SystemFields<Table>>,\n\t>(\n\t\tselection: ExactScalarSelection<Fields & TimestampFields & SystemFields<Table>, Selection>,\n\t): ScalarPaginationSchema<Fields & TimestampFields & SystemFields<Table>, Selection>\n\ttableName: Table\n\tstorage: StrictObject<Fields & TimestampFields>\n\tschema: ReturnType<typeof documentSchema<Fields & TimestampFields, Table>>\n\tinsertSchema: StrictObject<WriteFields<Fields, ServerFields>>\n\tupdateSchema: StrictObject<PartialFields<WriteFields<Fields, ServerFields>>>\n\tcommandInput: StrictObject<Pick<Fields & TimestampFields, CommandFields[number]>>\n\tpublicDto: StrictObject<Pick<Fields & TimestampFields, PublicFields[number]>>\n\ttable: TableDefinition<ConvexValidatorFromZod<StrictObject<Fields & TimestampFields>, 'required'>>\n\tinsert(): StrictObject<WriteFields<Fields, ServerFields>>\n\tinsert<Mask extends z.util.Mask<keyof WriteFields<Fields, ServerFields>>>(\n\t\tomit: Mask,\n\t): ZodObjectOmit<StrictObject<WriteFields<Fields, ServerFields>>, Mask>\n\tupdate(): StrictObject<PartialFields<WriteFields<Fields, ServerFields>>>\n\tupdate<Mask extends z.util.Mask<keyof WriteFields<Fields, ServerFields>>>(\n\t\tomit: Mask,\n\t): ZodObjectOmit<StrictObject<PartialFields<WriteFields<Fields, ServerFields>>>, Mask>\n\ttools: {\n\t\tinsert: StrictObject<Pick<Fields & TimestampFields, CommandFields[number]>>\n\t\tupdate: StrictObject<{\n\t\t\tdata: StrictObject<PartialFields<Pick<Fields & TimestampFields, CommandFields[number]>>>\n\t\t\tid: z.ZodType<GenericId<Table>, string>\n\t\t}>\n\t\tid: StrictObject<{ id: z.ZodType<GenericId<Table>, string> }>\n\t}\n}\n\n/** Defines one table and derives its storage, document, write, and DTO boundaries. */\nexport function zodTable<\n\tTable extends string,\n\tFields extends FieldSchemas,\n\tconst ServerFields extends readonly FieldKey<Fields>[] = readonly [],\n\tconst CommandFields extends readonly FieldKey<Fields>[] = readonly [],\n\tconst PublicFields extends readonly FieldKey<Fields & TimestampFields>[] = readonly [],\n>(\n\ttableName: Table,\n\tfields: (id: typeof zid) => Fields & OwnedFields<Fields>,\n\toptions: TableBoundaryOptions<Fields, ServerFields, CommandFields, PublicFields> = {},\n): TableBoundary<Table, Fields, ServerFields, CommandFields, PublicFields> {\n\tconst declared = fields(zid)\n\tassertOwnedFields(declared, ['_id', '_creationTime', ...TIMESTAMP_FIELDS])\n\tconst columns: Fields & TimestampFields = { ...declared, ...timestampFields }\n\tassertFieldLists(\n\t\tcolumns,\n\t\toptions.serverFields ?? [],\n\t\toptions.commandFields ?? [],\n\t\toptions.publicFields ?? [],\n\t)\n\tconst storage: z.ZodObject<Fields & TimestampFields, z.core.$strict> = z.object(columns).strict()\n\tconst schema = documentSchema(storage, tableName)\n\tconst omittedKeys: readonly (ServerFields[number] | (typeof TIMESTAMP_FIELDS)[number])[] = [\n\t\t...TIMESTAMP_FIELDS,\n\t\t...(options.serverFields ?? []),\n\t]\n\tconst commandKeys: readonly CommandFields[number][] = options.commandFields ?? []\n\tconst publicKeys: readonly PublicFields[number][] = options.publicFields ?? []\n\tconst insertSchema: z.ZodObject<WriteFields<Fields, ServerFields>, z.core.$strict> = z\n\t\t.object(omitFields(columns, omittedKeys))\n\t\t.strict()\n\tconst updateSchema = insertSchema.partial()\n\tconst commandInput: z.ZodObject<\n\t\tPick<Fields & TimestampFields, CommandFields[number]>,\n\t\tz.core.$strict\n\t> = z.object(pickFields(columns, commandKeys)).strict()\n\tconst publicDto: z.ZodObject<\n\t\tPick<Fields & TimestampFields, PublicFields[number]>,\n\t\tz.core.$strict\n\t> = z.object(pickFields(columns, publicKeys)).strict()\n\ttype Public = Pick<Fields & TimestampFields, PublicFields[number]>\n\ttype Row = z.input<typeof storage>\n\ttype RuntimeDtoFields = Public & FieldSchemas\n\ttype RuntimeDto = z.output<StrictObject<RuntimeDtoFields>> & { _id?: GenericId<Table> }\n\ttype RuntimeOptions = { _id?: boolean; extend?: FieldSchemas; values?: unknown }\n\tconst reservedDtoFields = new Set<string>([\n\t\t'_id',\n\t\t'_creationTime',\n\t\t'tenant',\n\t\t'__proto__',\n\t\t...TIMESTAMP_FIELDS,\n\t])\n\n\tfunction dto(): typeof publicDto\n\tfunction dto<const IncludeId extends boolean>(\n\t\tincludeId: IncludeId,\n\t): DtoSchema<Table, Public, IncludeId>\n\tfunction dto<const IncludeId extends boolean = false>(\n\t\toptions: DtoProjectionOptions<IncludeId>,\n\t): DtoSchema<Table, Public, IncludeId>\n\tfunction dto<const IncludeId extends boolean = false, const Extension extends FieldSchemas = {}>(\n\t\toptions: DtoOptions<IncludeId, Extension> & { extend?: DtoExtension<Public, Extension> },\n\t): DtoSchema<Table, Public, IncludeId, Extension>\n\tfunction dto(options?: boolean | RuntimeOptions) {\n\t\treturn deriveDto(options)\n\t}\n\n\tfunction deriveDto(options?: boolean | RuntimeOptions) {\n\t\tconst normalized = options === true || options === false ? { _id: options } : options\n\t\tconst extension = normalized?.extend ?? {}\n\t\tfor (const key of Object.keys(extension)) {\n\t\t\tif (reservedDtoFields.has(key) || Object.hasOwn(publicDto.shape, key)) {\n\t\t\t\tthrow new Error(`DTO extension collision for field \"${key}\" on table \"${tableName}\"`)\n\t\t\t}\n\t\t\tassertDtoValidationSchema(extension[key])\n\t\t}\n\t\tif (!normalized?._id && Object.keys(extension).length === 0) return publicDto\n\t\tconst resultSchema = z.object({ ...publicDto.shape, ...extension }).strict()\n\t\treturn normalized?._id ? resultSchema.extend({ _id: schema.shape._id }) : resultSchema\n\t}\n\n\tfunction toPublicDto(row: Row): z.output<typeof publicDto>\n\tfunction toPublicDto<const IncludeId extends boolean>(\n\t\trow: DtoRow<Row, IncludeId>,\n\t\tincludeId: IncludeId,\n\t): z.output<DtoSchema<Table, Public, IncludeId>>\n\tfunction toPublicDto<const IncludeId extends boolean = false>(\n\t\trow: DtoRow<Row, IncludeId>,\n\t\toptions: DtoProjectionOptions<IncludeId>,\n\t): z.output<DtoSchema<Table, Public, IncludeId>>\n\tfunction toPublicDto<\n\t\tconst IncludeId extends boolean = false,\n\t\tconst Extension extends FieldSchemas = {},\n\t>(\n\t\trow: DtoRow<Row, IncludeId>,\n\t\toptions: DtoOptions<IncludeId, Extension> & {\n\t\t\textend?: DtoExtension<Public, Extension>\n\t\t} & DtoValues<Extension>,\n\t): z.output<DtoSchema<Table, Public, IncludeId, Extension>>\n\tfunction toPublicDto(row: Row, options?: boolean | RuntimeOptions): RuntimeDto {\n\t\tconst normalized = options === true || options === false ? { _id: options } : options\n\t\t// Enforce extension collisions and validation-only schemas before parsing values.\n\t\tderiveDto(options)\n\t\tconst projected = publicDto.parse(\n\t\t\tObject.fromEntries(\n\t\t\t\tObject.keys(publicDto.shape).map((key) => {\n\t\t\t\t\t// SAFETY: publicDto contains only keys selected from the storage fields.\n\t\t\t\t\treturn [key, row[key as keyof typeof row]]\n\t\t\t\t}),\n\t\t\t),\n\t\t)\n\t\tconst extension = z\n\t\t\t.object(normalized?.extend ?? {})\n\t\t\t.strict()\n\t\t\t.parse(normalized?.values ?? {})\n\t\tconst result: RuntimeDto = { ...projected, ...extension }\n\t\tif (normalized?._id) {\n\t\t\tresult._id = schema.shape._id.parse('_id' in row ? row._id : undefined)\n\t\t}\n\t\treturn result\n\t}\n\n\ttype InsertSchema = typeof insertSchema\n\ttype UpdateSchema = typeof updateSchema\n\ttype InsertMask = z.util.Mask<keyof InsertSchema['shape']>\n\ttype UpdateMask = z.util.Mask<keyof UpdateSchema['shape']>\n\n\tfunction insert(): InsertSchema\n\tfunction insert<OmitMask extends InsertMask>(\n\t\tomit: OmitMask,\n\t): ZodObjectOmit<InsertSchema, OmitMask>\n\tfunction insert(omit?: InsertMask) {\n\t\t// SAFETY: InsertMask contains only insertSchema keys; the overload retains Zod's exact mask relationship.\n\t\treturn omit ? insertSchema.omit(omit as never) : insertSchema\n\t}\n\n\tfunction update(): UpdateSchema\n\tfunction update<OmitMask extends UpdateMask>(\n\t\tomit: OmitMask,\n\t): ZodObjectOmit<UpdateSchema, OmitMask>\n\tfunction update(omit?: UpdateMask) {\n\t\t// SAFETY: UpdateMask contains only updateSchema keys; the overload retains Zod's exact mask relationship.\n\t\treturn omit ? updateSchema.omit(omit as never) : updateSchema\n\t}\n\n\tconst nativeStorage = zodToConvex(storage)\n\tconst table: TableDefinition<ConvexValidatorFromZod<typeof storage, 'required'>> =\n\t\tdefineTable(nativeStorage)\n\ttype EntityFields = Fields & TimestampFields & SystemFields<Table>\n\tfunction paginationOpts<const Selection extends ScalarSelection<EntityFields>>(\n\t\tselection: ExactScalarSelection<EntityFields, Selection>,\n\t): ScalarPaginationSchema<EntityFields, Selection> {\n\t\treturn scalarPaginationSchema<EntityFields, Selection>(zodToConvex(schema).fields, selection)\n\t}\n\treturn {\n\t\ttableName,\n\t\tschema,\n\t\tstorage,\n\t\tinsertSchema,\n\t\tupdateSchema,\n\t\tcommandInput,\n\t\tpublicDto,\n\t\tdto,\n\t\ttoPublicDto,\n\t\tpaginationOpts,\n\t\ttable,\n\t\tinsert,\n\t\tupdate,\n\t\ttools: {\n\t\t\t// jsonSafeZid (not zid): tool masks feed generated JSON schemas, so\n\t\t\t// ids must present as plain strings while keeping the Id<...> type.\n\t\t\tinsert: commandInput,\n\t\t\tupdate: z.object({ data: commandInput.partial(), id: jsonSafeZid(tableName) }).strict(),\n\t\t\tid: z.object({ id: jsonSafeZid(tableName) }).strict(),\n\t\t},\n\t}\n}\n\nconst tenantFields = {\n\ttenant: z.string().min(1),\n} satisfies FieldSchemas\n\ntype TenantFields = typeof tenantFields\n\n/**\n * A zodTable whose rows are tenant-owned: injects the server-owned `tenant`\n * field (the tenancy boundary — see cvx-kit/tenancy). Like timestamps, it is\n * excluded from insert/update/command boundaries; handlers stamp it from\n * ctx.tenant, row-level security matches on it, and the tenantOwnership\n * trigger forbids reassigning it. Expose it via publicFields only when a DTO\n * genuinely needs it.\n */\nexport function tenantTable<\n\tTable extends string,\n\tFields extends FieldSchemas,\n\tconst ServerFields extends readonly FieldKey<Fields>[] = readonly [],\n\tconst CommandFields extends readonly FieldKey<Fields>[] = readonly [],\n\tconst PublicFields extends readonly FieldKey<Fields & TenantFields & TimestampFields>[] =\n\t\treadonly [],\n>(\n\ttableName: Table,\n\tfields: (\n\t\tid: typeof zid,\n\t) => Fields &\n\t\tOwnedFields<Fields> & { [Key in keyof Fields]: Key extends 'tenant' ? never : Fields[Key] },\n\toptions: TableBoundaryOptions<\n\t\tFields & TenantFields,\n\t\treadonly (ServerFields[number] | 'tenant')[],\n\t\tCommandFields,\n\t\tPublicFields\n\t> = {},\n) {\n\treturn zodTable<\n\t\tTable,\n\t\tFields & TenantFields,\n\t\treadonly (ServerFields[number] | 'tenant')[],\n\t\tCommandFields,\n\t\tPublicFields\n\t>(\n\t\ttableName,\n\t\t(id) => {\n\t\t\tconst declared = fields(id)\n\t\t\tassertOwnedFields(declared, ['tenant', '_id', '_creationTime', ...TIMESTAMP_FIELDS])\n\t\t\t// SAFETY: reserved keys were rejected before injecting tenant; the generic\n\t\t\t// wrapper forwards the same checked fields to the ordinary table constructor.\n\t\t\treturn { ...declared, ...tenantFields } as Fields &\n\t\t\t\tTenantFields &\n\t\t\t\tOwnedFields<Fields & TenantFields>\n\t\t},\n\t\t{\n\t\t\t...options,\n\t\t\tserverFields: [...(options.serverFields ?? []), 'tenant'],\n\t\t},\n\t)\n}\n\n/**\n * Merges per-module table maps into the application schema map, rejecting\n * duplicate table names across modules — the module-registry combinator for\n * domain/table.ts: `defineSchema(createModule(catalogTables, salesTables))`.\n */\nexport function createModule<const Maps extends readonly Record<string, TableDefinition<any>>[]>(\n\t...maps: Maps\n): UnionToIntersection<Maps[number]> {\n\tconst combined: Record<string, TableDefinition<any>> = {}\n\tfor (const map of maps) {\n\t\tfor (const [tableName, definition] of Object.entries(map)) {\n\t\t\tif (tableName in combined) {\n\t\t\t\tthrow new Error(`Table \"${tableName}\" is declared by more than one module`)\n\t\t\t}\n\t\t\tcombined[tableName] = definition\n\t\t}\n\t}\n\t// SAFETY: every input entry is copied, and duplicate keys are rejected above.\n\treturn combined as UnionToIntersection<Maps[number]>\n}\n\ntype UnionToIntersection<Union> = (\n\tUnion extends unknown ? (member: Union) => void : never\n) extends (member: infer Intersection) => void\n\t? Intersection\n\t: never\n\n/**\n * Cursor-pagination boundary schemas bridged from Convex's own validators:\n * `args.paginationOpts` for function args, `result` for the page shape.\n * Pair with `include(...).paginate(opts)` (cvx-kit/auth). The result object\n * is deliberately non-strict — Convex may attach engine fields (splitCursor,\n * pageStatus); the page items themselves are validated against the dto.\n * Note: under row-level security, pages may be SHORTER than numItems when\n * rules reject rows mid-page; cursors remain correct.\n */\nexport function paginated<Dto extends z.ZodType>(dto: Dto) {\n\treturn {\n\t\targs: { paginationOpts: convexToZod(paginationOptsValidator) },\n\t\tresult: z.object({\n\t\t\tpage: z.array(dto),\n\t\t\tisDone: z.boolean(),\n\t\t\tcontinueCursor: z.string(),\n\t\t\tsplitCursor: z.string().nullable().optional(),\n\t\t\tpageStatus: z.enum(['SplitRecommended', 'SplitRequired']).nullable().optional(),\n\t\t}),\n\t}\n}\n\ntype VariantSchema = z.ZodDiscriminatedUnion<readonly StrictObject<FieldSchemas>[], string>\ntype VariantDiscriminator<Schema extends VariantSchema> = Schema['_zod']['def']['discriminator']\ntype VariantTags<Schema extends VariantSchema> = Extract<\n\tz.output<Schema>[VariantDiscriminator<Schema>],\n\tstring\n>\ntype VariantBranch<Schema extends VariantSchema, Tag extends string> = Extract<\n\tSchema['options'][number],\n\tz.ZodObject<{ [Key in VariantDiscriminator<Schema>]: z.ZodLiteral<Tag> }, z.core.$strict>\n>\ntype VariantKeys<Schema extends VariantSchema, Tag extends string> = FieldKey<\n\tVariantBranch<Schema, Tag>['shape']\n>\n\n/** Boundary mode supports strict object branches with one string literal tag each. */\nexport type VariantBoundaryOptions<Schema extends VariantSchema> = {\n\tdiscriminator: VariantDiscriminator<Schema>\n\ttimestamps?: boolean\n\tvariants: {\n\t\t[Tag in VariantTags<Schema>]: {\n\t\t\tserverFields?: readonly Exclude<VariantKeys<Schema, Tag>, VariantDiscriminator<Schema>>[]\n\t\t\tcommandFields?: readonly Exclude<VariantKeys<Schema, Tag>, VariantDiscriminator<Schema>>[]\n\t\t\tpublicFields?: readonly (\n\t\t\t\t| Exclude<VariantKeys<Schema, Tag>, VariantDiscriminator<Schema>>\n\t\t\t\t| keyof TimestampFields\n\t\t\t)[]\n\t\t}\n\t}\n}\ntype VariantMaskKeys<Config, Mask extends string> = Config extends {\n\t[Key in Mask]?: readonly (infer Field)[]\n}\n\t? Extract<Field, string>\n\t: never\ntype CheckedVariantOptions<\n\tSchema extends VariantSchema,\n\tOptions extends VariantBoundaryOptions<Schema>,\n> = {\n\tvariants: {\n\t\t[Tag in keyof Options['variants']]: Tag extends VariantTags<Schema>\n\t\t\t? {\n\t\t\t\t\tcommandFields?: readonly Exclude<\n\t\t\t\t\t\tVariantKeys<Schema, Tag>,\n\t\t\t\t\t\tVariantDiscriminator<Schema> | VariantMaskKeys<Options['variants'][Tag], 'serverFields'>\n\t\t\t\t\t>[]\n\t\t\t\t\tpublicFields?: readonly (\n\t\t\t\t\t\t| Exclude<VariantKeys<Schema, Tag>, VariantDiscriminator<Schema>>\n\t\t\t\t\t\t| (Options extends { timestamps: true } ? keyof TimestampFields : never)\n\t\t\t\t\t)[]\n\t\t\t\t}\n\t\t\t: never\n\t}\n}\ntype VariantMode =\n\t| 'storage'\n\t| 'document'\n\t| 'insert'\n\t| 'update'\n\t| 'command'\n\t| 'commandUpdate'\n\t| 'public'\ntype VariantFields<\n\tTable extends string,\n\tBranch extends StrictObject<FieldSchemas>,\n\tDiscriminator extends string,\n\tConfig,\n\tTimestamps extends boolean,\n\tMode extends VariantMode,\n> = Mode extends 'storage'\n\t? Branch['shape'] & (true extends Timestamps ? TimestampFields : {})\n\t: Mode extends 'document'\n\t\t? VariantFields<Table, Branch, Discriminator, Config, Timestamps, 'storage'> &\n\t\t\t\tSystemFields<Table>\n\t\t: Mode extends 'public' | 'command'\n\t\t\t? Pick<\n\t\t\t\t\tVariantFields<Table, Branch, Discriminator, Config, Timestamps, 'storage'>,\n\t\t\t\t\tExtract<\n\t\t\t\t\t\t| Discriminator\n\t\t\t\t\t\t| VariantMaskKeys<Config, Mode extends 'public' ? 'publicFields' : 'commandFields'>,\n\t\t\t\t\t\tkeyof VariantFields<Table, Branch, Discriminator, Config, Timestamps, 'storage'>\n\t\t\t\t\t>\n\t\t\t\t>\n\t\t\t: Mode extends 'insert'\n\t\t\t\t? Omit<Branch['shape'], VariantMaskKeys<Config, 'serverFields'>>\n\t\t\t\t: PartialFields<\n\t\t\t\t\t\tOmit<\n\t\t\t\t\t\t\tVariantFields<\n\t\t\t\t\t\t\t\tTable,\n\t\t\t\t\t\t\t\tBranch,\n\t\t\t\t\t\t\t\tDiscriminator,\n\t\t\t\t\t\t\t\tConfig,\n\t\t\t\t\t\t\t\tTimestamps,\n\t\t\t\t\t\t\t\tMode extends 'update' ? 'insert' : 'command'\n\t\t\t\t\t\t\t>,\n\t\t\t\t\t\t\tDiscriminator\n\t\t\t\t\t\t>\n\t\t\t\t\t> &\n\t\t\t\t\t\tPick<Branch['shape'], Extract<Discriminator, keyof Branch['shape']>>\ntype DerivedVariantBranches<\n\tTable extends string,\n\tSchema extends VariantSchema,\n\tOptions extends VariantBoundaryOptions<Schema>,\n\tMode extends VariantMode,\n\tIncludeId extends boolean,\n\tBranches extends readonly StrictObject<FieldSchemas>[],\n> = {\n\t[Index in keyof Branches]: Branches[Index] extends StrictObject<FieldSchemas>\n\t\t? StrictObject<\n\t\t\t\tVariantFields<\n\t\t\t\t\tTable,\n\t\t\t\t\tBranches[Index],\n\t\t\t\t\tVariantDiscriminator<Schema>,\n\t\t\t\t\tOptions['variants'][Extract<\n\t\t\t\t\t\tz.output<Branches[Index]>[VariantDiscriminator<Schema>],\n\t\t\t\t\t\tkeyof Options['variants']\n\t\t\t\t\t>],\n\t\t\t\t\tOptions extends { timestamps: infer Enabled }\n\t\t\t\t\t\t? true extends Enabled\n\t\t\t\t\t\t\t? true\n\t\t\t\t\t\t\t: false\n\t\t\t\t\t\t: false,\n\t\t\t\t\tMode\n\t\t\t\t> &\n\t\t\t\t\t(IncludeId extends true ? { _id: Zid<Table> } : {})\n\t\t\t>\n\t\t: never\n}\ntype DerivedVariant<\n\tTable extends string,\n\tSchema extends VariantSchema,\n\tOptions extends VariantBoundaryOptions<Schema>,\n\tMode extends VariantMode,\n\tIncludeId extends boolean = false,\n> = IncludeId extends true\n\t? z.ZodDiscriminatedUnion<\n\t\t\tDerivedVariantBranches<Table, Schema, Options, Mode, true, Schema['options']>,\n\t\t\tVariantDiscriminator<Schema>\n\t\t>\n\t: z.ZodDiscriminatedUnion<\n\t\t\tDerivedVariantBranches<Table, Schema, Options, Mode, false, Schema['options']>,\n\t\t\tVariantDiscriminator<Schema>\n\t\t>\n\nexport type VariantTableBoundary<\n\tTable extends string,\n\tSchema extends VariantSchema,\n\tOptions extends VariantBoundaryOptions<Schema>,\n> = {\n\ttableName: Table\n\tstorage: DerivedVariant<Table, Schema, Options, 'storage'>\n\tschema: DerivedVariant<Table, Schema, Options, 'document'>\n\tinsertSchema: DerivedVariant<Table, Schema, Options, 'insert'>\n\tupdateSchema: DerivedVariant<Table, Schema, Options, 'update'>\n\tcommandInput: DerivedVariant<Table, Schema, Options, 'command'>\n\tpublicDto: DerivedVariant<Table, Schema, Options, 'public'>\n\ttable: TableDefinition<\n\t\tConvexValidatorFromZod<DerivedVariant<Table, Schema, Options, 'storage'>, 'required'>\n\t>\n\tdto(): DerivedVariant<Table, Schema, Options, 'public'>\n\tdto<const IncludeId extends boolean>(\n\t\tincludeId: IncludeId,\n\t): DerivedVariant<Table, Schema, Options, 'public', IncludeId>\n\ttoPublicDto(\n\t\trow: z.input<DerivedVariant<Table, Schema, Options, 'storage'>>,\n\t): z.output<DerivedVariant<Table, Schema, Options, 'public'>>\n\ttoPublicDto<const IncludeId extends boolean>(\n\t\trow: DtoRow<z.input<DerivedVariant<Table, Schema, Options, 'storage'>>, IncludeId>,\n\t\tincludeId: IncludeId,\n\t): z.output<DerivedVariant<Table, Schema, Options, 'public', IncludeId>>\n\ttools: {\n\t\tid: StrictObject<{ id: z.ZodType<GenericId<Table>, string> }>\n\t\tinsert: z.ZodType<\n\t\t\tz.output<DerivedVariant<Table, Schema, Options, 'command'>>,\n\t\t\tz.input<DerivedVariant<Table, Schema, Options, 'command'>>\n\t\t>\n\t\tupdate: StrictObject<{\n\t\t\tid: z.ZodType<GenericId<Table>, string>\n\t\t\tdata: z.ZodType<\n\t\t\t\tz.output<DerivedVariant<Table, Schema, Options, 'commandUpdate'>>,\n\t\t\t\tz.input<DerivedVariant<Table, Schema, Options, 'commandUpdate'>>\n\t\t\t>\n\t\t}>\n\t}\n}\n\n/** Legacy mode preserves arbitrary storage; the third argument opts into derived boundaries. */\nexport function zodVariantTable<Table extends string, Schema extends z.ZodType>(\n\ttableName: Table,\n\tstorage: Schema,\n): {\n\ttableName: Table\n\tstorage: Schema\n\tinsertSchema: Schema\n\ttable: TableDefinition<ConvexValidatorFromZod<Schema, 'required'>>\n}\nexport function zodVariantTable<\n\tTable extends string,\n\tSchema extends VariantSchema,\n\tconst Options extends VariantBoundaryOptions<Schema>,\n>(\n\ttableName: Table,\n\tstorage: Schema,\n\toptions: Options & CheckedVariantOptions<Schema, NoInfer<Options>>,\n): VariantTableBoundary<Table, Schema, Options>\nexport function zodVariantTable(\n\ttableName: string,\n\tstorage: z.ZodType,\n\toptions?: {\n\t\tdiscriminator: string\n\t\ttimestamps?: boolean\n\t\tvariants: Record<\n\t\t\tstring,\n\t\t\t{\n\t\t\t\tserverFields?: readonly string[]\n\t\t\t\tcommandFields?: readonly string[]\n\t\t\t\tpublicFields?: readonly string[]\n\t\t\t}\n\t\t>\n\t},\n) {\n\tif (options) return deriveVariantTable(tableName, storage, options)\n\treturn {\n\t\ttableName,\n\t\tstorage,\n\t\tinsertSchema: storage,\n\t\ttable: defineTable(zodToConvex(storage)),\n\t}\n}\n\n/**\n * A zid that presents as a plain string in generated JSON schemas so\n * LLM-tool inputs stay primitive, while keeping the Id type at compile time.\n */\nexport function jsonSafeZid<Table extends string>(\n\ttableName: Table,\n): z.ZodType<GenericId<Table>, string> {\n\tconst id = zid(tableName)\n\treturn z\n\t\t.string()\n\t\t.refine((value): value is GenericId<Table> => id.safeParse(value).success)\n\t\t.describe(`Convex document id for table \"${tableName}\"; validated against the table by Convex`)\n}\n\nfunction deriveVariantTable(\n\ttableName: string,\n\tdeclared: z.ZodType,\n\toptions: {\n\t\tdiscriminator: string\n\t\ttimestamps?: boolean\n\t\tvariants: Record<\n\t\t\tstring,\n\t\t\t{\n\t\t\t\tserverFields?: readonly string[]\n\t\t\t\tcommandFields?: readonly string[]\n\t\t\t\tpublicFields?: readonly string[]\n\t\t\t}\n\t\t>\n\t},\n) {\n\tif (\n\t\t!(declared instanceof z.ZodDiscriminatedUnion) ||\n\t\tdeclared.def.discriminator !== options.discriminator\n\t)\n\t\tthrow new Error(\n\t\t\t'Variant boundaries require a discriminated union with the configured discriminator',\n\t\t)\n\tif (declared.def.checks?.length)\n\t\tthrow new Error('Variant boundaries do not support union-level refinements')\n\tconst discriminator = options.discriminator\n\tif (['_id', '_creationTime', ...TIMESTAMP_FIELDS].includes(discriminator))\n\t\tthrow new Error('Variant discriminator cannot be a reserved field')\n\tconst branches = new Map<\n\t\tstring,\n\t\t{\n\t\t\tstorage: StrictObject<FieldSchemas>\n\t\t\tdocument: StrictObject<FieldSchemas>\n\t\t\tinsert: StrictObject<FieldSchemas>\n\t\t\tupdate: StrictObject<FieldSchemas>\n\t\t\tcommand: StrictObject<FieldSchemas>\n\t\t\tcommandUpdate: StrictObject<FieldSchemas>\n\t\t\tpublic: StrictObject<FieldSchemas>\n\t\t}\n\t>()\n\tfor (const branch of declared.options) {\n\t\tif (!(branch instanceof z.ZodObject) || !(branch.def.catchall instanceof z.ZodNever))\n\t\t\tthrow new Error('Variant boundaries require strict object branches')\n\t\tif (branch.def.checks?.length)\n\t\t\tthrow new Error('Variant boundaries do not support object-level refinements')\n\t\ttry {\n\t\t\tassertDtoValidationSchema(branch, new Set(), true)\n\t\t} catch (cause) {\n\t\t\tthrow new Error(\n\t\t\t\t'Variant boundaries require supported value-preserving field validators without object catchalls',\n\t\t\t\t{ cause },\n\t\t\t)\n\t\t}\n\t\tconst tagSchema = branch.shape[discriminator]\n\t\tif (!(tagSchema instanceof z.ZodLiteral) || tagSchema.values.size !== 1)\n\t\t\tthrow new Error('Variant branches require one string literal discriminator')\n\t\tconst tag = [...tagSchema.values][0]\n\t\tif (!z.string().safeParse(tag).success)\n\t\t\tthrow new Error('Variant branches require a string discriminator')\n\t\t// SAFETY: a single literal value was checked as a string above.\n\t\tconst tagValue = tag as string\n\t\tif (branches.has(tagValue)) throw new Error(`Duplicate variant discriminator \"${tagValue}\"`)\n\t\tif (!Object.hasOwn(options.variants, tagValue))\n\t\t\tthrow new Error(`Missing variant configuration \"${tagValue}\"`)\n\t\tconst config = options.variants[tagValue]\n\t\tassertOwnedFields(branch.shape, ['_id', '_creationTime', ...TIMESTAMP_FIELDS])\n\t\tconst columns = { ...branch.shape } satisfies FieldSchemas\n\t\tif (options.timestamps) Object.assign(columns, timestampFields)\n\t\tassertFieldLists(\n\t\t\tcolumns,\n\t\t\tconfig.serverFields ?? [],\n\t\t\tconfig.commandFields ?? [],\n\t\t\tconfig.publicFields ?? [],\n\t\t)\n\t\tfor (const mask of [config.serverFields, config.commandFields, config.publicFields]) {\n\t\t\tif (mask?.includes(discriminator))\n\t\t\t\tthrow new Error(\n\t\t\t\t\t'The variant discriminator is retained automatically and cannot appear in masks',\n\t\t\t\t)\n\t\t}\n\t\tconst stored = z.strictObject(columns)\n\t\tconst insert = z.strictObject(\n\t\t\tomitFields(columns, [...TIMESTAMP_FIELDS, ...(config.serverFields ?? [])]),\n\t\t)\n\t\tconst command = z.strictObject(\n\t\t\tpickFields(columns, [discriminator, ...(config.commandFields ?? [])]),\n\t\t)\n\t\tconst partial = (schema: StrictObject<FieldSchemas>) =>\n\t\t\tschema.partial().extend({ [discriminator]: tagSchema })\n\t\tbranches.set(tagValue, {\n\t\t\tstorage: stored,\n\t\t\tdocument: documentSchema(stored, tableName),\n\t\t\tinsert,\n\t\t\tupdate: partial(insert),\n\t\t\tcommand,\n\t\t\tcommandUpdate: partial(command),\n\t\t\tpublic: z.strictObject(pickFields(columns, [discriminator, ...(config.publicFields ?? [])])),\n\t\t})\n\t}\n\tfor (const tag of Object.keys(options.variants)) {\n\t\tif (!branches.has(tag)) throw new Error(`Unknown variant configuration \"${tag}\"`)\n\t}\n\tfunction union(mode: VariantMode, includeId = false, tool = false) {\n\t\tconst schemas = [...branches.values()].map((branch) => {\n\t\t\tconst schema = branch[mode]\n\t\t\tif (tool)\n\t\t\t\treturn z.strictObject(\n\t\t\t\t\tObject.fromEntries(\n\t\t\t\t\t\tObject.entries(schema.shape).map(([key, field]) => [key, variantToolField(field)]),\n\t\t\t\t\t),\n\t\t\t\t)\n\t\t\treturn includeId ? schema.extend({ _id: zid(tableName) }) : schema\n\t\t})\n\t\tif (!schemas.length) throw new Error('Variant boundaries require at least one branch')\n\t\t// SAFETY: all entries are checked strict objects with a unique required literal tag; nonempty checked above.\n\t\treturn z.discriminatedUnion(\n\t\t\tdiscriminator,\n\t\t\tschemas as [StrictObject<FieldSchemas>, ...StrictObject<FieldSchemas>[]],\n\t\t)\n\t}\n\tconst storage = union('storage')\n\tconst schema = union('document')\n\tconst insertSchema = union('insert')\n\tconst updateSchema = union('update')\n\tconst commandInput = union('command')\n\tconst publicDto = union('public')\n\tfunction dto(includeId = false) {\n\t\treturn includeId ? union('public', true) : publicDto\n\t}\n\tfunction toPublicDto(row: z.input<StrictObject<FieldSchemas>>, includeId = false) {\n\t\tconst tag = z.string().parse(row[discriminator])\n\t\tconst branch = branches.get(tag)\n\t\tif (!branch) throw new Error(`Unknown variant discriminator \"${tag}\"`)\n\t\tconst projection = includeId ? branch.public.extend({ _id: zid(tableName) }) : branch.public\n\t\treturn projection.parse(\n\t\t\tObject.fromEntries(\n\t\t\t\tObject.keys(projection.shape)\n\t\t\t\t\t.filter((key) => Object.hasOwn(row, key))\n\t\t\t\t\t.map((key) => [key, row[key]]),\n\t\t\t),\n\t\t)\n\t}\n\treturn {\n\t\ttableName,\n\t\tstorage,\n\t\tschema,\n\t\tinsertSchema,\n\t\tupdateSchema,\n\t\tcommandInput,\n\t\tpublicDto,\n\t\tdto,\n\t\ttoPublicDto,\n\t\ttable: defineTable(zodToConvex(storage)),\n\t\ttools: {\n\t\t\tid: z.strictObject({ id: jsonSafeZid(tableName) }),\n\t\t\tinsert: union('command', false, true),\n\t\t\tupdate: z.strictObject({\n\t\t\t\tid: jsonSafeZid(tableName),\n\t\t\t\tdata: union('commandUpdate', false, true),\n\t\t\t}),\n\t\t},\n\t}\n}\n\nfunction variantToolField(schema: z.core.$ZodType): z.ZodType {\n\tif (!(schema instanceof z.ZodType))\n\t\tthrow new Error('Variant tools require classic Zod field schemas')\n\tif (\n\t\tschema instanceof z.ZodBigInt ||\n\t\t(schema instanceof z.ZodLiteral &&\n\t\t\t[...schema.values].some((value) => z.bigint().safeParse(value).success))\n\t)\n\t\tthrow new Error(\n\t\t\t'Variant tool command fields cannot contain bigint; JSON Schema cannot represent it',\n\t\t)\n\tconst native = zodToConvex(schema)\n\tif (native.kind === 'id') {\n\t\tconst id = jsonSafeZid(native.tableName)\n\t\tif (native.isOptional === 'optional')\n\t\t\treturn id.optional().refine((value) => schema.safeParse(value).success)\n\t\treturn id.refine((value) => schema.safeParse(value).success)\n\t}\n\tif (schema instanceof z.ZodOptional)\n\t\treturn schema.clone({ ...schema.def, innerType: variantToolField(schema.unwrap()) })\n\tif (schema instanceof z.ZodNullable)\n\t\treturn schema.clone({ ...schema.def, innerType: variantToolField(schema.unwrap()) })\n\tif (schema instanceof z.ZodNonOptional)\n\t\treturn schema.clone({ ...schema.def, innerType: variantToolField(schema.unwrap()) })\n\tif (schema instanceof z.ZodArray)\n\t\treturn schema.clone({ ...schema.def, element: variantToolField(schema.element) })\n\tif (schema instanceof z.ZodObject) {\n\t\tconst fields = Object.fromEntries(\n\t\t\tObject.entries(schema.shape).map(([key, child]) => [key, variantToolField(child)]),\n\t\t)\n\t\treturn schema.clone(Object.assign({}, schema.def, { ['shape']: fields }))\n\t}\n\tif (schema instanceof z.ZodUnion)\n\t\treturn schema.clone({ ...schema.def, options: schema.options.map(variantToolField) })\n\tif (schema instanceof z.ZodRecord)\n\t\treturn schema.clone({\n\t\t\t...schema.def,\n\t\t\t// SAFETY: conversion preserves the original record key output; IDs remain strings.\n\t\t\tkeyType: variantToolField(schema.keyType) as z.core.$ZodRecordKey,\n\t\t\tvalueType: variantToolField(schema.valueType),\n\t\t})\n\tif (schema instanceof z.ZodTuple)\n\t\treturn schema.clone({\n\t\t\t...schema.def,\n\t\t\titems: schema.def.items.map(variantToolField),\n\t\t\trest: schema.def.rest ? variantToolField(schema.def.rest) : null,\n\t\t})\n\tif (schema instanceof z.ZodIntersection)\n\t\treturn schema.clone({\n\t\t\t...schema.def,\n\t\t\tleft: variantToolField(schema.def.left),\n\t\t\tright: variantToolField(schema.def.right),\n\t\t})\n\treturn schema\n}\n\ntype ZodObjectOmit<\n\tSchema extends z.ZodObject<any, any>,\n\tOmitMask extends z.util.Mask<keyof Schema['shape']>,\n> =\n\tSchema extends z.ZodObject<infer ObjectFields, infer Config>\n\t\t? z.ZodObject<\n\t\t\t\tz.util.Flatten<Omit<ObjectFields, Extract<keyof ObjectFields, keyof OmitMask>>>,\n\t\t\t\tConfig\n\t\t\t>\n\t\t: never\n\nfunction documentSchema<Fields extends FieldSchemas, Table extends string>(\n\tstorage: StrictObject<Fields>,\n\ttableName: Table,\n) {\n\treturn storage.extend({ _id: zid(tableName), _creationTime: z.number() })\n}\n\nfunction pickFields<Fields extends FieldSchemas, const Keys extends readonly FieldKey<Fields>[]>(\n\tfields: Fields,\n\tkeys: Keys,\n) {\n\t// SAFETY: each entry uses a requested key and its original validator, preserving Pick.\n\treturn Object.fromEntries(keys.map((key) => [key, fields[key]])) as Pick<Fields, Keys[number]>\n}\n\nfunction omitFields<Fields extends FieldSchemas, const Keys extends readonly FieldKey<Fields>[]>(\n\tfields: Fields,\n\tkeys: Keys,\n) {\n\tconst omitted = new Set<string>(keys)\n\t// SAFETY: filtering removes exactly the supplied keys and keeps every remaining validator.\n\treturn Object.fromEntries(Object.entries(fields).filter(([key]) => !omitted.has(key))) as Omit<\n\t\tFields,\n\t\tKeys[number]\n\t>\n}\n\ntype DtoPropertiesCheck = z.core.$ZodCheck & {\n\treadonly _zod: {\n\t\treadonly def: { readonly check: 'properties' } & Record<\n\t\t\t'shape',\n\t\t\tRecord<string, z.core.$ZodType>\n\t\t>\n\t}\n}\n\n/** Inspect Zod 4's discriminated definitions, failing closed for unsupported nodes.\n * Used by DTO extensions and opt-in variant boundaries; legacy schemas are unchanged.\n */\nfunction assertDtoValidationSchema(\n\tschema: z.core.$ZodType,\n\tseen = new Set<z.core.$ZodType>(),\n\tallowNativeIds = false,\n): void {\n\tif (seen.has(schema)) return\n\tseen.add(schema)\n\t// SAFETY: Zod 4 exposes its built-in schema definitions as this discriminated union.\n\tconst def = (schema as z.core.$ZodTypes)._zod.def\n\tconst reject = () => {\n\t\tthrow new Error('DTO extensions require supported value-preserving validation schemas')\n\t}\n\tif ('coerce' in def && def.coerce) reject()\n\tif ('normalize' in def && def.normalize) reject()\n\tconst visit = (child: z.core.$ZodType) => assertDtoValidationSchema(child, seen, allowNativeIds)\n\tfor (const check of def.checks ?? []) {\n\t\tif (check._zod.def.check === 'overwrite') reject()\n\t\tif ('normalize' in check._zod.def && check._zod.def.normalize) reject()\n\t\tif (check._zod.def.check === 'property') {\n\t\t\t// SAFETY: the property discriminator owns this embedded schema in Zod 4.\n\t\t\tvisit((check as z.core.$ZodCheckProperty)._zod.def.schema)\n\t\t}\n\t\tif (check._zod.def.check === 'properties') {\n\t\t\t// SAFETY: the properties discriminator owns this schema shape in Zod 4.\n\t\t\tfor (const child of Object.values((check as DtoPropertiesCheck)._zod.def.shape)) {\n\t\t\t\tvisit(child)\n\t\t\t}\n\t\t}\n\t}\n\tswitch (def.type) {\n\t\tcase 'custom':\n\t\t\tif (allowNativeIds && zodToConvex(schema).kind === 'id') return\n\t\t\treject()\n\t\t\treturn\n\t\tcase 'string':\n\t\tcase 'number':\n\t\tcase 'boolean':\n\t\tcase 'bigint':\n\t\tcase 'date':\n\t\tcase 'symbol':\n\t\tcase 'null':\n\t\tcase 'undefined':\n\t\tcase 'void':\n\t\tcase 'never':\n\t\tcase 'literal':\n\t\tcase 'enum':\n\t\t\treturn\n\t\tcase 'object':\n\t\t\tif (allowNativeIds && def.catchall && def.catchall._zod.def.type !== 'never')\n\t\t\t\tthrow new Error('Variant fields cannot use object catchalls; use a record field instead')\n\t\t\tfor (const child of Object.values(def.shape)) visit(child)\n\t\t\tif (def.catchall) visit(def.catchall)\n\t\t\treturn\n\t\tcase 'array':\n\t\t\tvisit(def.element)\n\t\t\treturn\n\t\tcase 'optional':\n\t\tcase 'nullable':\n\t\tcase 'nonoptional':\n\t\t\tvisit(def.innerType)\n\t\t\treturn\n\t\tcase 'union':\n\t\t\tfor (const child of def.options) visit(child)\n\t\t\treturn\n\t\tcase 'intersection':\n\t\t\tvisit(def.left)\n\t\t\tvisit(def.right)\n\t\t\treturn\n\t\tcase 'tuple':\n\t\t\tfor (const child of def.items) visit(child)\n\t\t\tif (def.rest) visit(def.rest)\n\t\t\treturn\n\t\tcase 'record':\n\t\t\tvisit(def.keyType)\n\t\t\tvisit(def.valueType)\n\t\t\treturn\n\t\tdefault:\n\t\t\treject()\n\t}\n}\n\nfunction assertOwnedFields(fields: FieldSchemas, reserved: readonly string[]): void {\n\tfor (const key of reserved) {\n\t\tif (Object.hasOwn(fields, key))\n\t\t\tthrow new Error(`Reserved table field \"${key}\" cannot be declared`)\n\t}\n}\n\nfunction assertFieldLists(\n\tfields: FieldSchemas,\n\tserver: readonly string[],\n\tcommand: readonly string[],\n\tpublicKeys: readonly string[],\n): void {\n\tfor (const key of [...server, ...command, ...publicKeys]) {\n\t\tif (!Object.hasOwn(fields, key)) throw new Error(`Unknown table field \"${key}\"`)\n\t}\n\tconst managed = new Set<string>([...TIMESTAMP_FIELDS, ...server])\n\tfor (const key of command) {\n\t\tif (managed.has(key)) throw new Error(`Server-owned field \"${key}\" cannot be a command input`)\n\t}\n}\n"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cvx-kit",
3
- "version": "0.1.14",
3
+ "version": "0.1.16",
4
4
  "description": "Reusable Convex application kit: foundation kernels, approvals component, zod table boundaries, WorkOS-backed auth function constructors, and audited command protocol.",
5
5
  "keywords": [
6
6
  "component",
@@ -18,6 +18,12 @@
18
18
  "type": "git",
19
19
  "url": "git+https://github.com/ImRLopezAG/cvx-kit.git"
20
20
  },
21
+ "files": [
22
+ "dist",
23
+ "src/test.ts",
24
+ "README.md",
25
+ "LICENSE"
26
+ ],
21
27
  "type": "module",
22
28
  "sideEffects": false,
23
29
  "exports": {
@@ -139,6 +145,7 @@
139
145
  "test": "vp test run --exclude test/package-contents.test.mjs",
140
146
  "test:package": "bun run build && vp test run test/package-contents.test.mjs",
141
147
  "test:package:ids": "bun run build && node scripts/test-packed-ids.mjs",
148
+ "test:package:variants": "bun run build && node scripts/test-packed-variants.mjs",
142
149
  "test:package:oxlint": "bun run build && node scripts/test-packed-oxlint.mjs",
143
150
  "test:package:effect": "bun run build && node scripts/test-packed-effect.mjs",
144
151
  "test:package:auth": "bun run build && node scripts/test-packed-auth.mjs",
@@ -146,8 +153,8 @@
146
153
  "test:package:smoke:effect": "bun run build && node scripts/smoke-packed-effect.mjs",
147
154
  "test:package:smoke:bun": "bun scripts/smoke-packed-components.mjs bun",
148
155
  "test:package:smoke:npm": "node scripts/smoke-packed-components.mjs npm",
149
- "docs:sync": "rm -f docs/*.md && cp src/docs/*.md docs/",
150
- "prepublishOnly": "bun run build && bun run typecheck && bun run test && bun run docs:sync",
156
+ "skills:check": "node scripts/check-skills.mjs",
157
+ "prepublishOnly": "bun run build && bun run typecheck && bun run test && bun run skills:check",
151
158
  "build:codegen": "convex codegen --component-dir ./src/components/foundation && convex codegen --component-dir ./src/components/approvals && vp pack",
152
159
  "release": "npm version patch && git push --follow-tags",
153
160
  "release:minor": "npm version minor && git push --follow-tags"
package/AGENTS.md DELETED
@@ -1,47 +0,0 @@
1
- # Orchestration
2
-
3
- <!-- Orchestration -->
4
-
5
- Use T3 Code to orchestrate the agents the new orchestrator V2 allows you to orchestrate multiple models for working together, I have some recommendations for model selection and orchestration:
6
-
7
- ## Models
8
-
9
- | Provider | Heavy | Medium | Light |
10
- | -------- | ----------- | ----------- | ---------------------- |
11
- | OpenAI | gpt-6-astra | gpt-6.1-sol | gpt-6-luna |
12
- | Claude | flabel-5.1 | opus-5.5 | sonnet-5.5 / haiku-5.5 |
13
-
14
- Haiku and Luna are very special models for short tasks such as research file reader and those tasks that wont consume more than 100K tokens.
15
-
16
- ## Workflow
17
-
18
- I have a workflow for implementing features and working which contains some skills within the process they don't fallow an order but depending how deep we are on context we use it but those skills are:
19
-
20
- - **ce-explain**: This I used it to verify if the AI is aligned with the user's intent, then got a back and forth conversation with the user to explain the feature and the context of the feature including research on the libraries internet and packages.
21
- - **ce-plan**: This I used it to plan the feature implementation.
22
- - **ce-work**: This I used it to work on the feature implementation.
23
-
24
- These are goated skills that are used to implement features and work on them, but the real workflow for implementation itself is:
25
-
26
- | Planners | workers | low workers | researcher | reviewers |
27
- | ----------- | ----------- | ----------- | ---------------------- | ----------- |
28
- | gpt-6-astra | gpt-6.1-sol | gpt-6-luna | gpt-6-luna | gpt-6-astra |
29
- | flabel-5.1 | opus-5.5 | sonnet-5.5 | sonnet-5.5 / haiku-5.5 | N/A |
30
-
31
- Invoke **reviewers** for code review, implementation review, and security review on changed code. Use **gpt-6-astra** at **Low** effort for that role.
32
-
33
- After the planning and research session I sent the `ce-work` message to the main thread with the fallowing context:
34
- "Work on this feature into a goal with multiple agents and make sure you test every phase. And you do a code review and an implementation review as well. Make sure every phase is tested before go to the other one And commit it as well. Make a security review to make sure everything is working correctly. Use a browser or any test you need to make sure you cover the needed and everything is working correctly."
35
-
36
- with the fallowing effort:
37
-
38
- | Model | Recommended Effort |
39
- | ----------- | --------------------------------------------- |
40
- | gpt-6-astra | Medium / Low worker; Low reviewer |
41
- | flabel-5.1 | low |
42
- | opus-5.5 | low |
43
- | gpt-6-luna | low(fast) |
44
- | gpt-6.1-sol | medium(fast) |
45
- | sonnet-5.5 | medium |
46
-
47
- <!-- Orchestration -->
package/CHANGELOG.md DELETED
@@ -1,324 +0,0 @@
1
- # Changelog
2
-
3
- All notable changes to cvx-kit are documented here. The format follows
4
- [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).
5
-
6
- **Semver contract (from 0.1.0):** while on 0.x, breaking changes land only on
7
- minor bumps; patches are additive or fixes. The breaking window formally
8
- closes at the follow-up consolidation release (package-name decision + full
9
- export-name API audit) — until then, the six 0.1.0 helper surfaces may still
10
- be renamed in a minor. Every release tag gets a GitHub Release whose notes
11
- are this file's matching section.
12
-
13
- ## [Unreleased]
14
-
15
- ## [0.1.14] - 2026-10-11
16
-
17
- ### Added
18
-
19
- - Typed relational queries with scalar and relationship filters, conditional indexes, global ascending or descending order, and bounded stream pagination.
20
- - Explicit relationship declarations for direct, self, and junction relationships, with paginated child continuations.
21
- - Managed query authorization, shared read budgets, and encrypted cursors bound to the query, principal, tenant, and parent relationship.
22
- - Table DTO options for validated IDs and extensions, including `toPublicDto(row, true)`, plus native-derived `paginationOpts` and page DTO helpers.
23
- - Oxlint enforcement for manual ID projections, copied pagination contracts, and unsafe relational query boundaries.
24
- - Dedicated querying documentation and updated table and rule documentation in `src/docs`.
25
-
26
- ### Fixed
27
-
28
- - Preserve shared validator graphs during native auth registration to avoid repeated validator expansion.
29
-
30
- ### Verified
31
-
32
- - Source, type, rule, and packed-consumer checks; 308 independently audited relational stress sequences across installed and minimum peer versions.
33
- - 33 HTTP responses exercised encrypted cursor pagination and rejection paths on a local Convex backend. Hosted production performance remains unmeasured.
34
-
35
- ## [0.1.13] - 2026-10-10
36
-
37
- ### Added
38
-
39
- - Implement contracted operations with `command.handler(handler, options?)` and
40
- `query.handler(handler, options?)` in both Promise and Effect registries.
41
- - Infer each handler's input and result from its operation object key, without
42
- repeating the operation name; preserve existing named helpers.
43
-
44
- ### Verified
45
-
46
- - Cover contract binding, validation, audits, and handler inference with 684
47
- runtime tests and strict type fixtures.
48
- - Compile the documentation examples and test packed npm/Bun consumers with
49
- and without Effect.
50
-
51
- ## [0.1.12] - 2026-10-10
52
-
53
- ### Added
54
-
55
- - Declare optional domain contracts with root errors, command classification,
56
- and exact command/query implementation keys in both Effect and Promise registries (#26).
57
- - Share a registry-level command audit default with per-operation overrides,
58
- preserving replay bypass, schema inference, and transactional rollback.
59
- - Use `createFoundation` for typed Promise registries without installing Effect.
60
- - Enforce reserved domain file declarations through the packaged Oxlint plugin,
61
- including constructor provenance and declarative contract ownership.
62
- - Document both contract APIs with packed-compiled examples and audit guidance.
63
-
64
- ### Verified
65
-
66
- - Cover native validation, error projection, rollback, audit selection, agent tools,
67
- workflow integration, and npm/Bun consumers with and without Effect.
68
- - Pass 680 runtime tests, 340 lint-rule tests, and both packed-component CI smoke tests.
69
-
70
- ## [0.1.11] - 2026-10-09
71
-
72
- ### Added
73
-
74
- - Configure shared post-auth Effect services and command/query handles once across
75
- all auth, role, admin, and system constructors with `createEffectAuthFunctions` (#24).
76
- - Keep query, mutation, action, and internal system capabilities separately typed
77
- and configured; preserve secured database wrapping and live action membership.
78
- - Document the shared application factory with packed-compiled examples and
79
- constructor capability guidance for coding agents.
80
-
81
- ### Verified
82
-
83
- - Cover denied authentication, roles and membership, request-local scopes, context
84
- collisions, nested command auditing, and registered mutation rollback.
85
- - Preserve packed native auth context compatibility on Convex 1.45 and 1.46.
86
-
87
- ## [0.1.10] - 2026-10-09
88
-
89
- ### Fixed
90
-
91
- - Preserve native Convex context types in auth, role, admin, and system function
92
- constructors so secured handlers bind directly to Effect registries (#22).
93
- - Install Standard Schema types explicitly so native contract input and output
94
- inference works in clean installations.
95
-
96
- ### Changed
97
-
98
- - Update package dependencies and migrate the development toolchain to Vite+ 1.1.
99
- - Require Convex 1.46 or newer and convex-helpers 0.1.127 or newer (below 0.2.0),
100
- matching workflow 0.4.10.
101
-
102
- ## [0.1.7] - 2026-10-07
103
-
104
- ### Added
105
-
106
- - Add optional Effect 4 command and query registries with cohesive ordinary,
107
- Promise, generator, and function handlers, injected services, and scoped API
108
- execution through native and custom Convex builders.
109
- - Add asynchronous operation contracts, explicit schema adapters, and checked
110
- transport for declared safe errors.
111
- - Add injectable audited Effect CRUD, host-owned transactional idempotency
112
- receipts, native durable workflow bindings, and selected domain operation tools.
113
- - Document server-side declaration, composition, API consumption, receipts,
114
- workflows, and tools with compile-checked public-package examples.
115
-
116
- ### Fixed
117
-
118
- - Preserve native validators, trusted authorization, RLS, triggers, audit, and
119
- rollback across API, workflow, and tool integrations.
120
- - Reconcile late workflow outcomes without allowing stale generations or late
121
- completion to overwrite canceled runs.
122
- - Validate retained receipt versions before fingerprints and replay, and require
123
- current authorization before disclosing replayed results.
124
-
125
- ## [0.1.6] - 2026-09-19
126
-
127
- ### Added
128
-
129
- - Add five opt-in consumer Oxlint rules for project structure, root wiring,
130
- application orchestration, internal function ownership, and domain file
131
- responsibilities. The packaged plugin now includes 20 rules.
132
- - Check colocated test presence, runtime import cycles, and shared-code ownership.
133
- Export `checkArchitecture` for standalone checks without copying architecture
134
- test suites into applications. These static checks do not replace behavior tests.
135
-
136
- ### Fixed
137
-
138
- - Resolve tsconfig aliases when checking consumer import boundaries and reject
139
- migration dependencies from application code.
140
- - Enforce documented ownership of domain implementations, table aggregation,
141
- query side effects, and component boundaries.
142
-
143
- ## [0.1.5] - 2026-09-18
144
-
145
- ### Fixed
146
-
147
- - Correct `cvx-kit/oxlint` to enforce the documented consumer `convex/` layout
148
- rather than this repository's `src/` layout. Keep the six library-authoring
149
- rules in repository tooling and publish 15 consumer rules, with coverage for
150
- domain boundaries, auth builders, thin adapters, facade ownership, table
151
- placement, vocabularies, bounded read syntax, and trigger-owned timestamps.
152
- - Replace consumer `entryPoints`/`packageName` options with `convexDir`; document
153
- migration, allowed exceptions, and the checks that still need runtime tests.
154
- Validate the packaged plugin against consumer fixtures installed by npm and Bun.
155
-
156
- ## [0.1.4] - 2026-09-18
157
-
158
- ### Added
159
-
160
- - Publish the TypeScript Oxlint plugin as `cvx-kit/oxlint`, with six rules for
161
- component isolation, environment access, schema placement, public facades,
162
- API ordering, and named private helpers. Consumer entry points and package
163
- self-import boundaries are configurable.
164
- - Enforce all 15 generic anti-slop rules in the repository and verify the
165
- published plugin through fresh npm and Bun installations in CI.
166
-
167
- ### Changed
168
-
169
- - Replace cast-heavy command, CRUD, tenancy, auth, webhook, and tool boundaries
170
- with schema-derived types and validation. Preserve distinct agent-tool result
171
- types and validate the emitted declarations in packed consumers.
172
- - Tighten TypeScript contracts for query middleware, include transforms, audit
173
- metadata, and webhook targets. See `docs/upgrading.md` for migration details.
174
- - Format owned source, tests, scripts, and documentation consistently.
175
-
176
- ## [0.1.3] - 2026-09-06
177
-
178
- ### Fixed
179
-
180
- - Fix Convex ID validation across package boundaries by sharing `convex-helpers`
181
- as a peer dependency. Export `zid`, `zodToConvex`, and `convexToZod` from
182
- `cvx-kit/zod-table`; verify differing compatible host versions under npm and Bun (#10).
183
- - Add `Command.withContext<Context, Extension>()` for schema-inferred guards,
184
- audit callbacks, operation middleware, and correlated registry middleware (#11).
185
- - Add invocation-local `prepare` hooks with authorized, validated replay and
186
- completion after audit, inside observation. Durable storage remains host-owned (#12).
187
- - Accept concrete and generic `convex-test` backends directly in registration helpers (#13).
188
- - Parse command results once after middleware; handler and middleware result types
189
- describe schema inputs, while audit, completion, and executor results describe outputs.
190
- - Accept raw command schema inputs at executor call sites while inferring parsed
191
- outputs for callbacks; reject incompatible typed host contexts and registry middleware.
192
- - See `docs/upgrading.md` for helper peer installation and transformed-result migration.
193
-
194
- ## [0.1.2] - 2026-08-21
195
-
196
- ### Added
197
-
198
- - `resolveOrganization` hook on `createAuthFunctions`: identity providers
199
- whose tokens carry no org claims (custom credentials, magic codes,
200
- memberships in app tables) can resolve organization and role from the
201
- database. When configured, the hook overrides claim-based resolution and
202
- fails closed — `null` or an error rejects with `FORBIDDEN`; its `roleSlug`
203
- still passes `mapRole`, tenancy derives from the hook's organization, and
204
- `verifyMembership` for actions is unchanged. Hook-less configurations are
205
- unaffected. ([#8](https://github.com/ImRLopezAG/cvx-kit/issues/8))
206
-
207
- ## [0.1.1] - 2026-08-17
208
-
209
- ### Fixed
210
-
211
- - Package Convex component schemas exclusively as discoverable `schema.js` and
212
- `schema.d.ts` files. This restores the approvals tables and the
213
- `approvalDecisions.by_runId_and_decidedAt` and
214
- `approvalDecisions.by_runId_and_stepKey_and_actor_actorRef` indexes without
215
- consumer `patchedDependencies` workarounds or canonicalization conflicts.
216
- - Keep compiled component imports aligned with the discoverable `schema.js`
217
- filename when runtime functions use the schema directly.
218
- - Include `stepKey` in the public approval callback evidence contract and
219
- export canonical Zod and Convex callback validators for strict consumers.
220
- - Use component-safe cursor pagination for approval request lists instead of
221
- Convex's app-only built-in `.paginate()` implementation.
222
-
223
- ### Added
224
-
225
- - Packed-tarball content checks and clean anonymous-deployment smoke tests for
226
- every bundled component under both Bun and npm installation.
227
- - `components.approvals.health.check`, which verifies the approvals schema
228
- version and required decision indexes with an actionable failure diagnostic.
229
- - Supported Convex, Zod, Bun, Node.js, and npm versions plus an approvals
230
- packaging migration note.
231
- - Packed callback and paginated-list smoke coverage through real host wrappers.
232
-
233
- ## [0.1.0] - 2026-08-14
234
-
235
- The big one: the full helper surface, in one release.
236
-
237
- ### Added
238
-
239
- - **Pagination bridge** — `paginated(dto)` boundary schemas
240
- (`cvx-kit/zod-table`) and an `include(...).paginate(opts, transform?)`
241
- terminal (`cvx-kit/auth`): cursor pagination bounded by the same maxRows
242
- policy as `execute`. Under row-level security, pages may be shorter than
243
- `numItems` (filtered rows); cursors remain correct.
244
- - **CRUD command factory** — `createCrudCommands` (`cvx-kit/crud`):
245
- create/update/archive operations generated from a zodTable, fully inside
246
- the audited command pipeline; soft-delete only; `enrich` is required for
247
- tenantTables (fails fast with `CRUD_ENRICH_REQUIRED`).
248
- - **State-machine helper** — `createStateMachine` (`cvx-kit/state-machine`):
249
- typed transition legality from constants tuples; `assert` throws
250
- `INVALID_TRANSITION` via the injected ErrorFactory, dropping straight into
251
- command guards.
252
- - **Rate-limit middleware** — `rateLimit` (`cvx-kit/middleware`): the first
253
- packaged middleware, over an injected `@convex-dev/rate-limiter` instance
254
- (structural typing — zero new kit dependencies). Keyed by `ctx.tenant` by
255
- default; a missing key is a configuration error
256
- (`RATE_LIMIT_KEY_MISSING`), never a silent shared bucket.
257
- - **Webhook boundary** — `createWebhookBoundary`, `recordWebhookEvent`,
258
- `webhookEventsTable` (`cvx-kit/webhooks`): raw-body signature verification
259
- (fail closed), natural-key dedup transactional inside the target internal
260
- mutation, host-owned dedup table.
261
- - **Agent tool generator** — `createAgentTools` (`cvx-kit/agent-tools`):
262
- tool records from the table tool masks, shape-compatible with
263
- `@convex-dev/agent`'s `createTool` without depending on it; mutation
264
- handlers route through command executors so agents get audited commands.
265
- - **Typed middleware context** — `Command.middleware<Ctx, Extension>` /
266
- `Query.middleware<Ctx, Extension>`: `next({ context })` is typed against
267
- the declared extension; registries and operations accept typed middleware
268
- without casts (`AnyCommandMiddleware`/`AnyQueryMiddleware` variance seam).
269
- - **Upgrade guide** — `docs/upgrading.md` ships in the package: old way →
270
- new way per feature for consumers on 0.0.x.
271
-
272
- ### Changed
273
-
274
- - `tools.update` / `tools.id` masks now use `jsonSafeZid` instead of `zid`,
275
- so ids present as plain strings in generated JSON schemas (compile-time
276
- `Id<...>` types preserved).
277
- - Release workflow now creates a GitHub Release with this file's section as
278
- notes, and action pins are updated past the Node 20 deprecation.
279
-
280
- ## [0.0.8] - 2026-08-14
281
-
282
- - Composable next()-based middleware for Command and Query kernels, inside
283
- pipeline invariants (registry-wide + per-operation, context enrichment,
284
- result re-parse).
285
-
286
- ## [0.0.7] - 2026-08-14
287
-
288
- - `systemQuery` constructor: internal, include-equipped, RLS-unwrapped.
289
- BREAKING: `createAuthFunctions` config requires the `internalQuery` builder.
290
-
291
- ## [0.0.6] - 2026-08-14
292
-
293
- - Materialized `convex.config.js` bridges (Convex CLI discovers components by
294
- that literal filename). BREAKING: mount via
295
- `cvx-kit/components/<name>/convex.config`; client facades no longer
296
- default-export the component config.
297
-
298
- ## [0.0.5] - 2026-08-14
299
-
300
- - BREAKING: the Foundation facade is the only runtime surface — kernel
301
- classes and execution utilities destructure from the instance.
302
-
303
- ## [0.0.4] - 2026-08-14
304
-
305
- - Tarball ships only `dist`, `docs`, and the source test helper
306
- (`.npmignore`); `cvx-kit/test` registers compiled dist modules.
307
-
308
- ## [0.0.3] - 2026-08-14
309
-
310
- - Opt-in tenancy and security controls: `tenantTable`, `createModule`,
311
- `security` config on `createAuthFunctions` (role rules + tenant RLS),
312
- `ctx.tenant`, `cvx-kit/tenancy`, `tenantOwnership` trigger. Command
313
- guards, permission checks, and the aggregate allowlist.
314
-
315
- ## [0.0.2] - 2026-08-13
316
-
317
- - Shipped package documentation (architecture, conventions, migration,
318
- llms) at `docs/`; opinionated timestamps on every table; single-path
319
- component mounts.
320
-
321
- ## [0.0.1] - 2026-08-13
322
-
323
- - Initial release: foundation + approvals components, zod-table boundaries,
324
- auth constructors, triggers, audited command protocol.