cvx-kit 0.1.13 → 0.1.15
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.
- package/AGENTS.md +47 -0
- package/CHANGELOG.md +33 -0
- package/README.md +142 -0
- package/dist/auth.d.mts +3 -1
- package/dist/auth.mjs +1 -1
- package/dist/auth.mjs.map +1 -1
- package/dist/index.d.mts +5 -2
- package/dist/index.mjs +1 -1
- package/dist/modules/effect/api-zod.d.mts +1 -1
- package/dist/oxlint/architecture.d.mts +2 -0
- package/dist/oxlint/architecture.mjs +1 -1
- package/dist/oxlint/architecture.mjs.map +1 -1
- package/dist/oxlint/ast.d.mts +10 -1
- package/dist/oxlint/ast.mjs +1 -1
- package/dist/oxlint/ast.mjs.map +1 -1
- package/dist/oxlint.d.mts +1 -1
- package/dist/oxlint.mjs +1 -1
- package/dist/oxlint.mjs.map +1 -1
- package/dist/querying/cursors.d.mts +50 -0
- package/dist/querying/cursors.mjs +2 -0
- package/dist/querying/cursors.mjs.map +1 -0
- package/dist/querying/execution.d.mts +30 -0
- package/dist/querying/execution.mjs +2 -0
- package/dist/querying/execution.mjs.map +1 -0
- package/dist/querying/filters.d.mts +136 -0
- package/dist/querying/filters.mjs +2 -0
- package/dist/querying/filters.mjs.map +1 -0
- package/dist/querying/planner.d.mts +50 -0
- package/dist/querying/planner.mjs +2 -0
- package/dist/querying/planner.mjs.map +1 -0
- package/dist/querying/relationships.d.mts +41 -0
- package/dist/querying/relationships.mjs +2 -0
- package/dist/querying/relationships.mjs.map +1 -0
- package/dist/querying/security.d.mts +107 -0
- package/dist/querying/security.mjs +2 -0
- package/dist/querying/security.mjs.map +1 -0
- package/dist/querying.d.mts +53 -0
- package/dist/querying.mjs +2 -0
- package/dist/querying.mjs.map +1 -0
- package/dist/relations-public.d.mts +2 -0
- package/dist/relations-public.mjs +1 -0
- package/dist/relations.d.mts +155 -0
- package/dist/relations.mjs +2 -0
- package/dist/relations.mjs.map +1 -0
- package/dist/zod-convex.d.mts +10 -0
- package/dist/zod-convex.mjs +2 -0
- package/dist/zod-convex.mjs.map +1 -0
- package/dist/zod-registration.d.mts +10 -0
- package/dist/zod-registration.mjs +2 -0
- package/dist/zod-registration.mjs.map +1 -0
- package/dist/zod-table.d.mts +63 -8
- package/dist/zod-table.mjs +1 -1
- package/dist/zod-table.mjs.map +1 -1
- package/docs/conventions.md +12 -0
- package/docs/llms.md +15 -5
- package/docs/oxlint.md +135 -25
- package/docs/querying.md +329 -0
- package/docs/zod-table.md +93 -13
- package/package.json +11 -1
- package/scripts/owned-process.mjs +140 -0
- package/scripts/owned-process.test.mjs +107 -0
- package/scripts/smoke-packed-querying.mjs +298 -0
- package/scripts/test-packed-effect.mjs +8 -1
- package/scripts/test-packed-oxlint.mjs +5 -1
- package/scripts/test-packed-querying.mjs +185 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"querying.mjs","names":["executorRequest","createQueryEngine","config","settings","options","planner","createPlanner","schema","relations","cursorCodec","createCursorCodec","maxPageSize","engineVersion","policyVersion","registryDigest","security","createManagedSecurity","querying","request","ctx","tableQuery","table","conditions","constraints","selection","route","spec","selected","path","declaredPath","target","name","edge","codec","createEnvironmentCursorCodec","pageSchema","assertRelationshipDepth","plan","input","byte","binding","executor","relationshipExecutor","result","executeQuery","permitted","row"],"sources":["../src/querying.ts"],"sourcesContent":["import type {\n\tGenericSchema,\n\tSchemaDefinition,\n\tDataModelFromSchemaDefinition,\n\tPaginationResult,\n} from 'convex/server'\nimport type { GenericId } from 'convex/values'\nimport type {\n\tRelationTables,\n\tRelationDeclarations,\n\tRelationRegistry,\n\tRelationRow,\n\tRelationSelection,\n\tRelationFilters,\n\tRelationFilterSelection,\n} from './relations'\nimport { createPlanner, type QueryInput, type StoredConstraint } from './querying/planner'\nimport { executeQuery, type ExecutionRequest } from './querying/execution'\nimport {\n\trelationshipExecutor,\n\tassertRelationshipDepth,\n\ttype OutputSelection,\n\ttype RelationDocument,\n} from './querying/relationships'\nimport {\n\tcreateCursorCodec,\n\tcreateEnvironmentCursorCodec,\n\ttype CursorCodecConfig,\n\ttype CursorBinding,\n} from './querying/cursors'\nimport {\n\tcreateManagedSecurity,\n\ttype ManagedSecurityConfig,\n\ttype ManagedQueryContext,\n\ttype ManagedBudgets,\n} from './querying/security'\nimport type { IndexCondition, NativePagination } from './querying/filters'\n\ntype FullMask<S> = {\n\t[K in keyof S]-?: NonNullable<S[K]> extends true ? true : FullMask<NonNullable<S[K]>>\n}\ntype Paths<\n\tD extends RelationDeclarations,\n\tT extends string,\n\tL extends readonly 1[] = [1, 1, 1, 1],\n> = L extends readonly [1, ...infer Rest extends 1[]]\n\t? {\n\t\t\t[K in keyof D[T] & string]:\n\t\t\t\t| (D[T][K]['cardinality'] extends 'many' ? K : never)\n\t\t\t\t| `${K}.${Paths<D, D[T][K]['target'], Rest>}`\n\t\t}[keyof D[T] & string]\n\t: never\ntype PathTarget<\n\tD extends RelationDeclarations,\n\tT extends string,\n\tP extends string,\n> = P extends `${infer Head}.${infer Rest}`\n\t? PathTarget<D, D[T][Head]['target'], Rest>\n\t: D[T][P]['target']\ntype RemainingDepth<P extends string, L extends readonly 1[]> = L extends readonly [\n\t1,\n\t...infer Rest extends 1[],\n]\n\t? P extends `${string}.${infer Tail}`\n\t\t? RemainingDepth<Tail, Rest>\n\t\t: Rest\n\t: []\ntype EngineArgs<\n\tTables extends RelationTables,\n\tD extends RelationDeclarations,\n\tT extends keyof Tables,\n> = NativePagination & {\n\tfilters?: RelationFilters<Tables, D, T, FullMask<RelationFilterSelection<Tables, D, T>>>\n\torder?: 'asc' | 'desc'\n}\n/** Typed declarative chain returned by the engine; named for consumer declaration emission. */\nexport interface TableQuery<\n\tTables extends RelationTables,\n\tD extends RelationDeclarations,\n\tT extends keyof Tables,\n\tS = {},\n\tL extends readonly 1[] = [1, 1, 1, 1],\n> {\n\twhen(value: IndexCondition['value'], index: string): TableQuery<Tables, D, T, S, L>\n\twhere(spec: NonNullable<EngineArgs<Tables, D, T>['filters']>): TableQuery<Tables, D, T, S, L>\n\twith<const Selection extends RelationSelection<Tables, D, T, L>>(\n\t\tselection: Selection & {\n\t\t\t[K in keyof Selection]: K extends keyof RelationSelection<Tables, D, T, L>\n\t\t\t\t? Selection[K]\n\t\t\t\t: never\n\t\t},\n\t): TableQuery<Tables, D, T, Selection, L>\n\trelation<const P extends Paths<D, Extract<T, string>>>(\n\t\tparent: GenericId<Tables[T]['tableName']>,\n\t\tpath: P,\n\t): Omit<\n\t\tTableQuery<\n\t\t\tTables,\n\t\t\tD,\n\t\t\tExtract<PathTarget<D, Extract<T, string>, P>, keyof Tables>,\n\t\t\t{},\n\t\t\tRemainingDepth<P, L>\n\t\t>,\n\t\t'relation'\n\t>\n\tpaginate(args: EngineArgs<Tables, D, T>): Promise<PaginationResult<RelationRow<Tables, D, T, S>>>\n}\nexport interface QueryEngineDeclaration<\n\tSchema extends SchemaDefinition<GenericSchema, boolean>,\n\tTables extends RelationTables,\n\tD extends RelationDeclarations,\n> {\n\tschema: Schema\n\trelations: RelationRegistry<Tables, D>\n}\n/** Advanced server configuration, separate from the normal schema/relations declaration. */\nexport interface QueryEngineOptions<Schema extends SchemaDefinition<GenericSchema, boolean>> {\n\t/** Explicit codecs validate at creation. Otherwise environment keys load at first paginate. */\n\tcursor?: CursorCodecConfig\n\tbudgets?: Partial<ManagedBudgets>\n\tmaxPageSize?: number\n\tpolicyVersion?: string\n\tengineVersion?: string\n\ttrustedAdapter?: ManagedSecurityConfig<DataModelFromSchemaDefinition<Schema>>['trustedAdapter']\n}\n\n/** @deprecated Use QueryEngineDeclaration and optional QueryEngineOptions separately. */\nexport interface QueryEngineConfig<\n\tSchema extends SchemaDefinition<GenericSchema, boolean>,\n\tTables extends RelationTables,\n\tD extends RelationDeclarations,\n>\n\textends QueryEngineDeclaration<Schema, Tables, D>, QueryEngineOptions<Schema> {\n\tcursor: CursorCodecConfig\n}\n\ntype QueryEngine<\n\tSchema extends SchemaDefinition<GenericSchema, boolean>,\n\tTables extends RelationTables,\n\tD extends RelationDeclarations,\n> = {\n\t(ctx: ManagedQueryContext<DataModelFromSchemaDefinition<Schema>>): {\n\t\t[T in keyof Tables]: TableQuery<Tables, D, T>\n\t}\n\ttables: RelationRegistry<Tables, D>['tables']\n}\n\n/** Central facade. Endpoint chains carry declarative constraints and explicit relationships. */\nexport function createQueryEngine<\n\tSchema extends SchemaDefinition<GenericSchema, boolean>,\n\tconst Tables extends RelationTables,\n\tconst D extends RelationDeclarations,\n>(\n\tconfig: QueryEngineDeclaration<Schema, Tables, D>,\n\toptions?: QueryEngineOptions<Schema>,\n): QueryEngine<Schema, Tables, D>\n/** @deprecated Pass advanced fields in the optional second argument. */\nexport function createQueryEngine<\n\tSchema extends SchemaDefinition<GenericSchema, boolean>,\n\tconst Tables extends RelationTables,\n\tconst D extends RelationDeclarations,\n>(\n\tconfig: QueryEngineDeclaration<Schema, Tables, D> &\n\t\tQueryEngineOptions<Schema> & { cursor: CursorCodecConfig },\n): QueryEngine<Schema, Tables, D>\nexport function createQueryEngine<\n\tSchema extends SchemaDefinition<GenericSchema, boolean>,\n\tconst Tables extends RelationTables,\n\tconst D extends RelationDeclarations,\n>(\n\tconfig: QueryEngineDeclaration<Schema, Tables, D> & QueryEngineOptions<Schema>,\n\toptions?: QueryEngineOptions<Schema>,\n) {\n\tconst { schema, relations } = config\n\t// Retain released one-argument calls; a second argument overrides legacy fields.\n\tconst settings = { ...config, ...options }\n\tconst planner = createPlanner(schema, relations)\n\tlet cursorCodec = settings.cursor === undefined ? undefined : createCursorCodec(settings.cursor)\n\tconst maxPageSize = settings.maxPageSize ?? 100\n\tif (!Number.isSafeInteger(maxPageSize) || maxPageSize <= 0 || maxPageSize > 100)\n\t\tthrow new Error('Invalid central page size')\n\tconst engineVersion = settings.engineVersion ?? 'scalar-1'\n\tconst policyVersion = settings.policyVersion ?? '1'\n\t// Bind the full immutable identity through a collision-resistant digest so\n\t// real application registries fit the codec's bounded AAD. Live guards still\n\t// inspect current schemas; this caches only the immutable version identity.\n\tlet registryDigest: string | undefined\n\tconst security = createManagedSecurity<DataModelFromSchemaDefinition<Schema>>({\n\t\ttables: Object.keys(relations.tables),\n\t\tpolicyVersion,\n\t\tbudgets: settings.budgets,\n\t\ttrustedAdapter: settings.trustedAdapter,\n\t})\n\tfunction querying(ctx: ManagedQueryContext<DataModelFromSchemaDefinition<Schema>>) {\n\t\tplanner.assertUnchanged()\n\t\tconst request = security(ctx)\n\t\tfunction tableQuery(\n\t\t\ttable: string,\n\t\t\tconditions: readonly IndexCondition[] = [],\n\t\t\tconstraints: readonly StoredConstraint[] = [],\n\t\t\tselection: OutputSelection = {},\n\t\t\troute?: { table: string; parent: string; path: string[] },\n\t\t) {\n\t\t\treturn Object.freeze({\n\t\t\t\twhen: (value: IndexCondition['value'], index: string) =>\n\t\t\t\t\ttableQuery(table, [...conditions, { value, index }], constraints, selection, route),\n\t\t\t\twhere: (spec: StoredConstraint) =>\n\t\t\t\t\ttableQuery(table, conditions, [...constraints, spec], selection, route),\n\t\t\t\twith: (selected: OutputSelection) =>\n\t\t\t\t\ttableQuery(table, conditions, constraints, selected, route),\n\t\t\t\trelation: (parent: string, declaredPath: string) => {\n\t\t\t\t\tconst path = declaredPath.split('.')\n\t\t\t\t\tif (!path.length || path.length > 4) throw new Error('INVALID_RELATION')\n\t\t\t\t\tlet target = table\n\t\t\t\t\tfor (const name of path) {\n\t\t\t\t\t\tconst edge = planner.metadata.declarations[target]?.[name]\n\t\t\t\t\t\tif (!edge) throw new Error('INVALID_RELATION')\n\t\t\t\t\t\ttarget = edge.target\n\t\t\t\t\t}\n\t\t\t\t\treturn tableQuery(target, conditions, constraints, {}, { table, parent, path })\n\t\t\t\t},\n\t\t\t\tasync paginate(input: QueryInput) {\n\t\t\t\t\t// Resolve once per global engine, before any native query or policy reads.\n\t\t\t\t\tconst codec = (cursorCodec ??= createEnvironmentCursorCodec())\n\t\t\t\t\tplanner.assertUnchanged()\n\t\t\t\t\tconst pageSchema = planner.page(table, selection)\n\t\t\t\t\tassertRelationshipDepth(selection, route?.path.length ?? 0)\n\t\t\t\t\tconst plan = planner.plan(table, input, route ? [] : conditions, constraints)\n\t\t\t\t\tif (plan.args.numItems > maxPageSize) throw new Error('Page size exceeds central ceiling')\n\t\t\t\t\t// Native root limits stay native; lowering those limits cannot raise\n\t\t\t\t\t// the independent shared request meter.\n\t\t\t\t\tplan.args.maximumRowsRead = Math.min(\n\t\t\t\t\t\tplan.args.maximumRowsRead ?? request.budgets.rawCandidates,\n\t\t\t\t\t\trequest.budgets.rawCandidates,\n\t\t\t\t\t)\n\t\t\t\t\tplan.args.maximumBytesRead = Math.min(\n\t\t\t\t\t\tplan.args.maximumBytesRead ?? request.budgets.documentBytes,\n\t\t\t\t\t\trequest.budgets.documentBytes,\n\t\t\t\t\t)\n\t\t\t\t\tregistryDigest ??= Array.from(\n\t\t\t\t\t\tnew Uint8Array(\n\t\t\t\t\t\t\tawait crypto.subtle.digest('SHA-256', new TextEncoder().encode(relations.identity)),\n\t\t\t\t\t\t),\n\t\t\t\t\t\t(byte) => byte.toString(16).padStart(2, '0'),\n\t\t\t\t\t).join('')\n\t\t\t\t\t// The digest await is a boundary too: mutation must be detected\n\t\t\t\t\t// before authenticated cursor validation or native query construction.\n\t\t\t\t\tplanner.assertUnchanged()\n\t\t\t\t\t// SAFETY: selection has passed the registry page validator before binding.\n\t\t\t\t\tconst binding: CursorBinding = {\n\t\t\t\t\t\ttable: route?.table ?? table,\n\t\t\t\t\t\tindex: plan.index?.name ?? 'by_creation_time',\n\t\t\t\t\t\torder: plan.args.order ?? 'asc',\n\t\t\t\t\t\tclientFilters: plan.clientIdentity,\n\t\t\t\t\t\t// Include output selection and the complete immutable scope in trusted identity.\n\t\t\t\t\t\tserverFilters: {\n\t\t\t\t\t\t\tpredicates: plan.serverIdentity,\n\t\t\t\t\t\t\tselection: selection as import('convex/values').Value,\n\t\t\t\t\t\t\tscope: { ...request.scope },\n\t\t\t\t\t\t},\n\t\t\t\t\t\trelationPath: [],\n\t\t\t\t\t\tprincipal: JSON.stringify(request.scope),\n\t\t\t\t\t\ttenant: request.scope.tenant,\n\t\t\t\t\t\tpolicyVersion,\n\t\t\t\t\t\tengineVersion,\n\t\t\t\t\t\tregistryVersion: registryDigest,\n\t\t\t\t\t}\n\t\t\t\t\t// The executor accepts registry-selected native tables, rather than a static DM key.\n\t\t\t\t\tconst executorRequest: unknown = request\n\t\t\t\t\t// SAFETY: only native DM types are erased at this private executor boundary.\n\t\t\t\t\tconst executor = relationshipExecutor(\n\t\t\t\t\t\tschema,\n\t\t\t\t\t\texecutorRequest as ExecutionRequest,\n\t\t\t\t\t\tplanner,\n\t\t\t\t\t\tcodec,\n\t\t\t\t\t\tbinding,\n\t\t\t\t\t)\n\t\t\t\t\tif (route)\n\t\t\t\t\t\treturn executor.continuation(\n\t\t\t\t\t\t\troute.table,\n\t\t\t\t\t\t\troute.parent,\n\t\t\t\t\t\t\troute.path,\n\t\t\t\t\t\t\tselection,\n\t\t\t\t\t\t\tplan.args,\n\t\t\t\t\t\t\tconditions,\n\t\t\t\t\t\t\tconstraints,\n\t\t\t\t\t\t)\n\t\t\t\t\tconst result = await executeQuery(\n\t\t\t\t\t\tschema,\n\t\t\t\t\t\trequest,\n\t\t\t\t\t\ttable,\n\t\t\t\t\t\tplan,\n\t\t\t\t\t\tplanner,\n\t\t\t\t\t\tcodec,\n\t\t\t\t\t\tbinding,\n\t\t\t\t\t\tasync (row, permitted) => {\n\t\t\t\t\t\t\t// SAFETY: metered native stream rows contain the validated system fields.\n\t\t\t\t\t\t\tif (\n\t\t\t\t\t\t\t\t!permitted ||\n\t\t\t\t\t\t\t\t!(await executor.matches(table, row as RelationDocument, plan.residual))\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t\treturn null\n\t\t\t\t\t\t\t// SAFETY: the same native row is authorized and matches the declared predicates.\n\t\t\t\t\t\t\treturn executor.output(table, row as RelationDocument, selection, plan.args)\n\t\t\t\t\t\t},\n\t\t\t\t\t)\n\t\t\t\t\tplanner.assertUnchanged()\n\t\t\t\t\treturn pageSchema.parse(result)\n\t\t\t\t},\n\t\t\t})\n\t\t}\n\t\t// SAFETY: each key comes from the exact validated registry; the planner\n\t\t// validates all input and projection while mapped types retain table brands.\n\t\treturn Object.freeze(\n\t\t\tObject.fromEntries(Object.keys(relations.tables).map((table) => [table, tableQuery(table)])),\n\t\t) as { [T in keyof Tables]: TableQuery<Tables, D, T> }\n\t}\n\treturn Object.assign(querying, { tables: relations.tables })\n}\n"],"mappings":"6WAqKA,SAAgBC,EAKf,EACA,EACC,CACD,GAAM,CAAE,SAAQ,aAAcC,EAExBC,EAAW,CAAE,GAAGD,EAAQ,GAAGE,CAAQ,EACnCC,EAAUC,EAAcC,EAAQC,CAAS,EAC3CC,EAAcN,EAAS,SAAW,IAAA,GAAY,IAAA,GAAYO,EAAkBP,EAAS,MAAM,EACzFQ,EAAcR,EAAS,aAAe,IAC5C,GAAI,CAAC,OAAO,cAAcQ,CAAW,GAAKA,GAAe,GAAKA,EAAc,IAC3E,MAAU,MAAM,2BAA2B,EAC5C,IAAMC,EAAgBT,EAAS,eAAiB,WAC1CU,EAAgBV,EAAS,eAAiB,IAI5CW,EACEC,EAAWC,EAA6D,CAC7E,OAAQ,OAAO,KAAKR,EAAU,MAAM,EACpC,gBACA,QAASL,EAAS,QAClB,eAAgBA,EAAS,cAC1B,CAAC,EACD,SAASc,EAAS,EAAiE,CAClFZ,EAAQ,gBAAgB,EACxB,IAAMa,EAAUH,EAASI,CAAG,EAC5B,SAASC,EACR,EACA,EAAwC,CAAC,EACzC,EAA2C,CAAC,EAC5C,EAA6B,CAAC,EAC9B,EACC,CACD,OAAO,OAAO,OAAO,CACpB,MAAO,EAAgC,IACtCA,EAAWC,EAAO,CAAC,GAAGC,EAAY,CAAE,QAAO,OAAM,CAAC,EAAGC,EAAaC,EAAWC,CAAK,EACnF,MAAQ,GACPL,EAAWC,EAAOC,EAAY,CAAC,GAAGC,EAAaG,CAAI,EAAGF,EAAWC,CAAK,EACvE,KAAO,GACNL,EAAWC,EAAOC,EAAYC,EAAaI,EAAUF,CAAK,EAC3D,UAAW,EAAgB,IAAyB,CACnD,IAAMG,EAAOC,EAAa,MAAM,GAAG,EACnC,GAAI,CAACD,EAAK,QAAUA,EAAK,OAAS,EAAG,MAAU,MAAM,kBAAkB,EACvE,IAAIE,EAAST,EACb,IAAK,IAAMU,KAAQH,EAAM,CACxB,IAAMI,EAAO3B,EAAQ,SAAS,aAAayB,EAAO,GAAGC,GACrD,GAAI,CAACC,EAAM,MAAU,MAAM,kBAAkB,EAC7C,EAASA,EAAK,MACf,CACA,OAAOZ,EAAWU,EAAQR,EAAYC,EAAa,CAAC,EAAG,CAAE,QAAO,SAAQ,MAAK,CAAC,CAC/E,EACA,MAAM,SAAS,EAAmB,CAEjC,IAAMU,EAAS,IAAgBC,EAA6B,EAC5D7B,EAAQ,gBAAgB,EACxB,IAAM8B,EAAa9B,EAAQ,KAAKgB,EAAOG,CAAS,EAChDY,EAAwBZ,EAAWC,GAAO,KAAK,QAAU,CAAC,EAC1D,IAAMY,EAAOhC,EAAQ,KAAKgB,EAAOiB,EAAOb,EAAQ,CAAC,EAAIH,EAAYC,CAAW,EAC5E,GAAIc,EAAK,KAAK,SAAW1B,EAAa,MAAU,MAAM,mCAAmC,EAGzF,EAAK,KAAK,gBAAkB,KAAK,IAChC0B,EAAK,KAAK,iBAAmBnB,EAAQ,QAAQ,cAC7CA,EAAQ,QAAQ,aACjB,EACA,EAAK,KAAK,iBAAmB,KAAK,IACjCmB,EAAK,KAAK,kBAAoBnB,EAAQ,QAAQ,cAC9CA,EAAQ,QAAQ,aACjB,EACA,IAAmB,MAAM,KACxB,IAAI,WACH,MAAM,OAAO,OAAO,OAAO,UAAW,IAAI,YAAY,CAAC,CAAC,OAAOV,EAAU,QAAQ,CAAC,CACnF,EACC,GAAS+B,EAAK,SAAS,EAAE,CAAC,CAAC,SAAS,EAAG,GAAG,CAC5C,CAAC,CAAC,KAAK,EAAE,EAGTlC,EAAQ,gBAAgB,EAExB,IAAMmC,EAAyB,CAC9B,MAAOf,GAAO,OAASJ,EACvB,MAAOgB,EAAK,OAAO,MAAQ,mBAC3B,MAAOA,EAAK,KAAK,OAAS,MAC1B,cAAeA,EAAK,eAEpB,cAAe,CACd,WAAYA,EAAK,eACN,YACX,MAAO,CAAE,GAAGnB,EAAQ,KAAM,CAC3B,EACA,aAAc,CAAC,EACf,UAAW,KAAK,UAAUA,EAAQ,KAAK,EACvC,OAAQA,EAAQ,MAAM,OACtB,gBACA,gBACA,gBAAiBJ,CAClB,EAIM2B,EAAWC,EAChBnC,EACAP,EACAK,EACA4B,EACAO,CACD,EACA,GAAIf,EACH,OAAOgB,EAAS,aACfhB,EAAM,MACNA,EAAM,OACNA,EAAM,KACND,EACAa,EAAK,KACLf,EACAC,CACD,EACD,IAAMoB,EAAS,MAAMC,EACpBrC,EACAW,EACAG,EACAgB,EACAhC,EACA4B,EACAO,EACA,MAAO,EAAK,IAGV,CAACK,GACD,CAAE,MAAMJ,EAAS,QAAQpB,EAAOyB,EAAyBT,EAAK,QAAQ,EAE/D,KAEDI,EAAS,OAAOpB,EAAOyB,EAAyBtB,EAAWa,EAAK,IAAI,CAE7E,EAEA,OADAhC,EAAQ,gBAAgB,EACjB8B,EAAW,MAAMQ,CAAM,CAC/B,CACD,CAAC,CACF,CAGA,OAAO,OAAO,OACb,OAAO,YAAY,OAAO,KAAKnC,EAAU,MAAM,CAAC,CAAC,IAAK,GAAU,CAACa,EAAOD,EAAWC,CAAK,CAAC,CAAC,CAAC,CAC5F,CACD,CACA,OAAO,OAAO,OAAOJ,EAAU,CAAE,OAAQT,EAAU,MAAO,CAAC,CAC5D"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import { FieldReference, RelationBuilder, RelationDeclarations, RelationEdge, RelationFilterSelection, RelationFilters, RelationRegistry, RelationRegistryIdentity, RelationRow, RelationSelection, RelationTable, RelationTableHelpers, RelationTables, ThroughReference, defineRelations } from "./relations.mjs";
|
|
2
|
+
export { type FieldReference, type RelationBuilder, type RelationDeclarations, type RelationEdge, type RelationFilterSelection, type RelationFilters, type RelationRegistry, type RelationRegistryIdentity, type RelationRow, type RelationSelection, type RelationTable, type RelationTableHelpers, type RelationTables, type ThroughReference, defineRelations };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{defineRelations as e}from"./relations.mjs";export{e as defineRelations};
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
import { PaginationOptionsSchema, ScalarPredicate, ScalarSelection } from "./querying/filters.mjs";
|
|
2
|
+
import { ConvexValidatorFromZod } from "convex-helpers/server/zod4";
|
|
3
|
+
import { PaginationResult, TableDefinition } from "convex/server";
|
|
4
|
+
import { z } from "zod";
|
|
5
|
+
import { GenericId, ValidatorJSON } from "convex/values";
|
|
6
|
+
//#region src/relations.d.ts
|
|
7
|
+
/** Object table boundaries only. Runtime metadata comes from native validators/export. */
|
|
8
|
+
export interface RelationTable {
|
|
9
|
+
tableName: string;
|
|
10
|
+
schema: z.ZodObject;
|
|
11
|
+
publicDto: z.ZodObject;
|
|
12
|
+
table: TableDefinition;
|
|
13
|
+
dto(includeId: true): z.ZodType;
|
|
14
|
+
}
|
|
15
|
+
export type RelationTables = Record<string, RelationTable>;
|
|
16
|
+
/** Internal named declaration dependency; excluded from the supported relations facade. */
|
|
17
|
+
export interface SelectionMask {
|
|
18
|
+
[key: string]: true | SelectionMask;
|
|
19
|
+
}
|
|
20
|
+
type Fields<T extends RelationTable> = T['schema']['shape'];
|
|
21
|
+
type Native<T extends RelationTable, K extends keyof Fields<T>> = ConvexValidatorFromZod<Fields<T>[K], 'required'>['type'];
|
|
22
|
+
declare const fieldBrand: unique symbol;
|
|
23
|
+
declare const edgeBrand: unique symbol;
|
|
24
|
+
type Comparable<Value> = Exclude<Value, null | undefined>;
|
|
25
|
+
type Same<A, B> = [Comparable<A> | Comparable<B>] extends [never] ? false : [Comparable<A>] extends [Comparable<B>] ? [Comparable<B>] extends [Comparable<A>] ? true : false : false;
|
|
26
|
+
export interface FieldReference<Table extends string, Field extends string, Value> {
|
|
27
|
+
readonly [fieldBrand]: Value;
|
|
28
|
+
readonly table: Table;
|
|
29
|
+
readonly field: Field;
|
|
30
|
+
through<J extends AnyField>(junction: J & (Same<Value, J[typeof fieldBrand]> extends true ? {} : never)): ThroughReference<Table, Field, Value, J>;
|
|
31
|
+
}
|
|
32
|
+
type AnyField = FieldReference<string, string, any>;
|
|
33
|
+
export interface ThroughReference<Table extends string, Field extends string, Value, Junction extends AnyField> {
|
|
34
|
+
readonly base: FieldReference<Table, Field, Value>;
|
|
35
|
+
readonly junction: Junction;
|
|
36
|
+
}
|
|
37
|
+
type AnyThrough = ThroughReference<string, string, any, AnyField>;
|
|
38
|
+
type Leg = AnyField | AnyThrough;
|
|
39
|
+
type Base<L extends Leg> = L extends AnyThrough ? L['base'] : L;
|
|
40
|
+
type JunctionTable<L extends Leg> = L extends AnyThrough ? L['junction']['table'] : never;
|
|
41
|
+
type CompatibleLegs<F extends Leg, T extends Leg> = F extends AnyThrough ? T extends AnyThrough ? Same<JunctionTable<F>, JunctionTable<T>> extends true ? {} : never : never : T extends AnyThrough ? never : Same<Base<F>[typeof fieldBrand], Base<T>[typeof fieldBrand]> extends true ? {} : never;
|
|
42
|
+
export interface RelationEdge<Source extends string, Target extends string, Cardinality extends 'one' | 'many'> {
|
|
43
|
+
readonly [edgeBrand]: true;
|
|
44
|
+
readonly source: Source;
|
|
45
|
+
readonly target: Target;
|
|
46
|
+
readonly cardinality: Cardinality;
|
|
47
|
+
readonly from: Leg;
|
|
48
|
+
readonly to: Leg;
|
|
49
|
+
}
|
|
50
|
+
type AnyEdge = RelationEdge<string, string, 'one' | 'many'>;
|
|
51
|
+
type FieldReferences<Tables extends RelationTables> = { [T in keyof Tables]: { [K in Extract<keyof Fields<Tables[T]>, string>]: FieldReference<Extract<T, string>, K, Native<Tables[T], K>>; }; };
|
|
52
|
+
type AllReferences<Tables extends RelationTables> = { [T in keyof Tables]: FieldReferences<Tables>[T][Extract<keyof FieldReferences<Tables>[T], string>]; }[keyof Tables];
|
|
53
|
+
type Builders<Tables extends RelationTables, C extends 'one' | 'many'> = { [T in keyof Tables]: <F extends AllReferences<Tables> | AnyThrough, To extends FieldReferences<Tables>[T][Extract<keyof FieldReferences<Tables>[T], string>] | AnyThrough>(spec: {
|
|
54
|
+
from: F;
|
|
55
|
+
to: To;
|
|
56
|
+
} & CompatibleLegs<F, To> & (Base<To>['table'] extends T ? {} : never)) => RelationEdge<Base<F>['table'], Extract<T, string>, C>; };
|
|
57
|
+
export type RelationBuilder<Tables extends RelationTables> = FieldReferences<Tables> & {
|
|
58
|
+
one: Builders<Tables, 'one'>;
|
|
59
|
+
many: Builders<Tables, 'many'>;
|
|
60
|
+
};
|
|
61
|
+
export type RelationDeclarations = Record<string, Record<string, AnyEdge>>;
|
|
62
|
+
type ExactDeclarations<Tables extends RelationTables, D extends RelationDeclarations> = { [T in keyof D]: T extends keyof Tables ? { [K in keyof D[T]]: K extends keyof Fields<Tables[T]> | 'and' | 'or' | 'not' | 'fields' | 'then' | '__proto__' | 'constructor' | 'prototype' ? never : D[T][K]['source'] extends T ? D[T][K] : never; } : never; };
|
|
63
|
+
type Depth = readonly [1, 1, 1, 1];
|
|
64
|
+
type Tail<D extends readonly 1[]> = D extends readonly [1, ...infer R extends 1[]] ? R : [];
|
|
65
|
+
type Edges<D, T> = T extends keyof D ? D[T] : {};
|
|
66
|
+
type Target<E> = E extends AnyEdge ? E['target'] : never;
|
|
67
|
+
export type RelationSelection<Tables extends RelationTables, D extends RelationDeclarations, T extends keyof Tables, Level extends readonly 1[] = Depth> = Level extends readonly [] ? Record<string, never> : { [K in keyof Edges<D, T>]?: true | RelationSelection<Tables, D, Extract<Target<Edges<D, T>[K]>, keyof Tables>, Tail<Level>>; };
|
|
68
|
+
export type RelationFilterSelection<Tables extends RelationTables, D extends RelationDeclarations, T extends keyof Tables, Level extends readonly 1[] = Depth> = ScalarSelection<Fields<Tables[T]>> & (Level extends readonly [] ? {} : { [K in keyof Edges<D, T>]?: RelationFilterSelection<Tables, D, Extract<Target<Edges<D, T>[K]>, keyof Tables>, Tail<Level>>; });
|
|
69
|
+
type ExactOutputMask<Tables extends RelationTables, D extends RelationDeclarations, T extends keyof Tables, S, L extends readonly 1[] = Depth> = S & { [K in keyof S]: L extends readonly [] ? never : K extends keyof Edges<D, T> ? S[K] extends true ? true : ExactOutputMask<Tables, D, Extract<Target<Edges<D, T>[K]>, keyof Tables>, S[K], Tail<L>> : never; };
|
|
70
|
+
type ExactFilterMask<Tables extends RelationTables, D extends RelationDeclarations, T extends keyof Tables, S, L extends readonly 1[] = Depth> = S & { [K in keyof S]: K extends keyof ScalarSelection<Fields<Tables[T]>> ? S[K] extends true ? true : never : L extends readonly [] ? never : K extends keyof Edges<D, T> ? S[K] extends true ? never : ExactFilterMask<Tables, D, Extract<Target<Edges<D, T>[K]>, keyof Tables>, S[K], Tail<L>> : never; };
|
|
71
|
+
type ScalarValues<T extends RelationTable, S, Side extends 'input' | 'output'> = { [K in Extract<keyof S, keyof Fields<T>>]?: ScalarPredicate<Fields<T>[K], Side>; };
|
|
72
|
+
export type RelationFilters<Tables extends RelationTables, D extends RelationDeclarations, T extends keyof Tables, S, Side extends 'input' | 'output' = 'output', Level extends readonly 1[] = Depth> = Omit<ScalarValues<Tables[T], S, Side>, 'and' | 'or' | 'not' | 'fields'> & {
|
|
73
|
+
fields?: ScalarValues<Tables[T], S, Side>;
|
|
74
|
+
} & (Level extends readonly [] ? {} : { [K in Extract<keyof S, keyof Edges<D, T>>]?: Edges<D, T>[K] extends RelationEdge<string, infer Target, infer C> ? C extends 'one' ? RelationFilters<Tables, D, Extract<Target, keyof Tables>, S[K], Side, Tail<Level>> | null : {
|
|
75
|
+
some: RelationFilters<Tables, D, Extract<Target, keyof Tables>, S[K], Side, Tail<Level>>;
|
|
76
|
+
} | {
|
|
77
|
+
none: RelationFilters<Tables, D, Extract<Target, keyof Tables>, S[K], Side, Tail<Level>>;
|
|
78
|
+
} : never; } & {
|
|
79
|
+
and?: RelationFilters<Tables, D, T, S, Side, Tail<Level>>[];
|
|
80
|
+
or?: RelationFilters<Tables, D, T, S, Side, Tail<Level>>[];
|
|
81
|
+
not?: RelationFilters<Tables, D, T, S, Side, Tail<Level>>;
|
|
82
|
+
});
|
|
83
|
+
type PublicRow<T extends RelationTable> = z.output<T['publicDto']> & {
|
|
84
|
+
_id: GenericId<T['tableName']>;
|
|
85
|
+
};
|
|
86
|
+
export type RelationRow<Tables extends RelationTables, D extends RelationDeclarations, T extends keyof Tables, S, Level extends readonly 1[] = Depth> = PublicRow<Tables[T]> & (Level extends readonly [] ? {} : { [K in keyof S]: K extends keyof Edges<D, T> ? Edges<D, T>[K] extends RelationEdge<string, infer Target, infer C> ? C extends 'one' ? RelationRow<Tables, D, Extract<Target, keyof Tables>, S[K] extends true ? {} : S[K], Tail<Level>> | null : PaginationResult<RelationRow<Tables, D, Extract<Target, keyof Tables>, S[K] extends true ? {} : S[K], Tail<Level>>> : never : never; });
|
|
87
|
+
export interface RelationTableHelpers<Tables extends RelationTables, D extends RelationDeclarations, T extends keyof Tables> {
|
|
88
|
+
paginationOpts<const S extends RelationFilterSelection<Tables, D, T>>(selection: ExactFilterMask<Tables, D, T, S>): PaginationOptionsSchema<RelationFilters<Tables, D, T, S>, RelationFilters<Tables, D, T, S, 'input'>>;
|
|
89
|
+
pageDto<const S extends RelationSelection<Tables, D, T>>(selection: ExactOutputMask<Tables, D, T, S>): z.ZodType<PaginationResult<RelationRow<Tables, D, T, S>>>;
|
|
90
|
+
}
|
|
91
|
+
export interface RelationRegistryIdentity {
|
|
92
|
+
readonly identity: string;
|
|
93
|
+
readonly version: 1;
|
|
94
|
+
}
|
|
95
|
+
export interface RelationRegistry<Tables extends RelationTables, D extends RelationDeclarations> {
|
|
96
|
+
readonly identity: string;
|
|
97
|
+
readonly version: 1;
|
|
98
|
+
readonly tables: { [T in keyof Tables]: RelationTableHelpers<Tables, D, T>; };
|
|
99
|
+
}
|
|
100
|
+
export interface RelationFieldMetadata {
|
|
101
|
+
readonly kind: string;
|
|
102
|
+
readonly optional: boolean;
|
|
103
|
+
readonly nullable: boolean;
|
|
104
|
+
readonly idTables: readonly string[];
|
|
105
|
+
readonly native: Readonly<ValidatorJSON>;
|
|
106
|
+
}
|
|
107
|
+
export interface RelationTableMetadata {
|
|
108
|
+
readonly fields: Readonly<Record<string, RelationFieldMetadata>>;
|
|
109
|
+
readonly indexes: readonly {
|
|
110
|
+
readonly name: string;
|
|
111
|
+
readonly fields: readonly string[];
|
|
112
|
+
}[];
|
|
113
|
+
}
|
|
114
|
+
export interface RelationMetadata {
|
|
115
|
+
readonly tables: Readonly<Record<string, RelationTableMetadata>>;
|
|
116
|
+
readonly declarations: Readonly<Record<string, Readonly<Record<string, AnyEdge>>>>;
|
|
117
|
+
}
|
|
118
|
+
/** No ID-field inference and no readers: this registry owns declarations/schema helpers only. */
|
|
119
|
+
export declare function defineRelations<const Tables extends RelationTables, const D extends RelationDeclarations>(tables: Tables, declare: (r: RelationBuilder<Tables>) => D & ExactDeclarations<Tables, D>): RelationRegistry<Tables, D>;
|
|
120
|
+
/** Internal owned executor bridge. Not an advertised root API. Every operation
|
|
121
|
+
* rechecks the live registry, including cached plans and individual projections.
|
|
122
|
+
*/
|
|
123
|
+
export declare function getRelationExecutor(registry: RelationRegistryIdentity): Readonly<{
|
|
124
|
+
assertUnchanged: () => void;
|
|
125
|
+
assertNativeTable: (table: string, definition: TableDefinition) => void;
|
|
126
|
+
assertSchema: (tables: Readonly<Record<string, TableDefinition>>) => void;
|
|
127
|
+
pagination(table: string): z.ZodObject<{
|
|
128
|
+
cursor: z.ZodUnion<readonly [z.ZodString, z.ZodNull]>;
|
|
129
|
+
endCursor: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodNull]>>;
|
|
130
|
+
id: z.ZodOptional<z.ZodNumber>;
|
|
131
|
+
numItems: z.ZodNumber;
|
|
132
|
+
maximumRowsRead: z.ZodOptional<z.ZodNumber>;
|
|
133
|
+
maximumBytesRead: z.ZodOptional<z.ZodNumber>;
|
|
134
|
+
filters: z.ZodOptional<z.ZodType<unknown, unknown, z.core.$ZodTypeInternals<unknown, unknown>>>;
|
|
135
|
+
order: z.ZodOptional<z.ZodEnum<{
|
|
136
|
+
asc: "asc";
|
|
137
|
+
desc: "desc";
|
|
138
|
+
}>>;
|
|
139
|
+
}, z.core.$strict>;
|
|
140
|
+
page(table: string, selection: SelectionMask): z.ZodObject<{
|
|
141
|
+
page: z.ZodArray<z.ZodType<unknown, unknown, z.core.$ZodTypeInternals<unknown, unknown>>>;
|
|
142
|
+
isDone: z.ZodBoolean;
|
|
143
|
+
continueCursor: z.ZodString;
|
|
144
|
+
splitCursor: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
145
|
+
pageStatus: z.ZodOptional<z.ZodNullable<z.ZodEnum<{
|
|
146
|
+
SplitRecommended: "SplitRecommended";
|
|
147
|
+
SplitRequired: "SplitRequired";
|
|
148
|
+
}>>>;
|
|
149
|
+
}, z.core.$strip>;
|
|
150
|
+
project(tables: Readonly<Record<string, TableDefinition>>, table: string, row: Record<string, import('convex/values').Value>, eligible: () => boolean): Record<string, unknown> | null;
|
|
151
|
+
}>;
|
|
152
|
+
/** Internal compiler/engine adapter. Registry identity alone cannot forge a registry. */
|
|
153
|
+
export declare function getRelationMetadata(registry: RelationRegistryIdentity): RelationMetadata;
|
|
154
|
+
//#endregion
|
|
155
|
+
//# sourceMappingURL=relations.d.mts.map
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{nativePagination as e,relationFilterSchema as t,scalarPredicateSchema as n}from"./querying/filters.mjs";import{paginated as r}from"./zod-table.mjs";import{zodToConvex as i}from"convex-helpers/server/zod4";import{z as a}from"zod";import{v as o}from"convex/values";const s=Symbol(`relationField`),c=Symbol(`relationEdge`),l=/* @__PURE__ */ new WeakMap,u=/* @__PURE__ */ new WeakMap,d=/* @__PURE__ */ new WeakMap,f=/* @__PURE__ */ new WeakSet,p=/* @__PURE__ */ new WeakSet,m=a.object({indexes:a.array(a.object({indexDescriptor:a.string(),fields:a.array(a.string())}))});function h(n,o){let c={},h=/* @__PURE__ */ new Set,g={},_={},v={};for(let[e,t]of Object.entries(n)){if(t.tableName!==e||[`one`,`many`,`__proto__`,`constructor`,`prototype`].includes(e))throw Error(`Invalid relation table "${e}"`);let n=t.dto(!0);if(!(n instanceof a.ZodObject))throw Error(`Expected object DTO`);let r=I(n),o=i(t.schema),l=k(t.table);M(l.documentType),N(e,o.fields,l.documentType);let u=m.parse(l).indexes.map(e=>({name:e.indexDescriptor,fields:[...e.fields]})).sort((e,t)=>e.name.localeCompare(t.name));M(A(i(n))),c[e]={fields:o.fields,indexes:u,dto:n,assertUnchanged:r};let p=Object.create(null);for(let[t,n]of Object.entries(o.fields)){let r={[s]:void 0,table:e,field:t,through(e){let t=d.get(e);if(!h.has(e)||!t||!S(n,t))throw Error(`Invalid junction field or registry`);let i=Object.freeze({base:r,junction:e});return f.add(i),i}};d.set(r,n),h.add(r),p[t]=Object.freeze(r)}g[e]=Object.freeze(p),_[e]=t=>x(e,`one`,t,h),v[e]=t=>x(e,`many`,t,h)}let C=o(Object.freeze({...g,one:Object.freeze(_),many:Object.freeze(v)})),T=Object.fromEntries(Object.entries(C).map(([e,t])=>[e,Object.freeze({...t})]));Object.freeze(T);for(let[e,t]of Object.entries(T)){if(!Object.hasOwn(n,e))throw Error(`Unknown source table "${e}"`);for(let[n,r]of Object.entries(t)){if(Object.hasOwn(c[e].fields,n)||[`and`,`or`,`not`,`fields`,`then`,`__proto__`,`constructor`,`prototype`].includes(n))throw Error(`Relation name collision "${n}"`);if(!p.has(r)||!h.has(b(r.from))||!h.has(b(r.to))||r.source!==e)throw Error(`Relation source bucket mismatch`);w(r,c)}}let P={metadata:c,declarations:T},F={};for(let i of Object.keys(n))F[i]={paginationOpts(n){return B(P),y(n),H(e.extend({filters:t(D(P,i,n)).optional(),order:a.enum([`asc`,`desc`]).optional()}),()=>B(P))},pageDto(e){return B(P),y(e),H(r(O(P,i,e)).result,()=>B(P))}};let L=JSON.stringify([1,Object.entries(c).sort(([e],[t])=>e.localeCompare(t)).map(([e,t])=>[e,Object.entries(t.fields).sort(([e],[t])=>e.localeCompare(t)).map(([e,t])=>[e,t.isOptional,A(t)]),t.indexes,j(A(i(t.dto)))]),Object.entries(T).sort(([e],[t])=>e.localeCompare(t)).map(([e,t])=>[e,Object.entries(t).sort(([e],[t])=>e.localeCompare(t)).map(([e,t])=>[e,t.cardinality,t.target,E(t.from),E(t.to)])])]),R=Object.freeze({identity:L,version:1,tables:Object.freeze(F)});l.set(R,U(P));let V=Object.freeze({...n}),W=Object.fromEntries(Object.entries(V).map(([e,t])=>{let n=z(t.schema,`stored`),r=JSON.stringify(k(t.table));return[e,()=>{if(n(),JSON.stringify(k(t.table))!==r)throw Error(`Native schema mutated after registry construction: ${e}`)}]}));return u.set(R,{internal:P,tables:V,assertStoredUnchanged:()=>{for(let e of Object.values(W))e()},assertNativeTable(e,t){if(!Object.hasOwn(V,e)||V[e].table!==t)throw Error(`Native schema/table ownership disagrees with relation registry`);W[e]()}}),R}function g(i){let o=u.get(i);if(!o)throw Error(`Unknown relation registry`);let s=()=>{B(o.internal),o.assertStoredUnchanged()},c=e=>{s();let t=Object.keys(o.tables);if(t.length!==Object.keys(e).length||t.some(t=>e[t]!==o.tables[t].table))throw Error(`Native schema/table ownership disagrees with relation registry`)};return s(),Object.freeze({assertUnchanged:s,assertNativeTable:o.assertNativeTable,assertSchema:c,pagination(r){s();let i=o.internal,c=/* @__PURE__ */ new Map;function l(e,t){let r=i.metadata[e];if(!r)throw Error(`Unknown query table`);let a=c.get(e);if(!a){a={};for(let[e,t]of Object.entries(r.fields))v(t)&&(a[e]=n(t).optional());c.set(e,a)}return{fields:a,relations:t>=4?{}:Object.fromEntries(Object.entries(i.declarations[e]??{}).map(([e,n])=>[e,{cardinality:n.cardinality,target:l(n.target,t+1)}]))}}return e.extend({filters:t(l(r,0)).optional(),order:a.enum([`asc`,`desc`]).optional()})},page(e,t){return s(),y(t),r(O(o.internal,e,t)).result},project(e,t,n,r){if(c(e),!r())return null;let i=o.internal.metadata[t]?.dto;if(!i)throw Error(`Unknown query table`);return i.parse(Object.fromEntries(Object.keys(i.shape).filter(e=>Object.hasOwn(n,e)).map(e=>[e,n[e]])))}})}function _(e){let t=l.get(e);if(!t)throw Error(`Unknown relation registry`);return t}function v(e){return[`id`,`string`,`float64`,`int64`,`boolean`,`null`,`literal`].includes(e.kind)||e.kind===`union`&&e.members.every(v)}function y(e){let t=[{value:e,depth:0,ancestors:[]}],n=0;for(;t.length;){let{value:e,depth:r,ancestors:i}=t.pop();if(++n>256||r>4||i.includes(e))throw Error(`Selection cycle or depth/node budget exceeded`);let a=Object.getPrototypeOf(e);if(a!==Object.prototype&&a!==null)throw Error(`Invalid selection`);let o=Reflect.ownKeys(e);if(o.length+n+t.length>256)throw Error(`Selection node budget exceeded`);for(let a of o){let o=Object.getOwnPropertyDescriptor(e,a);if(!o.enumerable||!(`value`in o)||String(a)!==a)throw Error(`Invalid selection property`);if(o.value!==!0)t.push({value:o.value,depth:r+1,ancestors:[...i,e]});else if(++n>256)throw Error(`Selection node budget exceeded`)}}}function b(e){return`base`in e?e.base:e}function x(e,t,n,r){for(let e of[n.from,n.to])if(!r.has(b(e))||`base`in e&&(!f.has(e)||!r.has(e.junction)))throw Error(`Foreign registry or invalid field reference`);if(b(n.to).table!==e)throw Error(`Wrong relation target table`);let i=Object.freeze({[c]:!0,source:b(n.from).table,target:e,cardinality:t,from:n.from,to:n.to});return p.add(i),i}function S(e,t){let n=C(e);return n.length>0&&JSON.stringify(n)===JSON.stringify(C(t))}function C(e){if(e.kind===`union`)return[...new Set(e.members.flatMap(C))].sort();if(e.kind===`null`)return[];if(![`id`,`string`,`float64`,`int64`,`boolean`,`literal`].includes(e.kind))throw Error(`Unsupported relation field kind`);return[JSON.stringify(A(e))]}function w(e,t){let n=e.from,r=e.to;if(`base`in n!=`base`in r)throw Error(`Both relation legs must use through`);if(`base`in n&&`base`in r){if(n.junction.table!==r.junction.table)throw Error(`Different junction tables`);T(t,n.junction.table,n.junction.field),T(t,e.target,r.base.field);return}if(!S(d.get(b(n)),d.get(b(r))))throw Error(`Incompatible relation field types`);T(t,e.target,b(r).field)}function T(e,t,n){if(n!==`_id`&&!e[t].indexes.some(e=>e.fields[0]===n))throw Error(`No active index begins with "${t}.${n}"`)}function E(e){return`base`in e?[e.base.table,e.base.field,e.junction.table,e.junction.field]:[e.table,e.field]}function D(e,t,r,i=0){let a={},o={};for(let[s,c]of Object.entries(r)){let r=e.metadata[t].fields[s],l=e.declarations[t]?.[s];if(c===!0&&r)a[s]=n(r).optional();else if(c!==!0&&l&&i<4)o[s]={cardinality:l.cardinality,target:D(e,l.target,c,i+1)};else throw Error(`Invalid relation filter selection "${t}.${s}"`)}return{fields:a,relations:o}}function O(e,t,n,i=0){let o={};for(let[a,s]of Object.entries(n)){let n=e.declarations[t]?.[a];if(!n||i>=4)throw Error(`Unknown or too deep relation "${t}.${a}"`);let c=s===!0?e.metadata[n.target].dto:O(e,n.target,s,i+1);o[a]=n.cardinality===`one`?c.nullable():r(c).result}let s=e.metadata[t].dto;if(!(s instanceof a.ZodObject))throw Error(`Expected object DTO`);return H(s.extend(o).strict(),()=>B(e))}function k(e){return e.export()}function A(e){return e.json}function j(e){if(Array.isArray(e))return`[${e.map(j).join(`,`)}]`;if(e!==null&&Object(e)===e){let t=e;return`{${Object.keys(t).sort().map(e=>`${JSON.stringify(e)}:${j(t[e])}`).join(`,`)}}`}return JSON.stringify(e)}function M(e){if(e===null||Object(e)!==e)return;let t=e;if(t.type===`any`)throw Error(`Unsupported native validation form`);for(let e of Object.values(t))M(e)}function N(e,t,n){let{_id:r,_creationTime:i,...a}=t;if(!r||!i||j(A(r))!==j(A(o.id(e)))||j(A(i))!==j(A(o.number()))||r.isOptional!==`required`||i.isOptional!==`required`||j(n)!==j(A(o.object(a))))throw Error(`Native stored document disagrees with boundary "${e}"`)}const P=a.object({field:a.string()}),F=new Set([P,P.pick({field:!0}),P.omit({field:!0}),P.extend({other:a.string()}),P.safeExtend({other:a.string()}),P.merge(a.object({other:a.string()})),P.partial(),P.required()].flatMap(e=>{let t=Object.getOwnPropertyDescriptor(e._zod.def,`shape`)?.get;return t?[Function.prototype.toString.call(t)]:[]}));function I(e){return z(e,`dto`)}const L=Function.prototype.toString.call(Object.getOwnPropertyDescriptor(a.string().default(``)._zod.def,`defaultValue`).get),R=Function.prototype.toString.call(Object.getOwnPropertyDescriptor(a.string().prefault(``)._zod.def,`defaultValue`).get);function z(e,t){let n=[],r=/* @__PURE__ */ new Set,i=[],o=/* @__PURE__ */ new Set,s=/* @__PURE__ */ new Set,c=[];function l(e,u){if(s.has(e))throw Error(`Unsupported cyclic DTO schema`);if(!o.has(e)){if(u>32||n.length>=4096)throw Error(`DTO schema graph budget exceeded`);o.add(e),s.add(e);try{if(e instanceof RegExp&&i.push({expression:e,source:e.source,flags:e.flags}),e instanceof a.core.$ZodCheck&&`check`in e._zod.def){if(t===`dto`&&e._zod.def.check===`overwrite`)throw Error(`Unsupported DTO overwrite check`);l(e._zod.def,u+1),n.push({object:e._zod,exactKeys:!1,keys:[`def`,`check`],values:[`def`,`check`].map(t=>Object.getOwnPropertyDescriptor(e._zod,t))});return}if(e instanceof a.core.$ZodType){let i=e._zod.def;if(t===`dto`&&(![`object`,`array`,`optional`,`nullable`,`nonoptional`,`union`,`intersection`,`tuple`,`record`,`string`,`number`,`boolean`,`bigint`,`null`,`never`,`literal`,`enum`].includes(i.type)||`coerce`in i&&i.coerce))throw Error(`Unsupported DTO schema "${i.type}"`);if(t===`stored`&&(i.type==="default"||i.type===`prefault`)){let e=Object.getOwnPropertyDescriptor(i,`defaultValue`);if(e?.get){if(e.set||Function.prototype.toString.call(e.get)!==(i.type==="default"?L:R))throw Error(`Unsupported stored schema accessor`);r.add(i)}}if(i.type===`object`){let t=Object.getOwnPropertyDescriptor(i,`shape`);if(t?.get){if(t.set||!F.has(Function.prototype.toString.call(t.get)))throw Error(`Unsupported DTO schema accessor`);let e=i.shape;l(e,u+1),Object.getOwnPropertyDescriptor(i,`shape`)?.get&&c.push({definition:i,fields:e})}if(e instanceof a.ZodObject){let t=Object.getOwnPropertyDescriptor(e,`shape`);if(t&&!(`value`in t))throw Error(`Unsupported DTO schema accessor`);l(e.shape,u+1)}}l(i,u+1),n.push({object:e._zod,exactKeys:!1,keys:[`def`],values:[Object.getOwnPropertyDescriptor(e._zod,`def`)]});return}let o=Reflect.ownKeys(e),s=o.map(t=>Object.getOwnPropertyDescriptor(e,t));if(s.some((t,n)=>!(`value`in t)&&!c.some(({definition:t})=>t===e&&o[n]===`shape`)&&!(r.has(e)&&o[n]===`defaultValue`)))throw Error(`Unsupported DTO schema accessor`);n.push({object:e,exactKeys:!0,keys:o,values:s});for(let e of s)e.value!==null&&Object(e.value)===e.value&&!(e.value instanceof Function)&&l(e.value,u+1)}finally{s.delete(e)}}}return l(e,0),()=>{for(let e of i)if(e.expression.source!==e.source||e.expression.flags!==e.flags)throw Error(`DTO schema mutated after registry construction`);for(let e of n){let t=e.keys;if(e.exactKeys&&Reflect.ownKeys(e.object).length!==t.length)throw Error(`DTO schema mutated after registry construction`);for(let n=0;n<t.length;n++){if(e.object instanceof RegExp&&t[n]===`lastIndex`)continue;let r=Object.getOwnPropertyDescriptor(e.object,t[n]),i=e.values[n];if(!r||r.value!==i.value||r.get!==i.get||r.set!==i.set||r.enumerable!==i.enumerable)throw Error(`DTO schema mutated after registry construction`)}}for(let{definition:e,fields:t}of c){let n=e.shape,r=Reflect.ownKeys(t);if(Reflect.ownKeys(n).length!==r.length||r.some(e=>Object.getOwnPropertyDescriptor(n,e)?.value!==Object.getOwnPropertyDescriptor(t,e)?.value))throw Error(`DTO schema mutated after registry construction`)}}}function B(e){for(let t of Object.values(e.metadata))t.assertUnchanged()}const V=a.core.$constructor(`GuardedDtoObject`,(e,t)=>{let n=t;a.ZodObject.init(e,t),e._zod.deferred??=[],e._zod.deferred.push(()=>{let t=e._zod.run;e._zod.run=(e,r)=>{try{n.assertUnchanged()}catch{return e.issues.push({code:`custom`,input:e.value,message:`DTO schema mutated after registry construction`}),e}return t(e,r)}})});function H(e,t){let n=e.shape,r={...e._zod.def,assertUnchanged:t};return Object.defineProperty(r,"shape",{enumerable:!0,configurable:!0,get:()=>(t(),n)}),new V(r)}function U(e){let t={};for(let[n,r]of Object.entries(e.metadata)){let e={};for(let[t,n]of Object.entries(r.fields))e[t]=Object.freeze({kind:n.kind,optional:n.isOptional===`optional`,nullable:W(n),idTables:Object.freeze(G(n)),native:K(A(n))});t[n]=Object.freeze({fields:Object.freeze(e),indexes:Object.freeze(r.indexes.map(e=>Object.freeze({name:e.name,fields:Object.freeze([...e.fields])})))})}return Object.freeze({tables:Object.freeze(t),declarations:e.declarations})}function W(e){return e.kind===`null`||e.kind===`union`&&e.members.some(W)}function G(e){return e.kind===`id`?[e.tableName]:e.kind===`union`?[...new Set(e.members.flatMap(G))].sort():[]}function K(e){let t=structuredClone(e),n=[t];for(;n.length;){let e=n.pop();if(Object(e)!==e)continue;let t=e;Object.freeze(t),n.push(...Object.values(t))}return t}export{h as defineRelations,g as getRelationExecutor,_ as getRelationMetadata};
|
|
2
|
+
//# sourceMappingURL=relations.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"relations.mjs","names":["fieldBrand","edgeBrand","registries","executorRegistries","refs","throughRefs","edgeRefs","indexExport","z","defineRelations","metadata","ownRefs","fields","one","many","name","table","tables","dto","assertUnchanged","dtoMutationGuard","native","zodToConvex","exported","nativeTableExport","assertNativeValidation","assertStoredDocument","indexes","index","a","b","nativeJson","tableRefs","field","validator","ref","junctionValidator","junction","compatible","result","makeEdge","spec","supplied","declare","declarations","edges","source","edge","base","validatePath","internal","helpers","assertRegistryUnchanged","assertSelection","selection","guardedDto","nativePagination","relationFilterSchema","filterGrammar","paginated","rowSchema","identity","data","canonicalNative","serializeLeg","registry","snapshotMetadata","ownedTables","storedGuards","schemaGuard","schemaMutationGuard","nativeSnapshot","guard","definition","getRelationExecutor","owned","assertSchema","names","scalarFields","grammar","scalarValidator","scalarPredicateSchema","depth","declaration","eligible","row","key","getRelationMetadata","pending","nodes","ancestors","value","prototype","keys","property","leg","own","target","leftDomain","domain","left","right","from","to","requireIndex","relations","mask","relationFields","object","container","child","stored","_id","_creationTime","v","document","objectAccessorSample","builtinObjectGetters","getter","schema","builtinDefaultGetter","builtinPrefaultGetter","fallbackDefinitions","patterns","seen","active","objectFields","visit","boundary","def","descriptor","publicFields","values","i","pattern","node","current","before","GuardedDtoObject","guarded","inst","run","payload","ctx","outputFields","hasNull","idTables","frozenNative","snapshot","next"],"sources":["../src/relations.ts"],"sourcesContent":["import { z } from 'zod'\nimport { zodToConvex, type ConvexValidatorFromZod } from 'convex-helpers/server/zod4'\nimport type { TableDefinition, PaginationResult } from 'convex/server'\nimport {\n\tv,\n\ttype GenericId,\n\ttype GenericValidator,\n\ttype ValidatorJSON,\n\ttype JSONValue,\n} from 'convex/values'\nimport { paginated } from './zod-table'\nimport {\n\tnativePagination,\n\trelationFilterSchema,\n\tscalarPredicateSchema,\n\ttype FieldSchemas,\n\ttype FilterGrammar,\n\ttype PaginationOptionsSchema,\n\ttype ScalarSelection,\n\ttype ScalarPredicate,\n} from './querying/filters'\n\n/** Object table boundaries only. Runtime metadata comes from native validators/export. */\nexport interface RelationTable {\n\ttableName: string\n\tschema: z.ZodObject\n\tpublicDto: z.ZodObject\n\ttable: TableDefinition\n\tdto(includeId: true): z.ZodType\n}\nexport type RelationTables = Record<string, RelationTable>\n/** Internal named declaration dependency; excluded from the supported relations facade. */\nexport interface SelectionMask {\n\t[key: string]: true | SelectionMask\n}\ntype Fields<T extends RelationTable> = T['schema']['shape']\ntype Native<T extends RelationTable, K extends keyof Fields<T>> = ConvexValidatorFromZod<\n\tFields<T>[K],\n\t'required'\n>['type']\nconst fieldBrand: unique symbol = Symbol('relationField')\nconst edgeBrand: unique symbol = Symbol('relationEdge')\ntype Comparable<Value> = Exclude<Value, null | undefined>\ntype Same<A, B> = [Comparable<A> | Comparable<B>] extends [never]\n\t? false\n\t: [Comparable<A>] extends [Comparable<B>]\n\t\t? [Comparable<B>] extends [Comparable<A>]\n\t\t\t? true\n\t\t\t: false\n\t\t: false\n\nexport interface FieldReference<Table extends string, Field extends string, Value> {\n\treadonly [fieldBrand]: Value\n\treadonly table: Table\n\treadonly field: Field\n\tthrough<J extends AnyField>(\n\t\tjunction: J & (Same<Value, J[typeof fieldBrand]> extends true ? {} : never),\n\t): ThroughReference<Table, Field, Value, J>\n}\ntype AnyField = FieldReference<string, string, any>\nexport interface ThroughReference<\n\tTable extends string,\n\tField extends string,\n\tValue,\n\tJunction extends AnyField,\n> {\n\treadonly base: FieldReference<Table, Field, Value>\n\treadonly junction: Junction\n}\ntype AnyThrough = ThroughReference<string, string, any, AnyField>\ntype Leg = AnyField | AnyThrough\ntype Base<L extends Leg> = L extends AnyThrough ? L['base'] : L\ntype JunctionTable<L extends Leg> = L extends AnyThrough ? L['junction']['table'] : never\ntype CompatibleLegs<F extends Leg, T extends Leg> = F extends AnyThrough\n\t? T extends AnyThrough\n\t\t? Same<JunctionTable<F>, JunctionTable<T>> extends true\n\t\t\t? {}\n\t\t\t: never\n\t\t: never\n\t: T extends AnyThrough\n\t\t? never\n\t\t: Same<Base<F>[typeof fieldBrand], Base<T>[typeof fieldBrand]> extends true\n\t\t\t? {}\n\t\t\t: never\n\nexport interface RelationEdge<\n\tSource extends string,\n\tTarget extends string,\n\tCardinality extends 'one' | 'many',\n> {\n\treadonly [edgeBrand]: true\n\treadonly source: Source\n\treadonly target: Target\n\treadonly cardinality: Cardinality\n\treadonly from: Leg\n\treadonly to: Leg\n}\ntype AnyEdge = RelationEdge<string, string, 'one' | 'many'>\ntype FieldReferences<Tables extends RelationTables> = {\n\t[T in keyof Tables]: {\n\t\t[K in Extract<keyof Fields<Tables[T]>, string>]: FieldReference<\n\t\t\tExtract<T, string>,\n\t\t\tK,\n\t\t\tNative<Tables[T], K>\n\t\t>\n\t}\n}\ntype AllReferences<Tables extends RelationTables> = {\n\t[T in keyof Tables]: FieldReferences<Tables>[T][Extract<keyof FieldReferences<Tables>[T], string>]\n}[keyof Tables]\ntype Builders<Tables extends RelationTables, C extends 'one' | 'many'> = {\n\t[T in keyof Tables]: <\n\t\tF extends AllReferences<Tables> | AnyThrough,\n\t\tTo extends\n\t\t\t| FieldReferences<Tables>[T][Extract<keyof FieldReferences<Tables>[T], string>]\n\t\t\t| AnyThrough,\n\t>(\n\t\tspec: { from: F; to: To } & CompatibleLegs<F, To> & (Base<To>['table'] extends T ? {} : never),\n\t) => RelationEdge<Base<F>['table'], Extract<T, string>, C>\n}\nexport type RelationBuilder<Tables extends RelationTables> = FieldReferences<Tables> & {\n\tone: Builders<Tables, 'one'>\n\tmany: Builders<Tables, 'many'>\n}\nexport type RelationDeclarations = Record<string, Record<string, AnyEdge>>\ntype ExactDeclarations<Tables extends RelationTables, D extends RelationDeclarations> = {\n\t[T in keyof D]: T extends keyof Tables\n\t\t? {\n\t\t\t\t[K in keyof D[T]]: K extends\n\t\t\t\t\t| keyof Fields<Tables[T]>\n\t\t\t\t\t| 'and'\n\t\t\t\t\t| 'or'\n\t\t\t\t\t| 'not'\n\t\t\t\t\t| 'fields'\n\t\t\t\t\t| 'then'\n\t\t\t\t\t| '__proto__'\n\t\t\t\t\t| 'constructor'\n\t\t\t\t\t| 'prototype'\n\t\t\t\t\t? never\n\t\t\t\t\t: D[T][K]['source'] extends T\n\t\t\t\t\t\t? D[T][K]\n\t\t\t\t\t\t: never\n\t\t\t}\n\t\t: never\n}\ntype Depth = readonly [1, 1, 1, 1]\ntype Tail<D extends readonly 1[]> = D extends readonly [1, ...infer R extends 1[]] ? R : []\ntype Edges<D, T> = T extends keyof D ? D[T] : {}\ntype Target<E> = E extends AnyEdge ? E['target'] : never\nexport type RelationSelection<\n\tTables extends RelationTables,\n\tD extends RelationDeclarations,\n\tT extends keyof Tables,\n\tLevel extends readonly 1[] = Depth,\n> = Level extends readonly []\n\t? Record<string, never>\n\t: {\n\t\t\t[K in keyof Edges<D, T>]?:\n\t\t\t\t| true\n\t\t\t\t| RelationSelection<Tables, D, Extract<Target<Edges<D, T>[K]>, keyof Tables>, Tail<Level>>\n\t\t}\nexport type RelationFilterSelection<\n\tTables extends RelationTables,\n\tD extends RelationDeclarations,\n\tT extends keyof Tables,\n\tLevel extends readonly 1[] = Depth,\n> = ScalarSelection<Fields<Tables[T]>> &\n\t(Level extends readonly []\n\t\t? {}\n\t\t: {\n\t\t\t\t[K in keyof Edges<D, T>]?: RelationFilterSelection<\n\t\t\t\t\tTables,\n\t\t\t\t\tD,\n\t\t\t\t\tExtract<Target<Edges<D, T>[K]>, keyof Tables>,\n\t\t\t\t\tTail<Level>\n\t\t\t\t>\n\t\t\t})\ntype ExactOutputMask<\n\tTables extends RelationTables,\n\tD extends RelationDeclarations,\n\tT extends keyof Tables,\n\tS,\n\tL extends readonly 1[] = Depth,\n> = S & {\n\t[K in keyof S]: L extends readonly []\n\t\t? never\n\t\t: K extends keyof Edges<D, T>\n\t\t\t? S[K] extends true\n\t\t\t\t? true\n\t\t\t\t: ExactOutputMask<Tables, D, Extract<Target<Edges<D, T>[K]>, keyof Tables>, S[K], Tail<L>>\n\t\t\t: never\n}\ntype ExactFilterMask<\n\tTables extends RelationTables,\n\tD extends RelationDeclarations,\n\tT extends keyof Tables,\n\tS,\n\tL extends readonly 1[] = Depth,\n> = S & {\n\t[K in keyof S]: K extends keyof ScalarSelection<Fields<Tables[T]>>\n\t\t? S[K] extends true\n\t\t\t? true\n\t\t\t: never\n\t\t: L extends readonly []\n\t\t\t? never\n\t\t\t: K extends keyof Edges<D, T>\n\t\t\t\t? S[K] extends true\n\t\t\t\t\t? never\n\t\t\t\t\t: ExactFilterMask<Tables, D, Extract<Target<Edges<D, T>[K]>, keyof Tables>, S[K], Tail<L>>\n\t\t\t\t: never\n}\ntype ScalarValues<T extends RelationTable, S, Side extends 'input' | 'output'> = {\n\t[K in Extract<keyof S, keyof Fields<T>>]?: ScalarPredicate<Fields<T>[K], Side>\n}\nexport type RelationFilters<\n\tTables extends RelationTables,\n\tD extends RelationDeclarations,\n\tT extends keyof Tables,\n\tS,\n\tSide extends 'input' | 'output' = 'output',\n\tLevel extends readonly 1[] = Depth,\n> = Omit<ScalarValues<Tables[T], S, Side>, 'and' | 'or' | 'not' | 'fields'> & {\n\tfields?: ScalarValues<Tables[T], S, Side>\n} & (Level extends readonly []\n\t\t? {}\n\t\t: {\n\t\t\t\t[K in Extract<keyof S, keyof Edges<D, T>>]?: Edges<D, T>[K] extends RelationEdge<\n\t\t\t\t\tstring,\n\t\t\t\t\tinfer Target,\n\t\t\t\t\tinfer C\n\t\t\t\t>\n\t\t\t\t\t? C extends 'one'\n\t\t\t\t\t\t? RelationFilters<\n\t\t\t\t\t\t\t\tTables,\n\t\t\t\t\t\t\t\tD,\n\t\t\t\t\t\t\t\tExtract<Target, keyof Tables>,\n\t\t\t\t\t\t\t\tS[K],\n\t\t\t\t\t\t\t\tSide,\n\t\t\t\t\t\t\t\tTail<Level>\n\t\t\t\t\t\t\t> | null\n\t\t\t\t\t\t:\n\t\t\t\t\t\t\t\t| {\n\t\t\t\t\t\t\t\t\t\tsome: RelationFilters<\n\t\t\t\t\t\t\t\t\t\t\tTables,\n\t\t\t\t\t\t\t\t\t\t\tD,\n\t\t\t\t\t\t\t\t\t\t\tExtract<Target, keyof Tables>,\n\t\t\t\t\t\t\t\t\t\t\tS[K],\n\t\t\t\t\t\t\t\t\t\t\tSide,\n\t\t\t\t\t\t\t\t\t\t\tTail<Level>\n\t\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t }\n\t\t\t\t\t\t\t\t| {\n\t\t\t\t\t\t\t\t\t\tnone: RelationFilters<\n\t\t\t\t\t\t\t\t\t\t\tTables,\n\t\t\t\t\t\t\t\t\t\t\tD,\n\t\t\t\t\t\t\t\t\t\t\tExtract<Target, keyof Tables>,\n\t\t\t\t\t\t\t\t\t\t\tS[K],\n\t\t\t\t\t\t\t\t\t\t\tSide,\n\t\t\t\t\t\t\t\t\t\t\tTail<Level>\n\t\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t }\n\t\t\t\t\t: never\n\t\t\t} & {\n\t\t\t\tand?: RelationFilters<Tables, D, T, S, Side, Tail<Level>>[]\n\t\t\t\tor?: RelationFilters<Tables, D, T, S, Side, Tail<Level>>[]\n\t\t\t\tnot?: RelationFilters<Tables, D, T, S, Side, Tail<Level>>\n\t\t\t})\ntype PublicRow<T extends RelationTable> = z.output<T['publicDto']> & {\n\t_id: GenericId<T['tableName']>\n}\nexport type RelationRow<\n\tTables extends RelationTables,\n\tD extends RelationDeclarations,\n\tT extends keyof Tables,\n\tS,\n\tLevel extends readonly 1[] = Depth,\n> = PublicRow<Tables[T]> &\n\t(Level extends readonly []\n\t\t? {}\n\t\t: {\n\t\t\t\t[K in keyof S]: K extends keyof Edges<D, T>\n\t\t\t\t\t? Edges<D, T>[K] extends RelationEdge<string, infer Target, infer C>\n\t\t\t\t\t\t? C extends 'one'\n\t\t\t\t\t\t\t? RelationRow<\n\t\t\t\t\t\t\t\t\tTables,\n\t\t\t\t\t\t\t\t\tD,\n\t\t\t\t\t\t\t\t\tExtract<Target, keyof Tables>,\n\t\t\t\t\t\t\t\t\tS[K] extends true ? {} : S[K],\n\t\t\t\t\t\t\t\t\tTail<Level>\n\t\t\t\t\t\t\t\t> | null\n\t\t\t\t\t\t\t: PaginationResult<\n\t\t\t\t\t\t\t\t\tRelationRow<\n\t\t\t\t\t\t\t\t\t\tTables,\n\t\t\t\t\t\t\t\t\t\tD,\n\t\t\t\t\t\t\t\t\t\tExtract<Target, keyof Tables>,\n\t\t\t\t\t\t\t\t\t\tS[K] extends true ? {} : S[K],\n\t\t\t\t\t\t\t\t\t\tTail<Level>\n\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t: never\n\t\t\t\t\t: never\n\t\t\t})\nexport interface RelationTableHelpers<\n\tTables extends RelationTables,\n\tD extends RelationDeclarations,\n\tT extends keyof Tables,\n> {\n\tpaginationOpts<const S extends RelationFilterSelection<Tables, D, T>>(\n\t\tselection: ExactFilterMask<Tables, D, T, S>,\n\t): PaginationOptionsSchema<\n\t\tRelationFilters<Tables, D, T, S>,\n\t\tRelationFilters<Tables, D, T, S, 'input'>\n\t>\n\tpageDto<const S extends RelationSelection<Tables, D, T>>(\n\t\tselection: ExactOutputMask<Tables, D, T, S>,\n\t): z.ZodType<PaginationResult<RelationRow<Tables, D, T, S>>>\n}\nexport interface RelationRegistryIdentity {\n\treadonly identity: string\n\treadonly version: 1\n}\nexport interface RelationRegistry<Tables extends RelationTables, D extends RelationDeclarations> {\n\treadonly identity: string\n\treadonly version: 1\n\treadonly tables: { [T in keyof Tables]: RelationTableHelpers<Tables, D, T> }\n}\n\nexport interface RelationFieldMetadata {\n\treadonly kind: string\n\treadonly optional: boolean\n\treadonly nullable: boolean\n\treadonly idTables: readonly string[]\n\treadonly native: Readonly<ValidatorJSON>\n}\nexport interface RelationTableMetadata {\n\treadonly fields: Readonly<Record<string, RelationFieldMetadata>>\n\treadonly indexes: readonly { readonly name: string; readonly fields: readonly string[] }[]\n}\ninterface TableMetadata {\n\tfields: Record<string, GenericValidator>\n\tindexes: { name: string; fields: string[] }[]\n\tdto: z.ZodObject\n\tassertUnchanged(): void\n}\ninterface RegistryMetadata {\n\tmetadata: Record<string, TableMetadata>\n\tdeclarations: RelationDeclarations\n}\nexport interface RelationMetadata {\n\treadonly tables: Readonly<Record<string, RelationTableMetadata>>\n\treadonly declarations: Readonly<Record<string, Readonly<Record<string, AnyEdge>>>>\n}\n\nconst registries = new WeakMap<RelationRegistryIdentity, RelationMetadata>()\n// Private executor state retains validators and projection, never a database reader.\nconst executorRegistries = new WeakMap<\n\tRelationRegistryIdentity,\n\t{\n\t\tinternal: RegistryMetadata\n\t\ttables: RelationTables\n\t\tassertStoredUnchanged(): void\n\t\tassertNativeTable(table: string, definition: TableDefinition): void\n\t}\n>()\nconst refs = new WeakMap<AnyField, GenericValidator>()\nconst throughRefs = new WeakSet<AnyThrough>()\nconst edgeRefs = new WeakSet<AnyEdge>()\nconst indexExport = z.object({\n\tindexes: z.array(z.object({ indexDescriptor: z.string(), fields: z.array(z.string()) })),\n})\n\n/** No ID-field inference and no readers: this registry owns declarations/schema helpers only. */\nexport function defineRelations<\n\tconst Tables extends RelationTables,\n\tconst D extends RelationDeclarations,\n>(\n\ttables: Tables,\n\tdeclare: (r: RelationBuilder<Tables>) => D & ExactDeclarations<Tables, D>,\n): RelationRegistry<Tables, D> {\n\tconst metadata: Record<string, TableMetadata> = {}\n\tconst ownRefs = new Set<AnyField>()\n\tconst fields: Record<string, Record<string, AnyField>> = {}\n\tconst one: Record<string, (spec: { from: Leg; to: Leg }) => AnyEdge> = {}\n\tconst many: Record<string, (spec: { from: Leg; to: Leg }) => AnyEdge> = {}\n\tfor (const [name, table] of Object.entries(tables)) {\n\t\tif (\n\t\t\ttable.tableName !== name ||\n\t\t\t['one', 'many', '__proto__', 'constructor', 'prototype'].includes(name)\n\t\t)\n\t\t\tthrow new Error(`Invalid relation table \"${name}\"`)\n\t\tconst dto = table.dto(true)\n\t\tif (!(dto instanceof z.ZodObject)) throw new Error('Expected object DTO')\n\t\tconst assertUnchanged = dtoMutationGuard(dto)\n\t\tconst native = zodToConvex(table.schema)\n\t\tconst exported = nativeTableExport(table.table)\n\t\tassertNativeValidation(exported.documentType)\n\t\tassertStoredDocument(name, native.fields, exported.documentType)\n\t\tconst indexes = indexExport\n\t\t\t.parse(exported)\n\t\t\t.indexes.map((index) => ({ name: index.indexDescriptor, fields: [...index.fields] }))\n\t\t\t.sort((a, b) => a.name.localeCompare(b.name))\n\t\tassertNativeValidation(nativeJson(zodToConvex(dto)))\n\t\tmetadata[name] = { fields: native.fields, indexes, dto, assertUnchanged }\n\t\tconst tableRefs: Record<string, AnyField> = Object.create(null)\n\t\tfor (const [field, validator] of Object.entries(native.fields)) {\n\t\t\tconst ref: AnyField = {\n\t\t\t\t[fieldBrand]: undefined,\n\t\t\t\ttable: name,\n\t\t\t\tfield,\n\t\t\t\tthrough<J extends AnyField>(\n\t\t\t\t\tjunction: J & (Same<any, J[typeof fieldBrand]> extends true ? {} : never),\n\t\t\t\t): ThroughReference<string, string, any, J> {\n\t\t\t\t\tconst junctionValidator = refs.get(junction)\n\t\t\t\t\tif (\n\t\t\t\t\t\t!ownRefs.has(junction) ||\n\t\t\t\t\t\t!junctionValidator ||\n\t\t\t\t\t\t!compatible(validator, junctionValidator)\n\t\t\t\t\t)\n\t\t\t\t\t\tthrow new Error('Invalid junction field or registry')\n\t\t\t\t\tconst result = Object.freeze({ base: ref, junction })\n\t\t\t\t\tthroughRefs.add(result)\n\t\t\t\t\treturn result\n\t\t\t\t},\n\t\t\t}\n\t\t\trefs.set(ref, validator)\n\t\t\townRefs.add(ref)\n\t\t\ttableRefs[field] = Object.freeze(ref)\n\t\t}\n\t\tfields[name] = Object.freeze(tableRefs)\n\t\tone[name] = (spec) => makeEdge(name, 'one', spec, ownRefs)\n\t\tmany[name] = (spec) => makeEdge(name, 'many', spec, ownRefs)\n\t}\n\t// SAFETY: every native field has a branded reference; mapped builders retain the literal names.\n\tconst builder = Object.freeze({\n\t\t...fields,\n\t\tone: Object.freeze(one),\n\t\tmany: Object.freeze(many),\n\t}) as RelationBuilder<Tables>\n\tconst supplied = declare(builder)\n\tconst declarations: RelationDeclarations = Object.fromEntries(\n\t\tObject.entries(supplied).map(([name, edges]) => [name, Object.freeze({ ...edges })]),\n\t)\n\tObject.freeze(declarations)\n\tfor (const [source, edges] of Object.entries(declarations)) {\n\t\tif (!Object.hasOwn(tables, source)) throw new Error(`Unknown source table \"${source}\"`)\n\t\tfor (const [name, edge] of Object.entries(edges)) {\n\t\t\tif (\n\t\t\t\tObject.hasOwn(metadata[source].fields, name) ||\n\t\t\t\t['and', 'or', 'not', 'fields', 'then', '__proto__', 'constructor', 'prototype'].includes(\n\t\t\t\t\tname,\n\t\t\t\t)\n\t\t\t)\n\t\t\t\tthrow new Error(`Relation name collision \"${name}\"`)\n\t\t\tif (\n\t\t\t\t!edgeRefs.has(edge) ||\n\t\t\t\t!ownRefs.has(base(edge.from)) ||\n\t\t\t\t!ownRefs.has(base(edge.to)) ||\n\t\t\t\tedge.source !== source\n\t\t\t)\n\t\t\t\tthrow new Error('Relation source bucket mismatch')\n\t\t\tvalidatePath(edge, metadata)\n\t\t}\n\t}\n\tconst internal: RegistryMetadata = { metadata, declarations }\n\tconst helpers: Record<\n\t\tstring,\n\t\t{\n\t\t\tpaginationOpts(selection: SelectionMask): z.ZodType\n\t\t\tpageDto(selection: SelectionMask): z.ZodType\n\t\t}\n\t> = {}\n\tfor (const table of Object.keys(tables))\n\t\thelpers[table] = {\n\t\t\tpaginationOpts(selection: SelectionMask): z.ZodType {\n\t\t\t\tassertRegistryUnchanged(internal)\n\t\t\t\tassertSelection(selection)\n\t\t\t\treturn guardedDto(\n\t\t\t\t\tnativePagination.extend({\n\t\t\t\t\t\tfilters: relationFilterSchema(filterGrammar(internal, table, selection)).optional(),\n\t\t\t\t\t\torder: z.enum(['asc', 'desc']).optional(),\n\t\t\t\t\t}),\n\t\t\t\t\t() => assertRegistryUnchanged(internal),\n\t\t\t\t)\n\t\t\t},\n\t\t\tpageDto(selection: SelectionMask): z.ZodType {\n\t\t\t\tassertRegistryUnchanged(internal)\n\t\t\t\tassertSelection(selection)\n\t\t\t\treturn guardedDto(paginated(rowSchema(internal, table, selection)).result, () =>\n\t\t\t\t\tassertRegistryUnchanged(internal),\n\t\t\t\t)\n\t\t\t},\n\t\t}\n\t// Stable, collision-free canonical metadata encoding. It is an identity, not a secret/hash.\n\tconst identity = JSON.stringify([\n\t\t1,\n\t\tObject.entries(metadata)\n\t\t\t.sort(([a], [b]) => a.localeCompare(b))\n\t\t\t.map(([name, data]) => [\n\t\t\t\tname,\n\t\t\t\tObject.entries(data.fields)\n\t\t\t\t\t.sort(([a], [b]) => a.localeCompare(b))\n\t\t\t\t\t.map(([field, validator]) => [field, validator.isOptional, nativeJson(validator)]),\n\t\t\t\tdata.indexes,\n\t\t\t\tcanonicalNative(nativeJson(zodToConvex(data.dto))),\n\t\t\t]),\n\t\tObject.entries(declarations)\n\t\t\t.sort(([a], [b]) => a.localeCompare(b))\n\t\t\t.map(([source, edges]) => [\n\t\t\t\tsource,\n\t\t\t\tObject.entries(edges)\n\t\t\t\t\t.sort(([a], [b]) => a.localeCompare(b))\n\t\t\t\t\t.map(([name, edge]) => [\n\t\t\t\t\t\tname,\n\t\t\t\t\t\tedge.cardinality,\n\t\t\t\t\t\tedge.target,\n\t\t\t\t\t\tserializeLeg(edge.from),\n\t\t\t\t\t\tserializeLeg(edge.to),\n\t\t\t\t\t]),\n\t\t\t]),\n\t])\n\t// SAFETY: helpers are assembled for every validated literal table and mask; schemas derive matching native fields/public DTOs.\n\tconst registry = Object.freeze({\n\t\tidentity,\n\t\tversion: 1,\n\t\ttables: Object.freeze(helpers),\n\t}) as RelationRegistry<Tables, D>\n\tregistries.set(registry, snapshotMetadata(internal))\n\tconst ownedTables = Object.freeze({ ...tables })\n\tconst storedGuards = Object.fromEntries(\n\t\tObject.entries(ownedTables).map(([name, table]) => {\n\t\t\tconst schemaGuard = schemaMutationGuard(table.schema, 'stored')\n\t\t\tconst nativeSnapshot = JSON.stringify(nativeTableExport(table.table))\n\t\t\treturn [\n\t\t\t\tname,\n\t\t\t\t() => {\n\t\t\t\t\tschemaGuard()\n\t\t\t\t\tif (JSON.stringify(nativeTableExport(table.table)) !== nativeSnapshot)\n\t\t\t\t\t\tthrow new Error(`Native schema mutated after registry construction: ${name}`)\n\t\t\t\t},\n\t\t\t]\n\t\t}),\n\t)\n\texecutorRegistries.set(registry, {\n\t\tinternal,\n\t\ttables: ownedTables,\n\t\tassertStoredUnchanged: () => {\n\t\t\tfor (const guard of Object.values(storedGuards)) guard()\n\t\t},\n\t\tassertNativeTable(table, definition) {\n\t\t\tif (!Object.hasOwn(ownedTables, table) || ownedTables[table].table !== definition)\n\t\t\t\tthrow new Error('Native schema/table ownership disagrees with relation registry')\n\t\t\tstoredGuards[table]()\n\t\t},\n\t})\n\treturn registry\n}\n\n/** Internal owned executor bridge. Not an advertised root API. Every operation\n * rechecks the live registry, including cached plans and individual projections.\n */\nexport function getRelationExecutor(registry: RelationRegistryIdentity) {\n\tconst owned = executorRegistries.get(registry)\n\tif (!owned) throw new Error('Unknown relation registry')\n\tconst assertUnchanged = () => {\n\t\tassertRegistryUnchanged(owned.internal)\n\t\towned.assertStoredUnchanged()\n\t}\n\tconst assertSchema = (tables: Readonly<Record<string, TableDefinition>>) => {\n\t\tassertUnchanged()\n\t\tconst names = Object.keys(owned.tables)\n\t\tif (\n\t\t\tnames.length !== Object.keys(tables).length ||\n\t\t\tnames.some((name) => tables[name] !== owned.tables[name].table)\n\t\t)\n\t\t\tthrow new Error('Native schema/table ownership disagrees with relation registry')\n\t}\n\tassertUnchanged()\n\treturn Object.freeze({\n\t\tassertUnchanged,\n\t\tassertNativeTable: owned.assertNativeTable,\n\t\tassertSchema,\n\t\tpagination(table: string) {\n\t\t\tassertUnchanged()\n\t\t\tconst internal = owned.internal\n\t\t\tconst scalarFields = new Map<string, FieldSchemas>()\n\t\t\tfunction grammar(name: string, depth: number): FilterGrammar {\n\t\t\t\tconst data = internal.metadata[name]\n\t\t\t\tif (!data) throw new Error('Unknown query table')\n\t\t\t\tlet fields = scalarFields.get(name)\n\t\t\t\tif (!fields) {\n\t\t\t\t\tfields = {}\n\t\t\t\t\tfor (const [name, validator] of Object.entries(data.fields)) {\n\t\t\t\t\t\t// Unsupported stored containers are not scalar-queryable. No validators\n\t\t\t\t\t\t// are reconstructed from JSON; these are the actual native validators.\n\t\t\t\t\t\tif (scalarValidator(validator))\n\t\t\t\t\t\t\tfields[name] = scalarPredicateSchema(validator).optional()\n\t\t\t\t\t}\n\t\t\t\t\tscalarFields.set(name, fields)\n\t\t\t\t}\n\t\t\t\treturn {\n\t\t\t\t\tfields,\n\t\t\t\t\trelations:\n\t\t\t\t\t\tdepth >= 4\n\t\t\t\t\t\t\t? {}\n\t\t\t\t\t\t\t: Object.fromEntries(\n\t\t\t\t\t\t\t\t\tObject.entries(internal.declarations[name] ?? {}).map(([edge, declaration]) => [\n\t\t\t\t\t\t\t\t\t\tedge,\n\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\tcardinality: declaration.cardinality,\n\t\t\t\t\t\t\t\t\t\t\ttarget: grammar(declaration.target, depth + 1),\n\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t]),\n\t\t\t\t\t\t\t\t),\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn nativePagination.extend({\n\t\t\t\tfilters: relationFilterSchema(grammar(table, 0)).optional(),\n\t\t\t\torder: z.enum(['asc', 'desc']).optional(),\n\t\t\t})\n\t\t},\n\t\tpage(table: string, selection: SelectionMask) {\n\t\t\tassertUnchanged()\n\t\t\tassertSelection(selection)\n\t\t\treturn paginated(rowSchema(owned.internal, table, selection)).result\n\t\t},\n\t\tproject(\n\t\t\ttables: Readonly<Record<string, TableDefinition>>,\n\t\t\ttable: string,\n\t\t\trow: Record<string, import('convex/values').Value>,\n\t\t\teligible: () => boolean,\n\t\t) {\n\t\t\tassertSchema(tables)\n\t\t\tif (!eligible()) return null\n\t\t\tconst dto = owned.internal.metadata[table]?.dto\n\t\t\tif (!dto) throw new Error('Unknown query table')\n\t\t\t// The strict DTO remains the authority. Pick its fields before parsing,\n\t\t\t// matching table projection without spreading any storage-only fields.\n\t\t\treturn dto.parse(\n\t\t\t\tObject.fromEntries(\n\t\t\t\t\tObject.keys(dto.shape)\n\t\t\t\t\t\t.filter((key) => Object.hasOwn(row, key))\n\t\t\t\t\t\t.map((key) => [key, row[key]]),\n\t\t\t\t),\n\t\t\t)\n\t\t},\n\t})\n}\n/** Internal compiler/engine adapter. Registry identity alone cannot forge a registry. */\nexport function getRelationMetadata(registry: RelationRegistryIdentity): RelationMetadata {\n\tconst metadata = registries.get(registry)\n\tif (!metadata) throw new Error('Unknown relation registry')\n\treturn metadata\n}\n\nfunction scalarValidator(validator: GenericValidator): boolean {\n\treturn (\n\t\t['id', 'string', 'float64', 'int64', 'boolean', 'null', 'literal'].includes(validator.kind) ||\n\t\t(validator.kind === 'union' && validator.members.every(scalarValidator))\n\t)\n}\n\nfunction assertSelection(selection: SelectionMask): void {\n\tconst pending: { value: SelectionMask; depth: number; ancestors: readonly SelectionMask[] }[] = [\n\t\t{ value: selection, depth: 0, ancestors: [] },\n\t]\n\tlet nodes = 0\n\twhile (pending.length) {\n\t\tconst { value, depth, ancestors } = pending.pop()!\n\t\tif (++nodes > 256 || depth > 4 || ancestors.includes(value))\n\t\t\tthrow new Error('Selection cycle or depth/node budget exceeded')\n\t\tconst prototype = Object.getPrototypeOf(value)\n\t\tif (prototype !== Object.prototype && prototype !== null) throw new Error('Invalid selection')\n\t\tconst keys = Reflect.ownKeys(value)\n\t\tif (keys.length + nodes + pending.length > 256)\n\t\t\tthrow new Error('Selection node budget exceeded')\n\t\tfor (const key of keys) {\n\t\t\tconst property = Object.getOwnPropertyDescriptor(value, key)!\n\t\t\tif (!property.enumerable || !('value' in property) || String(key) !== key)\n\t\t\t\tthrow new Error('Invalid selection property')\n\t\t\tif (property.value !== true)\n\t\t\t\tpending.push({ value: property.value, depth: depth + 1, ancestors: [...ancestors, value] })\n\t\t\telse if (++nodes > 256) throw new Error('Selection node budget exceeded')\n\t\t}\n\t}\n}\nfunction base(leg: Leg): AnyField {\n\treturn 'base' in leg ? leg.base : leg\n}\nfunction makeEdge(\n\ttarget: string,\n\tcardinality: 'one' | 'many',\n\tspec: { from: Leg; to: Leg },\n\town: Set<AnyField>,\n): AnyEdge {\n\tfor (const leg of [spec.from, spec.to]) {\n\t\tif (!own.has(base(leg)) || ('base' in leg && (!throughRefs.has(leg) || !own.has(leg.junction))))\n\t\t\tthrow new Error('Foreign registry or invalid field reference')\n\t}\n\tif (base(spec.to).table !== target) throw new Error('Wrong relation target table')\n\tconst result: AnyEdge = Object.freeze({\n\t\t[edgeBrand]: true as const,\n\t\tsource: base(spec.from).table,\n\t\ttarget,\n\t\tcardinality,\n\t\tfrom: spec.from,\n\t\tto: spec.to,\n\t})\n\tedgeRefs.add(result)\n\treturn result\n}\nfunction compatible(left: GenericValidator, right: GenericValidator): boolean {\n\tconst leftDomain = domain(left)\n\treturn leftDomain.length > 0 && JSON.stringify(leftDomain) === JSON.stringify(domain(right))\n}\nfunction domain(validator: GenericValidator): string[] {\n\tif (validator.kind === 'union') return [...new Set(validator.members.flatMap(domain))].sort()\n\tif (validator.kind === 'null') return []\n\tif (!['id', 'string', 'float64', 'int64', 'boolean', 'literal'].includes(validator.kind))\n\t\tthrow new Error('Unsupported relation field kind')\n\treturn [JSON.stringify(nativeJson(validator))]\n}\nfunction validatePath(edge: AnyEdge, metadata: Record<string, TableMetadata>): void {\n\tconst from = edge.from\n\tconst to = edge.to\n\tif ('base' in from !== 'base' in to) throw new Error('Both relation legs must use through')\n\tif ('base' in from && 'base' in to) {\n\t\tif (from.junction.table !== to.junction.table) throw new Error('Different junction tables')\n\t\trequireIndex(metadata, from.junction.table, from.junction.field)\n\t\trequireIndex(metadata, edge.target, to.base.field)\n\t\treturn\n\t}\n\tif (!compatible(refs.get(base(from))!, refs.get(base(to))!))\n\t\tthrow new Error('Incompatible relation field types')\n\trequireIndex(metadata, edge.target, base(to).field)\n}\nfunction requireIndex(metadata: Record<string, TableMetadata>, table: string, field: string): void {\n\tif (field !== '_id' && !metadata[table].indexes.some((index) => index.fields[0] === field))\n\t\tthrow new Error(`No active index begins with \"${table}.${field}\"`)\n}\nfunction serializeLeg(leg: Leg): string[] {\n\treturn 'base' in leg\n\t\t? [leg.base.table, leg.base.field, leg.junction.table, leg.junction.field]\n\t\t: [leg.table, leg.field]\n}\nfunction filterGrammar(\n\tregistry: RegistryMetadata,\n\ttable: string,\n\tselection: SelectionMask,\n\tdepth: number = 0,\n): FilterGrammar {\n\tconst fields: FieldSchemas = {}\n\tconst relations: FilterGrammar['relations'] = {}\n\tfor (const [key, mask] of Object.entries(selection)) {\n\t\tconst validator = registry.metadata[table].fields[key]\n\t\tconst edge = registry.declarations[table]?.[key]\n\t\tif (mask === true && validator) fields[key] = scalarPredicateSchema(validator).optional()\n\t\telse if (mask !== true && edge && depth < 4)\n\t\t\trelations[key] = {\n\t\t\t\tcardinality: edge.cardinality,\n\t\t\t\ttarget: filterGrammar(registry, edge.target, mask, depth + 1),\n\t\t\t}\n\t\telse throw new Error(`Invalid relation filter selection \"${table}.${key}\"`)\n\t}\n\treturn { fields, relations }\n}\nfunction rowSchema(\n\tregistry: RegistryMetadata,\n\ttable: string,\n\tselection: SelectionMask,\n\tdepth: number = 0,\n): z.ZodType {\n\tconst relationFields: FieldSchemas = {}\n\tfor (const [name, mask] of Object.entries(selection)) {\n\t\tconst edge = registry.declarations[table]?.[name]\n\t\tif (!edge || depth >= 4) throw new Error(`Unknown or too deep relation \"${table}.${name}\"`)\n\t\tconst target =\n\t\t\tmask === true\n\t\t\t\t? registry.metadata[edge.target].dto\n\t\t\t\t: rowSchema(registry, edge.target, mask, depth + 1)\n\t\trelationFields[name] = edge.cardinality === 'one' ? target.nullable() : paginated(target).result\n\t}\n\t// Keep caller validations; guard the supported graph before parsing or native conversion.\n\tconst dto = registry.metadata[table].dto\n\tif (!(dto instanceof z.ZodObject)) throw new Error('Expected object DTO')\n\treturn guardedDto(dto.extend(relationFields).strict(), () => assertRegistryUnchanged(registry))\n}\n\ninterface NativeTableExport {\n\tindexes: { indexDescriptor: string; fields: string[] }[]\n\tdocumentType: ValidatorJSON\n}\nfunction nativeTableExport(table: TableDefinition): NativeTableExport {\n\t// SAFETY: Convex exposes export at runtime but strips its internal signature from declarations.\n\treturn (table as TableDefinition & { export(): NativeTableExport }).export()\n}\nfunction nativeJson(validator: GenericValidator): ValidatorJSON {\n\t// SAFETY: native validators expose converter metadata at runtime; Convex strips json from declarations.\n\treturn (validator as GenericValidator & { json: ValidatorJSON }).json\n}\n\nfunction canonicalNative(value: JSONValue): string {\n\tif (Array.isArray(value)) return `[${value.map(canonicalNative).join(',')}]`\n\tif (value !== null && Object(value) === value) {\n\t\t// SAFETY: native JSON contains only JSON objects, arrays and primitives.\n\t\tconst object = value as { [key: string]: JSONValue }\n\t\treturn `{${Object.keys(object)\n\t\t\t.sort()\n\t\t\t.map((key) => `${JSON.stringify(key)}:${canonicalNative(object[key])}`)\n\t\t\t.join(',')}}`\n\t}\n\treturn JSON.stringify(value)\n}\n\nfunction assertNativeValidation(value: JSONValue): void {\n\tif (value === null || Object(value) !== value) return\n\t// SAFETY: native converter metadata contains only JSON containers and primitives.\n\tconst container = value as { [key: string]: JSONValue }\n\tif (container.type === 'any') throw new Error('Unsupported native validation form')\n\tfor (const child of Object.values(container)) assertNativeValidation(child)\n}\n\nfunction assertStoredDocument(\n\ttable: string,\n\tfields: Record<string, GenericValidator>,\n\tdocument: ValidatorJSON,\n): void {\n\tconst { _id, _creationTime, ...stored } = fields\n\tif (\n\t\t!_id ||\n\t\t!_creationTime ||\n\t\tcanonicalNative(nativeJson(_id)) !== canonicalNative(nativeJson(v.id(table))) ||\n\t\tcanonicalNative(nativeJson(_creationTime)) !== canonicalNative(nativeJson(v.number())) ||\n\t\t_id.isOptional !== 'required' ||\n\t\t_creationTime.isOptional !== 'required' ||\n\t\tcanonicalNative(document) !== canonicalNative(nativeJson(v.object(stored)))\n\t)\n\t\tthrow new Error(`Native stored document disagrees with boundary \"${table}\"`)\n}\n\ninterface DtoGraphNode {\n\tobject: object\n\texactKeys: boolean\n\tkeys: readonly PropertyKey[]\n\tvalues: readonly PropertyDescriptor[]\n}\n\n// Compare against this peer's own built-in accessor, using the intrinsic rather\n// than a caller-provided toString. Older Zod clones retain this accessor even\n// after reading shape, because it caches on the original definition.\nconst objectAccessorSample = z.object({ field: z.string() })\nconst builtinObjectGetters = new Set(\n\t[\n\t\tobjectAccessorSample,\n\t\tobjectAccessorSample.pick({ field: true }),\n\t\tobjectAccessorSample.omit({ field: true }),\n\t\tobjectAccessorSample.extend({ other: z.string() }),\n\t\tobjectAccessorSample.safeExtend({ other: z.string() }),\n\t\tobjectAccessorSample.merge(z.object({ other: z.string() })),\n\t\tobjectAccessorSample.partial(),\n\t\tobjectAccessorSample.required(),\n\t].flatMap((schema) => {\n\t\tconst getter = Object.getOwnPropertyDescriptor(schema._zod.def, 'shape')?.get\n\t\treturn getter ? [Function.prototype.toString.call(getter)] : []\n\t}),\n)\n\n/** Snapshot supported value-validation definitions, not Zod's mutable parse caches.\n * Functions remain the original validation functions; their captured application state\n * is outside the schema contract. Lazy/transform/default/coercion nodes fail closed.\n */\nfunction dtoMutationGuard(dto: z.ZodObject): () => void {\n\treturn schemaMutationGuard(dto, 'dto')\n}\n\n// Stored schemas already passed the native input boundary. Track their graph\n// independently of public DTO admissibility, without running any stored parser.\nconst builtinDefaultGetter = Function.prototype.toString.call(\n\tObject.getOwnPropertyDescriptor(z.string().default('')._zod.def, 'defaultValue')!.get!,\n)\nconst builtinPrefaultGetter = Function.prototype.toString.call(\n\tObject.getOwnPropertyDescriptor(z.string().prefault('')._zod.def, 'defaultValue')!.get!,\n)\n\nfunction schemaMutationGuard(dto: z.ZodObject, boundary: 'dto' | 'stored'): () => void {\n\tconst nodes: DtoGraphNode[] = []\n\tconst fallbackDefinitions = new Set<object>()\n\tconst patterns: { expression: RegExp; source: string; flags: string }[] = []\n\tconst seen = new Set<object>()\n\tconst active = new Set<object>()\n\tconst objectFields: {\n\t\tdefinition: z.core.$ZodObjectDef\n\t\tfields: Record<string, z.core.$ZodType>\n\t}[] = []\n\tfunction visit(value: DtoGraphNode['object'], depth: number): void {\n\t\tif (active.has(value)) throw new Error('Unsupported cyclic DTO schema')\n\t\tif (seen.has(value)) return\n\t\tif (depth > 32 || nodes.length >= 4096) throw new Error('DTO schema graph budget exceeded')\n\t\tseen.add(value)\n\t\tactive.add(value)\n\t\ttry {\n\t\t\tif (value instanceof RegExp)\n\t\t\t\tpatterns.push({ expression: value, source: value.source, flags: value.flags })\n\t\t\tif (value instanceof z.core.$ZodCheck && 'check' in value._zod.def) {\n\t\t\t\tif (boundary === 'dto' && value._zod.def.check === 'overwrite')\n\t\t\t\t\tthrow new Error('Unsupported DTO overwrite check')\n\t\t\t\tvisit(value._zod.def, depth + 1)\n\t\t\t\tnodes.push({\n\t\t\t\t\tobject: value._zod,\n\t\t\t\t\texactKeys: false,\n\t\t\t\t\tkeys: ['def', 'check'],\n\t\t\t\t\tvalues: ['def', 'check'].map((key) => Object.getOwnPropertyDescriptor(value._zod, key)!),\n\t\t\t\t})\n\t\t\t\treturn\n\t\t\t}\n\t\t\tif (value instanceof z.core.$ZodType) {\n\t\t\t\t// SAFETY: built-in Zod definitions form a discriminated union.\n\t\t\t\tconst def = (value as z.core.$ZodTypes)._zod.def\n\t\t\t\tif (\n\t\t\t\t\tboundary === 'dto' &&\n\t\t\t\t\t(![\n\t\t\t\t\t\t'object',\n\t\t\t\t\t\t'array',\n\t\t\t\t\t\t'optional',\n\t\t\t\t\t\t'nullable',\n\t\t\t\t\t\t'nonoptional',\n\t\t\t\t\t\t'union',\n\t\t\t\t\t\t'intersection',\n\t\t\t\t\t\t'tuple',\n\t\t\t\t\t\t'record',\n\t\t\t\t\t\t'string',\n\t\t\t\t\t\t'number',\n\t\t\t\t\t\t'boolean',\n\t\t\t\t\t\t'bigint',\n\t\t\t\t\t\t'null',\n\t\t\t\t\t\t'never',\n\t\t\t\t\t\t'literal',\n\t\t\t\t\t\t'enum',\n\t\t\t\t\t].includes(def.type) ||\n\t\t\t\t\t\t('coerce' in def && def.coerce))\n\t\t\t\t)\n\t\t\t\t\tthrow new Error(`Unsupported DTO schema \"${def.type}\"`)\n\t\t\t\tif (boundary === 'stored' && (def.type === 'default' || def.type === 'prefault')) {\n\t\t\t\t\tconst descriptor = Object.getOwnPropertyDescriptor(def, 'defaultValue')\n\t\t\t\t\tif (descriptor?.get) {\n\t\t\t\t\t\tif (\n\t\t\t\t\t\t\tdescriptor.set ||\n\t\t\t\t\t\t\tFunction.prototype.toString.call(descriptor.get) !==\n\t\t\t\t\t\t\t\t(def.type === 'default' ? builtinDefaultGetter : builtinPrefaultGetter)\n\t\t\t\t\t\t)\n\t\t\t\t\t\t\tthrow new Error('Unsupported stored schema accessor')\n\t\t\t\t\t\t// Snapshot the accessor identity below, never evaluate its fallback.\n\t\t\t\t\t\tfallbackDefinitions.add(def)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif (def.type === 'object') {\n\t\t\t\t\tconst descriptor = Object.getOwnPropertyDescriptor(def, 'shape')\n\t\t\t\t\tif (descriptor?.get) {\n\t\t\t\t\t\tif (\n\t\t\t\t\t\t\tdescriptor.set ||\n\t\t\t\t\t\t\t!builtinObjectGetters.has(Function.prototype.toString.call(descriptor.get))\n\t\t\t\t\t\t)\n\t\t\t\t\t\t\tthrow new Error('Unsupported DTO schema accessor')\n\t\t\t\t\t\tconst fields = def.shape\n\t\t\t\t\t\tvisit(fields, depth + 1)\n\t\t\t\t\t\t// A refined clone's getter can return fresh shallow copies.\n\t\t\t\t\t\t// Preserve that caller behavior and compare its fields separately.\n\t\t\t\t\t\tif (Object.getOwnPropertyDescriptor(def, 'shape')?.get)\n\t\t\t\t\t\t\tobjectFields.push({ definition: def, fields })\n\t\t\t\t\t}\n\t\t\t\t\tif (value instanceof z.ZodObject) {\n\t\t\t\t\t\tconst publicFields = Object.getOwnPropertyDescriptor(value, 'shape')\n\t\t\t\t\t\tif (publicFields && !('value' in publicFields))\n\t\t\t\t\t\t\tthrow new Error('Unsupported DTO schema accessor')\n\t\t\t\t\t\tvisit(value.shape, depth + 1)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tvisit(def, depth + 1)\n\t\t\t\t// Track definition replacement, without snapshotting caches initialized by parsing.\n\t\t\t\tnodes.push({\n\t\t\t\t\tobject: value._zod,\n\t\t\t\t\texactKeys: false,\n\t\t\t\t\tkeys: ['def'],\n\t\t\t\t\tvalues: [Object.getOwnPropertyDescriptor(value._zod, 'def')!],\n\t\t\t\t})\n\t\t\t\treturn\n\t\t\t}\n\t\t\tconst keys = Reflect.ownKeys(value)\n\t\t\tconst values = keys.map((key) => Object.getOwnPropertyDescriptor(value, key)!)\n\t\t\tif (\n\t\t\t\tvalues.some(\n\t\t\t\t\t(property, i) =>\n\t\t\t\t\t\t!('value' in property) &&\n\t\t\t\t\t\t!objectFields.some(({ definition }) => definition === value && keys[i] === 'shape') &&\n\t\t\t\t\t\t!(fallbackDefinitions.has(value) && keys[i] === 'defaultValue'),\n\t\t\t\t)\n\t\t\t)\n\t\t\t\tthrow new Error('Unsupported DTO schema accessor')\n\t\t\tnodes.push({ object: value, exactKeys: true, keys, values })\n\t\t\tfor (const property of values) {\n\t\t\t\tif (\n\t\t\t\t\tproperty.value !== null &&\n\t\t\t\t\tObject(property.value) === property.value &&\n\t\t\t\t\t!(property.value instanceof Function)\n\t\t\t\t)\n\t\t\t\t\tvisit(property.value, depth + 1)\n\t\t\t}\n\t\t} finally {\n\t\t\tactive.delete(value)\n\t\t}\n\t}\n\tvisit(dto, 0)\n\treturn () => {\n\t\tfor (const pattern of patterns)\n\t\t\tif (\n\t\t\t\tpattern.expression.source !== pattern.source ||\n\t\t\t\tpattern.expression.flags !== pattern.flags\n\t\t\t)\n\t\t\t\tthrow new Error('DTO schema mutated after registry construction')\n\t\tfor (const node of nodes) {\n\t\t\tconst keys = node.keys\n\t\t\tif (node.exactKeys && Reflect.ownKeys(node.object).length !== keys.length)\n\t\t\t\tthrow new Error('DTO schema mutated after registry construction')\n\t\t\tfor (let i = 0; i < keys.length; i++) {\n\t\t\t\t// Regex checks may update lastIndex while parsing; pattern identity is checked above.\n\t\t\t\tif (node.object instanceof RegExp && keys[i] === 'lastIndex') continue\n\t\t\t\tconst current = Object.getOwnPropertyDescriptor(node.object, keys[i])\n\t\t\t\tconst before = node.values[i]\n\t\t\t\tif (\n\t\t\t\t\t!current ||\n\t\t\t\t\tcurrent.value !== before.value ||\n\t\t\t\t\tcurrent.get !== before.get ||\n\t\t\t\t\tcurrent.set !== before.set ||\n\t\t\t\t\tcurrent.enumerable !== before.enumerable\n\t\t\t\t)\n\t\t\t\t\tthrow new Error('DTO schema mutated after registry construction')\n\t\t\t}\n\t\t}\n\t\tfor (const { definition, fields } of objectFields) {\n\t\t\tconst current = definition.shape\n\t\t\tconst keys = Reflect.ownKeys(fields)\n\t\t\tif (\n\t\t\t\tReflect.ownKeys(current).length !== keys.length ||\n\t\t\t\tkeys.some(\n\t\t\t\t\t(key) =>\n\t\t\t\t\t\tObject.getOwnPropertyDescriptor(current, key)?.value !==\n\t\t\t\t\t\tObject.getOwnPropertyDescriptor(fields, key)?.value,\n\t\t\t\t)\n\t\t\t)\n\t\t\t\tthrow new Error('DTO schema mutated after registry construction')\n\t\t}\n\t}\n}\n\nfunction assertRegistryUnchanged(registry: RegistryMetadata): void {\n\tfor (const table of Object.values(registry.metadata)) table.assertUnchanged()\n}\n\ninterface GuardedDtoDefinition extends z.core.$ZodObjectDef {\n\tassertUnchanged(): void\n}\nconst GuardedDtoObject = z.core.$constructor<z.ZodObject>('GuardedDtoObject', (inst, def) => {\n\t// SAFETY: only guardedDto creates this definition; Zod clones retain its guard.\n\tconst guarded = def as GuardedDtoDefinition\n\tz.ZodObject.init(inst, def)\n\t// Run after Zod's own deferred initializers, including its memoizer wrapper.\n\t// Guarding parse alone is too late for first-run schema introspection.\n\tinst._zod.deferred ??= []\n\tinst._zod.deferred.push(() => {\n\t\tconst run = inst._zod.run\n\t\tinst._zod.run = (payload, ctx) => {\n\t\t\ttry {\n\t\t\t\tguarded.assertUnchanged()\n\t\t\t} catch {\n\t\t\t\tpayload.issues.push({\n\t\t\t\t\tcode: 'custom',\n\t\t\t\t\tinput: payload.value,\n\t\t\t\t\tmessage: 'DTO schema mutated after registry construction',\n\t\t\t\t})\n\t\t\t\treturn payload\n\t\t\t}\n\t\t\treturn run(payload, ctx)\n\t\t}\n\t})\n})\nfunction guardedDto(dto: z.ZodObject, assertUnchanged: () => void): z.ZodObject {\n\tconst outputFields = dto.shape\n\tconst def: GuardedDtoDefinition = { ...dto._zod.def, assertUnchanged }\n\tObject.defineProperty(def, 'shape', {\n\t\tenumerable: true,\n\t\tconfigurable: true,\n\t\tget: () => {\n\t\t\tassertUnchanged()\n\t\t\treturn outputFields\n\t\t},\n\t})\n\treturn new GuardedDtoObject(def)\n}\n\nfunction snapshotMetadata(registry: RegistryMetadata): RelationMetadata {\n\tconst tables: Record<string, RelationTableMetadata> = {}\n\tfor (const [name, data] of Object.entries(registry.metadata)) {\n\t\tconst fields: Record<string, RelationFieldMetadata> = {}\n\t\tfor (const [field, validator] of Object.entries(data.fields))\n\t\t\tfields[field] = Object.freeze({\n\t\t\t\tkind: validator.kind,\n\t\t\t\toptional: validator.isOptional === 'optional',\n\t\t\t\tnullable: hasNull(validator),\n\t\t\t\tidTables: Object.freeze(idTables(validator)),\n\t\t\t\tnative: frozenNative(nativeJson(validator)),\n\t\t\t})\n\t\ttables[name] = Object.freeze({\n\t\t\tfields: Object.freeze(fields),\n\t\t\tindexes: Object.freeze(\n\t\t\t\tdata.indexes.map((index) =>\n\t\t\t\t\tObject.freeze({ name: index.name, fields: Object.freeze([...index.fields]) }),\n\t\t\t\t),\n\t\t\t),\n\t\t})\n\t}\n\treturn Object.freeze({ tables: Object.freeze(tables), declarations: registry.declarations })\n}\nfunction hasNull(validator: GenericValidator): boolean {\n\treturn (\n\t\tvalidator.kind === 'null' || (validator.kind === 'union' && validator.members.some(hasNull))\n\t)\n}\nfunction idTables(validator: GenericValidator): string[] {\n\treturn validator.kind === 'id'\n\t\t? [validator.tableName]\n\t\t: validator.kind === 'union'\n\t\t\t? [...new Set(validator.members.flatMap(idTables))].sort()\n\t\t\t: []\n}\nfunction frozenNative(native: ValidatorJSON): Readonly<ValidatorJSON> {\n\tconst snapshot = structuredClone(native)\n\tconst pending: JSONValue[] = [snapshot]\n\twhile (pending.length) {\n\t\tconst next = pending.pop()!\n\t\tif (Object(next) !== next) continue\n\t\t// SAFETY: native JSON metadata contains ordinary arrays/objects; the boxing test excludes primitives.\n\t\tconst container = next as JSONValue[] | { [key: string]: JSONValue }\n\t\tObject.freeze(container)\n\t\tpending.push(...Object.values(container))\n\t}\n\treturn snapshot\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { ConvexValidatorFromZod } from "convex-helpers/server/zod4";
|
|
2
|
+
import { z } from "zod";
|
|
3
|
+
//#region src/zod-convex.d.ts
|
|
4
|
+
/** Convert Zod inputs with the helper's grammar and native ID registry.
|
|
5
|
+
* Repeated filter containers share completed native validators within this call.
|
|
6
|
+
* Other schemas retain the helper's conversion behavior, including its errors.
|
|
7
|
+
*/
|
|
8
|
+
export declare function zodToConvex<Z extends z.core.$ZodType>(schema: Z): ConvexValidatorFromZod<Z, 'required'>;
|
|
9
|
+
//#endregion
|
|
10
|
+
//# sourceMappingURL=zod-convex.d.mts.map
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{zodToConvex as e}from"convex-helpers/server/zod4";import{z as t}from"zod";import{v as n}from"convex/values";import{vRequired as r}from"convex-helpers/validators";function i(i){let a=/* @__PURE__ */ new WeakMap,o=/* @__PURE__ */ new WeakSet;function s(i){if(o.has(i))throw Error(`CYCLIC_FILTER_SCHEMA`);let c=a.get(i);if(c)return c;o.add(i);try{let o;if(i instanceof t.core.$ZodObject)o=n.object(Object.fromEntries(Object.entries(i._zod.def.shape).map(([e,t])=>[e,s(t)])));else if(i instanceof t.core.$ZodArray){let e=s(i._zod.def.element);if(e.isOptional===`optional`)throw Error(`Arrays of optional values are not supported`);o=n.array(e)}else if(i instanceof t.core.$ZodUnion)o=n.union(...i._zod.def.options.map(s));else if(i instanceof t.core.$ZodOptional)o=n.optional(s(i._zod.def.innerType));else if(i instanceof t.core.$ZodNonOptional)o=r(s(i._zod.def.innerType));else if(i instanceof t.core.$ZodNullable){let e=s(i._zod.def.innerType);o=e.isOptional===`optional`?n.optional(n.union(r(e),n.null())):n.union(e,n.null())}else return e(i);return a.set(i,o),o}finally{o.delete(i)}}return s(i)}export{i as zodToConvex};
|
|
2
|
+
//# sourceMappingURL=zod-convex.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"zod-convex.mjs","names":["helperZodToConvex","zodToConvex$1","zodToConvex","completed","ancestors","convert","node","cached","result","z","v","key","child","inner","vRequired","schema"],"sources":["../src/zod-convex.ts"],"sourcesContent":["import {\n\tzodToConvex as helperZodToConvex,\n\ttype ConvexValidatorFromZod,\n} from 'convex-helpers/server/zod4'\nimport { vRequired } from 'convex-helpers/validators'\nimport { v, type GenericValidator } from 'convex/values'\nimport { z } from 'zod'\n\n/** Convert Zod inputs with the helper's grammar and native ID registry.\n * Repeated filter containers share completed native validators within this call.\n * Other schemas retain the helper's conversion behavior, including its errors.\n */\nexport function zodToConvex<Z extends z.core.$ZodType>(\n\tschema: Z,\n): ConvexValidatorFromZod<Z, 'required'> {\n\tconst completed = new WeakMap<z.core.$ZodType, GenericValidator>()\n\tconst ancestors = new WeakSet<z.core.$ZodType>()\n\n\tfunction convert(node: z.core.$ZodType): GenericValidator {\n\t\tif (ancestors.has(node)) throw new Error('CYCLIC_FILTER_SCHEMA')\n\t\tconst cached = completed.get(node)\n\t\tif (cached) return cached\n\t\tancestors.add(node)\n\t\ttry {\n\t\t\tlet result: GenericValidator\n\t\t\t// Public core definitions work for both standard Zod and Zod Mini.\n\t\t\tif (node instanceof z.core.$ZodObject) {\n\t\t\t\tresult = v.object(\n\t\t\t\t\tObject.fromEntries(\n\t\t\t\t\t\tObject.entries(node._zod.def.shape).map(([key, child]) => [key, convert(child)]),\n\t\t\t\t\t),\n\t\t\t\t)\n\t\t\t} else if (node instanceof z.core.$ZodArray) {\n\t\t\t\tconst inner = convert(node._zod.def.element)\n\t\t\t\tif (inner.isOptional === 'optional') {\n\t\t\t\t\tthrow new Error('Arrays of optional values are not supported')\n\t\t\t\t}\n\t\t\t\tresult = v.array(inner)\n\t\t\t} else if (node instanceof z.core.$ZodUnion) {\n\t\t\t\tresult = v.union(...node._zod.def.options.map(convert))\n\t\t\t} else if (node instanceof z.core.$ZodOptional) {\n\t\t\t\tresult = v.optional(convert(node._zod.def.innerType))\n\t\t\t} else if (node instanceof z.core.$ZodNonOptional) {\n\t\t\t\tresult = vRequired(convert(node._zod.def.innerType))\n\t\t\t} else if (node instanceof z.core.$ZodNullable) {\n\t\t\t\tconst inner = convert(node._zod.def.innerType)\n\t\t\t\tresult =\n\t\t\t\t\tinner.isOptional === 'optional'\n\t\t\t\t\t\t? v.optional(v.union(vRequired(inner), v.null()))\n\t\t\t\t\t\t: v.union(inner, v.null())\n\t\t\t} else {\n\t\t\t\t// Keep arbitrary non-filter schemas and native IDs helper-owned.\n\t\t\t\treturn helperZodToConvex(node)\n\t\t\t}\n\t\t\t// Never publish a partial validator; ancestor cycles fail before reuse.\n\t\t\tcompleted.set(node, result)\n\t\t\treturn result\n\t\t} finally {\n\t\t\tancestors.delete(node)\n\t\t}\n\t}\n\t// SAFETY: handled containers mirror helper conversion; all other nodes delegate\n\t// to that helper, retaining its original input-side validator type relationship.\n\treturn convert(schema) as ConvexValidatorFromZod<Z, 'required'>\n}\n"],"mappings":"yKAYA,SAAgBE,EACf,EACwC,CACxC,IAAMC,kBAAY,IAAI,QAChBC,kBAAY,IAAI,QAEtB,SAASC,EAAQ,EAAyC,CACzD,GAAID,EAAU,IAAIE,CAAI,EAAG,MAAU,MAAM,sBAAsB,EAC/D,IAAMC,EAASJ,EAAU,IAAIG,CAAI,EACjC,GAAIC,EAAQ,OAAOA,EACnBH,EAAU,IAAIE,CAAI,EAClB,GAAI,CACH,IAAIE,EAEJ,GAAIF,aAAgBG,EAAE,KAAK,WAC1B,EAASC,EAAE,OACV,OAAO,YACN,OAAO,QAAQJ,EAAK,KAAK,IAAI,KAAK,CAAC,CAAC,KAAK,CAACK,EAAKC,KAAW,CAACD,EAAKN,EAAQO,CAAK,CAAC,CAAC,CAChF,CACD,OACM,GAAIN,aAAgBG,EAAE,KAAK,UAAW,CAC5C,IAAMI,EAAQR,EAAQC,EAAK,KAAK,IAAI,OAAO,EAC3C,GAAIO,EAAM,aAAe,WACxB,MAAU,MAAM,6CAA6C,EAE9D,EAASH,EAAE,MAAMG,CAAK,CACvB,MAAO,GAAIP,aAAgBG,EAAE,KAAK,UACjC,EAASC,EAAE,MAAM,GAAGJ,EAAK,KAAK,IAAI,QAAQ,IAAID,CAAO,CAAC,OAChD,GAAIC,aAAgBG,EAAE,KAAK,aACjC,EAASC,EAAE,SAASL,EAAQC,EAAK,KAAK,IAAI,SAAS,CAAC,OAC9C,GAAIA,aAAgBG,EAAE,KAAK,gBACjC,EAASK,EAAUT,EAAQC,EAAK,KAAK,IAAI,SAAS,CAAC,OAC7C,GAAIA,aAAgBG,EAAE,KAAK,aAAc,CAC/C,IAAMI,EAAQR,EAAQC,EAAK,KAAK,IAAI,SAAS,EAC7C,EACCO,EAAM,aAAe,WAClBH,EAAE,SAASA,EAAE,MAAMI,EAAUD,CAAK,EAAGH,EAAE,KAAK,CAAC,CAAC,EAC9CA,EAAE,MAAMG,EAAOH,EAAE,KAAK,CAAC,CAC5B,MAEC,OAAOV,EAAkBM,CAAI,EAI9B,OADAH,EAAU,IAAIG,EAAME,CAAM,EACnBA,CACR,QAAU,CACTJ,EAAU,OAAOE,CAAI,CACtB,CACD,CAGA,OAAOD,EAAQU,CAAM,CACtB"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { CustomBuilder } from "convex-helpers/server/zod4";
|
|
2
|
+
import { ActionBuilder, FunctionVisibility, GenericActionCtx, GenericDataModel, GenericMutationCtx, GenericQueryCtx, MutationBuilder, QueryBuilder } from "convex/server";
|
|
3
|
+
import { PropertyValidators } from "convex/values";
|
|
4
|
+
import { Customization } from "convex-helpers/server/customFunctions";
|
|
5
|
+
//#region src/zod-registration.d.ts
|
|
6
|
+
export declare function zCustomQuery<CustomArgsValidator extends PropertyValidators, CustomCtx extends Record<string, any>, CustomMadeArgs extends Record<string, any>, Visibility extends FunctionVisibility, DataModel extends GenericDataModel, ExtraArgs extends Record<string, any> = object>(query: QueryBuilder<DataModel, Visibility>, customization: Customization<GenericQueryCtx<DataModel>, CustomArgsValidator, CustomCtx, CustomMadeArgs, ExtraArgs>): CustomBuilder<'query', CustomArgsValidator, CustomCtx, CustomMadeArgs, GenericQueryCtx<DataModel>, Visibility, ExtraArgs>;
|
|
7
|
+
export declare function zCustomMutation<CustomArgsValidator extends PropertyValidators, CustomCtx extends Record<string, any>, CustomMadeArgs extends Record<string, any>, Visibility extends FunctionVisibility, DataModel extends GenericDataModel, ExtraArgs extends Record<string, any> = object>(mutation: MutationBuilder<DataModel, Visibility>, customization: Customization<GenericMutationCtx<DataModel>, CustomArgsValidator, CustomCtx, CustomMadeArgs, ExtraArgs>): CustomBuilder<'mutation', CustomArgsValidator, CustomCtx, CustomMadeArgs, GenericMutationCtx<DataModel>, Visibility, ExtraArgs>;
|
|
8
|
+
export declare function zCustomAction<CustomArgsValidator extends PropertyValidators, CustomCtx extends Record<string, any>, CustomMadeArgs extends Record<string, any>, Visibility extends FunctionVisibility, DataModel extends GenericDataModel, ExtraArgs extends Record<string, any> = object>(action: ActionBuilder<DataModel, Visibility>, customization: Customization<GenericActionCtx<DataModel>, CustomArgsValidator, CustomCtx, CustomMadeArgs, ExtraArgs>): CustomBuilder<'action', CustomArgsValidator, CustomCtx, CustomMadeArgs, GenericActionCtx<DataModel>, Visibility, ExtraArgs>;
|
|
9
|
+
//#endregion
|
|
10
|
+
//# sourceMappingURL=zod-registration.d.mts.map
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{zodToConvex as e}from"./zod-convex.mjs";import{zodOutputToConvex as t}from"convex-helpers/server/zod4";import{ConvexError as n}from"convex/values";import{pick as r}from"convex-helpers";import{NoOp as i}from"convex-helpers/server/customFunctions";import{addFieldsToValidator as a}from"convex-helpers/validators";import*as o from"zod/v4";import*as s from"zod/v4/core";function c(e,t){return d(e,t)}function l(e,t){return d(e,t)}function u(e,t){return d(e,t)}function d(c,l){let u=l.input??i.input,d=l.args??i.args;return function(i){let{args:l,handler:f=i,skipConvexValidation:p=!1,returns:m,...h}=i,g=m&&!(m instanceof s.$ZodType)?o.object(m):m,_=g&&!p?{returns:t(g)}:null;if(l){let t=l;if(t instanceof s.$ZodType){if(t instanceof s.$ZodObject)t=t._zod.def.shape;else throw Error(`Unsupported zod type as args validator: `+t.constructor.name)}let i=e(o.object(t));return c({args:p?void 0:a(i,d),..._,handler:async(e,i)=>{let a=await u(e,r(i,Object.keys(d)),h),s=r(i,Object.keys(t)),c=await o.object(t).safeParseAsync(s);if(!c.success)throw new n({ZodError:JSON.parse(JSON.stringify(c.error.issues,null,2))});let l=c.data,p={...e,...a.ctx},m={...l,...a.args},_=await f(p,m),v=g?await g.parseAsync(_===void 0?null:_):_;return a.onSuccess&&await a.onSuccess({ctx:e,args:l,result:v}),v}})}if(p&&Object.keys(d).length>0)throw Error(`If you're using a custom function with arguments for the input customization, you cannot skip convex validation.`);return c({..._,handler:async(e,t)=>{let n=await u(e,t,h),r={...e,...n.ctx},i={...t,...n.args},a=await f(r,i),o=g?await g.parseAsync(a===void 0?null:a):a;return n.onSuccess&&await n.onSuccess({ctx:e,args:t,result:o}),o}})}}export{u as zCustomAction,l as zCustomMutation,c as zCustomQuery};
|
|
2
|
+
//# sourceMappingURL=zod-registration.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"zod-registration.mjs","names":["zodToConvex","zodToConvex$1","z","zCore","zCustomQuery","customFnBuilder","query","customization","zCustomMutation","mutation","zCustomAction","action","customInput","NoOp","inputArgs","fn","maybeObject","extra","returns","returnValidator","skipConvexValidation","zodOutputToConvex","args","argsValidator","convexValidator","builder","addFieldsToValidator","added","ctx","pick","allArgs","rawArgs","parsed","ConvexError","finalCtx","finalArgs","ret","handler","result"],"sources":["../src/zod-registration.ts"],"sourcesContent":["// Internal auth registration seam. Public wrapper contracts match convex-helpers zod4.\n// Keep the installed helper's registration branches; only argument conversion differs.\nimport { pick } from 'convex-helpers'\nimport { NoOp, type Customization } from 'convex-helpers/server/customFunctions'\nimport { zodOutputToConvex, type CustomBuilder } from 'convex-helpers/server/zod4'\nimport { addFieldsToValidator } from 'convex-helpers/validators'\nimport type {\n\tActionBuilder,\n\tFunctionVisibility,\n\tGenericActionCtx,\n\tGenericDataModel,\n\tGenericMutationCtx,\n\tGenericQueryCtx,\n\tMutationBuilder,\n\tQueryBuilder,\n} from 'convex/server'\nimport { ConvexError, type PropertyValidators, type Value } from 'convex/values'\nimport * as z from 'zod/v4'\nimport * as zCore from 'zod/v4/core'\nimport { zodToConvex } from './zod-convex'\n\nexport function zCustomQuery<\n\tCustomArgsValidator extends PropertyValidators,\n\tCustomCtx extends Record<string, any>,\n\tCustomMadeArgs extends Record<string, any>,\n\tVisibility extends FunctionVisibility,\n\tDataModel extends GenericDataModel,\n\tExtraArgs extends Record<string, any> = object,\n>(\n\tquery: QueryBuilder<DataModel, Visibility>,\n\tcustomization: Customization<\n\t\tGenericQueryCtx<DataModel>,\n\t\tCustomArgsValidator,\n\t\tCustomCtx,\n\t\tCustomMadeArgs,\n\t\tExtraArgs\n\t>,\n) {\n\t// SAFETY: the private adapter preserves helper registration semantics; this is\n\t// the same generic boundary assertion used by the public helper wrappers.\n\treturn customFnBuilder(query, customization) as CustomBuilder<\n\t\t'query',\n\t\tCustomArgsValidator,\n\t\tCustomCtx,\n\t\tCustomMadeArgs,\n\t\tGenericQueryCtx<DataModel>,\n\t\tVisibility,\n\t\tExtraArgs\n\t>\n}\n\nexport function zCustomMutation<\n\tCustomArgsValidator extends PropertyValidators,\n\tCustomCtx extends Record<string, any>,\n\tCustomMadeArgs extends Record<string, any>,\n\tVisibility extends FunctionVisibility,\n\tDataModel extends GenericDataModel,\n\tExtraArgs extends Record<string, any> = object,\n>(\n\tmutation: MutationBuilder<DataModel, Visibility>,\n\tcustomization: Customization<\n\t\tGenericMutationCtx<DataModel>,\n\t\tCustomArgsValidator,\n\t\tCustomCtx,\n\t\tCustomMadeArgs,\n\t\tExtraArgs\n\t>,\n) {\n\t// SAFETY: the private adapter preserves helper registration semantics; this is\n\t// the same generic boundary assertion used by the public helper wrappers.\n\treturn customFnBuilder(mutation, customization) as CustomBuilder<\n\t\t'mutation',\n\t\tCustomArgsValidator,\n\t\tCustomCtx,\n\t\tCustomMadeArgs,\n\t\tGenericMutationCtx<DataModel>,\n\t\tVisibility,\n\t\tExtraArgs\n\t>\n}\n\nexport function zCustomAction<\n\tCustomArgsValidator extends PropertyValidators,\n\tCustomCtx extends Record<string, any>,\n\tCustomMadeArgs extends Record<string, any>,\n\tVisibility extends FunctionVisibility,\n\tDataModel extends GenericDataModel,\n\tExtraArgs extends Record<string, any> = object,\n>(\n\taction: ActionBuilder<DataModel, Visibility>,\n\tcustomization: Customization<\n\t\tGenericActionCtx<DataModel>,\n\t\tCustomArgsValidator,\n\t\tCustomCtx,\n\t\tCustomMadeArgs,\n\t\tExtraArgs\n\t>,\n) {\n\t// SAFETY: the private adapter preserves helper registration semantics; this is\n\t// the same generic boundary assertion used by the public helper wrappers.\n\treturn customFnBuilder(action, customization) as CustomBuilder<\n\t\t'action',\n\t\tCustomArgsValidator,\n\t\tCustomCtx,\n\t\tCustomMadeArgs,\n\t\tGenericActionCtx<DataModel>,\n\t\tVisibility,\n\t\tExtraArgs\n\t>\n}\n\nfunction customFnBuilder(\n\tbuilder: (args: any) => any,\n\tcustomization: Customization<any, any, any, any, any>,\n) {\n\t// Looking forward to when input / args / ... are optional\n\tconst customInput: Customization<any, any, any, any, any>['input'] =\n\t\tcustomization.input ?? NoOp.input\n\tconst inputArgs = customization.args ?? NoOp.args\n\treturn function customBuilder(fn: any): any {\n\t\tconst { args, handler = fn, skipConvexValidation = false, returns: maybeObject, ...extra } = fn\n\n\t\tconst returns =\n\t\t\tmaybeObject && !(maybeObject instanceof zCore.$ZodType) ? z.object(maybeObject) : maybeObject\n\n\t\tconst returnValidator =\n\t\t\treturns && !skipConvexValidation ? { returns: zodOutputToConvex(returns) } : null\n\n\t\tif (args) {\n\t\t\tlet argsValidator = args\n\t\t\tif (argsValidator instanceof zCore.$ZodType) {\n\t\t\t\tif (argsValidator instanceof zCore.$ZodObject) {\n\t\t\t\t\targsValidator = argsValidator._zod.def.shape\n\t\t\t\t} else {\n\t\t\t\t\tthrow new Error(\n\t\t\t\t\t\t'Unsupported zod type as args validator: ' + argsValidator.constructor.name,\n\t\t\t\t\t)\n\t\t\t\t}\n\t\t\t}\n\t\t\t// One conversion preserves graph sharing across all user argument fields.\n\t\t\tconst convexValidator = zodToConvex(z.object(argsValidator))\n\t\t\treturn builder({\n\t\t\t\targs: skipConvexValidation ? undefined : addFieldsToValidator(convexValidator, inputArgs),\n\t\t\t\t...returnValidator,\n\t\t\t\thandler: async (ctx: any, allArgs: any) => {\n\t\t\t\t\tconst added = await customInput(ctx, pick(allArgs, Object.keys(inputArgs)), extra)\n\t\t\t\t\tconst rawArgs = pick(allArgs, Object.keys(argsValidator))\n\t\t\t\t\tconst parsed = await z.object(argsValidator).safeParseAsync(rawArgs)\n\t\t\t\t\tif (!parsed.success) {\n\t\t\t\t\t\tthrow new ConvexError({\n\t\t\t\t\t\t\t// SAFETY: serialized Zod issues are the helper's existing Convex Value[] error payload.\n\t\t\t\t\t\t\tZodError: JSON.parse(JSON.stringify(parsed.error.issues, null, 2)) as Value[],\n\t\t\t\t\t\t})\n\t\t\t\t\t}\n\t\t\t\t\tconst args = parsed.data\n\t\t\t\t\tconst finalCtx = { ...ctx, ...added.ctx }\n\t\t\t\t\tconst finalArgs = { ...args, ...added.args }\n\t\t\t\t\tconst ret = await handler(finalCtx, finalArgs)\n\t\t\t\t\t// We don't catch the error here. It's a developer error and we\n\t\t\t\t\t// don't want to risk exposing the unexpected value to the client.\n\t\t\t\t\tconst result = returns ? await returns.parseAsync(ret === undefined ? null : ret) : ret\n\t\t\t\t\tif (added.onSuccess) {\n\t\t\t\t\t\tawait added.onSuccess({ ctx, args, result })\n\t\t\t\t\t}\n\t\t\t\t\treturn result\n\t\t\t\t},\n\t\t\t})\n\t\t}\n\t\tif (skipConvexValidation && Object.keys(inputArgs).length > 0) {\n\t\t\tthrow new Error(\n\t\t\t\t\"If you're using a custom function with arguments for the input \" +\n\t\t\t\t\t'customization, you cannot skip convex validation.',\n\t\t\t)\n\t\t}\n\t\treturn builder({\n\t\t\t...returnValidator,\n\t\t\thandler: async (ctx: any, args: any) => {\n\t\t\t\tconst added = await customInput(ctx, args, extra)\n\t\t\t\tconst finalCtx = { ...ctx, ...added.ctx }\n\t\t\t\tconst finalArgs = { ...args, ...added.args }\n\t\t\t\tconst ret = await handler(finalCtx, finalArgs)\n\t\t\t\t// We don't catch the error here. It's a developer error and we\n\t\t\t\t// don't want to risk exposing the unexpected value to the client.\n\t\t\t\tconst result = returns ? await returns.parseAsync(ret === undefined ? null : ret) : ret\n\t\t\t\tif (added.onSuccess) {\n\t\t\t\t\tawait added.onSuccess({ ctx, args, result })\n\t\t\t\t}\n\t\t\t\treturn result\n\t\t\t},\n\t\t})\n\t}\n}\n"],"mappings":"qXAqBA,SAAgBI,EAQf,EACA,EAOC,CAGD,OAAOC,EAAgBC,EAAOC,CAAa,CAS5C,CAEA,SAAgBC,EAQf,EACA,EAOC,CAGD,OAAOH,EAAgBI,EAAUF,CAAa,CAS/C,CAEA,SAAgBG,EAQf,EACA,EAOC,CAGD,OAAOL,EAAgBM,EAAQJ,CAAa,CAS7C,CAEA,SAASF,EACR,EACA,EACC,CAED,IAAMO,EACLL,EAAc,OAASM,EAAK,MACvBC,EAAYP,EAAc,MAAQM,EAAK,KAC7C,OAAO,SAAuB,EAAc,CAC3C,GAAM,CAAE,OAAM,UAAUE,EAAI,uBAAuB,GAAO,QAASC,EAAa,GAAGC,GAAUF,EAEvFG,EACLF,GAAe,EAAEA,aAAuBb,EAAM,UAAYD,EAAE,OAAOc,CAAW,EAAIA,EAE7EG,EACLD,GAAW,CAACE,EAAuB,CAAE,QAASC,EAAkBH,CAAO,CAAE,EAAI,KAE9E,GAAII,EAAM,CACT,IAAIC,EAAgBD,EACpB,GAAIC,aAAyBpB,EAAM,SAAU,CAC5C,GAAIoB,aAAyBpB,EAAM,WAClC,EAAgBoB,EAAc,KAAK,IAAI,WAEvC,MAAU,MACT,2CAA6CA,EAAc,YAAY,IACxE,CAEF,CAEA,IAAMC,EAAkBxB,EAAYE,EAAE,OAAOqB,CAAa,CAAC,EAC3D,OAAOE,EAAQ,CACd,KAAML,EAAuB,IAAA,GAAYM,EAAqBF,EAAiBV,CAAS,EACxF,GAAGK,EACH,QAAS,MAAO,EAAU,IAAiB,CAC1C,IAAMQ,EAAQ,MAAMf,EAAYgB,EAAKC,EAAKC,EAAS,OAAO,KAAKhB,CAAS,CAAC,EAAGG,CAAK,EAC3Ec,EAAUF,EAAKC,EAAS,OAAO,KAAKP,CAAa,CAAC,EAClDS,EAAS,MAAM9B,EAAE,OAAOqB,CAAa,CAAC,CAAC,eAAeQ,CAAO,EACnE,GAAI,CAACC,EAAO,QACX,MAAM,IAAIC,EAAY,CAErB,SAAU,KAAK,MAAM,KAAK,UAAUD,EAAO,MAAM,OAAQ,KAAM,CAAC,CAAC,CAClE,CAAC,EAEF,IAAMV,EAAOU,EAAO,KACdE,EAAW,CAAE,GAAGN,EAAK,GAAGD,EAAM,GAAI,EAClCQ,EAAY,CAAE,GAAGb,EAAM,GAAGK,EAAM,IAAK,EACrCS,EAAM,MAAMC,EAAQH,EAAUC,CAAS,EAGvCG,EAASpB,EAAU,MAAMA,EAAQ,WAAWkB,IAAQ,IAAA,GAAY,KAAOA,CAAG,EAAIA,EAIpF,OAHIT,EAAM,WACT,MAAMA,EAAM,UAAU,CAAE,MAAK,OAAM,QAAO,CAAC,EAErCW,CACR,CACD,CAAC,CACF,CACA,GAAIlB,GAAwB,OAAO,KAAKN,CAAS,CAAC,CAAC,OAAS,EAC3D,MAAU,MACT,kHAED,EAED,OAAOW,EAAQ,CACd,GAAGN,EACH,QAAS,MAAO,EAAU,IAAc,CACvC,IAAMQ,EAAQ,MAAMf,EAAYgB,EAAKN,EAAML,CAAK,EAC1CiB,EAAW,CAAE,GAAGN,EAAK,GAAGD,EAAM,GAAI,EAClCQ,EAAY,CAAE,GAAGb,EAAM,GAAGK,EAAM,IAAK,EACrCS,EAAM,MAAMC,EAAQH,EAAUC,CAAS,EAGvCG,EAASpB,EAAU,MAAMA,EAAQ,WAAWkB,IAAQ,IAAA,GAAY,KAAOA,CAAG,EAAIA,EAIpF,OAHIT,EAAM,WACT,MAAMA,EAAM,UAAU,CAAE,MAAK,OAAM,QAAO,CAAC,EAErCW,CACR,CACD,CAAC,CACF,CACD"}
|