@prisma-next/sql-contract-ts 0.3.0-dev.8 → 0.3.0-pr.49.6

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/README.md CHANGED
@@ -10,7 +10,7 @@ This package contains the SQL-specific TypeScript contract authoring surface for
10
10
  - **Layer**: authoring
11
11
  - **Plane**: migration
12
12
 
13
- **Note**: SQL authoring may depend on SQL targets layer (e.g., `@prisma-next/sql-contract-types`) within the same domain.
13
+ **Note**: SQL authoring may depend on SQL core layer (e.g., `@prisma-next/sql-contract/types`) within the same domain.
14
14
 
15
15
  ## Overview
16
16
 
@@ -65,12 +65,34 @@ const contract = defineContract<CodecTypes>()
65
65
  t
66
66
  .column('id', { type: int4Column, nullable: false })
67
67
  .column('email', { type: textColumn, nullable: false })
68
- .primaryKey(['id']),
68
+ .primaryKey(['id'], 'user_pkey') // Named primary key
69
+ .unique(['email'], 'user_email_unique') // Named unique constraint
70
+ .index(['email'], 'user_email_idx'), // Named index
71
+ )
72
+ .table('post', (t) =>
73
+ t
74
+ .column('id', { type: int4Column, nullable: false })
75
+ .column('userId', { type: int4Column, nullable: false })
76
+ .column('title', { type: textColumn, nullable: false })
77
+ .primaryKey(['id'])
78
+ .foreignKey(['userId'], { table: 'user', columns: ['id'] }, 'post_userId_fkey'), // Named FK
69
79
  )
70
80
  .model('User', 'user', (m) => m.field('id', 'id').field('email', 'email'))
81
+ .model('Post', 'post', (m) => m.field('id', 'id').field('userId', 'userId').field('title', 'title'))
71
82
  .build();
72
83
  ```
73
84
 
85
+ #### Table Builder Methods
86
+
87
+ The table builder supports the following constraint methods:
88
+
89
+ | Method | Description |
90
+ |--------|-------------|
91
+ | `.primaryKey(columns, name?)` | Define primary key with optional name |
92
+ | `.unique(columns, name?)` | Add unique constraint with optional name |
93
+ | `.index(columns, name?)` | Add index with optional name |
94
+ | `.foreignKey(columns, references, name?)` | Add foreign key with optional name |
95
+
74
96
  ### Validating Contracts
75
97
 
76
98
  ```typescript
@@ -24,12 +24,26 @@ type BuildStorageTable<_TableName extends string, Columns extends Record<string,
24
24
  readonly columns: {
25
25
  readonly [K in keyof Columns]: Columns[K] extends ColumnBuilderState<string, infer Null, infer TType> ? BuildStorageColumn<Null & boolean, TType> : never;
26
26
  };
27
- readonly uniques: ReadonlyArray<never>;
28
- readonly indexes: ReadonlyArray<never>;
29
- readonly foreignKeys: ReadonlyArray<never>;
27
+ readonly uniques: ReadonlyArray<{
28
+ readonly columns: readonly string[];
29
+ readonly name?: string;
30
+ }>;
31
+ readonly indexes: ReadonlyArray<{
32
+ readonly columns: readonly string[];
33
+ readonly name?: string;
34
+ }>;
35
+ readonly foreignKeys: ReadonlyArray<{
36
+ readonly columns: readonly string[];
37
+ readonly references: {
38
+ readonly table: string;
39
+ readonly columns: readonly string[];
40
+ };
41
+ readonly name?: string;
42
+ }>;
30
43
  } & (PK extends readonly string[] ? {
31
44
  readonly primaryKey: {
32
45
  readonly columns: PK;
46
+ readonly name?: string;
33
47
  };
34
48
  } : Record<string, never>);
35
49
  type BuildStorage<Tables extends Record<string, TableBuilderState<string, Record<string, ColumnBuilderState<string, boolean, string>>, readonly string[] | undefined>>> = {
@@ -1 +1 @@
1
- {"version":3,"file":"contract-builder.d.ts","sourceRoot":"","sources":["../src/contract-builder.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"contract-builder.d.ts","sourceRoot":"","sources":["../src/contract-builder.ts"],"names":[],"mappings":"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"}
@@ -5,6 +5,7 @@ import {
5
5
  // src/contract-builder.ts
6
6
  import {
7
7
  ContractBuilder,
8
+ createTable,
8
9
  ModelBuilder,
9
10
  TableBuilder
10
11
  } from "@prisma-next/contract-authoring";
@@ -48,14 +49,28 @@ var SqlContractBuilder = class _SqlContractBuilder extends ContractBuilder {
48
49
  nullable: columnState.nullable ?? false
49
50
  };
50
51
  }
52
+ const uniques = (tableState.uniques ?? []).map((u) => ({
53
+ columns: u.columns,
54
+ ...u.name ? { name: u.name } : {}
55
+ }));
56
+ const indexes = (tableState.indexes ?? []).map((i) => ({
57
+ columns: i.columns,
58
+ ...i.name ? { name: i.name } : {}
59
+ }));
60
+ const foreignKeys = (tableState.foreignKeys ?? []).map((fk) => ({
61
+ columns: fk.columns,
62
+ references: fk.references,
63
+ ...fk.name ? { name: fk.name } : {}
64
+ }));
51
65
  const table = {
52
66
  columns,
53
- uniques: [],
54
- indexes: [],
55
- foreignKeys: [],
67
+ uniques,
68
+ indexes,
69
+ foreignKeys,
56
70
  ...tableState.primaryKey ? {
57
71
  primaryKey: {
58
- columns: tableState.primaryKey
72
+ columns: tableState.primaryKey,
73
+ ...tableState.primaryKeyName ? { name: tableState.primaryKeyName } : {}
59
74
  }
60
75
  } : {}
61
76
  };
@@ -187,7 +202,7 @@ var SqlContractBuilder = class _SqlContractBuilder extends ContractBuilder {
187
202
  });
188
203
  }
189
204
  table(name, callback) {
190
- const tableBuilder = new TableBuilder(name);
205
+ const tableBuilder = createTable(name);
191
206
  const result = callback(tableBuilder);
192
207
  const finalBuilder = result instanceof TableBuilder ? result : tableBuilder;
193
208
  const tableState = finalBuilder.build();
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/contract-builder.ts"],"sourcesContent":["import type { ExtensionPackRef, TargetPackRef } from '@prisma-next/contract/framework-components';\nimport type {\n ColumnBuilderState,\n ModelBuilderState,\n RelationDefinition,\n TableBuilderState,\n} from '@prisma-next/contract-authoring';\nimport {\n type BuildModels,\n type BuildRelations,\n type BuildStorageColumn,\n ContractBuilder,\n type ExtractColumns,\n type ExtractPrimaryKey,\n ModelBuilder,\n type Mutable,\n TableBuilder,\n} from '@prisma-next/contract-authoring';\nimport type {\n ModelDefinition,\n ModelField,\n SqlContract,\n SqlMappings,\n SqlStorage,\n} from '@prisma-next/sql-contract/types';\nimport { computeMappings } from './contract';\n\n/**\n * Type-level mappings structure for contracts built via `defineContract()`.\n *\n * Compile-time type helper (not a runtime object) that ensures mappings match what the builder\n * produces. `codecTypes` uses the generic `CodecTypes` parameter; `operationTypes` is always\n * empty since operations are added via extensions at runtime.\n *\n * **Difference from RuntimeContext**: This is a compile-time type for contract construction.\n * `RuntimeContext` is a runtime object with populated registries for query execution.\n *\n * @template C - The `CodecTypes` generic parameter passed to `defineContract<CodecTypes>()`\n */\ntype ContractBuilderMappings<C extends Record<string, { output: unknown }>> = Omit<\n SqlMappings,\n 'codecTypes' | 'operationTypes'\n> & {\n readonly codecTypes: C;\n readonly operationTypes: Record<string, never>;\n};\n\ntype BuildStorageTable<\n _TableName extends string,\n Columns extends Record<string, ColumnBuilderState<string, boolean, string>>,\n PK extends readonly string[] | undefined,\n> = {\n readonly columns: {\n readonly [K in keyof Columns]: Columns[K] extends ColumnBuilderState<\n string,\n infer Null,\n infer TType\n >\n ? BuildStorageColumn<Null & boolean, TType>\n : never;\n };\n readonly uniques: ReadonlyArray<never>;\n readonly indexes: ReadonlyArray<never>;\n readonly foreignKeys: ReadonlyArray<never>;\n} & (PK extends readonly string[]\n ? { readonly primaryKey: { readonly columns: PK } }\n : Record<string, never>);\n\ntype BuildStorage<\n Tables extends Record<\n string,\n TableBuilderState<\n string,\n Record<string, ColumnBuilderState<string, boolean, string>>,\n readonly string[] | undefined\n >\n >,\n> = {\n readonly tables: {\n readonly [K in keyof Tables]: BuildStorageTable<\n K & string,\n ExtractColumns<Tables[K]>,\n ExtractPrimaryKey<Tables[K]>\n >;\n };\n};\n\ntype BuildStorageTables<\n Tables extends Record<\n string,\n TableBuilderState<\n string,\n Record<string, ColumnBuilderState<string, boolean, string>>,\n readonly string[] | undefined\n >\n >,\n> = {\n readonly [K in keyof Tables]: BuildStorageTable<\n K & string,\n ExtractColumns<Tables[K]>,\n ExtractPrimaryKey<Tables[K]>\n >;\n};\n\nexport interface ColumnBuilder<Name extends string, Nullable extends boolean, Type extends string> {\n nullable<Value extends boolean>(value?: Value): ColumnBuilder<Name, Value, Type>;\n type<Id extends string>(id: Id): ColumnBuilder<Name, Nullable, Id>;\n build(): ColumnBuilderState<Name, Nullable, Type>;\n}\n\nclass SqlContractBuilder<\n CodecTypes extends Record<string, { output: unknown }> = Record<string, never>,\n Target extends string | undefined = undefined,\n Tables extends Record<\n string,\n TableBuilderState<\n string,\n Record<string, ColumnBuilderState<string, boolean, string>>,\n readonly string[] | undefined\n >\n > = Record<never, never>,\n Models extends Record<\n string,\n ModelBuilderState<string, string, Record<string, string>, Record<string, RelationDefinition>>\n > = Record<never, never>,\n CoreHash extends string | undefined = undefined,\n ExtensionPacks extends Record<string, unknown> | undefined = undefined,\n Capabilities extends Record<string, Record<string, boolean>> | undefined = undefined,\n> extends ContractBuilder<Target, Tables, Models, CoreHash, ExtensionPacks, Capabilities> {\n /**\n * This method is responsible for normalizing the contract IR by setting default values\n * for all required fields:\n * - `nullable`: defaults to `false` if not provided\n * - `uniques`: defaults to `[]` (empty array)\n * - `indexes`: defaults to `[]` (empty array)\n * - `foreignKeys`: defaults to `[]` (empty array)\n * - `relations`: defaults to `{}` (empty object) for both model-level and contract-level\n * - `nativeType`: required field set from column type descriptor when columns are defined\n *\n * The contract builder is the **only** place where normalization should occur.\n * Validators, parsers, and emitters should assume the contract is already normalized.\n *\n * **Required**: Use column type descriptors (e.g., `int4Column`, `textColumn`) when defining columns.\n * This ensures `nativeType` is set correctly at build time.\n *\n * @returns A normalized SqlContract with all required fields present\n */\n build(): Target extends string\n ? SqlContract<\n BuildStorage<Tables>,\n BuildModels<Models>,\n BuildRelations<Models>,\n ContractBuilderMappings<CodecTypes>\n > & {\n readonly schemaVersion: '1';\n readonly target: Target;\n readonly targetFamily: 'sql';\n readonly coreHash: CoreHash extends string ? CoreHash : string;\n } & (ExtensionPacks extends Record<string, unknown>\n ? { readonly extensionPacks: ExtensionPacks }\n : Record<string, never>) &\n (Capabilities extends Record<string, Record<string, boolean>>\n ? { readonly capabilities: Capabilities }\n : Record<string, never>)\n : never {\n // Type helper to ensure literal types are preserved in return type\n type BuiltContract = Target extends string\n ? SqlContract<\n BuildStorage<Tables>,\n BuildModels<Models>,\n BuildRelations<Models>,\n ContractBuilderMappings<CodecTypes>\n > & {\n readonly schemaVersion: '1';\n readonly target: Target;\n readonly targetFamily: 'sql';\n readonly coreHash: CoreHash extends string ? CoreHash : string;\n } & (ExtensionPacks extends Record<string, unknown>\n ? { readonly extensionPacks: ExtensionPacks }\n : Record<string, never>) &\n (Capabilities extends Record<string, Record<string, boolean>>\n ? { readonly capabilities: Capabilities }\n : Record<string, never>)\n : never;\n if (!this.state.target) {\n throw new Error('target is required. Call .target() before .build()');\n }\n\n const target = this.state.target as Target & string;\n\n const storageTables = {} as Partial<Mutable<BuildStorageTables<Tables>>>;\n\n for (const tableName of Object.keys(this.state.tables) as Array<keyof Tables & string>) {\n const tableState = this.state.tables[tableName];\n if (!tableState) continue;\n\n type TableKey = typeof tableName;\n type ColumnDefs = ExtractColumns<Tables[TableKey]>;\n type PrimaryKey = ExtractPrimaryKey<Tables[TableKey]>;\n\n const columns = {} as Partial<{\n [K in keyof ColumnDefs]: BuildStorageColumn<\n ColumnDefs[K]['nullable'] & boolean,\n ColumnDefs[K]['type']\n >;\n }>;\n\n for (const columnName in tableState.columns) {\n const columnState = tableState.columns[columnName];\n if (!columnState) continue;\n const codecId = columnState.type;\n const nativeType = columnState.nativeType;\n\n columns[columnName as keyof ColumnDefs] = {\n nativeType,\n codecId,\n nullable: (columnState.nullable ?? false) as ColumnDefs[keyof ColumnDefs]['nullable'] &\n boolean,\n } as BuildStorageColumn<\n ColumnDefs[keyof ColumnDefs]['nullable'] & boolean,\n ColumnDefs[keyof ColumnDefs]['type']\n >;\n }\n\n const table = {\n columns: columns as {\n [K in keyof ColumnDefs]: BuildStorageColumn<\n ColumnDefs[K]['nullable'] & boolean,\n ColumnDefs[K]['type']\n >;\n },\n uniques: [],\n indexes: [],\n foreignKeys: [],\n ...(tableState.primaryKey\n ? {\n primaryKey: {\n columns: tableState.primaryKey,\n },\n }\n : {}),\n } as unknown as BuildStorageTable<TableKey & string, ColumnDefs, PrimaryKey>;\n\n (storageTables as Mutable<BuildStorageTables<Tables>>)[tableName] = table;\n }\n\n const storage = { tables: storageTables as BuildStorageTables<Tables> } as BuildStorage<Tables>;\n\n // Build models - construct as partial first, then assert full type\n const modelsPartial: Partial<BuildModels<Models>> = {};\n\n // Iterate over models - TypeScript will see keys as string, but type assertion preserves literals\n for (const modelName in this.state.models) {\n const modelState = this.state.models[modelName];\n if (!modelState) continue;\n\n const modelStateTyped = modelState as unknown as {\n name: string;\n table: string;\n fields: Record<string, string>;\n };\n\n // Build fields object\n const fields: Partial<Record<string, ModelField>> = {};\n\n // Iterate over fields\n for (const fieldName in modelStateTyped.fields) {\n const columnName = modelStateTyped.fields[fieldName];\n if (columnName) {\n fields[fieldName] = {\n column: columnName,\n };\n }\n }\n\n // Assign to models - type assertion preserves literal keys\n (modelsPartial as unknown as Record<string, ModelDefinition>)[modelName] = {\n storage: {\n table: modelStateTyped.table,\n },\n fields: fields as Record<string, ModelField>,\n relations: {},\n };\n }\n\n // Build relations object - organized by table name\n const relationsPartial: Partial<Record<string, Record<string, RelationDefinition>>> = {};\n\n // Iterate over models to collect relations\n for (const modelName in this.state.models) {\n const modelState = this.state.models[modelName];\n if (!modelState) continue;\n\n const modelStateTyped = modelState as unknown as {\n name: string;\n table: string;\n fields: Record<string, string>;\n relations: Record<string, RelationDefinition>;\n };\n\n const tableName = modelStateTyped.table;\n if (!tableName) continue;\n\n // Only initialize relations object for this table if it has relations\n if (modelStateTyped.relations && Object.keys(modelStateTyped.relations).length > 0) {\n if (!relationsPartial[tableName]) {\n relationsPartial[tableName] = {};\n }\n\n // Add relations from this model to the table's relations\n const tableRelations = relationsPartial[tableName];\n if (tableRelations) {\n for (const relationName in modelStateTyped.relations) {\n const relation = modelStateTyped.relations[relationName];\n if (relation) {\n tableRelations[relationName] = relation;\n }\n }\n }\n }\n }\n\n const models = modelsPartial as unknown as BuildModels<Models>;\n\n const baseMappings = computeMappings(\n models as unknown as Record<string, ModelDefinition>,\n storage as SqlStorage,\n );\n\n const mappings = {\n ...baseMappings,\n codecTypes: {} as CodecTypes,\n operationTypes: {} as Record<string, never>,\n } as ContractBuilderMappings<CodecTypes>;\n\n const extensionNamespaces = this.state.extensionNamespaces ?? [];\n const extensionPacks: Record<string, unknown> = { ...(this.state.extensionPacks || {}) };\n for (const namespace of extensionNamespaces) {\n if (!Object.hasOwn(extensionPacks, namespace)) {\n extensionPacks[namespace] = {};\n }\n }\n\n // Construct contract with explicit type that matches the generic parameters\n // This ensures TypeScript infers literal types from the generics, not runtime values\n // Always include relations, even if empty (normalized to empty object)\n const contract = {\n schemaVersion: '1' as const,\n target,\n targetFamily: 'sql' as const,\n coreHash: this.state.coreHash || 'sha256:ts-builder-placeholder',\n models,\n relations: relationsPartial,\n storage,\n mappings,\n extensionPacks,\n capabilities: this.state.capabilities || {},\n meta: {},\n sources: {},\n } as unknown as BuiltContract;\n\n return contract as unknown as ReturnType<\n SqlContractBuilder<\n CodecTypes,\n Target,\n Tables,\n Models,\n CoreHash,\n ExtensionPacks,\n Capabilities\n >['build']\n >;\n }\n\n override target<T extends string>(\n packRef: TargetPackRef<'sql', T>,\n ): SqlContractBuilder<CodecTypes, T, Tables, Models, CoreHash, ExtensionPacks, Capabilities> {\n return new SqlContractBuilder<\n CodecTypes,\n T,\n Tables,\n Models,\n CoreHash,\n ExtensionPacks,\n Capabilities\n >({\n ...this.state,\n target: packRef.targetId,\n });\n }\n\n extensionPacks(\n packs: Record<string, ExtensionPackRef<'sql', string>>,\n ): SqlContractBuilder<\n CodecTypes,\n Target,\n Tables,\n Models,\n CoreHash,\n ExtensionPacks,\n Capabilities\n > {\n if (!this.state.target) {\n throw new Error('extensionPacks() requires target() to be called first');\n }\n\n const namespaces = new Set(this.state.extensionNamespaces ?? []);\n\n for (const packRef of Object.values(packs)) {\n if (!packRef) continue;\n\n if (packRef.kind !== 'extension') {\n throw new Error(\n `extensionPacks() only accepts extension pack refs. Received kind \\\"${packRef.kind}\\\".`,\n );\n }\n\n if (packRef.familyId !== 'sql') {\n throw new Error(\n `extension pack \\\"${packRef.id}\\\" targets family \\\"${packRef.familyId}\\\" but this builder targets \\\"sql\\\".`,\n );\n }\n\n if (packRef.targetId && packRef.targetId !== this.state.target) {\n throw new Error(\n `extension pack \\\"${packRef.id}\\\" targets \\\"${packRef.targetId}\\\" but builder target is \\\"${this.state.target}\\\".`,\n );\n }\n\n namespaces.add(packRef.id);\n }\n\n return new SqlContractBuilder<\n CodecTypes,\n Target,\n Tables,\n Models,\n CoreHash,\n ExtensionPacks,\n Capabilities\n >({\n ...this.state,\n extensionNamespaces: [...namespaces],\n });\n }\n\n override capabilities<C extends Record<string, Record<string, boolean>>>(\n capabilities: C,\n ): SqlContractBuilder<CodecTypes, Target, Tables, Models, CoreHash, ExtensionPacks, C> {\n return new SqlContractBuilder<CodecTypes, Target, Tables, Models, CoreHash, ExtensionPacks, C>({\n ...this.state,\n capabilities,\n });\n }\n\n override coreHash<H extends string>(\n hash: H,\n ): SqlContractBuilder<CodecTypes, Target, Tables, Models, H, ExtensionPacks, Capabilities> {\n return new SqlContractBuilder<\n CodecTypes,\n Target,\n Tables,\n Models,\n H,\n ExtensionPacks,\n Capabilities\n >({\n ...this.state,\n coreHash: hash,\n });\n }\n\n override table<\n TableName extends string,\n T extends TableBuilder<\n TableName,\n Record<string, ColumnBuilderState<string, boolean, string>>,\n readonly string[] | undefined\n >,\n >(\n name: TableName,\n callback: (t: TableBuilder<TableName>) => T | undefined,\n ): SqlContractBuilder<\n CodecTypes,\n Target,\n Tables & Record<TableName, ReturnType<T['build']>>,\n Models,\n CoreHash,\n ExtensionPacks,\n Capabilities\n > {\n const tableBuilder = new TableBuilder<TableName>(name);\n const result = callback(tableBuilder);\n const finalBuilder = result instanceof TableBuilder ? result : tableBuilder;\n const tableState = finalBuilder.build();\n\n return new SqlContractBuilder<\n CodecTypes,\n Target,\n Tables & Record<TableName, ReturnType<T['build']>>,\n Models,\n CoreHash,\n ExtensionPacks,\n Capabilities\n >({\n ...this.state,\n tables: { ...this.state.tables, [name]: tableState } as Tables &\n Record<TableName, ReturnType<T['build']>>,\n });\n }\n\n override model<\n ModelName extends string,\n TableName extends string,\n M extends ModelBuilder<\n ModelName,\n TableName,\n Record<string, string>,\n Record<string, RelationDefinition>\n >,\n >(\n name: ModelName,\n table: TableName,\n callback: (\n m: ModelBuilder<ModelName, TableName, Record<string, string>, Record<never, never>>,\n ) => M | undefined,\n ): SqlContractBuilder<\n CodecTypes,\n Target,\n Tables,\n Models & Record<ModelName, ReturnType<M['build']>>,\n CoreHash,\n ExtensionPacks,\n Capabilities\n > {\n const modelBuilder = new ModelBuilder<ModelName, TableName>(name, table);\n const result = callback(modelBuilder);\n const finalBuilder = result instanceof ModelBuilder ? result : modelBuilder;\n const modelState = finalBuilder.build();\n\n return new SqlContractBuilder<\n CodecTypes,\n Target,\n Tables,\n Models & Record<ModelName, ReturnType<M['build']>>,\n CoreHash,\n ExtensionPacks,\n Capabilities\n >({\n ...this.state,\n models: { ...this.state.models, [name]: modelState } as Models &\n Record<ModelName, ReturnType<M['build']>>,\n });\n }\n}\n\nexport function defineContract<\n CodecTypes extends Record<string, { output: unknown }> = Record<string, never>,\n>(): SqlContractBuilder<CodecTypes> {\n return new SqlContractBuilder<CodecTypes>();\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../src/contract-builder.ts"],"sourcesContent":["import type { ExtensionPackRef, TargetPackRef } from '@prisma-next/contract/framework-components';\nimport type {\n ColumnBuilderState,\n ModelBuilderState,\n RelationDefinition,\n TableBuilderState,\n} from '@prisma-next/contract-authoring';\nimport {\n type BuildModels,\n type BuildRelations,\n type BuildStorageColumn,\n ContractBuilder,\n createTable,\n type ExtractColumns,\n type ExtractPrimaryKey,\n ModelBuilder,\n type Mutable,\n TableBuilder,\n} from '@prisma-next/contract-authoring';\nimport type {\n ModelDefinition,\n ModelField,\n SqlContract,\n SqlMappings,\n SqlStorage,\n} from '@prisma-next/sql-contract/types';\nimport { computeMappings } from './contract';\n\n/**\n * Type-level mappings structure for contracts built via `defineContract()`.\n *\n * Compile-time type helper (not a runtime object) that ensures mappings match what the builder\n * produces. `codecTypes` uses the generic `CodecTypes` parameter; `operationTypes` is always\n * empty since operations are added via extensions at runtime.\n *\n * **Difference from RuntimeContext**: This is a compile-time type for contract construction.\n * `RuntimeContext` is a runtime object with populated registries for query execution.\n *\n * @template C - The `CodecTypes` generic parameter passed to `defineContract<CodecTypes>()`\n */\ntype ContractBuilderMappings<C extends Record<string, { output: unknown }>> = Omit<\n SqlMappings,\n 'codecTypes' | 'operationTypes'\n> & {\n readonly codecTypes: C;\n readonly operationTypes: Record<string, never>;\n};\n\ntype BuildStorageTable<\n _TableName extends string,\n Columns extends Record<string, ColumnBuilderState<string, boolean, string>>,\n PK extends readonly string[] | undefined,\n> = {\n readonly columns: {\n readonly [K in keyof Columns]: Columns[K] extends ColumnBuilderState<\n string,\n infer Null,\n infer TType\n >\n ? BuildStorageColumn<Null & boolean, TType>\n : never;\n };\n readonly uniques: ReadonlyArray<{ readonly columns: readonly string[]; readonly name?: string }>;\n readonly indexes: ReadonlyArray<{ readonly columns: readonly string[]; readonly name?: string }>;\n readonly foreignKeys: ReadonlyArray<{\n readonly columns: readonly string[];\n readonly references: { readonly table: string; readonly columns: readonly string[] };\n readonly name?: string;\n }>;\n} & (PK extends readonly string[]\n ? { readonly primaryKey: { readonly columns: PK; readonly name?: string } }\n : Record<string, never>);\n\ntype BuildStorage<\n Tables extends Record<\n string,\n TableBuilderState<\n string,\n Record<string, ColumnBuilderState<string, boolean, string>>,\n readonly string[] | undefined\n >\n >,\n> = {\n readonly tables: {\n readonly [K in keyof Tables]: BuildStorageTable<\n K & string,\n ExtractColumns<Tables[K]>,\n ExtractPrimaryKey<Tables[K]>\n >;\n };\n};\n\ntype BuildStorageTables<\n Tables extends Record<\n string,\n TableBuilderState<\n string,\n Record<string, ColumnBuilderState<string, boolean, string>>,\n readonly string[] | undefined\n >\n >,\n> = {\n readonly [K in keyof Tables]: BuildStorageTable<\n K & string,\n ExtractColumns<Tables[K]>,\n ExtractPrimaryKey<Tables[K]>\n >;\n};\n\nexport interface ColumnBuilder<Name extends string, Nullable extends boolean, Type extends string> {\n nullable<Value extends boolean>(value?: Value): ColumnBuilder<Name, Value, Type>;\n type<Id extends string>(id: Id): ColumnBuilder<Name, Nullable, Id>;\n build(): ColumnBuilderState<Name, Nullable, Type>;\n}\n\nclass SqlContractBuilder<\n CodecTypes extends Record<string, { output: unknown }> = Record<string, never>,\n Target extends string | undefined = undefined,\n Tables extends Record<\n string,\n TableBuilderState<\n string,\n Record<string, ColumnBuilderState<string, boolean, string>>,\n readonly string[] | undefined\n >\n > = Record<never, never>,\n Models extends Record<\n string,\n ModelBuilderState<string, string, Record<string, string>, Record<string, RelationDefinition>>\n > = Record<never, never>,\n CoreHash extends string | undefined = undefined,\n ExtensionPacks extends Record<string, unknown> | undefined = undefined,\n Capabilities extends Record<string, Record<string, boolean>> | undefined = undefined,\n> extends ContractBuilder<Target, Tables, Models, CoreHash, ExtensionPacks, Capabilities> {\n /**\n * This method is responsible for normalizing the contract IR by setting default values\n * for all required fields:\n * - `nullable`: defaults to `false` if not provided\n * - `uniques`: defaults to `[]` (empty array)\n * - `indexes`: defaults to `[]` (empty array)\n * - `foreignKeys`: defaults to `[]` (empty array)\n * - `relations`: defaults to `{}` (empty object) for both model-level and contract-level\n * - `nativeType`: required field set from column type descriptor when columns are defined\n *\n * The contract builder is the **only** place where normalization should occur.\n * Validators, parsers, and emitters should assume the contract is already normalized.\n *\n * **Required**: Use column type descriptors (e.g., `int4Column`, `textColumn`) when defining columns.\n * This ensures `nativeType` is set correctly at build time.\n *\n * @returns A normalized SqlContract with all required fields present\n */\n build(): Target extends string\n ? SqlContract<\n BuildStorage<Tables>,\n BuildModels<Models>,\n BuildRelations<Models>,\n ContractBuilderMappings<CodecTypes>\n > & {\n readonly schemaVersion: '1';\n readonly target: Target;\n readonly targetFamily: 'sql';\n readonly coreHash: CoreHash extends string ? CoreHash : string;\n } & (ExtensionPacks extends Record<string, unknown>\n ? { readonly extensionPacks: ExtensionPacks }\n : Record<string, never>) &\n (Capabilities extends Record<string, Record<string, boolean>>\n ? { readonly capabilities: Capabilities }\n : Record<string, never>)\n : never {\n // Type helper to ensure literal types are preserved in return type\n type BuiltContract = Target extends string\n ? SqlContract<\n BuildStorage<Tables>,\n BuildModels<Models>,\n BuildRelations<Models>,\n ContractBuilderMappings<CodecTypes>\n > & {\n readonly schemaVersion: '1';\n readonly target: Target;\n readonly targetFamily: 'sql';\n readonly coreHash: CoreHash extends string ? CoreHash : string;\n } & (ExtensionPacks extends Record<string, unknown>\n ? { readonly extensionPacks: ExtensionPacks }\n : Record<string, never>) &\n (Capabilities extends Record<string, Record<string, boolean>>\n ? { readonly capabilities: Capabilities }\n : Record<string, never>)\n : never;\n if (!this.state.target) {\n throw new Error('target is required. Call .target() before .build()');\n }\n\n const target = this.state.target as Target & string;\n\n const storageTables = {} as Partial<Mutable<BuildStorageTables<Tables>>>;\n\n for (const tableName of Object.keys(this.state.tables) as Array<keyof Tables & string>) {\n const tableState = this.state.tables[tableName];\n if (!tableState) continue;\n\n type TableKey = typeof tableName;\n type ColumnDefs = ExtractColumns<Tables[TableKey]>;\n type PrimaryKey = ExtractPrimaryKey<Tables[TableKey]>;\n\n const columns = {} as Partial<{\n [K in keyof ColumnDefs]: BuildStorageColumn<\n ColumnDefs[K]['nullable'] & boolean,\n ColumnDefs[K]['type']\n >;\n }>;\n\n for (const columnName in tableState.columns) {\n const columnState = tableState.columns[columnName];\n if (!columnState) continue;\n const codecId = columnState.type;\n const nativeType = columnState.nativeType;\n\n columns[columnName as keyof ColumnDefs] = {\n nativeType,\n codecId,\n nullable: (columnState.nullable ?? false) as ColumnDefs[keyof ColumnDefs]['nullable'] &\n boolean,\n } as BuildStorageColumn<\n ColumnDefs[keyof ColumnDefs]['nullable'] & boolean,\n ColumnDefs[keyof ColumnDefs]['type']\n >;\n }\n\n // Build uniques from table state\n const uniques = (tableState.uniques ?? []).map((u) => ({\n columns: u.columns,\n ...(u.name ? { name: u.name } : {}),\n }));\n\n // Build indexes from table state\n const indexes = (tableState.indexes ?? []).map((i) => ({\n columns: i.columns,\n ...(i.name ? { name: i.name } : {}),\n }));\n\n // Build foreign keys from table state\n const foreignKeys = (tableState.foreignKeys ?? []).map((fk) => ({\n columns: fk.columns,\n references: fk.references,\n ...(fk.name ? { name: fk.name } : {}),\n }));\n\n const table = {\n columns: columns as {\n [K in keyof ColumnDefs]: BuildStorageColumn<\n ColumnDefs[K]['nullable'] & boolean,\n ColumnDefs[K]['type']\n >;\n },\n uniques,\n indexes,\n foreignKeys,\n ...(tableState.primaryKey\n ? {\n primaryKey: {\n columns: tableState.primaryKey,\n ...(tableState.primaryKeyName ? { name: tableState.primaryKeyName } : {}),\n },\n }\n : {}),\n } as unknown as BuildStorageTable<TableKey & string, ColumnDefs, PrimaryKey>;\n\n (storageTables as Mutable<BuildStorageTables<Tables>>)[tableName] = table;\n }\n\n const storage = { tables: storageTables as BuildStorageTables<Tables> } as BuildStorage<Tables>;\n\n // Build models - construct as partial first, then assert full type\n const modelsPartial: Partial<BuildModels<Models>> = {};\n\n // Iterate over models - TypeScript will see keys as string, but type assertion preserves literals\n for (const modelName in this.state.models) {\n const modelState = this.state.models[modelName];\n if (!modelState) continue;\n\n const modelStateTyped = modelState as unknown as {\n name: string;\n table: string;\n fields: Record<string, string>;\n };\n\n // Build fields object\n const fields: Partial<Record<string, ModelField>> = {};\n\n // Iterate over fields\n for (const fieldName in modelStateTyped.fields) {\n const columnName = modelStateTyped.fields[fieldName];\n if (columnName) {\n fields[fieldName] = {\n column: columnName,\n };\n }\n }\n\n // Assign to models - type assertion preserves literal keys\n (modelsPartial as unknown as Record<string, ModelDefinition>)[modelName] = {\n storage: {\n table: modelStateTyped.table,\n },\n fields: fields as Record<string, ModelField>,\n relations: {},\n };\n }\n\n // Build relations object - organized by table name\n const relationsPartial: Partial<Record<string, Record<string, RelationDefinition>>> = {};\n\n // Iterate over models to collect relations\n for (const modelName in this.state.models) {\n const modelState = this.state.models[modelName];\n if (!modelState) continue;\n\n const modelStateTyped = modelState as unknown as {\n name: string;\n table: string;\n fields: Record<string, string>;\n relations: Record<string, RelationDefinition>;\n };\n\n const tableName = modelStateTyped.table;\n if (!tableName) continue;\n\n // Only initialize relations object for this table if it has relations\n if (modelStateTyped.relations && Object.keys(modelStateTyped.relations).length > 0) {\n if (!relationsPartial[tableName]) {\n relationsPartial[tableName] = {};\n }\n\n // Add relations from this model to the table's relations\n const tableRelations = relationsPartial[tableName];\n if (tableRelations) {\n for (const relationName in modelStateTyped.relations) {\n const relation = modelStateTyped.relations[relationName];\n if (relation) {\n tableRelations[relationName] = relation;\n }\n }\n }\n }\n }\n\n const models = modelsPartial as unknown as BuildModels<Models>;\n\n const baseMappings = computeMappings(\n models as unknown as Record<string, ModelDefinition>,\n storage as SqlStorage,\n );\n\n const mappings = {\n ...baseMappings,\n codecTypes: {} as CodecTypes,\n operationTypes: {} as Record<string, never>,\n } as ContractBuilderMappings<CodecTypes>;\n\n const extensionNamespaces = this.state.extensionNamespaces ?? [];\n const extensionPacks: Record<string, unknown> = { ...(this.state.extensionPacks || {}) };\n for (const namespace of extensionNamespaces) {\n if (!Object.hasOwn(extensionPacks, namespace)) {\n extensionPacks[namespace] = {};\n }\n }\n\n // Construct contract with explicit type that matches the generic parameters\n // This ensures TypeScript infers literal types from the generics, not runtime values\n // Always include relations, even if empty (normalized to empty object)\n const contract = {\n schemaVersion: '1' as const,\n target,\n targetFamily: 'sql' as const,\n coreHash: this.state.coreHash || 'sha256:ts-builder-placeholder',\n models,\n relations: relationsPartial,\n storage,\n mappings,\n extensionPacks,\n capabilities: this.state.capabilities || {},\n meta: {},\n sources: {},\n } as unknown as BuiltContract;\n\n return contract as unknown as ReturnType<\n SqlContractBuilder<\n CodecTypes,\n Target,\n Tables,\n Models,\n CoreHash,\n ExtensionPacks,\n Capabilities\n >['build']\n >;\n }\n\n override target<T extends string>(\n packRef: TargetPackRef<'sql', T>,\n ): SqlContractBuilder<CodecTypes, T, Tables, Models, CoreHash, ExtensionPacks, Capabilities> {\n return new SqlContractBuilder<\n CodecTypes,\n T,\n Tables,\n Models,\n CoreHash,\n ExtensionPacks,\n Capabilities\n >({\n ...this.state,\n target: packRef.targetId,\n });\n }\n\n extensionPacks(\n packs: Record<string, ExtensionPackRef<'sql', string>>,\n ): SqlContractBuilder<\n CodecTypes,\n Target,\n Tables,\n Models,\n CoreHash,\n ExtensionPacks,\n Capabilities\n > {\n if (!this.state.target) {\n throw new Error('extensionPacks() requires target() to be called first');\n }\n\n const namespaces = new Set(this.state.extensionNamespaces ?? []);\n\n for (const packRef of Object.values(packs)) {\n if (!packRef) continue;\n\n if (packRef.kind !== 'extension') {\n throw new Error(\n `extensionPacks() only accepts extension pack refs. Received kind \"${packRef.kind}\".`,\n );\n }\n\n if (packRef.familyId !== 'sql') {\n throw new Error(\n `extension pack \"${packRef.id}\" targets family \"${packRef.familyId}\" but this builder targets \"sql\".`,\n );\n }\n\n if (packRef.targetId && packRef.targetId !== this.state.target) {\n throw new Error(\n `extension pack \"${packRef.id}\" targets \"${packRef.targetId}\" but builder target is \"${this.state.target}\".`,\n );\n }\n\n namespaces.add(packRef.id);\n }\n\n return new SqlContractBuilder<\n CodecTypes,\n Target,\n Tables,\n Models,\n CoreHash,\n ExtensionPacks,\n Capabilities\n >({\n ...this.state,\n extensionNamespaces: [...namespaces],\n });\n }\n\n override capabilities<C extends Record<string, Record<string, boolean>>>(\n capabilities: C,\n ): SqlContractBuilder<CodecTypes, Target, Tables, Models, CoreHash, ExtensionPacks, C> {\n return new SqlContractBuilder<CodecTypes, Target, Tables, Models, CoreHash, ExtensionPacks, C>({\n ...this.state,\n capabilities,\n });\n }\n\n override coreHash<H extends string>(\n hash: H,\n ): SqlContractBuilder<CodecTypes, Target, Tables, Models, H, ExtensionPacks, Capabilities> {\n return new SqlContractBuilder<\n CodecTypes,\n Target,\n Tables,\n Models,\n H,\n ExtensionPacks,\n Capabilities\n >({\n ...this.state,\n coreHash: hash,\n });\n }\n\n override table<\n TableName extends string,\n T extends TableBuilder<\n TableName,\n Record<string, ColumnBuilderState<string, boolean, string>>,\n readonly string[] | undefined\n >,\n >(\n name: TableName,\n callback: (t: TableBuilder<TableName>) => T | undefined,\n ): SqlContractBuilder<\n CodecTypes,\n Target,\n Tables & Record<TableName, ReturnType<T['build']>>,\n Models,\n CoreHash,\n ExtensionPacks,\n Capabilities\n > {\n const tableBuilder = createTable(name);\n const result = callback(tableBuilder);\n const finalBuilder = result instanceof TableBuilder ? result : tableBuilder;\n const tableState = finalBuilder.build();\n\n return new SqlContractBuilder<\n CodecTypes,\n Target,\n Tables & Record<TableName, ReturnType<T['build']>>,\n Models,\n CoreHash,\n ExtensionPacks,\n Capabilities\n >({\n ...this.state,\n tables: { ...this.state.tables, [name]: tableState } as Tables &\n Record<TableName, ReturnType<T['build']>>,\n });\n }\n\n override model<\n ModelName extends string,\n TableName extends string,\n M extends ModelBuilder<\n ModelName,\n TableName,\n Record<string, string>,\n Record<string, RelationDefinition>\n >,\n >(\n name: ModelName,\n table: TableName,\n callback: (\n m: ModelBuilder<ModelName, TableName, Record<string, string>, Record<never, never>>,\n ) => M | undefined,\n ): SqlContractBuilder<\n CodecTypes,\n Target,\n Tables,\n Models & Record<ModelName, ReturnType<M['build']>>,\n CoreHash,\n ExtensionPacks,\n Capabilities\n > {\n const modelBuilder = new ModelBuilder<ModelName, TableName>(name, table);\n const result = callback(modelBuilder);\n const finalBuilder = result instanceof ModelBuilder ? result : modelBuilder;\n const modelState = finalBuilder.build();\n\n return new SqlContractBuilder<\n CodecTypes,\n Target,\n Tables,\n Models & Record<ModelName, ReturnType<M['build']>>,\n CoreHash,\n ExtensionPacks,\n Capabilities\n >({\n ...this.state,\n models: { ...this.state.models, [name]: modelState } as Models &\n Record<ModelName, ReturnType<M['build']>>,\n });\n }\n}\n\nexport function defineContract<\n CodecTypes extends Record<string, { output: unknown }> = Record<string, never>,\n>(): SqlContractBuilder<CodecTypes> {\n return new SqlContractBuilder<CodecTypes>();\n}\n"],"mappings":"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","names":[]}
package/package.json CHANGED
@@ -1,23 +1,23 @@
1
1
  {
2
2
  "name": "@prisma-next/sql-contract-ts",
3
- "version": "0.3.0-dev.8",
3
+ "version": "0.3.0-pr.49.6",
4
4
  "type": "module",
5
5
  "sideEffects": false,
6
6
  "description": "SQL-specific TypeScript contract authoring surface for Prisma Next",
7
7
  "dependencies": {
8
8
  "arktype": "^2.1.25",
9
9
  "ts-toolbelt": "^9.6.0",
10
- "@prisma-next/contract": "0.3.0-dev.8",
11
- "@prisma-next/contract-authoring": "0.3.0-dev.8",
12
- "@prisma-next/sql-contract": "0.3.0-dev.8"
10
+ "@prisma-next/contract": "0.3.0-pr.49.6",
11
+ "@prisma-next/contract-authoring": "0.3.0-pr.49.6",
12
+ "@prisma-next/sql-contract": "0.3.0-pr.49.6"
13
13
  },
14
14
  "devDependencies": {
15
15
  "@types/pg": "8.16.0",
16
- "@vitest/coverage-v8": "4.0.16",
17
16
  "pg": "8.16.3",
18
17
  "tsup": "8.5.1",
19
18
  "typescript": "5.9.3",
20
19
  "vitest": "4.0.16",
20
+ "@prisma-next/tsconfig": "0.0.0",
21
21
  "@prisma-next/test-utils": "0.0.1"
22
22
  },
23
23
  "files": [
@@ -41,9 +41,9 @@
41
41
  "test": "vitest run",
42
42
  "test:coverage": "vitest run --coverage",
43
43
  "typecheck": "tsc --project tsconfig.json --noEmit",
44
- "lint": "biome check . --config-path ../../../../biome.json --error-on-warnings",
45
- "lint:fix": "biome check --write . --config-path ../../../../biome.json",
46
- "lint:fix:unsafe": "biome check --write --unsafe . --config-path ../../../../biome.json",
47
- "clean": "node ../../../../scripts/clean.mjs"
44
+ "lint": "biome check . --error-on-warnings",
45
+ "lint:fix": "biome check --write .",
46
+ "lint:fix:unsafe": "biome check --write --unsafe .",
47
+ "clean": "rm -rf dist coverage .tmp-output"
48
48
  }
49
49
  }
@@ -10,6 +10,7 @@ import {
10
10
  type BuildRelations,
11
11
  type BuildStorageColumn,
12
12
  ContractBuilder,
13
+ createTable,
13
14
  type ExtractColumns,
14
15
  type ExtractPrimaryKey,
15
16
  ModelBuilder,
@@ -59,11 +60,15 @@ type BuildStorageTable<
59
60
  ? BuildStorageColumn<Null & boolean, TType>
60
61
  : never;
61
62
  };
62
- readonly uniques: ReadonlyArray<never>;
63
- readonly indexes: ReadonlyArray<never>;
64
- readonly foreignKeys: ReadonlyArray<never>;
63
+ readonly uniques: ReadonlyArray<{ readonly columns: readonly string[]; readonly name?: string }>;
64
+ readonly indexes: ReadonlyArray<{ readonly columns: readonly string[]; readonly name?: string }>;
65
+ readonly foreignKeys: ReadonlyArray<{
66
+ readonly columns: readonly string[];
67
+ readonly references: { readonly table: string; readonly columns: readonly string[] };
68
+ readonly name?: string;
69
+ }>;
65
70
  } & (PK extends readonly string[]
66
- ? { readonly primaryKey: { readonly columns: PK } }
71
+ ? { readonly primaryKey: { readonly columns: PK; readonly name?: string } }
67
72
  : Record<string, never>);
68
73
 
69
74
  type BuildStorage<
@@ -222,6 +227,25 @@ class SqlContractBuilder<
222
227
  >;
223
228
  }
224
229
 
230
+ // Build uniques from table state
231
+ const uniques = (tableState.uniques ?? []).map((u) => ({
232
+ columns: u.columns,
233
+ ...(u.name ? { name: u.name } : {}),
234
+ }));
235
+
236
+ // Build indexes from table state
237
+ const indexes = (tableState.indexes ?? []).map((i) => ({
238
+ columns: i.columns,
239
+ ...(i.name ? { name: i.name } : {}),
240
+ }));
241
+
242
+ // Build foreign keys from table state
243
+ const foreignKeys = (tableState.foreignKeys ?? []).map((fk) => ({
244
+ columns: fk.columns,
245
+ references: fk.references,
246
+ ...(fk.name ? { name: fk.name } : {}),
247
+ }));
248
+
225
249
  const table = {
226
250
  columns: columns as {
227
251
  [K in keyof ColumnDefs]: BuildStorageColumn<
@@ -229,13 +253,14 @@ class SqlContractBuilder<
229
253
  ColumnDefs[K]['type']
230
254
  >;
231
255
  },
232
- uniques: [],
233
- indexes: [],
234
- foreignKeys: [],
256
+ uniques,
257
+ indexes,
258
+ foreignKeys,
235
259
  ...(tableState.primaryKey
236
260
  ? {
237
261
  primaryKey: {
238
262
  columns: tableState.primaryKey,
263
+ ...(tableState.primaryKeyName ? { name: tableState.primaryKeyName } : {}),
239
264
  },
240
265
  }
241
266
  : {}),
@@ -411,19 +436,19 @@ class SqlContractBuilder<
411
436
 
412
437
  if (packRef.kind !== 'extension') {
413
438
  throw new Error(
414
- `extensionPacks() only accepts extension pack refs. Received kind \"${packRef.kind}\".`,
439
+ `extensionPacks() only accepts extension pack refs. Received kind "${packRef.kind}".`,
415
440
  );
416
441
  }
417
442
 
418
443
  if (packRef.familyId !== 'sql') {
419
444
  throw new Error(
420
- `extension pack \"${packRef.id}\" targets family \"${packRef.familyId}\" but this builder targets \"sql\".`,
445
+ `extension pack "${packRef.id}" targets family "${packRef.familyId}" but this builder targets "sql".`,
421
446
  );
422
447
  }
423
448
 
424
449
  if (packRef.targetId && packRef.targetId !== this.state.target) {
425
450
  throw new Error(
426
- `extension pack \"${packRef.id}\" targets \"${packRef.targetId}\" but builder target is \"${this.state.target}\".`,
451
+ `extension pack "${packRef.id}" targets "${packRef.targetId}" but builder target is "${this.state.target}".`,
427
452
  );
428
453
  }
429
454
 
@@ -489,7 +514,7 @@ class SqlContractBuilder<
489
514
  ExtensionPacks,
490
515
  Capabilities
491
516
  > {
492
- const tableBuilder = new TableBuilder<TableName>(name);
517
+ const tableBuilder = createTable(name);
493
518
  const result = callback(tableBuilder);
494
519
  const finalBuilder = result instanceof TableBuilder ? result : tableBuilder;
495
520
  const tableState = finalBuilder.build();