@prisma-next/sql-contract-emitter 0.3.0-dev.24 → 0.3.0-dev.25

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/dist/index.d.ts CHANGED
@@ -1,13 +1,19 @@
1
1
  import type { ContractIR } from '@prisma-next/contract/ir';
2
- import type { TypesImportSpec, ValidationContext } from '@prisma-next/contract/types';
3
- import type { ModelDefinition, SqlStorage } from '@prisma-next/sql-contract/types';
2
+ import type { GenerateContractTypesOptions, TypesImportSpec, ValidationContext } from '@prisma-next/contract/types';
3
+ import type { ModelDefinition, SqlStorage, StorageColumn } from '@prisma-next/sql-contract/types';
4
4
  export declare const sqlTargetFamilyHook: {
5
5
  readonly id: "sql";
6
6
  readonly validateTypes: (ir: ContractIR, _ctx: ValidationContext) => void;
7
7
  readonly validateStructure: (ir: ContractIR) => void;
8
- readonly generateContractTypes: (ir: ContractIR, codecTypeImports: ReadonlyArray<TypesImportSpec>, operationTypeImports: ReadonlyArray<TypesImportSpec>) => string;
8
+ readonly generateContractTypes: (ir: ContractIR, codecTypeImports: ReadonlyArray<TypesImportSpec>, operationTypeImports: ReadonlyArray<TypesImportSpec>, options?: GenerateContractTypesOptions) => string;
9
9
  readonly generateStorageType: (storage: SqlStorage) => string;
10
- readonly generateModelsType: (models: Record<string, ModelDefinition> | undefined, storage: SqlStorage) => string;
10
+ /**
11
+ * Renders the TypeScript type for a column.
12
+ * Uses parameterized renderer if column has typeParams and renderer exists.
13
+ * Falls back to CodecTypes['codecId']['output'] for scalar codecs.
14
+ */
15
+ readonly renderColumnType: (column: StorageColumn, storage: SqlStorage, parameterizedRenderers?: GenerateContractTypesOptions["parameterizedRenderers"]) => string;
16
+ readonly generateModelsType: (models: Record<string, ModelDefinition> | undefined, storage: SqlStorage, parameterizedRenderers?: GenerateContractTypesOptions["parameterizedRenderers"]) => string;
11
17
  readonly generateRelationsType: (relations: Record<string, unknown> | undefined) => string;
12
18
  readonly generateMappingsType: (models: Record<string, ModelDefinition> | undefined, storage: SqlStorage, codecTypes: string, operationTypes: string) => string;
13
19
  };
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAC;AAC3D,OAAO,KAAK,EAAE,eAAe,EAAE,iBAAiB,EAAE,MAAM,6BAA6B,CAAC;AACtF,OAAO,KAAK,EACV,eAAe,EAEf,UAAU,EAEX,MAAM,iCAAiC,CAAC;AAEzC,eAAO,MAAM,mBAAmB;;iCAGZ,UAAU,QAAQ,iBAAiB,KAAG,IAAI;qCA6BtC,UAAU,KAAG,IAAI;yCA2JjC,UAAU,oBACI,aAAa,CAAC,eAAe,CAAC,wBAC1B,aAAa,CAAC,eAAe,CAAC,KACnD,MAAM;4CAyCoB,UAAU,KAAG,MAAM;0CAwDtC,MAAM,CAAC,MAAM,EAAE,eAAe,CAAC,GAAG,SAAS,WAC1C,UAAU,KAClB,MAAM;gDA8DwB,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,KAAG,MAAM;4CAkEnE,MAAM,CAAC,MAAM,EAAE,eAAe,CAAC,GAAG,SAAS,WAC1C,UAAU,cACP,MAAM,kBACF,MAAM,KACrB,MAAM;CAsDD,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAC;AAC3D,OAAO,KAAK,EACV,4BAA4B,EAC5B,eAAe,EACf,iBAAiB,EAClB,MAAM,6BAA6B,CAAC;AACrC,OAAO,KAAK,EACV,eAAe,EAEf,UAAU,EACV,aAAa,EAEd,MAAM,iCAAiC,CAAC;AAGzC,eAAO,MAAM,mBAAmB;;iCAGZ,UAAU,QAAQ,iBAAiB,KAAG,IAAI;qCA6BtC,UAAU,KAAG,IAAI;yCAyJjC,UAAU,oBACI,aAAa,CAAC,eAAe,CAAC,wBAC1B,aAAa,CAAC,eAAe,CAAC,YAC1C,4BAA4B,KACrC,MAAM;4CA0CoB,UAAU,KAAG,MAAM;IAuDhD;;;;OAIG;wCAEO,aAAa,WACZ,UAAU,2BACM,4BAA4B,CAAC,wBAAwB,CAAC,KAC9E,MAAM;0CA2BC,MAAM,CAAC,MAAM,EAAE,eAAe,CAAC,GAAG,SAAS,WAC1C,UAAU,2BACM,4BAA4B,CAAC,wBAAwB,CAAC,KAC9E,MAAM;gDA4DwB,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,KAAG,MAAM;4CAkEnE,MAAM,CAAC,MAAM,EAAE,eAAe,CAAC,GAAG,SAAS,WAC1C,UAAU,cACP,MAAM,kBACF,MAAM,KACrB,MAAM;CAsDD,CAAC"}
package/dist/index.js CHANGED
@@ -1,4 +1,5 @@
1
1
  // src/index.ts
2
+ import { assertDefined } from "@prisma-next/utils/assertions";
2
3
  var sqlTargetFamilyHook = {
3
4
  id: "sql",
4
5
  validateTypes(ir, _ctx) {
@@ -45,9 +46,7 @@ var sqlTargetFamilyHook = {
45
46
  throw new Error(`Model "${modelName}" references non-existent table "${tableName}"`);
46
47
  }
47
48
  const table = storage.tables[tableName];
48
- if (!table) {
49
- throw new Error(`Model "${modelName}" references non-existent table "${tableName}"`);
50
- }
49
+ assertDefined(table, `Model "${modelName}" references non-existent table "${tableName}"`);
51
50
  if (!table.primaryKey) {
52
51
  throw new Error(`Model "${modelName}" table "${tableName}" is missing a primary key`);
53
52
  }
@@ -132,11 +131,10 @@ var sqlTargetFamilyHook = {
132
131
  );
133
132
  }
134
133
  const referencedTable = storage.tables[fk.references.table];
135
- if (!referencedTable) {
136
- throw new Error(
137
- `Table "${tableName}" foreignKey references non-existent table "${fk.references.table}"`
138
- );
139
- }
134
+ assertDefined(
135
+ referencedTable,
136
+ `Table "${tableName}" foreignKey references non-existent table "${fk.references.table}"`
137
+ );
140
138
  const referencedColumnNames = new Set(Object.keys(referencedTable.columns));
141
139
  for (const colName of fk.references.columns) {
142
140
  if (!referencedColumnNames.has(colName)) {
@@ -153,7 +151,7 @@ var sqlTargetFamilyHook = {
153
151
  }
154
152
  }
155
153
  },
156
- generateContractTypes(ir, codecTypeImports, operationTypeImports) {
154
+ generateContractTypes(ir, codecTypeImports, operationTypeImports, options) {
157
155
  const allImports = [...codecTypeImports, ...operationTypeImports];
158
156
  const importLines = allImports.map(
159
157
  (imp) => `import type { ${imp.named} as ${imp.alias} } from '${imp.package}';`
@@ -162,8 +160,9 @@ var sqlTargetFamilyHook = {
162
160
  const operationTypes = operationTypeImports.map((imp) => imp.alias).join(" & ");
163
161
  const storage = ir.storage;
164
162
  const models = ir.models;
163
+ const parameterizedRenderers = options?.parameterizedRenderers;
165
164
  const storageType = this.generateStorageType(storage);
166
- const modelsType = this.generateModelsType(models, storage);
165
+ const modelsType = this.generateModelsType(models, storage, parameterizedRenderers);
167
166
  const relationsType = this.generateRelationsType(ir.relations);
168
167
  const mappingsType = this.generateMappingsType(models, storage, codecTypes, operationTypes);
169
168
  return `// \u26A0\uFE0F GENERATED FILE - DO NOT EDIT
@@ -230,7 +229,31 @@ export type Relations = Contract['relations'];
230
229
  }
231
230
  return `{ readonly tables: { ${tables.join("; ")} } }`;
232
231
  },
233
- generateModelsType(models, storage) {
232
+ /**
233
+ * Renders the TypeScript type for a column.
234
+ * Uses parameterized renderer if column has typeParams and renderer exists.
235
+ * Falls back to CodecTypes['codecId']['output'] for scalar codecs.
236
+ */
237
+ renderColumnType(column, storage, parameterizedRenderers) {
238
+ const codecId = column.codecId;
239
+ if (column.typeRef && storage.types) {
240
+ const typeInstance = storage.types[column.typeRef];
241
+ if (typeInstance) {
242
+ const renderer = parameterizedRenderers?.get(typeInstance.codecId);
243
+ if (renderer) {
244
+ return renderer.render(typeInstance.typeParams, { codecTypesName: "CodecTypes" });
245
+ }
246
+ }
247
+ }
248
+ if (column.typeParams) {
249
+ const renderer = parameterizedRenderers?.get(codecId);
250
+ if (renderer) {
251
+ return renderer.render(column.typeParams, { codecTypesName: "CodecTypes" });
252
+ }
253
+ }
254
+ return `CodecTypes['${codecId}']['output']`;
255
+ },
256
+ generateModelsType(models, storage, parameterizedRenderers) {
234
257
  if (!models) {
235
258
  return "Record<string, never>";
236
259
  }
@@ -246,9 +269,9 @@ export type Relations = Contract['relations'];
246
269
  fields.push(`readonly ${fieldName}: { readonly column: '${field.column}' }`);
247
270
  continue;
248
271
  }
249
- const typeId = column.codecId;
272
+ const baseType = this.renderColumnType(column, storage, parameterizedRenderers);
250
273
  const nullable = column.nullable ?? false;
251
- const jsType = nullable ? `CodecTypes['${typeId}']['output'] | null` : `CodecTypes['${typeId}']['output']`;
274
+ const jsType = nullable ? `${baseType} | null` : baseType;
252
275
  fields.push(`readonly ${fieldName}: ${jsType}`);
253
276
  }
254
277
  } else {
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts"],"sourcesContent":["import type { ContractIR } from '@prisma-next/contract/ir';\nimport type { TypesImportSpec, ValidationContext } from '@prisma-next/contract/types';\nimport type {\n ModelDefinition,\n ModelField,\n SqlStorage,\n StorageTable,\n} from '@prisma-next/sql-contract/types';\n\nexport const sqlTargetFamilyHook = {\n id: 'sql',\n\n validateTypes(ir: ContractIR, _ctx: ValidationContext): void {\n const storage = ir.storage as SqlStorage | undefined;\n if (!storage || !storage.tables) {\n return;\n }\n\n // Validate codec ID format (ns/name@version). Adapter-provided codecs are available regardless of contract.extensionPacks (which is for framework extensions); TypeScript prevents invalid usage and runtime validates availability.\n\n const typeIdRegex = /^([^/]+)\\/([^@]+)@(\\d+)$/;\n\n for (const [tableName, tableUnknown] of Object.entries(storage.tables)) {\n const table = tableUnknown as StorageTable;\n for (const [colName, colUnknown] of Object.entries(table.columns)) {\n const col = colUnknown as { codecId?: string };\n const codecId = col.codecId;\n if (!codecId) {\n throw new Error(`Column \"${colName}\" in table \"${tableName}\" is missing codecId`);\n }\n\n const match = codecId.match(typeIdRegex);\n if (!match || !match[1]) {\n throw new Error(\n `Column \"${colName}\" in table \"${tableName}\" has invalid codec ID format \"${codecId}\". Expected format: ns/name@version`,\n );\n }\n }\n }\n },\n\n validateStructure(ir: ContractIR): void {\n if (ir.targetFamily !== 'sql') {\n throw new Error(`Expected targetFamily \"sql\", got \"${ir.targetFamily}\"`);\n }\n\n const storage = ir.storage as SqlStorage | undefined;\n if (!storage || !storage.tables) {\n throw new Error('SQL contract must have storage.tables');\n }\n\n const models = ir.models as Record<string, ModelDefinition> | undefined;\n const tableNames = new Set(Object.keys(storage.tables));\n\n if (models) {\n for (const [modelName, modelUnknown] of Object.entries(models)) {\n const model = modelUnknown as ModelDefinition;\n if (!model.storage?.table) {\n throw new Error(`Model \"${modelName}\" is missing storage.table`);\n }\n\n const tableName = model.storage.table;\n if (!tableNames.has(tableName)) {\n throw new Error(`Model \"${modelName}\" references non-existent table \"${tableName}\"`);\n }\n\n const table = storage.tables[tableName];\n if (!table) {\n throw new Error(`Model \"${modelName}\" references non-existent table \"${tableName}\"`);\n }\n\n if (!table.primaryKey) {\n throw new Error(`Model \"${modelName}\" table \"${tableName}\" is missing a primary key`);\n }\n\n const columnNames = new Set(Object.keys(table.columns));\n if (!model.fields || Object.keys(model.fields).length === 0) {\n throw new Error(`Model \"${modelName}\" is missing fields`);\n }\n\n for (const [fieldName, fieldUnknown] of Object.entries(model.fields)) {\n const field = fieldUnknown as ModelField;\n if (!field.column) {\n throw new Error(`Model \"${modelName}\" field \"${fieldName}\" is missing column property`);\n }\n\n if (!columnNames.has(field.column)) {\n throw new Error(\n `Model \"${modelName}\" field \"${fieldName}\" references non-existent column \"${field.column}\" in table \"${tableName}\"`,\n );\n }\n }\n\n if (!model.relations || typeof model.relations !== 'object') {\n throw new Error(\n `Model \"${modelName}\" is missing required field \"relations\" (must be an object)`,\n );\n }\n }\n }\n\n for (const [tableName, tableUnknown] of Object.entries(storage.tables)) {\n const table = tableUnknown as StorageTable;\n const columnNames = new Set(Object.keys(table.columns));\n\n // Column structure (nullable, nativeType, codecId) and table arrays (uniques, indexes, foreignKeys)\n // are validated by Arktype schema validation - no need to re-check here.\n // We only validate logical consistency (foreign key references, model references, etc.)\n\n if (!Array.isArray(table.uniques)) {\n throw new Error(\n `Table \"${tableName}\" is missing required field \"uniques\" (must be an array)`,\n );\n }\n if (!Array.isArray(table.indexes)) {\n throw new Error(\n `Table \"${tableName}\" is missing required field \"indexes\" (must be an array)`,\n );\n }\n if (!Array.isArray(table.foreignKeys)) {\n throw new Error(\n `Table \"${tableName}\" is missing required field \"foreignKeys\" (must be an array)`,\n );\n }\n\n if (table.primaryKey) {\n for (const colName of table.primaryKey.columns) {\n if (!columnNames.has(colName)) {\n throw new Error(\n `Table \"${tableName}\" primaryKey references non-existent column \"${colName}\"`,\n );\n }\n }\n }\n\n for (const unique of table.uniques) {\n for (const colName of unique.columns) {\n if (!columnNames.has(colName)) {\n throw new Error(\n `Table \"${tableName}\" unique constraint references non-existent column \"${colName}\"`,\n );\n }\n }\n }\n\n for (const index of table.indexes) {\n for (const colName of index.columns) {\n if (!columnNames.has(colName)) {\n throw new Error(\n `Table \"${tableName}\" index references non-existent column \"${colName}\"`,\n );\n }\n }\n }\n\n for (const fk of table.foreignKeys) {\n for (const colName of fk.columns) {\n if (!columnNames.has(colName)) {\n throw new Error(\n `Table \"${tableName}\" foreignKey references non-existent column \"${colName}\"`,\n );\n }\n }\n\n if (!tableNames.has(fk.references.table)) {\n throw new Error(\n `Table \"${tableName}\" foreignKey references non-existent table \"${fk.references.table}\"`,\n );\n }\n\n const referencedTable = storage.tables[fk.references.table];\n if (!referencedTable) {\n throw new Error(\n `Table \"${tableName}\" foreignKey references non-existent table \"${fk.references.table}\"`,\n );\n }\n\n const referencedColumnNames = new Set(Object.keys(referencedTable.columns));\n for (const colName of fk.references.columns) {\n if (!referencedColumnNames.has(colName)) {\n throw new Error(\n `Table \"${tableName}\" foreignKey references non-existent column \"${colName}\" in table \"${fk.references.table}\"`,\n );\n }\n }\n\n if (fk.columns.length !== fk.references.columns.length) {\n throw new Error(\n `Table \"${tableName}\" foreignKey column count (${fk.columns.length}) does not match referenced column count (${fk.references.columns.length})`,\n );\n }\n }\n }\n },\n\n generateContractTypes(\n ir: ContractIR,\n codecTypeImports: ReadonlyArray<TypesImportSpec>,\n operationTypeImports: ReadonlyArray<TypesImportSpec>,\n ): string {\n const allImports = [...codecTypeImports, ...operationTypeImports];\n const importLines = allImports.map(\n (imp) => `import type { ${imp.named} as ${imp.alias} } from '${imp.package}';`,\n );\n\n const codecTypes = codecTypeImports.map((imp) => imp.alias).join(' & ');\n const operationTypes = operationTypeImports.map((imp) => imp.alias).join(' & ');\n\n const storage = ir.storage as SqlStorage;\n const models = ir.models as Record<string, ModelDefinition>;\n\n const storageType = this.generateStorageType(storage);\n const modelsType = this.generateModelsType(models, storage);\n const relationsType = this.generateRelationsType(ir.relations);\n const mappingsType = this.generateMappingsType(models, storage, codecTypes, operationTypes);\n\n return `// ⚠️ GENERATED FILE - DO NOT EDIT\n// This file is automatically generated by 'prisma-next contract emit'.\n// To regenerate, run: prisma-next contract emit\n${importLines.join('\\n')}\n\nimport type { SqlContract, SqlStorage, SqlMappings, ModelDefinition } from '@prisma-next/sql-contract/types';\n\nexport type CodecTypes = ${codecTypes || 'Record<string, never>'};\nexport type LaneCodecTypes = CodecTypes;\nexport type OperationTypes = ${operationTypes || 'Record<string, never>'};\n\nexport type Contract = SqlContract<\n ${storageType},\n ${modelsType},\n ${relationsType},\n ${mappingsType}\n>;\n\nexport type Tables = Contract['storage']['tables'];\nexport type Models = Contract['models'];\nexport type Relations = Contract['relations'];\n`;\n },\n\n generateStorageType(storage: SqlStorage): string {\n const tables: string[] = [];\n for (const [tableName, table] of Object.entries(storage.tables)) {\n const columns: string[] = [];\n for (const [colName, col] of Object.entries(table.columns)) {\n const nullable = col.nullable ? 'true' : 'false';\n const nativeType = `'${col.nativeType}'`;\n const codecId = `'${col.codecId}'`;\n columns.push(\n `readonly ${colName}: { readonly nativeType: ${nativeType}; readonly codecId: ${codecId}; readonly nullable: ${nullable} }`,\n );\n }\n\n const tableParts: string[] = [`columns: { ${columns.join('; ')} }`];\n\n if (table.primaryKey) {\n const pkCols = table.primaryKey.columns.map((c) => `'${c}'`).join(', ');\n const pkName = table.primaryKey.name ? `; readonly name: '${table.primaryKey.name}'` : '';\n tableParts.push(`primaryKey: { readonly columns: readonly [${pkCols}]${pkName} }`);\n }\n\n const uniques = table.uniques\n .map((u) => {\n const cols = u.columns.map((c: string) => `'${c}'`).join(', ');\n const name = u.name ? `; readonly name: '${u.name}'` : '';\n return `{ readonly columns: readonly [${cols}]${name} }`;\n })\n .join(', ');\n tableParts.push(`uniques: readonly [${uniques}]`);\n\n const indexes = table.indexes\n .map((i) => {\n const cols = i.columns.map((c: string) => `'${c}'`).join(', ');\n const name = i.name ? `; readonly name: '${i.name}'` : '';\n return `{ readonly columns: readonly [${cols}]${name} }`;\n })\n .join(', ');\n tableParts.push(`indexes: readonly [${indexes}]`);\n\n const fks = table.foreignKeys\n .map((fk) => {\n const cols = fk.columns.map((c: string) => `'${c}'`).join(', ');\n const refCols = fk.references.columns.map((c: string) => `'${c}'`).join(', ');\n const name = fk.name ? `; readonly name: '${fk.name}'` : '';\n return `{ readonly columns: readonly [${cols}]; readonly references: { readonly table: '${fk.references.table}'; readonly columns: readonly [${refCols}] }${name} }`;\n })\n .join(', ');\n tableParts.push(`foreignKeys: readonly [${fks}]`);\n\n tables.push(`readonly ${tableName}: { ${tableParts.join('; ')} }`);\n }\n\n return `{ readonly tables: { ${tables.join('; ')} } }`;\n },\n\n generateModelsType(\n models: Record<string, ModelDefinition> | undefined,\n storage: SqlStorage,\n ): string {\n if (!models) {\n return 'Record<string, never>';\n }\n\n const modelTypes: string[] = [];\n for (const [modelName, model] of Object.entries(models)) {\n const fields: string[] = [];\n const tableName = model.storage.table;\n const table = storage.tables[tableName];\n\n if (table) {\n for (const [fieldName, field] of Object.entries(model.fields)) {\n const column = table.columns[field.column];\n if (!column) {\n fields.push(`readonly ${fieldName}: { readonly column: '${field.column}' }`);\n continue;\n }\n\n const typeId = column.codecId;\n const nullable = column.nullable ?? false;\n const jsType = nullable\n ? `CodecTypes['${typeId}']['output'] | null`\n : `CodecTypes['${typeId}']['output']`;\n\n fields.push(`readonly ${fieldName}: ${jsType}`);\n }\n } else {\n for (const [fieldName, field] of Object.entries(model.fields)) {\n fields.push(`readonly ${fieldName}: { readonly column: '${field.column}' }`);\n }\n }\n\n const relations: string[] = [];\n for (const [relName, rel] of Object.entries(model.relations)) {\n if (typeof rel === 'object' && rel !== null && 'on' in rel) {\n const on = rel.on as { parentCols?: string[]; childCols?: string[] };\n if (on.parentCols && on.childCols) {\n const parentCols = on.parentCols.map((c) => `'${c}'`).join(', ');\n const childCols = on.childCols.map((c) => `'${c}'`).join(', ');\n relations.push(\n `readonly ${relName}: { readonly on: { readonly parentCols: readonly [${parentCols}]; readonly childCols: readonly [${childCols}] } }`,\n );\n }\n }\n }\n\n const modelParts: string[] = [\n `storage: { readonly table: '${tableName}' }`,\n `fields: { ${fields.join('; ')} }`,\n ];\n\n if (relations.length > 0) {\n modelParts.push(`relations: { ${relations.join('; ')} }`);\n }\n\n modelTypes.push(`readonly ${modelName}: { ${modelParts.join('; ')} }`);\n }\n\n return `{ ${modelTypes.join('; ')} }`;\n },\n\n generateRelationsType(relations: Record<string, unknown> | undefined): string {\n if (!relations || Object.keys(relations).length === 0) {\n return 'Record<string, never>';\n }\n\n const tableEntries: string[] = [];\n for (const [tableName, relsValue] of Object.entries(relations)) {\n if (typeof relsValue !== 'object' || relsValue === null) {\n continue;\n }\n const rels = relsValue as Record<string, unknown>;\n const relationEntries: string[] = [];\n for (const [relName, relValue] of Object.entries(rels)) {\n if (typeof relValue !== 'object' || relValue === null) {\n relationEntries.push(`readonly ${relName}: unknown`);\n continue;\n }\n const { to, cardinality, on, through } = relValue as {\n readonly to?: string;\n readonly cardinality?: string;\n readonly on?: {\n readonly parentCols?: readonly string[];\n readonly childCols?: readonly string[];\n };\n readonly through?: {\n readonly table: string;\n readonly parentCols: readonly string[];\n readonly childCols: readonly string[];\n };\n };\n\n const parts: string[] = [];\n if (to) {\n parts.push(`readonly to: '${to}'`);\n }\n if (cardinality) {\n parts.push(`readonly cardinality: '${cardinality}'`);\n }\n if (on?.parentCols && on.childCols) {\n const parentCols = on.parentCols.map((c) => `'${c}'`).join(', ');\n const childCols = on.childCols.map((c) => `'${c}'`).join(', ');\n parts.push(\n `readonly on: { readonly parentCols: readonly [${parentCols}]; readonly childCols: readonly [${childCols}] }`,\n );\n }\n if (through) {\n const parentCols = through.parentCols.map((c) => `'${c}'`).join(', ');\n const childCols = through.childCols.map((c) => `'${c}'`).join(', ');\n parts.push(\n `readonly through: { readonly table: '${through.table}'; readonly parentCols: readonly [${parentCols}]; readonly childCols: readonly [${childCols}] }`,\n );\n }\n\n relationEntries.push(\n parts.length > 0\n ? `readonly ${relName}: { ${parts.join('; ')} }`\n : `readonly ${relName}: unknown`,\n );\n }\n tableEntries.push(`readonly ${tableName}: { ${relationEntries.join('; ')} }`);\n }\n\n return `{ ${tableEntries.join('; ')} }`;\n },\n\n generateMappingsType(\n models: Record<string, ModelDefinition> | undefined,\n storage: SqlStorage,\n codecTypes: string,\n operationTypes: string,\n ): string {\n if (!models) {\n return `SqlMappings & { readonly codecTypes: ${codecTypes || 'Record<string, never>'}; readonly operationTypes: ${operationTypes || 'Record<string, never>'}; }`;\n }\n\n const modelToTable: string[] = [];\n const tableToModel: string[] = [];\n const fieldToColumn: string[] = [];\n const columnToField: string[] = [];\n\n for (const [modelName, model] of Object.entries(models)) {\n const tableName = model.storage.table;\n modelToTable.push(`readonly ${modelName}: '${tableName}'`);\n tableToModel.push(`readonly ${tableName}: '${modelName}'`);\n\n const fieldMap: string[] = [];\n for (const [fieldName, field] of Object.entries(model.fields)) {\n fieldMap.push(`readonly ${fieldName}: '${field.column}'`);\n }\n\n if (fieldMap.length > 0) {\n fieldToColumn.push(`readonly ${modelName}: { ${fieldMap.join('; ')} }`);\n }\n\n if (storage.tables[tableName]) {\n const colMap: string[] = [];\n for (const [fieldName, field] of Object.entries(model.fields)) {\n colMap.push(`readonly ${field.column}: '${fieldName}'`);\n }\n\n if (colMap.length > 0) {\n columnToField.push(`readonly ${tableName}: { ${colMap.join('; ')} }`);\n }\n }\n }\n\n const parts: string[] = [];\n if (modelToTable.length > 0) {\n parts.push(`modelToTable: { ${modelToTable.join('; ')} }`);\n }\n if (tableToModel.length > 0) {\n parts.push(`tableToModel: { ${tableToModel.join('; ')} }`);\n }\n if (fieldToColumn.length > 0) {\n parts.push(`fieldToColumn: { ${fieldToColumn.join('; ')} }`);\n }\n if (columnToField.length > 0) {\n parts.push(`columnToField: { ${columnToField.join('; ')} }`);\n }\n parts.push(`codecTypes: ${codecTypes || 'Record<string, never>'}`);\n parts.push(`operationTypes: ${operationTypes || 'Record<string, never>'}`);\n\n return `{ ${parts.join('; ')} }`;\n },\n} as const;\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../src/index.ts"],"sourcesContent":["import type { ContractIR } from '@prisma-next/contract/ir';\nimport type {\n GenerateContractTypesOptions,\n TypesImportSpec,\n ValidationContext,\n} from '@prisma-next/contract/types';\nimport type {\n ModelDefinition,\n ModelField,\n SqlStorage,\n StorageColumn,\n StorageTable,\n} from '@prisma-next/sql-contract/types';\nimport { assertDefined } from '@prisma-next/utils/assertions';\n\nexport const sqlTargetFamilyHook = {\n id: 'sql',\n\n validateTypes(ir: ContractIR, _ctx: ValidationContext): void {\n const storage = ir.storage as SqlStorage | undefined;\n if (!storage || !storage.tables) {\n return;\n }\n\n // Validate codec ID format (ns/name@version). Adapter-provided codecs are available regardless of contract.extensionPacks (which is for framework extensions); TypeScript prevents invalid usage and runtime validates availability.\n\n const typeIdRegex = /^([^/]+)\\/([^@]+)@(\\d+)$/;\n\n for (const [tableName, tableUnknown] of Object.entries(storage.tables)) {\n const table = tableUnknown as StorageTable;\n for (const [colName, colUnknown] of Object.entries(table.columns)) {\n const col = colUnknown as { codecId?: string };\n const codecId = col.codecId;\n if (!codecId) {\n throw new Error(`Column \"${colName}\" in table \"${tableName}\" is missing codecId`);\n }\n\n const match = codecId.match(typeIdRegex);\n if (!match || !match[1]) {\n throw new Error(\n `Column \"${colName}\" in table \"${tableName}\" has invalid codec ID format \"${codecId}\". Expected format: ns/name@version`,\n );\n }\n }\n }\n },\n\n validateStructure(ir: ContractIR): void {\n if (ir.targetFamily !== 'sql') {\n throw new Error(`Expected targetFamily \"sql\", got \"${ir.targetFamily}\"`);\n }\n\n const storage = ir.storage as SqlStorage | undefined;\n if (!storage || !storage.tables) {\n throw new Error('SQL contract must have storage.tables');\n }\n\n const models = ir.models as Record<string, ModelDefinition> | undefined;\n const tableNames = new Set(Object.keys(storage.tables));\n\n if (models) {\n for (const [modelName, modelUnknown] of Object.entries(models)) {\n const model = modelUnknown as ModelDefinition;\n if (!model.storage?.table) {\n throw new Error(`Model \"${modelName}\" is missing storage.table`);\n }\n\n const tableName = model.storage.table;\n if (!tableNames.has(tableName)) {\n throw new Error(`Model \"${modelName}\" references non-existent table \"${tableName}\"`);\n }\n\n const table: StorageTable | undefined = storage.tables[tableName];\n assertDefined(table, `Model \"${modelName}\" references non-existent table \"${tableName}\"`);\n\n if (!table.primaryKey) {\n throw new Error(`Model \"${modelName}\" table \"${tableName}\" is missing a primary key`);\n }\n\n const columnNames = new Set(Object.keys(table.columns));\n if (!model.fields || Object.keys(model.fields).length === 0) {\n throw new Error(`Model \"${modelName}\" is missing fields`);\n }\n\n for (const [fieldName, fieldUnknown] of Object.entries(model.fields)) {\n const field = fieldUnknown as ModelField;\n if (!field.column) {\n throw new Error(`Model \"${modelName}\" field \"${fieldName}\" is missing column property`);\n }\n\n if (!columnNames.has(field.column)) {\n throw new Error(\n `Model \"${modelName}\" field \"${fieldName}\" references non-existent column \"${field.column}\" in table \"${tableName}\"`,\n );\n }\n }\n\n if (!model.relations || typeof model.relations !== 'object') {\n throw new Error(\n `Model \"${modelName}\" is missing required field \"relations\" (must be an object)`,\n );\n }\n }\n }\n\n for (const [tableName, tableUnknown] of Object.entries(storage.tables)) {\n const table = tableUnknown as StorageTable;\n const columnNames = new Set(Object.keys(table.columns));\n\n // Column structure (nullable, nativeType, codecId) and table arrays (uniques, indexes, foreignKeys)\n // are validated by Arktype schema validation - no need to re-check here.\n // We only validate logical consistency (foreign key references, model references, etc.)\n\n if (!Array.isArray(table.uniques)) {\n throw new Error(\n `Table \"${tableName}\" is missing required field \"uniques\" (must be an array)`,\n );\n }\n if (!Array.isArray(table.indexes)) {\n throw new Error(\n `Table \"${tableName}\" is missing required field \"indexes\" (must be an array)`,\n );\n }\n if (!Array.isArray(table.foreignKeys)) {\n throw new Error(\n `Table \"${tableName}\" is missing required field \"foreignKeys\" (must be an array)`,\n );\n }\n\n if (table.primaryKey) {\n for (const colName of table.primaryKey.columns) {\n if (!columnNames.has(colName)) {\n throw new Error(\n `Table \"${tableName}\" primaryKey references non-existent column \"${colName}\"`,\n );\n }\n }\n }\n\n for (const unique of table.uniques) {\n for (const colName of unique.columns) {\n if (!columnNames.has(colName)) {\n throw new Error(\n `Table \"${tableName}\" unique constraint references non-existent column \"${colName}\"`,\n );\n }\n }\n }\n\n for (const index of table.indexes) {\n for (const colName of index.columns) {\n if (!columnNames.has(colName)) {\n throw new Error(\n `Table \"${tableName}\" index references non-existent column \"${colName}\"`,\n );\n }\n }\n }\n\n for (const fk of table.foreignKeys) {\n for (const colName of fk.columns) {\n if (!columnNames.has(colName)) {\n throw new Error(\n `Table \"${tableName}\" foreignKey references non-existent column \"${colName}\"`,\n );\n }\n }\n\n if (!tableNames.has(fk.references.table)) {\n throw new Error(\n `Table \"${tableName}\" foreignKey references non-existent table \"${fk.references.table}\"`,\n );\n }\n\n // Table existence guaranteed by Set.has() check above\n const referencedTable: StorageTable | undefined = storage.tables[fk.references.table];\n assertDefined(\n referencedTable,\n `Table \"${tableName}\" foreignKey references non-existent table \"${fk.references.table}\"`,\n );\n\n const referencedColumnNames = new Set(Object.keys(referencedTable.columns));\n for (const colName of fk.references.columns) {\n if (!referencedColumnNames.has(colName)) {\n throw new Error(\n `Table \"${tableName}\" foreignKey references non-existent column \"${colName}\" in table \"${fk.references.table}\"`,\n );\n }\n }\n\n if (fk.columns.length !== fk.references.columns.length) {\n throw new Error(\n `Table \"${tableName}\" foreignKey column count (${fk.columns.length}) does not match referenced column count (${fk.references.columns.length})`,\n );\n }\n }\n }\n },\n\n generateContractTypes(\n ir: ContractIR,\n codecTypeImports: ReadonlyArray<TypesImportSpec>,\n operationTypeImports: ReadonlyArray<TypesImportSpec>,\n options?: GenerateContractTypesOptions,\n ): string {\n const allImports = [...codecTypeImports, ...operationTypeImports];\n const importLines = allImports.map(\n (imp) => `import type { ${imp.named} as ${imp.alias} } from '${imp.package}';`,\n );\n\n const codecTypes = codecTypeImports.map((imp) => imp.alias).join(' & ');\n const operationTypes = operationTypeImports.map((imp) => imp.alias).join(' & ');\n\n const storage = ir.storage as SqlStorage;\n const models = ir.models as Record<string, ModelDefinition>;\n const parameterizedRenderers = options?.parameterizedRenderers;\n\n const storageType = this.generateStorageType(storage);\n const modelsType = this.generateModelsType(models, storage, parameterizedRenderers);\n const relationsType = this.generateRelationsType(ir.relations);\n const mappingsType = this.generateMappingsType(models, storage, codecTypes, operationTypes);\n\n return `// ⚠️ GENERATED FILE - DO NOT EDIT\n// This file is automatically generated by 'prisma-next contract emit'.\n// To regenerate, run: prisma-next contract emit\n${importLines.join('\\n')}\n\nimport type { SqlContract, SqlStorage, SqlMappings, ModelDefinition } from '@prisma-next/sql-contract/types';\n\nexport type CodecTypes = ${codecTypes || 'Record<string, never>'};\nexport type LaneCodecTypes = CodecTypes;\nexport type OperationTypes = ${operationTypes || 'Record<string, never>'};\n\nexport type Contract = SqlContract<\n ${storageType},\n ${modelsType},\n ${relationsType},\n ${mappingsType}\n>;\n\nexport type Tables = Contract['storage']['tables'];\nexport type Models = Contract['models'];\nexport type Relations = Contract['relations'];\n`;\n },\n\n generateStorageType(storage: SqlStorage): string {\n const tables: string[] = [];\n for (const [tableName, table] of Object.entries(storage.tables)) {\n const columns: string[] = [];\n for (const [colName, col] of Object.entries(table.columns)) {\n const nullable = col.nullable ? 'true' : 'false';\n const nativeType = `'${col.nativeType}'`;\n const codecId = `'${col.codecId}'`;\n columns.push(\n `readonly ${colName}: { readonly nativeType: ${nativeType}; readonly codecId: ${codecId}; readonly nullable: ${nullable} }`,\n );\n }\n\n const tableParts: string[] = [`columns: { ${columns.join('; ')} }`];\n\n if (table.primaryKey) {\n const pkCols = table.primaryKey.columns.map((c) => `'${c}'`).join(', ');\n const pkName = table.primaryKey.name ? `; readonly name: '${table.primaryKey.name}'` : '';\n tableParts.push(`primaryKey: { readonly columns: readonly [${pkCols}]${pkName} }`);\n }\n\n const uniques = table.uniques\n .map((u) => {\n const cols = u.columns.map((c: string) => `'${c}'`).join(', ');\n const name = u.name ? `; readonly name: '${u.name}'` : '';\n return `{ readonly columns: readonly [${cols}]${name} }`;\n })\n .join(', ');\n tableParts.push(`uniques: readonly [${uniques}]`);\n\n const indexes = table.indexes\n .map((i) => {\n const cols = i.columns.map((c: string) => `'${c}'`).join(', ');\n const name = i.name ? `; readonly name: '${i.name}'` : '';\n return `{ readonly columns: readonly [${cols}]${name} }`;\n })\n .join(', ');\n tableParts.push(`indexes: readonly [${indexes}]`);\n\n const fks = table.foreignKeys\n .map((fk) => {\n const cols = fk.columns.map((c: string) => `'${c}'`).join(', ');\n const refCols = fk.references.columns.map((c: string) => `'${c}'`).join(', ');\n const name = fk.name ? `; readonly name: '${fk.name}'` : '';\n return `{ readonly columns: readonly [${cols}]; readonly references: { readonly table: '${fk.references.table}'; readonly columns: readonly [${refCols}] }${name} }`;\n })\n .join(', ');\n tableParts.push(`foreignKeys: readonly [${fks}]`);\n\n tables.push(`readonly ${tableName}: { ${tableParts.join('; ')} }`);\n }\n\n return `{ readonly tables: { ${tables.join('; ')} } }`;\n },\n\n /**\n * Renders the TypeScript type for a column.\n * Uses parameterized renderer if column has typeParams and renderer exists.\n * Falls back to CodecTypes['codecId']['output'] for scalar codecs.\n */\n renderColumnType(\n column: StorageColumn,\n storage: SqlStorage,\n parameterizedRenderers?: GenerateContractTypesOptions['parameterizedRenderers'],\n ): string {\n const codecId = column.codecId;\n\n // Check for typeRef - use the referenced type instance's params\n if (column.typeRef && storage.types) {\n const typeInstance = storage.types[column.typeRef];\n if (typeInstance) {\n const renderer = parameterizedRenderers?.get(typeInstance.codecId);\n if (renderer) {\n return renderer.render(typeInstance.typeParams, { codecTypesName: 'CodecTypes' });\n }\n }\n }\n\n // Check for inline typeParams\n if (column.typeParams) {\n const renderer = parameterizedRenderers?.get(codecId);\n if (renderer) {\n return renderer.render(column.typeParams, { codecTypesName: 'CodecTypes' });\n }\n }\n\n // Default: scalar codec type\n return `CodecTypes['${codecId}']['output']`;\n },\n\n generateModelsType(\n models: Record<string, ModelDefinition> | undefined,\n storage: SqlStorage,\n parameterizedRenderers?: GenerateContractTypesOptions['parameterizedRenderers'],\n ): string {\n if (!models) {\n return 'Record<string, never>';\n }\n\n const modelTypes: string[] = [];\n for (const [modelName, model] of Object.entries(models)) {\n const fields: string[] = [];\n const tableName = model.storage.table;\n const table = storage.tables[tableName];\n\n if (table) {\n for (const [fieldName, field] of Object.entries(model.fields)) {\n const column = table.columns[field.column];\n if (!column) {\n fields.push(`readonly ${fieldName}: { readonly column: '${field.column}' }`);\n continue;\n }\n\n const baseType = this.renderColumnType(column, storage, parameterizedRenderers);\n const nullable = column.nullable ?? false;\n const jsType = nullable ? `${baseType} | null` : baseType;\n\n fields.push(`readonly ${fieldName}: ${jsType}`);\n }\n } else {\n for (const [fieldName, field] of Object.entries(model.fields)) {\n fields.push(`readonly ${fieldName}: { readonly column: '${field.column}' }`);\n }\n }\n\n const relations: string[] = [];\n for (const [relName, rel] of Object.entries(model.relations)) {\n if (typeof rel === 'object' && rel !== null && 'on' in rel) {\n const on = rel.on as { parentCols?: string[]; childCols?: string[] };\n if (on.parentCols && on.childCols) {\n const parentCols = on.parentCols.map((c) => `'${c}'`).join(', ');\n const childCols = on.childCols.map((c) => `'${c}'`).join(', ');\n relations.push(\n `readonly ${relName}: { readonly on: { readonly parentCols: readonly [${parentCols}]; readonly childCols: readonly [${childCols}] } }`,\n );\n }\n }\n }\n\n const modelParts: string[] = [\n `storage: { readonly table: '${tableName}' }`,\n `fields: { ${fields.join('; ')} }`,\n ];\n\n if (relations.length > 0) {\n modelParts.push(`relations: { ${relations.join('; ')} }`);\n }\n\n modelTypes.push(`readonly ${modelName}: { ${modelParts.join('; ')} }`);\n }\n\n return `{ ${modelTypes.join('; ')} }`;\n },\n\n generateRelationsType(relations: Record<string, unknown> | undefined): string {\n if (!relations || Object.keys(relations).length === 0) {\n return 'Record<string, never>';\n }\n\n const tableEntries: string[] = [];\n for (const [tableName, relsValue] of Object.entries(relations)) {\n if (typeof relsValue !== 'object' || relsValue === null) {\n continue;\n }\n const rels = relsValue as Record<string, unknown>;\n const relationEntries: string[] = [];\n for (const [relName, relValue] of Object.entries(rels)) {\n if (typeof relValue !== 'object' || relValue === null) {\n relationEntries.push(`readonly ${relName}: unknown`);\n continue;\n }\n const { to, cardinality, on, through } = relValue as {\n readonly to?: string;\n readonly cardinality?: string;\n readonly on?: {\n readonly parentCols?: readonly string[];\n readonly childCols?: readonly string[];\n };\n readonly through?: {\n readonly table: string;\n readonly parentCols: readonly string[];\n readonly childCols: readonly string[];\n };\n };\n\n const parts: string[] = [];\n if (to) {\n parts.push(`readonly to: '${to}'`);\n }\n if (cardinality) {\n parts.push(`readonly cardinality: '${cardinality}'`);\n }\n if (on?.parentCols && on.childCols) {\n const parentCols = on.parentCols.map((c) => `'${c}'`).join(', ');\n const childCols = on.childCols.map((c) => `'${c}'`).join(', ');\n parts.push(\n `readonly on: { readonly parentCols: readonly [${parentCols}]; readonly childCols: readonly [${childCols}] }`,\n );\n }\n if (through) {\n const parentCols = through.parentCols.map((c) => `'${c}'`).join(', ');\n const childCols = through.childCols.map((c) => `'${c}'`).join(', ');\n parts.push(\n `readonly through: { readonly table: '${through.table}'; readonly parentCols: readonly [${parentCols}]; readonly childCols: readonly [${childCols}] }`,\n );\n }\n\n relationEntries.push(\n parts.length > 0\n ? `readonly ${relName}: { ${parts.join('; ')} }`\n : `readonly ${relName}: unknown`,\n );\n }\n tableEntries.push(`readonly ${tableName}: { ${relationEntries.join('; ')} }`);\n }\n\n return `{ ${tableEntries.join('; ')} }`;\n },\n\n generateMappingsType(\n models: Record<string, ModelDefinition> | undefined,\n storage: SqlStorage,\n codecTypes: string,\n operationTypes: string,\n ): string {\n if (!models) {\n return `SqlMappings & { readonly codecTypes: ${codecTypes || 'Record<string, never>'}; readonly operationTypes: ${operationTypes || 'Record<string, never>'}; }`;\n }\n\n const modelToTable: string[] = [];\n const tableToModel: string[] = [];\n const fieldToColumn: string[] = [];\n const columnToField: string[] = [];\n\n for (const [modelName, model] of Object.entries(models)) {\n const tableName = model.storage.table;\n modelToTable.push(`readonly ${modelName}: '${tableName}'`);\n tableToModel.push(`readonly ${tableName}: '${modelName}'`);\n\n const fieldMap: string[] = [];\n for (const [fieldName, field] of Object.entries(model.fields)) {\n fieldMap.push(`readonly ${fieldName}: '${field.column}'`);\n }\n\n if (fieldMap.length > 0) {\n fieldToColumn.push(`readonly ${modelName}: { ${fieldMap.join('; ')} }`);\n }\n\n if (storage.tables[tableName]) {\n const colMap: string[] = [];\n for (const [fieldName, field] of Object.entries(model.fields)) {\n colMap.push(`readonly ${field.column}: '${fieldName}'`);\n }\n\n if (colMap.length > 0) {\n columnToField.push(`readonly ${tableName}: { ${colMap.join('; ')} }`);\n }\n }\n }\n\n const parts: string[] = [];\n if (modelToTable.length > 0) {\n parts.push(`modelToTable: { ${modelToTable.join('; ')} }`);\n }\n if (tableToModel.length > 0) {\n parts.push(`tableToModel: { ${tableToModel.join('; ')} }`);\n }\n if (fieldToColumn.length > 0) {\n parts.push(`fieldToColumn: { ${fieldToColumn.join('; ')} }`);\n }\n if (columnToField.length > 0) {\n parts.push(`columnToField: { ${columnToField.join('; ')} }`);\n }\n parts.push(`codecTypes: ${codecTypes || 'Record<string, never>'}`);\n parts.push(`operationTypes: ${operationTypes || 'Record<string, never>'}`);\n\n return `{ ${parts.join('; ')} }`;\n },\n} as const;\n"],"mappings":"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","names":[]}
package/package.json CHANGED
@@ -1,13 +1,14 @@
1
1
  {
2
2
  "name": "@prisma-next/sql-contract-emitter",
3
- "version": "0.3.0-dev.24",
3
+ "version": "0.3.0-dev.25",
4
4
  "type": "module",
5
5
  "sideEffects": false,
6
6
  "description": "SQL emitter hook for Prisma Next",
7
7
  "dependencies": {
8
- "@prisma-next/emitter": "0.3.0-dev.24",
9
- "@prisma-next/contract": "0.3.0-dev.24",
10
- "@prisma-next/sql-contract": "0.3.0-dev.24"
8
+ "@prisma-next/contract": "0.3.0-dev.25",
9
+ "@prisma-next/emitter": "0.3.0-dev.25",
10
+ "@prisma-next/sql-contract": "0.3.0-dev.25",
11
+ "@prisma-next/utils": "0.3.0-dev.25"
11
12
  },
12
13
  "devDependencies": {
13
14
  "tsup": "8.5.1",
package/src/index.ts CHANGED
@@ -1,11 +1,17 @@
1
1
  import type { ContractIR } from '@prisma-next/contract/ir';
2
- import type { TypesImportSpec, ValidationContext } from '@prisma-next/contract/types';
2
+ import type {
3
+ GenerateContractTypesOptions,
4
+ TypesImportSpec,
5
+ ValidationContext,
6
+ } from '@prisma-next/contract/types';
3
7
  import type {
4
8
  ModelDefinition,
5
9
  ModelField,
6
10
  SqlStorage,
11
+ StorageColumn,
7
12
  StorageTable,
8
13
  } from '@prisma-next/sql-contract/types';
14
+ import { assertDefined } from '@prisma-next/utils/assertions';
9
15
 
10
16
  export const sqlTargetFamilyHook = {
11
17
  id: 'sql',
@@ -64,10 +70,8 @@ export const sqlTargetFamilyHook = {
64
70
  throw new Error(`Model "${modelName}" references non-existent table "${tableName}"`);
65
71
  }
66
72
 
67
- const table = storage.tables[tableName];
68
- if (!table) {
69
- throw new Error(`Model "${modelName}" references non-existent table "${tableName}"`);
70
- }
73
+ const table: StorageTable | undefined = storage.tables[tableName];
74
+ assertDefined(table, `Model "${modelName}" references non-existent table "${tableName}"`);
71
75
 
72
76
  if (!table.primaryKey) {
73
77
  throw new Error(`Model "${modelName}" table "${tableName}" is missing a primary key`);
@@ -168,12 +172,12 @@ export const sqlTargetFamilyHook = {
168
172
  );
169
173
  }
170
174
 
171
- const referencedTable = storage.tables[fk.references.table];
172
- if (!referencedTable) {
173
- throw new Error(
174
- `Table "${tableName}" foreignKey references non-existent table "${fk.references.table}"`,
175
- );
176
- }
175
+ // Table existence guaranteed by Set.has() check above
176
+ const referencedTable: StorageTable | undefined = storage.tables[fk.references.table];
177
+ assertDefined(
178
+ referencedTable,
179
+ `Table "${tableName}" foreignKey references non-existent table "${fk.references.table}"`,
180
+ );
177
181
 
178
182
  const referencedColumnNames = new Set(Object.keys(referencedTable.columns));
179
183
  for (const colName of fk.references.columns) {
@@ -197,6 +201,7 @@ export const sqlTargetFamilyHook = {
197
201
  ir: ContractIR,
198
202
  codecTypeImports: ReadonlyArray<TypesImportSpec>,
199
203
  operationTypeImports: ReadonlyArray<TypesImportSpec>,
204
+ options?: GenerateContractTypesOptions,
200
205
  ): string {
201
206
  const allImports = [...codecTypeImports, ...operationTypeImports];
202
207
  const importLines = allImports.map(
@@ -208,9 +213,10 @@ export const sqlTargetFamilyHook = {
208
213
 
209
214
  const storage = ir.storage as SqlStorage;
210
215
  const models = ir.models as Record<string, ModelDefinition>;
216
+ const parameterizedRenderers = options?.parameterizedRenderers;
211
217
 
212
218
  const storageType = this.generateStorageType(storage);
213
- const modelsType = this.generateModelsType(models, storage);
219
+ const modelsType = this.generateModelsType(models, storage, parameterizedRenderers);
214
220
  const relationsType = this.generateRelationsType(ir.relations);
215
221
  const mappingsType = this.generateMappingsType(models, storage, codecTypes, operationTypes);
216
222
 
@@ -293,9 +299,45 @@ export type Relations = Contract['relations'];
293
299
  return `{ readonly tables: { ${tables.join('; ')} } }`;
294
300
  },
295
301
 
302
+ /**
303
+ * Renders the TypeScript type for a column.
304
+ * Uses parameterized renderer if column has typeParams and renderer exists.
305
+ * Falls back to CodecTypes['codecId']['output'] for scalar codecs.
306
+ */
307
+ renderColumnType(
308
+ column: StorageColumn,
309
+ storage: SqlStorage,
310
+ parameterizedRenderers?: GenerateContractTypesOptions['parameterizedRenderers'],
311
+ ): string {
312
+ const codecId = column.codecId;
313
+
314
+ // Check for typeRef - use the referenced type instance's params
315
+ if (column.typeRef && storage.types) {
316
+ const typeInstance = storage.types[column.typeRef];
317
+ if (typeInstance) {
318
+ const renderer = parameterizedRenderers?.get(typeInstance.codecId);
319
+ if (renderer) {
320
+ return renderer.render(typeInstance.typeParams, { codecTypesName: 'CodecTypes' });
321
+ }
322
+ }
323
+ }
324
+
325
+ // Check for inline typeParams
326
+ if (column.typeParams) {
327
+ const renderer = parameterizedRenderers?.get(codecId);
328
+ if (renderer) {
329
+ return renderer.render(column.typeParams, { codecTypesName: 'CodecTypes' });
330
+ }
331
+ }
332
+
333
+ // Default: scalar codec type
334
+ return `CodecTypes['${codecId}']['output']`;
335
+ },
336
+
296
337
  generateModelsType(
297
338
  models: Record<string, ModelDefinition> | undefined,
298
339
  storage: SqlStorage,
340
+ parameterizedRenderers?: GenerateContractTypesOptions['parameterizedRenderers'],
299
341
  ): string {
300
342
  if (!models) {
301
343
  return 'Record<string, never>';
@@ -315,11 +357,9 @@ export type Relations = Contract['relations'];
315
357
  continue;
316
358
  }
317
359
 
318
- const typeId = column.codecId;
360
+ const baseType = this.renderColumnType(column, storage, parameterizedRenderers);
319
361
  const nullable = column.nullable ?? false;
320
- const jsType = nullable
321
- ? `CodecTypes['${typeId}']['output'] | null`
322
- : `CodecTypes['${typeId}']['output']`;
362
+ const jsType = nullable ? `${baseType} | null` : baseType;
323
363
 
324
364
  fields.push(`readonly ${fieldName}: ${jsType}`);
325
365
  }