@prisma-next/sql-contract-emitter 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +67 -0
- package/dist/index.d.ts +83 -0
- package/dist/index.js +408 -0
- package/dist/index.js.map +1 -0
- package/package.json +35 -0
package/README.md
ADDED
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
# @prisma-next/sql-contract-emitter
|
|
2
|
+
|
|
3
|
+
SQL emitter hook for Prisma Next.
|
|
4
|
+
|
|
5
|
+
## Overview
|
|
6
|
+
|
|
7
|
+
This package provides the SQL-specific emitter hook implementation for the Prisma Next emitter. It validates SQL contracts and generates TypeScript type definitions for SQL contracts. It's part of the SQL tooling layer (migration plane) and implements the `TargetFamilyHook` interface.
|
|
8
|
+
|
|
9
|
+
## Responsibilities
|
|
10
|
+
|
|
11
|
+
- **Contract Validation**: Validates SQL contract structure and types
|
|
12
|
+
- `validateTypes()`: Validates type IDs against referenced extensions (receives `ValidationContext` with `extensionIds`)
|
|
13
|
+
- `validateStructure()`: Validates SQL-specific contract structure (tables, models, constraints)
|
|
14
|
+
|
|
15
|
+
- **Type Generation**: Generates TypeScript type definitions for SQL contracts
|
|
16
|
+
- `generateContractTypes()`: Generates `contract.d.ts` file content (receives separate `codecTypeImports` and `operationTypeImports` arrays)
|
|
17
|
+
|
|
18
|
+
## Dependencies
|
|
19
|
+
|
|
20
|
+
- **Depends on**:
|
|
21
|
+
- `@prisma-next/contract` (contract IR, `TargetFamilyHook` SPI, `ValidationContext`, `TypesImportSpec` - types moved to shared plane)
|
|
22
|
+
- `@prisma-next/emitter` (emitter core, `EmitOptions`, `EmitResult`)
|
|
23
|
+
- `@prisma-next/sql-contract` (SQL contract type definitions)
|
|
24
|
+
- **Depended on by**:
|
|
25
|
+
- `@prisma-next/cli` (uses for contract emission)
|
|
26
|
+
- `@prisma-next/integration-tests` (uses for contract emission tests)
|
|
27
|
+
|
|
28
|
+
## Architecture
|
|
29
|
+
|
|
30
|
+
```mermaid
|
|
31
|
+
flowchart TD
|
|
32
|
+
subgraph "Framework Tooling Layer"
|
|
33
|
+
EMITTER[@prisma-next/emitter]
|
|
34
|
+
CLI[@prisma-next/cli]
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
subgraph "SQL Tooling Layer"
|
|
38
|
+
SQL_EMITTER[@prisma-next/sql-contract-emitter]
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
subgraph "SQL Core Layer (Shared Plane)"
|
|
42
|
+
CT[@prisma-next/sql-contract]
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
EMITTER --> SQL_EMITTER
|
|
46
|
+
CT --> SQL_EMITTER
|
|
47
|
+
SQL_EMITTER --> CLI
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
## Usage
|
|
51
|
+
|
|
52
|
+
### Using the SQL Emitter Hook
|
|
53
|
+
|
|
54
|
+
```typescript
|
|
55
|
+
import { emit } from '@prisma-next/emitter';
|
|
56
|
+
import { sqlTargetFamilyHook } from '@prisma-next/sql-contract-emitter';
|
|
57
|
+
|
|
58
|
+
const result = await emit(contractIR, options, sqlTargetFamilyHook);
|
|
59
|
+
|
|
60
|
+
// result.contractDts contains generated TypeScript types
|
|
61
|
+
// result.contractJson contains validated contract JSON
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
## Related Documentation
|
|
65
|
+
|
|
66
|
+
- [Package Layering](../../../../docs/architecture docs/Package-Layering.md)
|
|
67
|
+
- [ADR 140 - Package Layering & Target-Family Namespacing](../../../../docs/architecture docs/adrs/ADR 140 - Package Layering & Target-Family Namespacing.md)
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import { SqlStorage, ModelDefinition } from '@prisma-next/sql-contract/types';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* ContractIR types and factories for building contract intermediate representation.
|
|
5
|
+
* ContractIR is family-agnostic and used by authoring, emitter, and no-emit runtime.
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* ContractIR represents the intermediate representation of a contract.
|
|
9
|
+
* It is family-agnostic and contains generic storage, models, and relations.
|
|
10
|
+
* Note: coreHash and profileHash are computed by the emitter, not part of the IR.
|
|
11
|
+
*/
|
|
12
|
+
interface ContractIR<TStorage extends Record<string, unknown> = Record<string, unknown>, TModels extends Record<string, unknown> = Record<string, unknown>, TRelations extends Record<string, unknown> = Record<string, unknown>> {
|
|
13
|
+
readonly schemaVersion: string;
|
|
14
|
+
readonly targetFamily: string;
|
|
15
|
+
readonly target: string;
|
|
16
|
+
readonly models: TModels;
|
|
17
|
+
readonly relations: TRelations;
|
|
18
|
+
readonly storage: TStorage;
|
|
19
|
+
readonly extensions: Record<string, unknown>;
|
|
20
|
+
readonly capabilities: Record<string, Record<string, boolean>>;
|
|
21
|
+
readonly meta: Record<string, unknown>;
|
|
22
|
+
readonly sources: Record<string, unknown>;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
type ArgSpec = {
|
|
26
|
+
readonly kind: 'typeId';
|
|
27
|
+
readonly type: string;
|
|
28
|
+
} | {
|
|
29
|
+
readonly kind: 'param';
|
|
30
|
+
} | {
|
|
31
|
+
readonly kind: 'literal';
|
|
32
|
+
};
|
|
33
|
+
type ReturnSpec = {
|
|
34
|
+
readonly kind: 'typeId';
|
|
35
|
+
readonly type: string;
|
|
36
|
+
} | {
|
|
37
|
+
readonly kind: 'builtin';
|
|
38
|
+
readonly type: 'number' | 'boolean' | 'string';
|
|
39
|
+
};
|
|
40
|
+
interface OperationSignature {
|
|
41
|
+
readonly forTypeId: string;
|
|
42
|
+
readonly method: string;
|
|
43
|
+
readonly args: ReadonlyArray<ArgSpec>;
|
|
44
|
+
readonly returns: ReturnSpec;
|
|
45
|
+
readonly capabilities?: ReadonlyArray<string>;
|
|
46
|
+
}
|
|
47
|
+
interface OperationRegistry {
|
|
48
|
+
register(op: OperationSignature): void;
|
|
49
|
+
byType(typeId: string): ReadonlyArray<OperationSignature>;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Specifies how to import TypeScript types from a package.
|
|
54
|
+
* Used in extension pack manifests to declare codec and operation type imports.
|
|
55
|
+
*/
|
|
56
|
+
interface TypesImportSpec {
|
|
57
|
+
readonly package: string;
|
|
58
|
+
readonly named: string;
|
|
59
|
+
readonly alias: string;
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Validation context passed to TargetFamilyHook.validateTypes().
|
|
63
|
+
* Contains pre-assembled operation registry, type imports, and extension IDs.
|
|
64
|
+
*/
|
|
65
|
+
interface ValidationContext {
|
|
66
|
+
readonly operationRegistry?: OperationRegistry;
|
|
67
|
+
readonly codecTypeImports?: ReadonlyArray<TypesImportSpec>;
|
|
68
|
+
readonly operationTypeImports?: ReadonlyArray<TypesImportSpec>;
|
|
69
|
+
readonly extensionIds?: ReadonlyArray<string>;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
declare const sqlTargetFamilyHook: {
|
|
73
|
+
readonly id: "sql";
|
|
74
|
+
readonly validateTypes: (ir: ContractIR, ctx: ValidationContext) => void;
|
|
75
|
+
readonly validateStructure: (ir: ContractIR) => void;
|
|
76
|
+
readonly generateContractTypes: (ir: ContractIR, codecTypeImports: ReadonlyArray<TypesImportSpec>, operationTypeImports: ReadonlyArray<TypesImportSpec>) => string;
|
|
77
|
+
readonly generateStorageType: (storage: SqlStorage) => string;
|
|
78
|
+
readonly generateModelsType: (models: Record<string, ModelDefinition> | undefined, storage: SqlStorage) => string;
|
|
79
|
+
readonly generateRelationsType: (relations: Record<string, unknown> | undefined) => string;
|
|
80
|
+
readonly generateMappingsType: (models: Record<string, ModelDefinition> | undefined, storage: SqlStorage, codecTypes: string, operationTypes: string) => string;
|
|
81
|
+
};
|
|
82
|
+
|
|
83
|
+
export { sqlTargetFamilyHook };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,408 @@
|
|
|
1
|
+
// src/index.ts
|
|
2
|
+
var sqlTargetFamilyHook = {
|
|
3
|
+
id: "sql",
|
|
4
|
+
validateTypes(ir, ctx) {
|
|
5
|
+
const storage = ir.storage;
|
|
6
|
+
if (!storage || !storage.tables) {
|
|
7
|
+
return;
|
|
8
|
+
}
|
|
9
|
+
const referencedNamespaces = /* @__PURE__ */ new Set();
|
|
10
|
+
const extensions = ir.extensions;
|
|
11
|
+
if (extensions) {
|
|
12
|
+
for (const namespace of Object.keys(extensions)) {
|
|
13
|
+
referencedNamespaces.add(namespace);
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
if (ctx.extensionIds) {
|
|
17
|
+
for (const extensionId of ctx.extensionIds) {
|
|
18
|
+
const namespaceMatch = extensionId.match(/^([^/]+)/);
|
|
19
|
+
if (namespaceMatch?.[1]) {
|
|
20
|
+
referencedNamespaces.add(namespaceMatch[1]);
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
const typeIdRegex = /^([^/]+)\/([^@]+)@(\d+)$/;
|
|
25
|
+
for (const [tableName, tableUnknown] of Object.entries(storage.tables)) {
|
|
26
|
+
const table = tableUnknown;
|
|
27
|
+
for (const [colName, colUnknown] of Object.entries(table.columns)) {
|
|
28
|
+
const col = colUnknown;
|
|
29
|
+
if (!col.type) {
|
|
30
|
+
throw new Error(`Column "${colName}" in table "${tableName}" is missing type`);
|
|
31
|
+
}
|
|
32
|
+
if (!typeIdRegex.test(col.type)) {
|
|
33
|
+
throw new Error(
|
|
34
|
+
`Column "${colName}" in table "${tableName}" has invalid type ID format "${col.type}". Expected format: ns/name@version`
|
|
35
|
+
);
|
|
36
|
+
}
|
|
37
|
+
const match = col.type.match(typeIdRegex);
|
|
38
|
+
if (!match || !match[1]) {
|
|
39
|
+
continue;
|
|
40
|
+
}
|
|
41
|
+
const namespace = match[1];
|
|
42
|
+
if (!referencedNamespaces.has(namespace)) {
|
|
43
|
+
throw new Error(
|
|
44
|
+
`Column "${colName}" in table "${tableName}" uses type ID "${col.type}" from namespace "${namespace}" which is not referenced in contract.extensions`
|
|
45
|
+
);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
},
|
|
50
|
+
validateStructure(ir) {
|
|
51
|
+
if (ir.targetFamily !== "sql") {
|
|
52
|
+
throw new Error(`Expected targetFamily "sql", got "${ir.targetFamily}"`);
|
|
53
|
+
}
|
|
54
|
+
const storage = ir.storage;
|
|
55
|
+
if (!storage || !storage.tables) {
|
|
56
|
+
throw new Error("SQL contract must have storage.tables");
|
|
57
|
+
}
|
|
58
|
+
const models = ir.models;
|
|
59
|
+
const tableNames = new Set(Object.keys(storage.tables));
|
|
60
|
+
if (models) {
|
|
61
|
+
for (const [modelName, modelUnknown] of Object.entries(models)) {
|
|
62
|
+
const model = modelUnknown;
|
|
63
|
+
if (!model.storage?.table) {
|
|
64
|
+
throw new Error(`Model "${modelName}" is missing storage.table`);
|
|
65
|
+
}
|
|
66
|
+
const tableName = model.storage.table;
|
|
67
|
+
if (!tableNames.has(tableName)) {
|
|
68
|
+
throw new Error(`Model "${modelName}" references non-existent table "${tableName}"`);
|
|
69
|
+
}
|
|
70
|
+
const table = storage.tables[tableName];
|
|
71
|
+
if (!table) {
|
|
72
|
+
throw new Error(`Model "${modelName}" references non-existent table "${tableName}"`);
|
|
73
|
+
}
|
|
74
|
+
if (!table.primaryKey) {
|
|
75
|
+
throw new Error(`Model "${modelName}" table "${tableName}" is missing a primary key`);
|
|
76
|
+
}
|
|
77
|
+
const columnNames = new Set(Object.keys(table.columns));
|
|
78
|
+
if (!model.fields || Object.keys(model.fields).length === 0) {
|
|
79
|
+
throw new Error(`Model "${modelName}" is missing fields`);
|
|
80
|
+
}
|
|
81
|
+
for (const [fieldName, fieldUnknown] of Object.entries(model.fields)) {
|
|
82
|
+
const field = fieldUnknown;
|
|
83
|
+
if (!field.column) {
|
|
84
|
+
throw new Error(`Model "${modelName}" field "${fieldName}" is missing column property`);
|
|
85
|
+
}
|
|
86
|
+
if (!columnNames.has(field.column)) {
|
|
87
|
+
throw new Error(
|
|
88
|
+
`Model "${modelName}" field "${fieldName}" references non-existent column "${field.column}" in table "${tableName}"`
|
|
89
|
+
);
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
if (!model.relations || typeof model.relations !== "object") {
|
|
93
|
+
throw new Error(
|
|
94
|
+
`Model "${modelName}" is missing required field "relations" (must be an object)`
|
|
95
|
+
);
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
for (const [tableName, tableUnknown] of Object.entries(storage.tables)) {
|
|
100
|
+
const table = tableUnknown;
|
|
101
|
+
const columnNames = new Set(Object.keys(table.columns));
|
|
102
|
+
for (const [colName, col] of Object.entries(table.columns)) {
|
|
103
|
+
if (typeof col.nullable !== "boolean") {
|
|
104
|
+
throw new Error(
|
|
105
|
+
`Table "${tableName}" column "${colName}" is missing required field "nullable" (must be a boolean)`
|
|
106
|
+
);
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
if (!Array.isArray(table.uniques)) {
|
|
110
|
+
throw new Error(
|
|
111
|
+
`Table "${tableName}" is missing required field "uniques" (must be an array)`
|
|
112
|
+
);
|
|
113
|
+
}
|
|
114
|
+
if (!Array.isArray(table.indexes)) {
|
|
115
|
+
throw new Error(
|
|
116
|
+
`Table "${tableName}" is missing required field "indexes" (must be an array)`
|
|
117
|
+
);
|
|
118
|
+
}
|
|
119
|
+
if (!Array.isArray(table.foreignKeys)) {
|
|
120
|
+
throw new Error(
|
|
121
|
+
`Table "${tableName}" is missing required field "foreignKeys" (must be an array)`
|
|
122
|
+
);
|
|
123
|
+
}
|
|
124
|
+
if (table.primaryKey) {
|
|
125
|
+
for (const colName of table.primaryKey.columns) {
|
|
126
|
+
if (!columnNames.has(colName)) {
|
|
127
|
+
throw new Error(
|
|
128
|
+
`Table "${tableName}" primaryKey references non-existent column "${colName}"`
|
|
129
|
+
);
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
for (const unique of table.uniques) {
|
|
134
|
+
for (const colName of unique.columns) {
|
|
135
|
+
if (!columnNames.has(colName)) {
|
|
136
|
+
throw new Error(
|
|
137
|
+
`Table "${tableName}" unique constraint references non-existent column "${colName}"`
|
|
138
|
+
);
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
for (const index of table.indexes) {
|
|
143
|
+
for (const colName of index.columns) {
|
|
144
|
+
if (!columnNames.has(colName)) {
|
|
145
|
+
throw new Error(
|
|
146
|
+
`Table "${tableName}" index references non-existent column "${colName}"`
|
|
147
|
+
);
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
for (const fk of table.foreignKeys) {
|
|
152
|
+
for (const colName of fk.columns) {
|
|
153
|
+
if (!columnNames.has(colName)) {
|
|
154
|
+
throw new Error(
|
|
155
|
+
`Table "${tableName}" foreignKey references non-existent column "${colName}"`
|
|
156
|
+
);
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
if (!tableNames.has(fk.references.table)) {
|
|
160
|
+
throw new Error(
|
|
161
|
+
`Table "${tableName}" foreignKey references non-existent table "${fk.references.table}"`
|
|
162
|
+
);
|
|
163
|
+
}
|
|
164
|
+
const referencedTable = storage.tables[fk.references.table];
|
|
165
|
+
if (!referencedTable) {
|
|
166
|
+
throw new Error(
|
|
167
|
+
`Table "${tableName}" foreignKey references non-existent table "${fk.references.table}"`
|
|
168
|
+
);
|
|
169
|
+
}
|
|
170
|
+
const referencedColumnNames = new Set(Object.keys(referencedTable.columns));
|
|
171
|
+
for (const colName of fk.references.columns) {
|
|
172
|
+
if (!referencedColumnNames.has(colName)) {
|
|
173
|
+
throw new Error(
|
|
174
|
+
`Table "${tableName}" foreignKey references non-existent column "${colName}" in table "${fk.references.table}"`
|
|
175
|
+
);
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
if (fk.columns.length !== fk.references.columns.length) {
|
|
179
|
+
throw new Error(
|
|
180
|
+
`Table "${tableName}" foreignKey column count (${fk.columns.length}) does not match referenced column count (${fk.references.columns.length})`
|
|
181
|
+
);
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
},
|
|
186
|
+
generateContractTypes(ir, codecTypeImports, operationTypeImports) {
|
|
187
|
+
const allImports = [...codecTypeImports, ...operationTypeImports];
|
|
188
|
+
const importLines = allImports.map(
|
|
189
|
+
(imp) => `import type { ${imp.named} as ${imp.alias} } from '${imp.package}';`
|
|
190
|
+
);
|
|
191
|
+
const codecTypes = codecTypeImports.map((imp) => imp.alias).join(" & ");
|
|
192
|
+
const operationTypes = operationTypeImports.map((imp) => imp.alias).join(" & ");
|
|
193
|
+
const storage = ir.storage;
|
|
194
|
+
const models = ir.models;
|
|
195
|
+
const storageType = this.generateStorageType(storage);
|
|
196
|
+
const modelsType = this.generateModelsType(models, storage);
|
|
197
|
+
const relationsType = this.generateRelationsType(ir.relations);
|
|
198
|
+
const mappingsType = this.generateMappingsType(models, storage, codecTypes, operationTypes);
|
|
199
|
+
return `// \u26A0\uFE0F GENERATED FILE - DO NOT EDIT
|
|
200
|
+
// This file is automatically generated by 'prisma-next emit'.
|
|
201
|
+
// To regenerate, run: prisma-next emit
|
|
202
|
+
${importLines.join("\n")}
|
|
203
|
+
|
|
204
|
+
import type { SqlContract, SqlStorage, SqlMappings, ModelDefinition } from '@prisma-next/sql-contract/types';
|
|
205
|
+
|
|
206
|
+
export type CodecTypes = ${codecTypes || "Record<string, never>"};
|
|
207
|
+
export type LaneCodecTypes = CodecTypes;
|
|
208
|
+
export type OperationTypes = ${operationTypes || "Record<string, never>"};
|
|
209
|
+
|
|
210
|
+
export type Contract = SqlContract<
|
|
211
|
+
${storageType},
|
|
212
|
+
${modelsType},
|
|
213
|
+
${relationsType},
|
|
214
|
+
${mappingsType}
|
|
215
|
+
>;
|
|
216
|
+
|
|
217
|
+
export type Tables = Contract['storage']['tables'];
|
|
218
|
+
export type Models = Contract['models'];
|
|
219
|
+
export type Relations = Contract['relations'];
|
|
220
|
+
`;
|
|
221
|
+
},
|
|
222
|
+
generateStorageType(storage) {
|
|
223
|
+
const tables = [];
|
|
224
|
+
for (const [tableName, table] of Object.entries(storage.tables)) {
|
|
225
|
+
const columns = [];
|
|
226
|
+
for (const [colName, col] of Object.entries(table.columns)) {
|
|
227
|
+
const nullable = col.nullable ? "true" : "false";
|
|
228
|
+
const type = col.type ? `'${col.type}'` : "string";
|
|
229
|
+
columns.push(
|
|
230
|
+
`readonly ${colName}: { readonly type: ${type}; readonly nullable: ${nullable} }`
|
|
231
|
+
);
|
|
232
|
+
}
|
|
233
|
+
const tableParts = [`columns: { ${columns.join("; ")} }`];
|
|
234
|
+
if (table.primaryKey) {
|
|
235
|
+
const pkCols = table.primaryKey.columns.map((c) => `'${c}'`).join(", ");
|
|
236
|
+
const pkName = table.primaryKey.name ? `; readonly name: '${table.primaryKey.name}'` : "";
|
|
237
|
+
tableParts.push(`primaryKey: { readonly columns: readonly [${pkCols}]${pkName} }`);
|
|
238
|
+
}
|
|
239
|
+
const uniques = table.uniques.map((u) => {
|
|
240
|
+
const cols = u.columns.map((c) => `'${c}'`).join(", ");
|
|
241
|
+
const name = u.name ? `; readonly name: '${u.name}'` : "";
|
|
242
|
+
return `{ readonly columns: readonly [${cols}]${name} }`;
|
|
243
|
+
}).join(", ");
|
|
244
|
+
tableParts.push(`uniques: readonly [${uniques}]`);
|
|
245
|
+
const indexes = table.indexes.map((i) => {
|
|
246
|
+
const cols = i.columns.map((c) => `'${c}'`).join(", ");
|
|
247
|
+
const name = i.name ? `; readonly name: '${i.name}'` : "";
|
|
248
|
+
return `{ readonly columns: readonly [${cols}]${name} }`;
|
|
249
|
+
}).join(", ");
|
|
250
|
+
tableParts.push(`indexes: readonly [${indexes}]`);
|
|
251
|
+
const fks = table.foreignKeys.map((fk) => {
|
|
252
|
+
const cols = fk.columns.map((c) => `'${c}'`).join(", ");
|
|
253
|
+
const refCols = fk.references.columns.map((c) => `'${c}'`).join(", ");
|
|
254
|
+
const name = fk.name ? `; readonly name: '${fk.name}'` : "";
|
|
255
|
+
return `{ readonly columns: readonly [${cols}]; readonly references: { readonly table: '${fk.references.table}'; readonly columns: readonly [${refCols}] }${name} }`;
|
|
256
|
+
}).join(", ");
|
|
257
|
+
tableParts.push(`foreignKeys: readonly [${fks}]`);
|
|
258
|
+
tables.push(`readonly ${tableName}: { ${tableParts.join("; ")} }`);
|
|
259
|
+
}
|
|
260
|
+
return `{ readonly tables: { ${tables.join("; ")} } }`;
|
|
261
|
+
},
|
|
262
|
+
generateModelsType(models, storage) {
|
|
263
|
+
if (!models) {
|
|
264
|
+
return "Record<string, never>";
|
|
265
|
+
}
|
|
266
|
+
const modelTypes = [];
|
|
267
|
+
for (const [modelName, model] of Object.entries(models)) {
|
|
268
|
+
const fields = [];
|
|
269
|
+
const tableName = model.storage.table;
|
|
270
|
+
const table = storage.tables[tableName];
|
|
271
|
+
if (table) {
|
|
272
|
+
for (const [fieldName, field] of Object.entries(model.fields)) {
|
|
273
|
+
const column = table.columns[field.column];
|
|
274
|
+
if (!column) {
|
|
275
|
+
fields.push(`readonly ${fieldName}: { readonly column: '${field.column}' }`);
|
|
276
|
+
continue;
|
|
277
|
+
}
|
|
278
|
+
const typeId = column.type || "string";
|
|
279
|
+
const nullable = column.nullable ?? false;
|
|
280
|
+
const jsType = nullable ? `CodecTypes['${typeId}']['output'] | null` : `CodecTypes['${typeId}']['output']`;
|
|
281
|
+
fields.push(`readonly ${fieldName}: ${jsType}`);
|
|
282
|
+
}
|
|
283
|
+
} else {
|
|
284
|
+
for (const [fieldName, field] of Object.entries(model.fields)) {
|
|
285
|
+
fields.push(`readonly ${fieldName}: { readonly column: '${field.column}' }`);
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
const relations = [];
|
|
289
|
+
for (const [relName, rel] of Object.entries(model.relations)) {
|
|
290
|
+
if (typeof rel === "object" && rel !== null && "on" in rel) {
|
|
291
|
+
const on = rel.on;
|
|
292
|
+
if (on.parentCols && on.childCols) {
|
|
293
|
+
const parentCols = on.parentCols.map((c) => `'${c}'`).join(", ");
|
|
294
|
+
const childCols = on.childCols.map((c) => `'${c}'`).join(", ");
|
|
295
|
+
relations.push(
|
|
296
|
+
`readonly ${relName}: { readonly on: { readonly parentCols: readonly [${parentCols}]; readonly childCols: readonly [${childCols}] } }`
|
|
297
|
+
);
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
const modelParts = [
|
|
302
|
+
`storage: { readonly table: '${tableName}' }`,
|
|
303
|
+
`fields: { ${fields.join("; ")} }`
|
|
304
|
+
];
|
|
305
|
+
if (relations.length > 0) {
|
|
306
|
+
modelParts.push(`relations: { ${relations.join("; ")} }`);
|
|
307
|
+
}
|
|
308
|
+
modelTypes.push(`readonly ${modelName}: { ${modelParts.join("; ")} }`);
|
|
309
|
+
}
|
|
310
|
+
return `{ ${modelTypes.join("; ")} }`;
|
|
311
|
+
},
|
|
312
|
+
generateRelationsType(relations) {
|
|
313
|
+
if (!relations || Object.keys(relations).length === 0) {
|
|
314
|
+
return "Record<string, never>";
|
|
315
|
+
}
|
|
316
|
+
const tableEntries = [];
|
|
317
|
+
for (const [tableName, relsValue] of Object.entries(relations)) {
|
|
318
|
+
if (typeof relsValue !== "object" || relsValue === null) {
|
|
319
|
+
continue;
|
|
320
|
+
}
|
|
321
|
+
const rels = relsValue;
|
|
322
|
+
const relationEntries = [];
|
|
323
|
+
for (const [relName, relValue] of Object.entries(rels)) {
|
|
324
|
+
if (typeof relValue !== "object" || relValue === null) {
|
|
325
|
+
relationEntries.push(`readonly ${relName}: unknown`);
|
|
326
|
+
continue;
|
|
327
|
+
}
|
|
328
|
+
const { to, cardinality, on, through } = relValue;
|
|
329
|
+
const parts = [];
|
|
330
|
+
if (to) {
|
|
331
|
+
parts.push(`readonly to: '${to}'`);
|
|
332
|
+
}
|
|
333
|
+
if (cardinality) {
|
|
334
|
+
parts.push(`readonly cardinality: '${cardinality}'`);
|
|
335
|
+
}
|
|
336
|
+
if (on?.parentCols && on.childCols) {
|
|
337
|
+
const parentCols = on.parentCols.map((c) => `'${c}'`).join(", ");
|
|
338
|
+
const childCols = on.childCols.map((c) => `'${c}'`).join(", ");
|
|
339
|
+
parts.push(
|
|
340
|
+
`readonly on: { readonly parentCols: readonly [${parentCols}]; readonly childCols: readonly [${childCols}] }`
|
|
341
|
+
);
|
|
342
|
+
}
|
|
343
|
+
if (through) {
|
|
344
|
+
const parentCols = through.parentCols.map((c) => `'${c}'`).join(", ");
|
|
345
|
+
const childCols = through.childCols.map((c) => `'${c}'`).join(", ");
|
|
346
|
+
parts.push(
|
|
347
|
+
`readonly through: { readonly table: '${through.table}'; readonly parentCols: readonly [${parentCols}]; readonly childCols: readonly [${childCols}] }`
|
|
348
|
+
);
|
|
349
|
+
}
|
|
350
|
+
relationEntries.push(
|
|
351
|
+
parts.length > 0 ? `readonly ${relName}: { ${parts.join("; ")} }` : `readonly ${relName}: unknown`
|
|
352
|
+
);
|
|
353
|
+
}
|
|
354
|
+
tableEntries.push(`readonly ${tableName}: { ${relationEntries.join("; ")} }`);
|
|
355
|
+
}
|
|
356
|
+
return `{ ${tableEntries.join("; ")} }`;
|
|
357
|
+
},
|
|
358
|
+
generateMappingsType(models, storage, codecTypes, operationTypes) {
|
|
359
|
+
if (!models) {
|
|
360
|
+
return `SqlMappings & { readonly codecTypes: ${codecTypes || "Record<string, never>"}; readonly operationTypes: ${operationTypes || "Record<string, never>"}; }`;
|
|
361
|
+
}
|
|
362
|
+
const modelToTable = [];
|
|
363
|
+
const tableToModel = [];
|
|
364
|
+
const fieldToColumn = [];
|
|
365
|
+
const columnToField = [];
|
|
366
|
+
for (const [modelName, model] of Object.entries(models)) {
|
|
367
|
+
const tableName = model.storage.table;
|
|
368
|
+
modelToTable.push(`readonly ${modelName}: '${tableName}'`);
|
|
369
|
+
tableToModel.push(`readonly ${tableName}: '${modelName}'`);
|
|
370
|
+
const fieldMap = [];
|
|
371
|
+
for (const [fieldName, field] of Object.entries(model.fields)) {
|
|
372
|
+
fieldMap.push(`readonly ${fieldName}: '${field.column}'`);
|
|
373
|
+
}
|
|
374
|
+
if (fieldMap.length > 0) {
|
|
375
|
+
fieldToColumn.push(`readonly ${modelName}: { ${fieldMap.join("; ")} }`);
|
|
376
|
+
}
|
|
377
|
+
if (storage.tables[tableName]) {
|
|
378
|
+
const colMap = [];
|
|
379
|
+
for (const [fieldName, field] of Object.entries(model.fields)) {
|
|
380
|
+
colMap.push(`readonly ${field.column}: '${fieldName}'`);
|
|
381
|
+
}
|
|
382
|
+
if (colMap.length > 0) {
|
|
383
|
+
columnToField.push(`readonly ${tableName}: { ${colMap.join("; ")} }`);
|
|
384
|
+
}
|
|
385
|
+
}
|
|
386
|
+
}
|
|
387
|
+
const parts = [];
|
|
388
|
+
if (modelToTable.length > 0) {
|
|
389
|
+
parts.push(`modelToTable: { ${modelToTable.join("; ")} }`);
|
|
390
|
+
}
|
|
391
|
+
if (tableToModel.length > 0) {
|
|
392
|
+
parts.push(`tableToModel: { ${tableToModel.join("; ")} }`);
|
|
393
|
+
}
|
|
394
|
+
if (fieldToColumn.length > 0) {
|
|
395
|
+
parts.push(`fieldToColumn: { ${fieldToColumn.join("; ")} }`);
|
|
396
|
+
}
|
|
397
|
+
if (columnToField.length > 0) {
|
|
398
|
+
parts.push(`columnToField: { ${columnToField.join("; ")} }`);
|
|
399
|
+
}
|
|
400
|
+
parts.push(`codecTypes: ${codecTypes || "Record<string, never>"}`);
|
|
401
|
+
parts.push(`operationTypes: ${operationTypes || "Record<string, never>"}`);
|
|
402
|
+
return `{ ${parts.join("; ")} }`;
|
|
403
|
+
}
|
|
404
|
+
};
|
|
405
|
+
export {
|
|
406
|
+
sqlTargetFamilyHook
|
|
407
|
+
};
|
|
408
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +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 const referencedNamespaces = new Set<string>();\n\n // Collect namespaces from ir.extensions\n const extensions = ir.extensions as Record<string, unknown> | undefined;\n if (extensions) {\n for (const namespace of Object.keys(extensions)) {\n referencedNamespaces.add(namespace);\n }\n }\n\n // Also validate against extensionIds from context for consistency\n if (ctx.extensionIds) {\n for (const extensionId of ctx.extensionIds) {\n // Extract namespace from extension ID (format: namespace/name@version or just namespace)\n const namespaceMatch = extensionId.match(/^([^/]+)/);\n if (namespaceMatch?.[1]) {\n referencedNamespaces.add(namespaceMatch[1]);\n }\n }\n }\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 { type: string; nullable?: boolean };\n if (!col.type) {\n throw new Error(`Column \"${colName}\" in table \"${tableName}\" is missing type`);\n }\n\n if (!typeIdRegex.test(col.type)) {\n throw new Error(\n `Column \"${colName}\" in table \"${tableName}\" has invalid type ID format \"${col.type}\". Expected format: ns/name@version`,\n );\n }\n\n const match = col.type.match(typeIdRegex);\n if (!match || !match[1]) {\n continue;\n }\n\n const namespace = match[1];\n if (!referencedNamespaces.has(namespace)) {\n throw new Error(\n `Column \"${colName}\" in table \"${tableName}\" uses type ID \"${col.type}\" from namespace \"${namespace}\" which is not referenced in contract.extensions`,\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 for (const [colName, col] of Object.entries(table.columns)) {\n if (typeof col.nullable !== 'boolean') {\n throw new Error(\n `Table \"${tableName}\" column \"${colName}\" is missing required field \"nullable\" (must be a boolean)`,\n );\n }\n }\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 emit'.\n// To regenerate, run: prisma-next 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 type = col.type ? `'${col.type}'` : 'string';\n columns.push(\n `readonly ${colName}: { readonly type: ${type}; 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.type || 'string';\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":[]}
|
package/package.json
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@prisma-next/sql-contract-emitter",
|
|
3
|
+
"version": "0.0.1",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"sideEffects": false,
|
|
6
|
+
"description": "SQL emitter hook for Prisma Next",
|
|
7
|
+
"dependencies": {
|
|
8
|
+
"@prisma-next/sql-contract": "0.0.1",
|
|
9
|
+
"@prisma-next/emitter": "0.0.1"
|
|
10
|
+
},
|
|
11
|
+
"devDependencies": {
|
|
12
|
+
"tsup": "^8.3.0",
|
|
13
|
+
"typescript": "^5.9.3",
|
|
14
|
+
"vite-tsconfig-paths": "^5.1.4",
|
|
15
|
+
"vitest": "^2.1.1",
|
|
16
|
+
"@prisma-next/test-utils": "0.0.1"
|
|
17
|
+
},
|
|
18
|
+
"files": [
|
|
19
|
+
"dist"
|
|
20
|
+
],
|
|
21
|
+
"exports": {
|
|
22
|
+
".": {
|
|
23
|
+
"types": "./dist/index.d.ts",
|
|
24
|
+
"import": "./dist/index.js"
|
|
25
|
+
}
|
|
26
|
+
},
|
|
27
|
+
"scripts": {
|
|
28
|
+
"build": "tsup --config tsup.config.ts",
|
|
29
|
+
"test": "vitest run --passWithNoTests",
|
|
30
|
+
"test:coverage": "vitest run --coverage --passWithNoTests",
|
|
31
|
+
"typecheck": "tsc --project tsconfig.json --noEmit",
|
|
32
|
+
"lint": "biome check . --config-path ../../../../biome.json --error-on-warnings",
|
|
33
|
+
"clean": "node ../../../../scripts/clean.mjs"
|
|
34
|
+
}
|
|
35
|
+
}
|