🎩 You're Invited:Meet the Socket team at Black Hat in Las Vegas, August 3-6.RSVP
Sign In

@prisma-next/sql-contract-emitter

Package Overview
Dependencies
Maintainers
4
Versions
972
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@prisma-next/sql-contract-emitter - npm Package Compare versions

Comparing version
0.14.0
to
0.15.0-dev.1
+7
-1
dist/index.d.mts

@@ -1,2 +0,3 @@

import { Contract, ContractModelBase } from "@prisma-next/contract/types";
import { Contract, ContractModelBase, JsonValue } from "@prisma-next/contract/types";
import { CodecLookup } from "@prisma-next/framework-components/codec";
import { GenerateContractTypesOptions, ValidationContext } from "@prisma-next/framework-components/emission";

@@ -12,2 +13,7 @@

readonly resolveFieldTypeParams: (_modelName: string, fieldName: string, model: ContractModelBase, contract: Contract) => Record<string, unknown> | undefined;
readonly resolveFieldValueSet: (_modelName: string, fieldName: string, model: ContractModelBase, contract: Contract) => {
readonly encodedValues: readonly JsonValue[];
readonly codecId: string;
} | undefined;
readonly getStorageTypeExports: (contract: Contract, codecLookup?: CodecLookup) => string | undefined;
readonly getFamilyImports: () => string[];

@@ -14,0 +20,0 @@ readonly getFamilyTypeAliases: (options?: GenerateContractTypesOptions) => string;

+1
-1

@@ -1,1 +0,1 @@

{"version":3,"file":"index.d.mts","names":[],"sources":["../src/index.ts"],"mappings":";;;;cAoCa,WAAA;EAAA;qCAGa,QAAA,EAAQ,IAAA,EAAQ,iBAAA;EAAA,uCA4BZ,QAAA;EAAA,yCA8KE,QAAA,EAAQ,mBAAA;EAAA,wDAQK,KAAA,EAAS,iBAAA;EAAA,sDAuBhC,SAAA,UACD,KAAA,EACV,iBAAA,EAAiB,QAAA,EACd,QAAA,KACT,MAAA;EAAA;4CAwC4B,4BAAA;EAAA;0DAwBY,YAAA;AAAA"}
{"version":3,"file":"index.d.mts","names":[],"sources":["../src/index.ts"],"mappings":";;;;;cA8Ca,WAAA;EAAA;qCAGa,QAAA,EAAQ,IAAA,EAAQ,iBAAA;EAAA,uCA4BZ,QAAA;EAAA,yCA8KE,QAAA,EAAQ,mBAAA;EAAA,wDAQK,KAAA,EAAS,iBAAA;EAAA,sDAuBhC,SAAA,UACD,KAAA,EACV,iBAAA,EAAiB,QAAA,EACd,QAAA,KACT,MAAA;EAAA,oDAgCiB,SAAA,UACD,KAAA,EACV,iBAAA,EAAiB,QAAA,EACd,QAAA;IAAA,SACE,aAAA,WAAwB,SAAA;IAAA,SAAsB,OAAA;EAAA;EAAA,2CAmC5B,QAAA,EAAQ,WAAA,GAAgB,WAAA;EAAA;4CAuBzB,4BAAA;EAAA;0DAwBY,YAAA;AAAA"}

@@ -1,3 +0,5 @@

import { serializeNamespaceId, serializeObjectKey, serializeValue } from "@prisma-next/emitter/domain-type-generation";
import { renderValueSetType, serializeNamespaceId, serializeObjectKey, serializeValue } from "@prisma-next/emitter/domain-type-generation";
import { isSafeTypeExpression } from "@prisma-next/emitter/type-expression-safety";
import { UNBOUND_NAMESPACE_ID, entityAt } from "@prisma-next/framework-components/ir";
import { blindCast } from "@prisma-next/utils/casts";
//#region src/index.ts

@@ -124,2 +126,34 @@ function serializeTypeParamsLiteral(params) {

},
resolveFieldValueSet(_modelName, fieldName, model, contract) {
const sqlModel = blindCast(model);
const storageField = sqlModel.storage?.fields?.[fieldName];
if (!storageField) return void 0;
const storage = blindCast(contract.storage);
if (!storage) return void 0;
const storageNamespaceId = sqlModel.storage.namespaceId;
if (!storageNamespaceId) return void 0;
const column = entityAt(storage, {
namespaceId: storageNamespaceId,
entityKind: "table",
entityName: sqlModel.storage.table
})?.columns[storageField.column];
if (!column?.valueSet) return void 0;
const valueSet = entityAt(storage, {
namespaceId: column.valueSet.namespaceId,
entityKind: column.valueSet.entityKind,
entityName: column.valueSet.entityName
});
if (!valueSet) return void 0;
return {
encodedValues: valueSet.values,
codecId: column.codecId
};
},
getStorageTypeExports(contract, codecLookup) {
const storage = blindCast(contract.storage);
if (!storage?.namespaces) return void 0;
const outputMap = generateStorageColumnTypesMap(storage, "output", codecLookup);
const inputMap = generateStorageColumnTypesMap(storage, "input", codecLookup);
return [`export type StorageColumnTypes = ${outputMap};`, `export type StorageColumnInputTypes = ${inputMap};`].join("\n");
},
getFamilyImports() {

@@ -145,3 +179,3 @@ return [

getTypeMapsExpression() {
return "TypeMapsType<CodecTypes, QueryOperationTypes, FieldOutputTypes, FieldInputTypes>";
return "TypeMapsType<CodecTypes, QueryOperationTypes, FieldOutputTypes, FieldInputTypes, StorageColumnTypes, StorageColumnInputTypes>";
},

@@ -156,2 +190,54 @@ getContractWrapper(contractBaseName, typeMapsName) {

};
function columnTypeParams(storage, column) {
if (column.typeRef) {
const typeInstance = storage.types?.[column.typeRef];
if (typeInstance === void 0) return void 0;
return blindCast(typeInstance).typeParams;
}
return column.typeParams;
}
function renderRefinedCodecType(column, side, params, codecLookup) {
if (codecLookup && params && Object.keys(params).length > 0) {
const rendered = side === "output" ? codecLookup.renderOutputTypeFor(column.codecId, params) : codecLookup.renderInputTypeFor?.(column.codecId, params);
if (rendered && isSafeTypeExpression(rendered)) return rendered;
}
return `CodecTypes[${serializeValue(column.codecId)}][${serializeValue(side)}]`;
}
function computeColumnType(storage, column, side, codecLookup) {
let base;
if (column.valueSet) {
const valueSet = entityAt(storage, {
namespaceId: column.valueSet.namespaceId,
entityKind: column.valueSet.entityKind,
entityName: column.valueSet.entityName
});
base = valueSet ? renderValueSetType(valueSet.values, column.codecId, side, codecLookup) : void 0;
}
if (base === void 0) base = renderRefinedCodecType(column, side, columnTypeParams(storage, column), codecLookup);
if (column.many === true) base = `ReadonlyArray<${base}>`;
return column.nullable ? `${base} | null` : base;
}
function generateStorageColumnTypesMap(storage, side, codecLookup) {
const namespaceEntries = Object.entries(storage.namespaces ?? {}).sort(([a], [b]) => a.localeCompare(b));
if (namespaceEntries.length === 0) return "Record<string, never>";
const nsParts = [];
for (const [nsId, ns] of namespaceEntries) {
const tables = blindCast(ns.entries.table ?? {});
const tableEntries = Object.entries(tables).sort(([a], [b]) => a.localeCompare(b));
const tableParts = [];
for (const [tableName, table] of tableEntries) {
const colEntries = Object.entries(table.columns).sort(([a], [b]) => a.localeCompare(b));
const colParts = [];
for (const [colName, col] of colEntries) {
const colType = computeColumnType(storage, col, side, codecLookup);
colParts.push(`readonly ${serializeObjectKey(colName)}: ${colType}`);
}
const colMap = colParts.length > 0 ? `{ ${colParts.join("; ")} }` : "{}";
tableParts.push(`readonly ${serializeObjectKey(tableName)}: ${colMap}`);
}
const tableMap = tableParts.length > 0 ? `{ ${tableParts.join("; ")} }` : "{}";
nsParts.push(`readonly ${serializeObjectKey(nsId)}: ${tableMap}`);
}
return `{ ${nsParts.join("; ")} }`;
}
function generateDocumentScopedStorageTypesType(types) {

@@ -170,12 +256,13 @@ if (!types || Object.keys(types).length === 0) return;

}
function generateNamespaceValueSetType(valueSet) {
if (Object.keys(valueSet).length === 0) return "Record<string, never>";
const entries = [];
for (const [name, vs] of Object.entries(valueSet)) {
const valuesLiteral = vs.values.map((v) => serializeValue(v)).join(", ");
entries.push(`readonly ${serializeObjectKey(name)}: { readonly kind: 'valueSet'; readonly values: readonly [${valuesLiteral}] }`);
}
return `{ ${entries.join("; ")} }`;
/**
* Literalizes the `valueSet` entries slot — a core SQL entity kind (alongside
* `table`), not a pack-contributed one, so naming it here isn't a
* family→target layering leak. This is the only non-`table` entries slot with
* a type-level consumer (`db.nativeEnums`, `packages/3-extensions/postgres`):
* pack-contributed slots (`role`, `policy`, `native_enum`, …) have none and
* are not emitted.
*/
function generateValueSetBlockType(valueSets) {
return `{ ${Object.entries(valueSets).sort(([a], [b]) => a.localeCompare(b)).map(([name, valueSet]) => `readonly ${serializeObjectKey(name)}: ${serializeValue(valueSet)}`).join("; ")} }`;
}
const SQL_NAMESPACE_KIND_FALLBACK = "sql-namespace";
function namespaceSerializedKind(ns) {

@@ -185,3 +272,3 @@ const kind = ns.kind;

if (typeof kind === "string") return `readonly kind: ${serializeValue(kind)}`;
return `readonly kind: '${SQL_NAMESPACE_KIND_FALLBACK}'`;
throw new Error(`Namespace '${ns.id}' has no string kind — all namespaces must be target concretions with a defined kind property.`);
}

@@ -217,3 +304,3 @@ function generateTableLiteralType(table) {

const name = fk.name ? `; readonly name: ${serializeValue(fk.name)}` : "";
return `{ readonly source: ${`{ readonly namespaceId: ${serializeNamespaceId(String(fk.source.namespaceId))}; readonly tableName: ${serializeValue(fk.source.tableName)}; readonly columns: readonly [${srcCols}] }`}; readonly target: ${`{ readonly namespaceId: ${serializeNamespaceId(String(fk.target.namespaceId))}; readonly tableName: ${serializeValue(fk.target.tableName)}; readonly columns: readonly [${tgtCols}] }`}${name}; readonly constraint: ${fk.constraint}; readonly index: ${fk.index} }`;
return `{ readonly source: ${`{ readonly namespaceId: ${serializeNamespaceId(String(fk.source.namespaceId))}; readonly tableName: ${serializeValue(fk.source.tableName)}; readonly columns: readonly [${srcCols}] }`}; readonly target: ${`{ readonly namespaceId: ${serializeNamespaceId(String(fk.target.namespaceId))}; readonly tableName: ${serializeValue(fk.target.tableName)}; readonly columns: readonly [${tgtCols}] }`}${name} }`;
}).join(", ");

@@ -235,6 +322,5 @@ tableParts.push(`foreignKeys: readonly [${fks}]`);

const kindSuffix = `; ${namespaceSerializedKind(ns)}`;
const tablesType = generateTablesMapType(ns.entries.table ?? {});
const valueSetSlot = ns.entries.valueSet;
const entriesParts = [`readonly table: ${tablesType}`];
if (valueSetSlot !== void 0 && Object.keys(valueSetSlot).length > 0) entriesParts.push(`readonly valueSet: ${generateNamespaceValueSetType(valueSetSlot)}`);
const entriesParts = [`readonly table: ${generateTablesMapType(ns.entries.table ?? {})}`];
const valueSetEntries = ns.entries.valueSet;
if (valueSetEntries !== void 0 && Object.keys(valueSetEntries).length > 0) entriesParts.push(`readonly valueSet: ${generateValueSetBlockType(valueSetEntries)}`);
const entriesType = `{ ${entriesParts.join("; ")} }`;

@@ -241,0 +327,0 @@ parts.push(`readonly ${serializeObjectKey(name)}: { readonly id: ${serializeValue(ns.id)}${kindSuffix}; readonly entries: ${entriesType} }`);

@@ -1,1 +0,1 @@

{"version":3,"file":"index.mjs","names":["col","codecShape"],"sources":["../src/index.ts"],"sourcesContent":["import type { Contract, ContractModel, ContractModelBase } from '@prisma-next/contract/types';\nimport {\n serializeNamespaceId,\n serializeObjectKey,\n serializeValue,\n} from '@prisma-next/emitter/domain-type-generation';\nimport type {\n GenerateContractTypesOptions,\n ValidationContext,\n} from '@prisma-next/framework-components/emission';\nimport {\n entityAt,\n type Namespace,\n UNBOUND_NAMESPACE_ID,\n} from '@prisma-next/framework-components/ir';\nimport type {\n SqlModelStorage,\n SqlStorage,\n StorageTable,\n StorageTypeInstance,\n StorageValueSet,\n} from '@prisma-next/sql-contract/types';\n\nfunction serializeTypeParamsLiteral(params: Record<string, unknown> | undefined): string {\n if (!params || Object.keys(params).length === 0) {\n return 'Record<string, never>';\n }\n\n const entries: string[] = [];\n for (const [key, value] of Object.entries(params)) {\n entries.push(`readonly ${serializeObjectKey(key)}: ${serializeValue(value)}`);\n }\n\n return `{ ${entries.join('; ')} }`;\n}\n\nexport const sqlEmission = {\n id: 'sql',\n\n validateTypes(contract: Contract, _ctx: ValidationContext): void {\n const storage = contract.storage as unknown as SqlStorage | undefined;\n if (!storage?.namespaces) {\n return;\n }\n\n const typeIdRegex = /^([^/]+)\\/([^@]+)@(\\d+)$/;\n\n for (const ns of Object.values(storage.namespaces)) {\n for (const [tableName, table] of Object.entries(ns.entries.table ?? {})) {\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?.[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\n validateStructure(contract: Contract): void {\n if (contract.targetFamily !== 'sql') {\n throw new Error(`Expected targetFamily \"sql\", got \"${contract.targetFamily}\"`);\n }\n\n const storage = contract.storage as unknown as SqlStorage | undefined;\n if (!storage?.namespaces) {\n throw new Error('SQL contract must have storage.namespaces');\n }\n\n const tableNamesSeenAcrossNamespaces = new Map<string, string>();\n for (const [nsId, ns] of Object.entries(storage.namespaces)) {\n for (const tableName of Object.keys(ns.entries.table ?? {})) {\n const existingNs = tableNamesSeenAcrossNamespaces.get(tableName);\n if (existingNs !== undefined && existingNs !== nsId) {\n throw new Error(\n `Duplicate table name \"${tableName}\" in namespaces \"${existingNs}\" and \"${nsId}\"`,\n );\n }\n tableNamesSeenAcrossNamespaces.set(tableName, nsId);\n }\n }\n\n const tableNames = new Set<string>();\n for (const ns of Object.values(storage.namespaces)) {\n for (const t of Object.keys(ns.entries.table ?? {})) {\n tableNames.add(t);\n }\n }\n\n for (const [namespaceId, domainNs] of Object.entries(contract.domain.namespaces)) {\n const models = domainNs.models as Record<string, ContractModel<SqlModelStorage>>;\n for (const [modelName, model] of Object.entries(models)) {\n const qualifiedName = `${namespaceId}:${modelName}`;\n if (!model.storage?.table) {\n throw new Error(`Model \"${qualifiedName}\" is missing storage.table`);\n }\n if (!model.storage.namespaceId) {\n throw new Error(`Model \"${qualifiedName}\" is missing storage.namespaceId`);\n }\n if (model.storage.namespaceId !== namespaceId) {\n throw new Error(\n `Model \"${qualifiedName}\" storage.namespaceId \"${model.storage.namespaceId}\" does not match domain namespace \"${namespaceId}\"`,\n );\n }\n\n const tableName = model.storage.table;\n const table = entityAt<StorageTable>(storage, {\n namespaceId,\n entityKind: 'table',\n entityName: tableName,\n });\n if (!table) {\n throw new Error(\n `Model \"${qualifiedName}\" references non-existent table \"${namespaceId}.${tableName}\"`,\n );\n }\n const columnNames = new Set(Object.keys(table.columns));\n const storageFields = model.storage.fields;\n if (!storageFields || Object.keys(storageFields).length === 0) {\n throw new Error(`Model \"${qualifiedName}\" is missing storage.fields`);\n }\n\n for (const [fieldName, field] of Object.entries(storageFields)) {\n if (!field.column) {\n throw new Error(\n `Model \"${qualifiedName}\" field \"${fieldName}\" is missing column property`,\n );\n }\n\n if (!columnNames.has(field.column)) {\n throw new Error(\n `Model \"${qualifiedName}\" 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 \"${qualifiedName}\" is missing required field \"relations\" (must be an object)`,\n );\n }\n }\n }\n\n for (const ns of Object.values(storage.namespaces)) {\n for (const [tableName, table] of Object.entries(ns.entries.table ?? {})) {\n const columnNames = new Set(Object.keys(table.columns));\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.source.columns) {\n if (!columnNames.has(colName)) {\n throw new Error(\n `Table \"${tableName}\" foreignKey references non-existent column \"${colName}\"`,\n );\n }\n }\n\n const referencedTable = entityAt<StorageTable>(storage, {\n namespaceId: fk.target.namespaceId,\n entityKind: 'table',\n entityName: fk.target.tableName,\n });\n if (!referencedTable) {\n throw new Error(\n `Table \"${tableName}\" foreignKey references non-existent table \"${fk.target.tableName}\" in namespace \"${fk.target.namespaceId}\"`,\n );\n }\n\n const referencedColumnNames = new Set(Object.keys(referencedTable.columns));\n for (const colName of fk.target.columns) {\n if (!referencedColumnNames.has(colName)) {\n throw new Error(\n `Table \"${tableName}\" foreignKey references non-existent column \"${colName}\" in table \"${fk.target.tableName}\"`,\n );\n }\n }\n\n if (fk.source.columns.length !== fk.target.columns.length) {\n throw new Error(\n `Table \"${tableName}\" foreignKey column count (${fk.source.columns.length}) does not match referenced column count (${fk.target.columns.length})`,\n );\n }\n }\n }\n }\n },\n\n generateStorageType(contract: Contract, storageHashTypeName: string): string {\n const storage = contract.storage as unknown as SqlStorage;\n const namespacesType = generateStorageNamespacesType(storage.namespaces);\n const docTypes = generateDocumentScopedStorageTypesType(storage.types);\n const typesClause = docTypes === undefined ? '' : `; readonly types: ${docTypes}`;\n return `{ readonly namespaces: ${namespacesType}${typesClause}; readonly storageHash: ${storageHashTypeName} }`;\n },\n\n generateModelStorageType(_modelName: string, model: ContractModelBase): string {\n const sqlModel = model as ContractModel<SqlModelStorage>;\n const tableName = sqlModel.storage.table;\n const storageFields = sqlModel.storage.fields;\n\n const storageParts = [\n `readonly table: ${serializeValue(tableName)}`,\n `readonly namespaceId: ${serializeValue(sqlModel.storage.namespaceId)}`,\n ];\n if (Object.keys(storageFields).length > 0) {\n const fieldParts: string[] = [];\n for (const [fieldName, field] of Object.entries(storageFields)) {\n fieldParts.push(\n `readonly ${serializeObjectKey(fieldName)}: { readonly column: ${serializeValue(field.column)} }`,\n );\n }\n storageParts.push(`readonly fields: { ${fieldParts.join('; ')} }`);\n }\n\n return `{ ${storageParts.join('; ')} }`;\n },\n\n resolveFieldTypeParams(\n _modelName: string,\n fieldName: string,\n model: ContractModelBase,\n contract: Contract,\n ): Record<string, unknown> | undefined {\n const sqlModel = model as ContractModel<SqlModelStorage>;\n const storageField = sqlModel.storage?.fields?.[fieldName];\n if (!storageField) return undefined;\n\n const storage = contract.storage as unknown as SqlStorage | undefined;\n if (!storage) return undefined;\n\n const tableName = sqlModel.storage.table;\n const storageNamespaceId = sqlModel.storage.namespaceId;\n if (!storageNamespaceId) return undefined;\n\n const table = entityAt<StorageTable>(storage, {\n namespaceId: storageNamespaceId,\n entityKind: 'table',\n entityName: tableName,\n });\n if (!table) return undefined;\n\n const column = table.columns[storageField.column];\n if (!column) return undefined;\n\n if (column.typeRef) {\n const typeInstance = storage.types?.[column.typeRef];\n if (typeInstance === undefined) return undefined;\n const codecShape = typeInstance as Partial<StorageTypeInstance>;\n return codecShape.typeParams;\n }\n return column.typeParams;\n },\n\n getFamilyImports(): string[] {\n return [\n 'import type {',\n ' ContractWithTypeMaps,',\n ' TypeMaps as TypeMapsType,',\n \"} from '@prisma-next/sql-contract/types';\",\n ];\n },\n\n getFamilyTypeAliases(options?: GenerateContractTypesOptions): string {\n const queryOperationTypeImports = options?.queryOperationTypeImports ?? [];\n const queryOperationAliases = queryOperationTypeImports\n .filter((imp) => imp.named === 'QueryOperationTypes')\n .map((imp) => `${imp.alias}<CodecTypes>`);\n const queryOperationTypes =\n queryOperationAliases.length > 0\n ? queryOperationAliases.join(' & ')\n : 'Record<string, never>';\n\n return [\n 'export type LaneCodecTypes = CodecTypes;',\n `export type QueryOperationTypes = ${queryOperationTypes};`,\n 'type DefaultLiteralValue<CodecId extends string, _Encoded> =',\n ' CodecId extends keyof CodecTypes',\n \" ? CodecTypes[CodecId]['output']\",\n ' : _Encoded;',\n ].join('\\n');\n },\n\n getTypeMapsExpression(): string {\n return 'TypeMapsType<CodecTypes, QueryOperationTypes, FieldOutputTypes, FieldInputTypes>';\n },\n\n getContractWrapper(contractBaseName: string, typeMapsName: string): string {\n return [\n `export type Contract = ContractWithTypeMaps<${contractBaseName}, ${typeMapsName}>;`,\n '',\n \"export type Namespaces = Contract['storage']['namespaces'];\",\n ].join('\\n');\n },\n} as const;\n\nfunction generateDocumentScopedStorageTypesType(types: SqlStorage['types']): string | undefined {\n if (!types || Object.keys(types).length === 0) {\n return undefined;\n }\n\n const typeEntries: string[] = [];\n for (const [typeName, typeInstance] of Object.entries(types)) {\n const codecInstanceShape = typeInstance as Partial<StorageTypeInstance>;\n if (\n typeof codecInstanceShape.codecId !== 'string' ||\n typeof codecInstanceShape.nativeType !== 'string'\n ) {\n throw new Error(\n `Unknown storage type kind for \"${typeName}\" in document-scoped storage.types; expected a codec-instance triple.`,\n );\n }\n const codecId = serializeValue(codecInstanceShape.codecId);\n const nativeType = serializeValue(codecInstanceShape.nativeType);\n const typeParamsStr = serializeTypeParamsLiteral(codecInstanceShape.typeParams);\n typeEntries.push(\n `readonly ${typeName}: { readonly kind: 'codec-instance'; readonly codecId: ${codecId}; readonly nativeType: ${nativeType}; readonly typeParams: ${typeParamsStr} }`,\n );\n }\n\n return `{ ${typeEntries.join('; ')} }`;\n}\n\nfunction generateNamespaceValueSetType(\n valueSet: Readonly<Record<string, StorageValueSet>>,\n): string {\n if (Object.keys(valueSet).length === 0) {\n return 'Record<string, never>';\n }\n const entries: string[] = [];\n for (const [name, vs] of Object.entries(valueSet)) {\n const valuesLiteral = vs.values.map((v) => serializeValue(v)).join(', ');\n entries.push(\n `readonly ${serializeObjectKey(name)}: { readonly kind: 'valueSet'; readonly values: readonly [${valuesLiteral}] }`,\n );\n }\n return `{ ${entries.join('; ')} }`;\n}\n\nconst SQL_NAMESPACE_KIND_FALLBACK = 'sql-namespace' as const;\n\nfunction namespaceSerializedKind(ns: Namespace): string {\n const kind = ns.kind;\n if (kind === 'schema') {\n const id = ns.id;\n const lit = id === UNBOUND_NAMESPACE_ID ? 'postgres-unbound-schema' : 'postgres-schema';\n return `readonly kind: '${lit}'`;\n }\n if (typeof kind === 'string') {\n return `readonly kind: ${serializeValue(kind)}`;\n }\n // Plain-literal namespaces built via the contract-ts DSL bypass the\n // class-level `Object.defineProperty(this, 'kind', { value, enumerable: false })`\n // path, so `ns.kind` is missing on the runtime object. Surfacing the\n // framework-default kind here keeps the emitted `.d.ts` literal\n // structurally assignable to `Namespace`, which now requires `kind`.\n return `readonly kind: '${SQL_NAMESPACE_KIND_FALLBACK}'`;\n}\n\nfunction generateTableLiteralType(table: StorageTable): string {\n const columns: string[] = [];\n for (const [colName, col] of Object.entries(table.columns)) {\n const nullable = col.nullable ? 'true' : 'false';\n const nativeType = serializeValue(col.nativeType);\n const codecId = serializeValue(col.codecId);\n const defaultSpec = col.default\n ? col.default.kind === 'literal'\n ? `; readonly default: { readonly kind: 'literal'; readonly value: DefaultLiteralValue<${codecId}, ${serializeValue(\n col.default.value,\n )}> }`\n : `; readonly default: { readonly kind: 'function'; readonly expression: ${serializeValue(\n col.default.expression,\n )} }`\n : '';\n const typeParamsSpec =\n col.typeParams && Object.keys(col.typeParams).length > 0\n ? `; readonly typeParams: ${serializeTypeParamsLiteral(col.typeParams)}`\n : '';\n const typeRefSpec = col.typeRef ? `; readonly typeRef: ${serializeValue(col.typeRef)}` : '';\n columns.push(\n `readonly ${colName}: { readonly nativeType: ${nativeType}; readonly codecId: ${codecId}; readonly nullable: ${nullable}${defaultSpec}${typeParamsSpec}${typeRefSpec} }`,\n );\n }\n\n const tableParts: string[] = [`columns: { ${columns.join('; ')} }`];\n\n if (table.primaryKey) {\n const pkCols = table.primaryKey.columns.map((c) => serializeValue(c)).join(', ');\n const pkName = table.primaryKey.name\n ? `; readonly name: ${serializeValue(table.primaryKey.name)}`\n : '';\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) => serializeValue(c)).join(', ');\n const name = u.name ? `; readonly name: ${serializeValue(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) => serializeValue(c)).join(', ');\n const name = i.name !== undefined ? `; readonly name: ${serializeValue(i.name)}` : '';\n const indexType = i.type !== undefined ? `; readonly type: ${serializeValue(i.type)}` : '';\n const indexOptions =\n i.options !== undefined ? `; readonly options: ${serializeValue(i.options)}` : '';\n return `{ readonly columns: readonly [${cols}]${name}${indexType}${indexOptions} }`;\n })\n .join(', ');\n tableParts.push(`indexes: readonly [${indexes}]`);\n\n const fks = table.foreignKeys\n .map((fk) => {\n const srcCols = fk.source.columns.map((c: string) => serializeValue(c)).join(', ');\n const tgtCols = fk.target.columns.map((c: string) => serializeValue(c)).join(', ');\n const name = fk.name ? `; readonly name: ${serializeValue(fk.name)}` : '';\n const srcRef = `{ readonly namespaceId: ${serializeNamespaceId(String(fk.source.namespaceId))}; readonly tableName: ${serializeValue(fk.source.tableName)}; readonly columns: readonly [${srcCols}] }`;\n const tgtRef = `{ readonly namespaceId: ${serializeNamespaceId(String(fk.target.namespaceId))}; readonly tableName: ${serializeValue(fk.target.tableName)}; readonly columns: readonly [${tgtCols}] }`;\n return `{ readonly source: ${srcRef}; readonly target: ${tgtRef}${name}; readonly constraint: ${fk.constraint}; readonly index: ${fk.index} }`;\n })\n .join(', ');\n tableParts.push(`foreignKeys: readonly [${fks}]`);\n\n return `{ ${tableParts.join('; ')} }`;\n}\n\nfunction generateTablesMapType(tables: Readonly<Record<string, StorageTable>>): string {\n const tableEntries: string[] = [];\n for (const [tableName, table] of Object.entries(tables).sort(([a], [b]) => a.localeCompare(b))) {\n tableEntries.push(`readonly ${tableName}: ${generateTableLiteralType(table)}`);\n }\n if (tableEntries.length === 0) {\n // Empty namespaces must emit `{}` (whose `keyof` is `never`), not\n // `Record<string, never>` (whose `keyof` is `string`). The latter\n // collapses `Db<C>` to a string-indexed shape and erases literal\n // table-name inference at every consumer site that walks all\n // namespaces (e.g. `db.sql.<tableName>`).\n return '{}';\n }\n return `{ ${tableEntries.join('; ')} }`;\n}\n\nfunction generateStorageNamespacesType(namespaces: SqlStorage['namespaces']): string {\n const entries = Object.entries(namespaces ?? {}).sort(([a], [b]) => a.localeCompare(b));\n if (entries.length === 0) {\n return 'Record<string, never>';\n }\n const parts: string[] = [];\n for (const [name, ns] of entries) {\n const kindSuffix = `; ${namespaceSerializedKind(ns)}`;\n const tablesType = generateTablesMapType(\n (ns.entries.table ?? {}) as Readonly<Record<string, StorageTable>>,\n );\n const valueSetSlot = ns.entries.valueSet;\n const entriesParts = [`readonly table: ${tablesType}`];\n if (valueSetSlot !== undefined && Object.keys(valueSetSlot).length > 0) {\n entriesParts.push(`readonly valueSet: ${generateNamespaceValueSetType(valueSetSlot)}`);\n }\n const entriesType = `{ ${entriesParts.join('; ')} }`;\n parts.push(\n `readonly ${serializeObjectKey(name)}: { readonly id: ${serializeValue(ns.id)}${kindSuffix}; readonly entries: ${entriesType} }`,\n );\n }\n return `{ ${parts.join('; ')} }`;\n}\n"],"mappings":"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"}
{"version":3,"file":"index.mjs","names":["col","codecShape"],"sources":["../src/index.ts"],"sourcesContent":["import type {\n Contract,\n ContractModel,\n ContractModelBase,\n JsonValue,\n} from '@prisma-next/contract/types';\nimport {\n renderValueSetType,\n serializeNamespaceId,\n serializeObjectKey,\n serializeValue,\n} from '@prisma-next/emitter/domain-type-generation';\nimport { isSafeTypeExpression } from '@prisma-next/emitter/type-expression-safety';\nimport type { CodecLookup } from '@prisma-next/framework-components/codec';\nimport type {\n GenerateContractTypesOptions,\n ValidationContext,\n} from '@prisma-next/framework-components/emission';\nimport {\n entityAt,\n type Namespace,\n UNBOUND_NAMESPACE_ID,\n} from '@prisma-next/framework-components/ir';\nimport type {\n SqlModelStorage,\n SqlStorage,\n StorageColumn,\n StorageTable,\n StorageTypeInstance,\n StorageValueSet,\n} from '@prisma-next/sql-contract/types';\nimport { blindCast } from '@prisma-next/utils/casts';\n\nfunction serializeTypeParamsLiteral(params: Record<string, unknown> | undefined): string {\n if (!params || Object.keys(params).length === 0) {\n return 'Record<string, never>';\n }\n\n const entries: string[] = [];\n for (const [key, value] of Object.entries(params)) {\n entries.push(`readonly ${serializeObjectKey(key)}: ${serializeValue(value)}`);\n }\n\n return `{ ${entries.join('; ')} }`;\n}\n\nexport const sqlEmission = {\n id: 'sql',\n\n validateTypes(contract: Contract, _ctx: ValidationContext): void {\n const storage = contract.storage as unknown as SqlStorage | undefined;\n if (!storage?.namespaces) {\n return;\n }\n\n const typeIdRegex = /^([^/]+)\\/([^@]+)@(\\d+)$/;\n\n for (const ns of Object.values(storage.namespaces)) {\n for (const [tableName, table] of Object.entries(ns.entries.table ?? {})) {\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?.[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\n validateStructure(contract: Contract): void {\n if (contract.targetFamily !== 'sql') {\n throw new Error(`Expected targetFamily \"sql\", got \"${contract.targetFamily}\"`);\n }\n\n const storage = contract.storage as unknown as SqlStorage | undefined;\n if (!storage?.namespaces) {\n throw new Error('SQL contract must have storage.namespaces');\n }\n\n const tableNamesSeenAcrossNamespaces = new Map<string, string>();\n for (const [nsId, ns] of Object.entries(storage.namespaces)) {\n for (const tableName of Object.keys(ns.entries.table ?? {})) {\n const existingNs = tableNamesSeenAcrossNamespaces.get(tableName);\n if (existingNs !== undefined && existingNs !== nsId) {\n throw new Error(\n `Duplicate table name \"${tableName}\" in namespaces \"${existingNs}\" and \"${nsId}\"`,\n );\n }\n tableNamesSeenAcrossNamespaces.set(tableName, nsId);\n }\n }\n\n const tableNames = new Set<string>();\n for (const ns of Object.values(storage.namespaces)) {\n for (const t of Object.keys(ns.entries.table ?? {})) {\n tableNames.add(t);\n }\n }\n\n for (const [namespaceId, domainNs] of Object.entries(contract.domain.namespaces)) {\n const models = domainNs.models as Record<string, ContractModel<SqlModelStorage>>;\n for (const [modelName, model] of Object.entries(models)) {\n const qualifiedName = `${namespaceId}:${modelName}`;\n if (!model.storage?.table) {\n throw new Error(`Model \"${qualifiedName}\" is missing storage.table`);\n }\n if (!model.storage.namespaceId) {\n throw new Error(`Model \"${qualifiedName}\" is missing storage.namespaceId`);\n }\n if (model.storage.namespaceId !== namespaceId) {\n throw new Error(\n `Model \"${qualifiedName}\" storage.namespaceId \"${model.storage.namespaceId}\" does not match domain namespace \"${namespaceId}\"`,\n );\n }\n\n const tableName = model.storage.table;\n const table = entityAt<StorageTable>(storage, {\n namespaceId,\n entityKind: 'table',\n entityName: tableName,\n });\n if (!table) {\n throw new Error(\n `Model \"${qualifiedName}\" references non-existent table \"${namespaceId}.${tableName}\"`,\n );\n }\n const columnNames = new Set(Object.keys(table.columns));\n const storageFields = model.storage.fields;\n if (!storageFields || Object.keys(storageFields).length === 0) {\n throw new Error(`Model \"${qualifiedName}\" is missing storage.fields`);\n }\n\n for (const [fieldName, field] of Object.entries(storageFields)) {\n if (!field.column) {\n throw new Error(\n `Model \"${qualifiedName}\" field \"${fieldName}\" is missing column property`,\n );\n }\n\n if (!columnNames.has(field.column)) {\n throw new Error(\n `Model \"${qualifiedName}\" 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 \"${qualifiedName}\" is missing required field \"relations\" (must be an object)`,\n );\n }\n }\n }\n\n for (const ns of Object.values(storage.namespaces)) {\n for (const [tableName, table] of Object.entries(ns.entries.table ?? {})) {\n const columnNames = new Set(Object.keys(table.columns));\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.source.columns) {\n if (!columnNames.has(colName)) {\n throw new Error(\n `Table \"${tableName}\" foreignKey references non-existent column \"${colName}\"`,\n );\n }\n }\n\n const referencedTable = entityAt<StorageTable>(storage, {\n namespaceId: fk.target.namespaceId,\n entityKind: 'table',\n entityName: fk.target.tableName,\n });\n if (!referencedTable) {\n throw new Error(\n `Table \"${tableName}\" foreignKey references non-existent table \"${fk.target.tableName}\" in namespace \"${fk.target.namespaceId}\"`,\n );\n }\n\n const referencedColumnNames = new Set(Object.keys(referencedTable.columns));\n for (const colName of fk.target.columns) {\n if (!referencedColumnNames.has(colName)) {\n throw new Error(\n `Table \"${tableName}\" foreignKey references non-existent column \"${colName}\" in table \"${fk.target.tableName}\"`,\n );\n }\n }\n\n if (fk.source.columns.length !== fk.target.columns.length) {\n throw new Error(\n `Table \"${tableName}\" foreignKey column count (${fk.source.columns.length}) does not match referenced column count (${fk.target.columns.length})`,\n );\n }\n }\n }\n }\n },\n\n generateStorageType(contract: Contract, storageHashTypeName: string): string {\n const storage = contract.storage as unknown as SqlStorage;\n const namespacesType = generateStorageNamespacesType(storage.namespaces);\n const docTypes = generateDocumentScopedStorageTypesType(storage.types);\n const typesClause = docTypes === undefined ? '' : `; readonly types: ${docTypes}`;\n return `{ readonly namespaces: ${namespacesType}${typesClause}; readonly storageHash: ${storageHashTypeName} }`;\n },\n\n generateModelStorageType(_modelName: string, model: ContractModelBase): string {\n const sqlModel = model as ContractModel<SqlModelStorage>;\n const tableName = sqlModel.storage.table;\n const storageFields = sqlModel.storage.fields;\n\n const storageParts = [\n `readonly table: ${serializeValue(tableName)}`,\n `readonly namespaceId: ${serializeValue(sqlModel.storage.namespaceId)}`,\n ];\n if (Object.keys(storageFields).length > 0) {\n const fieldParts: string[] = [];\n for (const [fieldName, field] of Object.entries(storageFields)) {\n fieldParts.push(\n `readonly ${serializeObjectKey(fieldName)}: { readonly column: ${serializeValue(field.column)} }`,\n );\n }\n storageParts.push(`readonly fields: { ${fieldParts.join('; ')} }`);\n }\n\n return `{ ${storageParts.join('; ')} }`;\n },\n\n resolveFieldTypeParams(\n _modelName: string,\n fieldName: string,\n model: ContractModelBase,\n contract: Contract,\n ): Record<string, unknown> | undefined {\n const sqlModel = model as ContractModel<SqlModelStorage>;\n const storageField = sqlModel.storage?.fields?.[fieldName];\n if (!storageField) return undefined;\n\n const storage = contract.storage as unknown as SqlStorage | undefined;\n if (!storage) return undefined;\n\n const tableName = sqlModel.storage.table;\n const storageNamespaceId = sqlModel.storage.namespaceId;\n if (!storageNamespaceId) return undefined;\n\n const table = entityAt<StorageTable>(storage, {\n namespaceId: storageNamespaceId,\n entityKind: 'table',\n entityName: tableName,\n });\n if (!table) return undefined;\n\n const column = table.columns[storageField.column];\n if (!column) return undefined;\n\n if (column.typeRef) {\n const typeInstance = storage.types?.[column.typeRef];\n if (typeInstance === undefined) return undefined;\n const codecShape = typeInstance as Partial<StorageTypeInstance>;\n return codecShape.typeParams;\n }\n return column.typeParams;\n },\n\n resolveFieldValueSet(\n _modelName: string,\n fieldName: string,\n model: ContractModelBase,\n contract: Contract,\n ): { readonly encodedValues: readonly JsonValue[]; readonly codecId: string } | undefined {\n const sqlModel = blindCast<\n ContractModel<SqlModelStorage>,\n 'a sql-family model carries SqlModelStorage in storage'\n >(model);\n const storageField = sqlModel.storage?.fields?.[fieldName];\n if (!storageField) return undefined;\n\n const storage = blindCast<\n SqlStorage | undefined,\n 'contract.storage is SqlStorage for sql family'\n >(contract.storage);\n if (!storage) return undefined;\n\n const storageNamespaceId = sqlModel.storage.namespaceId;\n if (!storageNamespaceId) return undefined;\n\n const table = entityAt<StorageTable>(storage, {\n namespaceId: storageNamespaceId,\n entityKind: 'table',\n entityName: sqlModel.storage.table,\n });\n const column = table?.columns[storageField.column];\n if (!column?.valueSet) return undefined;\n\n const valueSet = entityAt<StorageValueSet>(storage, {\n namespaceId: column.valueSet.namespaceId,\n entityKind: column.valueSet.entityKind,\n entityName: column.valueSet.entityName,\n });\n if (!valueSet) return undefined;\n\n return { encodedValues: valueSet.values, codecId: column.codecId };\n },\n\n getStorageTypeExports(contract: Contract, codecLookup?: CodecLookup): string | undefined {\n const storage = blindCast<\n SqlStorage | undefined,\n 'contract.storage is SqlStorage for sql family'\n >(contract.storage);\n if (!storage?.namespaces) return undefined;\n const outputMap = generateStorageColumnTypesMap(storage, 'output', codecLookup);\n const inputMap = generateStorageColumnTypesMap(storage, 'input', codecLookup);\n return [\n `export type StorageColumnTypes = ${outputMap};`,\n `export type StorageColumnInputTypes = ${inputMap};`,\n ].join('\\n');\n },\n\n getFamilyImports(): string[] {\n return [\n 'import type {',\n ' ContractWithTypeMaps,',\n ' TypeMaps as TypeMapsType,',\n \"} from '@prisma-next/sql-contract/types';\",\n ];\n },\n\n getFamilyTypeAliases(options?: GenerateContractTypesOptions): string {\n const queryOperationTypeImports = options?.queryOperationTypeImports ?? [];\n const queryOperationAliases = queryOperationTypeImports\n .filter((imp) => imp.named === 'QueryOperationTypes')\n .map((imp) => `${imp.alias}<CodecTypes>`);\n const queryOperationTypes =\n queryOperationAliases.length > 0\n ? queryOperationAliases.join(' & ')\n : 'Record<string, never>';\n\n return [\n 'export type LaneCodecTypes = CodecTypes;',\n `export type QueryOperationTypes = ${queryOperationTypes};`,\n 'type DefaultLiteralValue<CodecId extends string, _Encoded> =',\n ' CodecId extends keyof CodecTypes',\n \" ? CodecTypes[CodecId]['output']\",\n ' : _Encoded;',\n ].join('\\n');\n },\n\n getTypeMapsExpression(): string {\n return 'TypeMapsType<CodecTypes, QueryOperationTypes, FieldOutputTypes, FieldInputTypes, StorageColumnTypes, StorageColumnInputTypes>';\n },\n\n getContractWrapper(contractBaseName: string, typeMapsName: string): string {\n return [\n `export type Contract = ContractWithTypeMaps<${contractBaseName}, ${typeMapsName}>;`,\n '',\n \"export type Namespaces = Contract['storage']['namespaces'];\",\n ].join('\\n');\n },\n} as const;\n\ntype ColumnTypeSide = 'output' | 'input';\n\nfunction columnTypeParams(\n storage: SqlStorage,\n column: StorageColumn,\n): Record<string, unknown> | undefined {\n if (column.typeRef) {\n const typeInstance = storage.types?.[column.typeRef];\n if (typeInstance === undefined) return undefined;\n return blindCast<\n Partial<StorageTypeInstance>,\n 'storage.types entries are codec-instance triples carrying optional typeParams'\n >(typeInstance).typeParams;\n }\n return column.typeParams;\n}\n\nfunction renderRefinedCodecType(\n column: StorageColumn,\n side: ColumnTypeSide,\n params: Record<string, unknown> | undefined,\n codecLookup: CodecLookup | undefined,\n): string {\n if (codecLookup && params && Object.keys(params).length > 0) {\n const rendered =\n side === 'output'\n ? codecLookup.renderOutputTypeFor(column.codecId, params)\n : codecLookup.renderInputTypeFor?.(column.codecId, params);\n if (rendered && isSafeTypeExpression(rendered)) {\n return rendered;\n }\n }\n return `CodecTypes[${serializeValue(column.codecId)}][${serializeValue(side)}]`;\n}\n\nfunction computeColumnType(\n storage: SqlStorage,\n column: StorageColumn,\n side: ColumnTypeSide,\n codecLookup: CodecLookup | undefined,\n): string {\n let base: string | undefined;\n if (column.valueSet) {\n const valueSet = entityAt<StorageValueSet>(storage, {\n namespaceId: column.valueSet.namespaceId,\n entityKind: column.valueSet.entityKind,\n entityName: column.valueSet.entityName,\n });\n base = valueSet\n ? renderValueSetType(valueSet.values, column.codecId, side, codecLookup)\n : undefined;\n }\n if (base === undefined) {\n base = renderRefinedCodecType(column, side, columnTypeParams(storage, column), codecLookup);\n }\n if (column.many === true) base = `ReadonlyArray<${base}>`;\n return column.nullable ? `${base} | null` : base;\n}\n\nfunction generateStorageColumnTypesMap(\n storage: SqlStorage,\n side: ColumnTypeSide,\n codecLookup: CodecLookup | undefined,\n): string {\n const namespaceEntries = Object.entries(storage.namespaces ?? {}).sort(([a], [b]) =>\n a.localeCompare(b),\n );\n if (namespaceEntries.length === 0) return 'Record<string, never>';\n\n const nsParts: string[] = [];\n for (const [nsId, ns] of namespaceEntries) {\n const tables = blindCast<\n Readonly<Record<string, StorageTable>>,\n 'same pattern as generateTablesMapType below'\n >(ns.entries.table ?? {});\n const tableEntries = Object.entries(tables).sort(([a], [b]) => a.localeCompare(b));\n const tableParts: string[] = [];\n\n for (const [tableName, table] of tableEntries) {\n const colEntries = Object.entries(table.columns).sort(([a], [b]) => a.localeCompare(b));\n const colParts: string[] = [];\n\n for (const [colName, col] of colEntries) {\n const colType = computeColumnType(storage, col, side, codecLookup);\n colParts.push(`readonly ${serializeObjectKey(colName)}: ${colType}`);\n }\n\n const colMap = colParts.length > 0 ? `{ ${colParts.join('; ')} }` : '{}';\n tableParts.push(`readonly ${serializeObjectKey(tableName)}: ${colMap}`);\n }\n\n const tableMap = tableParts.length > 0 ? `{ ${tableParts.join('; ')} }` : '{}';\n nsParts.push(`readonly ${serializeObjectKey(nsId)}: ${tableMap}`);\n }\n\n return `{ ${nsParts.join('; ')} }`;\n}\n\nfunction generateDocumentScopedStorageTypesType(types: SqlStorage['types']): string | undefined {\n if (!types || Object.keys(types).length === 0) {\n return undefined;\n }\n\n const typeEntries: string[] = [];\n for (const [typeName, typeInstance] of Object.entries(types)) {\n const codecInstanceShape = typeInstance as Partial<StorageTypeInstance>;\n if (\n typeof codecInstanceShape.codecId !== 'string' ||\n typeof codecInstanceShape.nativeType !== 'string'\n ) {\n throw new Error(\n `Unknown storage type kind for \"${typeName}\" in document-scoped storage.types; expected a codec-instance triple.`,\n );\n }\n const codecId = serializeValue(codecInstanceShape.codecId);\n const nativeType = serializeValue(codecInstanceShape.nativeType);\n const typeParamsStr = serializeTypeParamsLiteral(codecInstanceShape.typeParams);\n typeEntries.push(\n `readonly ${typeName}: { readonly kind: 'codec-instance'; readonly codecId: ${codecId}; readonly nativeType: ${nativeType}; readonly typeParams: ${typeParamsStr} }`,\n );\n }\n\n return `{ ${typeEntries.join('; ')} }`;\n}\n\n/**\n * Literalizes the `valueSet` entries slot — a core SQL entity kind (alongside\n * `table`), not a pack-contributed one, so naming it here isn't a\n * family→target layering leak. This is the only non-`table` entries slot with\n * a type-level consumer (`db.nativeEnums`, `packages/3-extensions/postgres`):\n * pack-contributed slots (`role`, `policy`, `native_enum`, …) have none and\n * are not emitted.\n */\nfunction generateValueSetBlockType(valueSets: Readonly<Record<string, StorageValueSet>>): string {\n const entries = Object.entries(valueSets)\n .sort(([a], [b]) => a.localeCompare(b))\n .map(([name, valueSet]) => `readonly ${serializeObjectKey(name)}: ${serializeValue(valueSet)}`);\n return `{ ${entries.join('; ')} }`;\n}\n\nfunction namespaceSerializedKind(ns: Namespace): string {\n const kind = ns.kind;\n if (kind === 'schema') {\n const id = ns.id;\n const lit = id === UNBOUND_NAMESPACE_ID ? 'postgres-unbound-schema' : 'postgres-schema';\n return `readonly kind: '${lit}'`;\n }\n if (typeof kind === 'string') {\n return `readonly kind: ${serializeValue(kind)}`;\n }\n throw new Error(\n `Namespace '${ns.id}' has no string kind — all namespaces must be target concretions with a defined kind property.`,\n );\n}\n\nfunction generateTableLiteralType(table: StorageTable): string {\n const columns: string[] = [];\n for (const [colName, col] of Object.entries(table.columns)) {\n const nullable = col.nullable ? 'true' : 'false';\n const nativeType = serializeValue(col.nativeType);\n const codecId = serializeValue(col.codecId);\n const defaultSpec = col.default\n ? col.default.kind === 'literal'\n ? `; readonly default: { readonly kind: 'literal'; readonly value: DefaultLiteralValue<${codecId}, ${serializeValue(\n col.default.value,\n )}> }`\n : `; readonly default: { readonly kind: 'function'; readonly expression: ${serializeValue(\n col.default.expression,\n )} }`\n : '';\n const typeParamsSpec =\n col.typeParams && Object.keys(col.typeParams).length > 0\n ? `; readonly typeParams: ${serializeTypeParamsLiteral(col.typeParams)}`\n : '';\n const typeRefSpec = col.typeRef ? `; readonly typeRef: ${serializeValue(col.typeRef)}` : '';\n columns.push(\n `readonly ${colName}: { readonly nativeType: ${nativeType}; readonly codecId: ${codecId}; readonly nullable: ${nullable}${defaultSpec}${typeParamsSpec}${typeRefSpec} }`,\n );\n }\n\n const tableParts: string[] = [`columns: { ${columns.join('; ')} }`];\n\n if (table.primaryKey) {\n const pkCols = table.primaryKey.columns.map((c) => serializeValue(c)).join(', ');\n const pkName = table.primaryKey.name\n ? `; readonly name: ${serializeValue(table.primaryKey.name)}`\n : '';\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) => serializeValue(c)).join(', ');\n const name = u.name ? `; readonly name: ${serializeValue(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) => serializeValue(c)).join(', ');\n const name = i.name !== undefined ? `; readonly name: ${serializeValue(i.name)}` : '';\n const indexType = i.type !== undefined ? `; readonly type: ${serializeValue(i.type)}` : '';\n const indexOptions =\n i.options !== undefined ? `; readonly options: ${serializeValue(i.options)}` : '';\n return `{ readonly columns: readonly [${cols}]${name}${indexType}${indexOptions} }`;\n })\n .join(', ');\n tableParts.push(`indexes: readonly [${indexes}]`);\n\n const fks = table.foreignKeys\n .map((fk) => {\n const srcCols = fk.source.columns.map((c: string) => serializeValue(c)).join(', ');\n const tgtCols = fk.target.columns.map((c: string) => serializeValue(c)).join(', ');\n const name = fk.name ? `; readonly name: ${serializeValue(fk.name)}` : '';\n const srcRef = `{ readonly namespaceId: ${serializeNamespaceId(String(fk.source.namespaceId))}; readonly tableName: ${serializeValue(fk.source.tableName)}; readonly columns: readonly [${srcCols}] }`;\n const tgtRef = `{ readonly namespaceId: ${serializeNamespaceId(String(fk.target.namespaceId))}; readonly tableName: ${serializeValue(fk.target.tableName)}; readonly columns: readonly [${tgtCols}] }`;\n return `{ readonly source: ${srcRef}; readonly target: ${tgtRef}${name} }`;\n })\n .join(', ');\n tableParts.push(`foreignKeys: readonly [${fks}]`);\n\n return `{ ${tableParts.join('; ')} }`;\n}\n\nfunction generateTablesMapType(tables: Readonly<Record<string, StorageTable>>): string {\n const tableEntries: string[] = [];\n for (const [tableName, table] of Object.entries(tables).sort(([a], [b]) => a.localeCompare(b))) {\n tableEntries.push(`readonly ${tableName}: ${generateTableLiteralType(table)}`);\n }\n if (tableEntries.length === 0) {\n // Empty namespaces must emit `{}` (whose `keyof` is `never`), not\n // `Record<string, never>` (whose `keyof` is `string`). The latter\n // collapses `Db<C>` to a string-indexed shape and erases literal\n // table-name inference at every consumer site that walks all\n // namespaces (e.g. `db.sql.<tableName>`).\n return '{}';\n }\n return `{ ${tableEntries.join('; ')} }`;\n}\n\nfunction generateStorageNamespacesType(namespaces: SqlStorage['namespaces']): string {\n const entries = Object.entries(namespaces ?? {}).sort(([a], [b]) => a.localeCompare(b));\n if (entries.length === 0) {\n return 'Record<string, never>';\n }\n const parts: string[] = [];\n for (const [name, ns] of entries) {\n const kindSuffix = `; ${namespaceSerializedKind(ns)}`;\n const tablesType = generateTablesMapType(\n (ns.entries.table ?? {}) as Readonly<Record<string, StorageTable>>,\n );\n const entriesParts = [`readonly table: ${tablesType}`];\n const valueSetEntries = ns.entries.valueSet;\n if (valueSetEntries !== undefined && Object.keys(valueSetEntries).length > 0) {\n entriesParts.push(`readonly valueSet: ${generateValueSetBlockType(valueSetEntries)}`);\n }\n const entriesType = `{ ${entriesParts.join('; ')} }`;\n parts.push(\n `readonly ${serializeObjectKey(name)}: { readonly id: ${serializeValue(ns.id)}${kindSuffix}; readonly entries: ${entriesType} }`,\n );\n }\n return `{ ${parts.join('; ')} }`;\n}\n"],"mappings":"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"}
{
"name": "@prisma-next/sql-contract-emitter",
"version": "0.14.0",
"version": "0.15.0-dev.1",
"license": "Apache-2.0",

@@ -9,15 +9,15 @@ "type": "module",

"dependencies": {
"@prisma-next/contract": "0.14.0",
"@prisma-next/emitter": "0.14.0",
"@prisma-next/framework-components": "0.14.0",
"@prisma-next/sql-contract": "0.14.0",
"@prisma-next/utils": "0.14.0"
"@prisma-next/contract": "0.15.0-dev.1",
"@prisma-next/emitter": "0.15.0-dev.1",
"@prisma-next/framework-components": "0.15.0-dev.1",
"@prisma-next/sql-contract": "0.15.0-dev.1",
"@prisma-next/utils": "0.15.0-dev.1"
},
"devDependencies": {
"@prisma-next/test-utils": "0.14.0",
"@prisma-next/tsconfig": "0.14.0",
"@prisma-next/tsdown": "0.14.0",
"tsdown": "0.22.1",
"@prisma-next/test-utils": "0.15.0-dev.1",
"@prisma-next/tsconfig": "0.15.0-dev.1",
"@prisma-next/tsdown": "0.15.0-dev.1",
"tsdown": "0.22.3",
"typescript": "5.9.3",
"vitest": "4.1.8"
"vitest": "4.1.10"
},

@@ -24,0 +24,0 @@ "peerDependencies": {

@@ -1,3 +0,9 @@

import type { Contract, ContractModel, ContractModelBase } from '@prisma-next/contract/types';
import type {
Contract,
ContractModel,
ContractModelBase,
JsonValue,
} from '@prisma-next/contract/types';
import {
renderValueSetType,
serializeNamespaceId,

@@ -7,2 +13,4 @@ serializeObjectKey,

} from '@prisma-next/emitter/domain-type-generation';
import { isSafeTypeExpression } from '@prisma-next/emitter/type-expression-safety';
import type { CodecLookup } from '@prisma-next/framework-components/codec';
import type {

@@ -20,2 +28,3 @@ GenerateContractTypesOptions,

SqlStorage,
StorageColumn,
StorageTable,

@@ -25,2 +34,3 @@ StorageTypeInstance,

} from '@prisma-next/sql-contract/types';
import { blindCast } from '@prisma-next/utils/casts';

@@ -311,2 +321,56 @@ function serializeTypeParamsLiteral(params: Record<string, unknown> | undefined): string {

resolveFieldValueSet(
_modelName: string,
fieldName: string,
model: ContractModelBase,
contract: Contract,
): { readonly encodedValues: readonly JsonValue[]; readonly codecId: string } | undefined {
const sqlModel = blindCast<
ContractModel<SqlModelStorage>,
'a sql-family model carries SqlModelStorage in storage'
>(model);
const storageField = sqlModel.storage?.fields?.[fieldName];
if (!storageField) return undefined;
const storage = blindCast<
SqlStorage | undefined,
'contract.storage is SqlStorage for sql family'
>(contract.storage);
if (!storage) return undefined;
const storageNamespaceId = sqlModel.storage.namespaceId;
if (!storageNamespaceId) return undefined;
const table = entityAt<StorageTable>(storage, {
namespaceId: storageNamespaceId,
entityKind: 'table',
entityName: sqlModel.storage.table,
});
const column = table?.columns[storageField.column];
if (!column?.valueSet) return undefined;
const valueSet = entityAt<StorageValueSet>(storage, {
namespaceId: column.valueSet.namespaceId,
entityKind: column.valueSet.entityKind,
entityName: column.valueSet.entityName,
});
if (!valueSet) return undefined;
return { encodedValues: valueSet.values, codecId: column.codecId };
},
getStorageTypeExports(contract: Contract, codecLookup?: CodecLookup): string | undefined {
const storage = blindCast<
SqlStorage | undefined,
'contract.storage is SqlStorage for sql family'
>(contract.storage);
if (!storage?.namespaces) return undefined;
const outputMap = generateStorageColumnTypesMap(storage, 'output', codecLookup);
const inputMap = generateStorageColumnTypesMap(storage, 'input', codecLookup);
return [
`export type StorageColumnTypes = ${outputMap};`,
`export type StorageColumnInputTypes = ${inputMap};`,
].join('\n');
},
getFamilyImports(): string[] {

@@ -342,3 +406,3 @@ return [

getTypeMapsExpression(): string {
return 'TypeMapsType<CodecTypes, QueryOperationTypes, FieldOutputTypes, FieldInputTypes>';
return 'TypeMapsType<CodecTypes, QueryOperationTypes, FieldOutputTypes, FieldInputTypes, StorageColumnTypes, StorageColumnInputTypes>';
},

@@ -355,2 +419,100 @@

type ColumnTypeSide = 'output' | 'input';
function columnTypeParams(
storage: SqlStorage,
column: StorageColumn,
): Record<string, unknown> | undefined {
if (column.typeRef) {
const typeInstance = storage.types?.[column.typeRef];
if (typeInstance === undefined) return undefined;
return blindCast<
Partial<StorageTypeInstance>,
'storage.types entries are codec-instance triples carrying optional typeParams'
>(typeInstance).typeParams;
}
return column.typeParams;
}
function renderRefinedCodecType(
column: StorageColumn,
side: ColumnTypeSide,
params: Record<string, unknown> | undefined,
codecLookup: CodecLookup | undefined,
): string {
if (codecLookup && params && Object.keys(params).length > 0) {
const rendered =
side === 'output'
? codecLookup.renderOutputTypeFor(column.codecId, params)
: codecLookup.renderInputTypeFor?.(column.codecId, params);
if (rendered && isSafeTypeExpression(rendered)) {
return rendered;
}
}
return `CodecTypes[${serializeValue(column.codecId)}][${serializeValue(side)}]`;
}
function computeColumnType(
storage: SqlStorage,
column: StorageColumn,
side: ColumnTypeSide,
codecLookup: CodecLookup | undefined,
): string {
let base: string | undefined;
if (column.valueSet) {
const valueSet = entityAt<StorageValueSet>(storage, {
namespaceId: column.valueSet.namespaceId,
entityKind: column.valueSet.entityKind,
entityName: column.valueSet.entityName,
});
base = valueSet
? renderValueSetType(valueSet.values, column.codecId, side, codecLookup)
: undefined;
}
if (base === undefined) {
base = renderRefinedCodecType(column, side, columnTypeParams(storage, column), codecLookup);
}
if (column.many === true) base = `ReadonlyArray<${base}>`;
return column.nullable ? `${base} | null` : base;
}
function generateStorageColumnTypesMap(
storage: SqlStorage,
side: ColumnTypeSide,
codecLookup: CodecLookup | undefined,
): string {
const namespaceEntries = Object.entries(storage.namespaces ?? {}).sort(([a], [b]) =>
a.localeCompare(b),
);
if (namespaceEntries.length === 0) return 'Record<string, never>';
const nsParts: string[] = [];
for (const [nsId, ns] of namespaceEntries) {
const tables = blindCast<
Readonly<Record<string, StorageTable>>,
'same pattern as generateTablesMapType below'
>(ns.entries.table ?? {});
const tableEntries = Object.entries(tables).sort(([a], [b]) => a.localeCompare(b));
const tableParts: string[] = [];
for (const [tableName, table] of tableEntries) {
const colEntries = Object.entries(table.columns).sort(([a], [b]) => a.localeCompare(b));
const colParts: string[] = [];
for (const [colName, col] of colEntries) {
const colType = computeColumnType(storage, col, side, codecLookup);
colParts.push(`readonly ${serializeObjectKey(colName)}: ${colType}`);
}
const colMap = colParts.length > 0 ? `{ ${colParts.join('; ')} }` : '{}';
tableParts.push(`readonly ${serializeObjectKey(tableName)}: ${colMap}`);
}
const tableMap = tableParts.length > 0 ? `{ ${tableParts.join('; ')} }` : '{}';
nsParts.push(`readonly ${serializeObjectKey(nsId)}: ${tableMap}`);
}
return `{ ${nsParts.join('; ')} }`;
}
function generateDocumentScopedStorageTypesType(types: SqlStorage['types']): string | undefined {

@@ -383,20 +545,17 @@ if (!types || Object.keys(types).length === 0) {

function generateNamespaceValueSetType(
valueSet: Readonly<Record<string, StorageValueSet>>,
): string {
if (Object.keys(valueSet).length === 0) {
return 'Record<string, never>';
}
const entries: string[] = [];
for (const [name, vs] of Object.entries(valueSet)) {
const valuesLiteral = vs.values.map((v) => serializeValue(v)).join(', ');
entries.push(
`readonly ${serializeObjectKey(name)}: { readonly kind: 'valueSet'; readonly values: readonly [${valuesLiteral}] }`,
);
}
/**
* Literalizes the `valueSet` entries slot — a core SQL entity kind (alongside
* `table`), not a pack-contributed one, so naming it here isn't a
* family→target layering leak. This is the only non-`table` entries slot with
* a type-level consumer (`db.nativeEnums`, `packages/3-extensions/postgres`):
* pack-contributed slots (`role`, `policy`, `native_enum`, …) have none and
* are not emitted.
*/
function generateValueSetBlockType(valueSets: Readonly<Record<string, StorageValueSet>>): string {
const entries = Object.entries(valueSets)
.sort(([a], [b]) => a.localeCompare(b))
.map(([name, valueSet]) => `readonly ${serializeObjectKey(name)}: ${serializeValue(valueSet)}`);
return `{ ${entries.join('; ')} }`;
}
const SQL_NAMESPACE_KIND_FALLBACK = 'sql-namespace' as const;
function namespaceSerializedKind(ns: Namespace): string {

@@ -412,8 +571,5 @@ const kind = ns.kind;

}
// Plain-literal namespaces built via the contract-ts DSL bypass the
// class-level `Object.defineProperty(this, 'kind', { value, enumerable: false })`
// path, so `ns.kind` is missing on the runtime object. Surfacing the
// framework-default kind here keeps the emitted `.d.ts` literal
// structurally assignable to `Namespace`, which now requires `kind`.
return `readonly kind: '${SQL_NAMESPACE_KIND_FALLBACK}'`;
throw new Error(
`Namespace '${ns.id}' has no string kind — all namespaces must be target concretions with a defined kind property.`,
);
}

@@ -484,3 +640,3 @@

const tgtRef = `{ readonly namespaceId: ${serializeNamespaceId(String(fk.target.namespaceId))}; readonly tableName: ${serializeValue(fk.target.tableName)}; readonly columns: readonly [${tgtCols}] }`;
return `{ readonly source: ${srcRef}; readonly target: ${tgtRef}${name}; readonly constraint: ${fk.constraint}; readonly index: ${fk.index} }`;
return `{ readonly source: ${srcRef}; readonly target: ${tgtRef}${name} }`;
})

@@ -520,6 +676,6 @@ .join(', ');

);
const valueSetSlot = ns.entries.valueSet;
const entriesParts = [`readonly table: ${tablesType}`];
if (valueSetSlot !== undefined && Object.keys(valueSetSlot).length > 0) {
entriesParts.push(`readonly valueSet: ${generateNamespaceValueSetType(valueSetSlot)}`);
const valueSetEntries = ns.entries.valueSet;
if (valueSetEntries !== undefined && Object.keys(valueSetEntries).length > 0) {
entriesParts.push(`readonly valueSet: ${generateValueSetBlockType(valueSetEntries)}`);
}

@@ -526,0 +682,0 @@ const entriesType = `{ ${entriesParts.join('; ')} }`;