@prisma-next/sql-contract-ts 0.3.0-dev.5 → 0.3.0-dev.50
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 +78 -12
- package/dist/config-types.d.mts +8 -0
- package/dist/config-types.d.mts.map +1 -0
- package/dist/config-types.mjs +14 -0
- package/dist/config-types.mjs.map +1 -0
- package/dist/contract-builder.d.mts +110 -0
- package/dist/contract-builder.d.mts.map +1 -0
- package/dist/contract-builder.mjs +385 -0
- package/dist/contract-builder.mjs.map +1 -0
- package/package.json +32 -19
- package/schemas/data-contract-sql-v1.json +168 -8
- package/src/config-types.ts +11 -0
- package/src/contract-builder.ts +372 -42
- package/src/contract.ts +107 -96
- package/src/exports/config-types.ts +2 -0
- package/dist/chunk-SEOX3AAQ.js +0 -309
- package/dist/chunk-SEOX3AAQ.js.map +0 -1
- package/dist/contract-builder.d.ts +0 -87
- package/dist/contract-builder.d.ts.map +0 -1
- package/dist/contract.d.ts +0 -50
- package/dist/contract.d.ts.map +0 -1
- package/dist/exports/contract-builder.d.ts +0 -3
- package/dist/exports/contract-builder.d.ts.map +0 -1
- package/dist/exports/contract-builder.js +0 -216
- package/dist/exports/contract-builder.js.map +0 -1
- package/dist/exports/contract.d.ts +0 -2
- package/dist/exports/contract.d.ts.map +0 -1
- package/dist/exports/contract.js +0 -9
- package/dist/exports/contract.js.map +0 -1
- package/src/exports/contract.ts +0 -1
package/src/contract-builder.ts
CHANGED
|
@@ -1,6 +1,17 @@
|
|
|
1
1
|
import type { ExtensionPackRef, TargetPackRef } from '@prisma-next/contract/framework-components';
|
|
2
|
+
import type {
|
|
3
|
+
ColumnDefault,
|
|
4
|
+
ColumnDefaultLiteralInputValue,
|
|
5
|
+
ColumnDefaultLiteralValue,
|
|
6
|
+
ExecutionMutationDefault,
|
|
7
|
+
ExecutionMutationDefaultValue,
|
|
8
|
+
TaggedRaw,
|
|
9
|
+
} from '@prisma-next/contract/types';
|
|
2
10
|
import type {
|
|
3
11
|
ColumnBuilderState,
|
|
12
|
+
ColumnTypeDescriptor,
|
|
13
|
+
ContractBuilderState,
|
|
14
|
+
ForeignKeyDefaultsState,
|
|
4
15
|
ModelBuilderState,
|
|
5
16
|
RelationDefinition,
|
|
6
17
|
TableBuilderState,
|
|
@@ -10,21 +21,114 @@ import {
|
|
|
10
21
|
type BuildRelations,
|
|
11
22
|
type BuildStorageColumn,
|
|
12
23
|
ContractBuilder,
|
|
24
|
+
createTable,
|
|
13
25
|
type ExtractColumns,
|
|
14
26
|
type ExtractPrimaryKey,
|
|
15
27
|
ModelBuilder,
|
|
16
28
|
type Mutable,
|
|
17
29
|
TableBuilder,
|
|
18
30
|
} from '@prisma-next/contract-authoring';
|
|
19
|
-
import
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
31
|
+
import {
|
|
32
|
+
applyFkDefaults,
|
|
33
|
+
type ModelDefinition,
|
|
34
|
+
type ModelField,
|
|
35
|
+
type ReferentialAction,
|
|
36
|
+
type SqlContract,
|
|
37
|
+
type SqlMappings,
|
|
38
|
+
type SqlStorage,
|
|
39
|
+
type StorageTypeInstance,
|
|
25
40
|
} from '@prisma-next/sql-contract/types';
|
|
41
|
+
import { ifDefined } from '@prisma-next/utils/defined';
|
|
26
42
|
import { computeMappings } from './contract';
|
|
27
43
|
|
|
44
|
+
type ColumnDefaultForCodec<
|
|
45
|
+
CodecTypes extends Record<string, { output: unknown }>,
|
|
46
|
+
CodecId extends string,
|
|
47
|
+
> =
|
|
48
|
+
| {
|
|
49
|
+
readonly kind: 'literal';
|
|
50
|
+
readonly value: CodecId extends keyof CodecTypes ? CodecTypes[CodecId]['output'] : unknown;
|
|
51
|
+
}
|
|
52
|
+
| { readonly kind: 'function'; readonly expression: string };
|
|
53
|
+
|
|
54
|
+
type SqlNullableColumnOptions<
|
|
55
|
+
Descriptor extends ColumnTypeDescriptor,
|
|
56
|
+
CodecTypes extends Record<string, { output: unknown }>,
|
|
57
|
+
> = {
|
|
58
|
+
readonly type: Descriptor;
|
|
59
|
+
readonly nullable: true;
|
|
60
|
+
readonly typeParams?: Record<string, unknown>;
|
|
61
|
+
readonly default?: ColumnDefaultForCodec<CodecTypes, Descriptor['codecId']>;
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
type SqlNonNullableColumnOptions<
|
|
65
|
+
Descriptor extends ColumnTypeDescriptor,
|
|
66
|
+
CodecTypes extends Record<string, { output: unknown }>,
|
|
67
|
+
> = {
|
|
68
|
+
readonly type: Descriptor;
|
|
69
|
+
readonly nullable?: false;
|
|
70
|
+
readonly typeParams?: Record<string, unknown>;
|
|
71
|
+
readonly default?: ColumnDefaultForCodec<CodecTypes, Descriptor['codecId']>;
|
|
72
|
+
};
|
|
73
|
+
|
|
74
|
+
type SqlGeneratedColumnOptions<
|
|
75
|
+
Descriptor extends ColumnTypeDescriptor,
|
|
76
|
+
CodecTypes extends Record<string, { output: unknown }>,
|
|
77
|
+
> = Omit<SqlNonNullableColumnOptions<Descriptor, CodecTypes>, 'default' | 'nullable'> & {
|
|
78
|
+
readonly nullable?: false;
|
|
79
|
+
readonly generated: ExecutionMutationDefaultValue;
|
|
80
|
+
};
|
|
81
|
+
|
|
82
|
+
type SqlColumnOptions<
|
|
83
|
+
Descriptor extends ColumnTypeDescriptor,
|
|
84
|
+
CodecTypes extends Record<string, { output: unknown }>,
|
|
85
|
+
> =
|
|
86
|
+
| SqlNullableColumnOptions<Descriptor, CodecTypes>
|
|
87
|
+
| SqlNonNullableColumnOptions<Descriptor, CodecTypes>;
|
|
88
|
+
|
|
89
|
+
export interface SqlTableBuilder<
|
|
90
|
+
Name extends string,
|
|
91
|
+
CodecTypes extends Record<string, { output: unknown }>,
|
|
92
|
+
Columns extends Record<string, ColumnBuilderState<string, boolean, string>> = Record<
|
|
93
|
+
never,
|
|
94
|
+
ColumnBuilderState<string, boolean, string>
|
|
95
|
+
>,
|
|
96
|
+
PrimaryKey extends readonly string[] | undefined = undefined,
|
|
97
|
+
> extends Omit<TableBuilder<Name, Columns, PrimaryKey>, 'column' | 'generated'> {
|
|
98
|
+
column<ColName extends string, Descriptor extends ColumnTypeDescriptor>(
|
|
99
|
+
name: ColName,
|
|
100
|
+
options: SqlNullableColumnOptions<Descriptor, CodecTypes>,
|
|
101
|
+
): TableBuilder<
|
|
102
|
+
Name,
|
|
103
|
+
Columns & Record<ColName, ColumnBuilderState<ColName, true, Descriptor['codecId']>>,
|
|
104
|
+
PrimaryKey
|
|
105
|
+
>;
|
|
106
|
+
column<ColName extends string, Descriptor extends ColumnTypeDescriptor>(
|
|
107
|
+
name: ColName,
|
|
108
|
+
options: SqlNonNullableColumnOptions<Descriptor, CodecTypes>,
|
|
109
|
+
): TableBuilder<
|
|
110
|
+
Name,
|
|
111
|
+
Columns & Record<ColName, ColumnBuilderState<ColName, false, Descriptor['codecId']>>,
|
|
112
|
+
PrimaryKey
|
|
113
|
+
>;
|
|
114
|
+
column<ColName extends string, Descriptor extends ColumnTypeDescriptor>(
|
|
115
|
+
name: ColName,
|
|
116
|
+
options: SqlColumnOptions<Descriptor, CodecTypes>,
|
|
117
|
+
): TableBuilder<
|
|
118
|
+
Name,
|
|
119
|
+
Columns & Record<ColName, ColumnBuilderState<ColName, boolean, Descriptor['codecId']>>,
|
|
120
|
+
PrimaryKey
|
|
121
|
+
>;
|
|
122
|
+
generated<ColName extends string, Descriptor extends ColumnTypeDescriptor>(
|
|
123
|
+
name: ColName,
|
|
124
|
+
options: SqlGeneratedColumnOptions<Descriptor, CodecTypes>,
|
|
125
|
+
): TableBuilder<
|
|
126
|
+
Name,
|
|
127
|
+
Columns & Record<ColName, ColumnBuilderState<ColName, false, Descriptor['codecId']>>,
|
|
128
|
+
PrimaryKey
|
|
129
|
+
>;
|
|
130
|
+
}
|
|
131
|
+
|
|
28
132
|
/**
|
|
29
133
|
* Type-level mappings structure for contracts built via `defineContract()`.
|
|
30
134
|
*
|
|
@@ -32,8 +136,8 @@ import { computeMappings } from './contract';
|
|
|
32
136
|
* produces. `codecTypes` uses the generic `CodecTypes` parameter; `operationTypes` is always
|
|
33
137
|
* empty since operations are added via extensions at runtime.
|
|
34
138
|
*
|
|
35
|
-
* **Difference from
|
|
36
|
-
* `
|
|
139
|
+
* **Difference from ExecutionContext**: This is a compile-time type for contract construction.
|
|
140
|
+
* `ExecutionContext` is a runtime object with populated registries for query execution.
|
|
37
141
|
*
|
|
38
142
|
* @template C - The `CodecTypes` generic parameter passed to `defineContract<CodecTypes>()`
|
|
39
143
|
*/
|
|
@@ -59,11 +163,19 @@ type BuildStorageTable<
|
|
|
59
163
|
? BuildStorageColumn<Null & boolean, TType>
|
|
60
164
|
: never;
|
|
61
165
|
};
|
|
62
|
-
readonly uniques: ReadonlyArray<
|
|
63
|
-
readonly indexes: ReadonlyArray<
|
|
64
|
-
readonly foreignKeys: ReadonlyArray<
|
|
166
|
+
readonly uniques: ReadonlyArray<{ readonly columns: readonly string[]; readonly name?: string }>;
|
|
167
|
+
readonly indexes: ReadonlyArray<{ readonly columns: readonly string[]; readonly name?: string }>;
|
|
168
|
+
readonly foreignKeys: ReadonlyArray<{
|
|
169
|
+
readonly columns: readonly string[];
|
|
170
|
+
readonly references: { readonly table: string; readonly columns: readonly string[] };
|
|
171
|
+
readonly name?: string;
|
|
172
|
+
readonly onDelete?: ReferentialAction;
|
|
173
|
+
readonly onUpdate?: ReferentialAction;
|
|
174
|
+
readonly constraint: boolean;
|
|
175
|
+
readonly index: boolean;
|
|
176
|
+
}>;
|
|
65
177
|
} & (PK extends readonly string[]
|
|
66
|
-
? { readonly primaryKey: { readonly columns: PK } }
|
|
178
|
+
? { readonly primaryKey: { readonly columns: PK; readonly name?: string } }
|
|
67
179
|
: Record<string, never>);
|
|
68
180
|
|
|
69
181
|
type BuildStorage<
|
|
@@ -75,6 +187,7 @@ type BuildStorage<
|
|
|
75
187
|
readonly string[] | undefined
|
|
76
188
|
>
|
|
77
189
|
>,
|
|
190
|
+
Types extends Record<string, StorageTypeInstance>,
|
|
78
191
|
> = {
|
|
79
192
|
readonly tables: {
|
|
80
193
|
readonly [K in keyof Tables]: BuildStorageTable<
|
|
@@ -83,6 +196,7 @@ type BuildStorage<
|
|
|
83
196
|
ExtractPrimaryKey<Tables[K]>
|
|
84
197
|
>;
|
|
85
198
|
};
|
|
199
|
+
readonly types: Types;
|
|
86
200
|
};
|
|
87
201
|
|
|
88
202
|
type BuildStorageTables<
|
|
@@ -108,6 +222,52 @@ export interface ColumnBuilder<Name extends string, Nullable extends boolean, Ty
|
|
|
108
222
|
build(): ColumnBuilderState<Name, Nullable, Type>;
|
|
109
223
|
}
|
|
110
224
|
|
|
225
|
+
function isPlainObject(value: unknown): value is Record<string, unknown> {
|
|
226
|
+
if (typeof value !== 'object' || value === null) return false;
|
|
227
|
+
const proto = Object.getPrototypeOf(value);
|
|
228
|
+
return proto === Object.prototype || proto === null;
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
function isJsonValue(value: unknown): value is ColumnDefaultLiteralValue {
|
|
232
|
+
if (value === null) return true;
|
|
233
|
+
const valueType = typeof value;
|
|
234
|
+
if (valueType === 'string' || valueType === 'number' || valueType === 'boolean') return true;
|
|
235
|
+
if (Array.isArray(value)) {
|
|
236
|
+
return value.every((item) => isJsonValue(item));
|
|
237
|
+
}
|
|
238
|
+
if (isPlainObject(value)) {
|
|
239
|
+
return Object.values(value).every((item) => isJsonValue(item));
|
|
240
|
+
}
|
|
241
|
+
return false;
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
function encodeDefaultLiteralValue(
|
|
245
|
+
value: ColumnDefaultLiteralInputValue,
|
|
246
|
+
): ColumnDefaultLiteralValue {
|
|
247
|
+
if (typeof value === 'bigint') {
|
|
248
|
+
return { $type: 'bigint', value: value.toString() };
|
|
249
|
+
}
|
|
250
|
+
if (value instanceof Date) {
|
|
251
|
+
return value.toISOString();
|
|
252
|
+
}
|
|
253
|
+
if (isJsonValue(value)) {
|
|
254
|
+
if (isPlainObject(value) && '$type' in value) {
|
|
255
|
+
return { $type: 'raw', value } satisfies TaggedRaw;
|
|
256
|
+
}
|
|
257
|
+
return value;
|
|
258
|
+
}
|
|
259
|
+
throw new Error(
|
|
260
|
+
'Unsupported column default literal value: expected JSON-safe value, bigint, or Date.',
|
|
261
|
+
);
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
function encodeColumnDefault(defaultInput: ColumnDefault): ColumnDefault {
|
|
265
|
+
if (defaultInput.kind === 'function') {
|
|
266
|
+
return { kind: 'function', expression: defaultInput.expression };
|
|
267
|
+
}
|
|
268
|
+
return { kind: 'literal', value: encodeDefaultLiteralValue(defaultInput.value) };
|
|
269
|
+
}
|
|
270
|
+
|
|
111
271
|
class SqlContractBuilder<
|
|
112
272
|
CodecTypes extends Record<string, { output: unknown }> = Record<string, never>,
|
|
113
273
|
Target extends string | undefined = undefined,
|
|
@@ -123,10 +283,21 @@ class SqlContractBuilder<
|
|
|
123
283
|
string,
|
|
124
284
|
ModelBuilderState<string, string, Record<string, string>, Record<string, RelationDefinition>>
|
|
125
285
|
> = Record<never, never>,
|
|
126
|
-
|
|
286
|
+
Types extends Record<string, StorageTypeInstance> = Record<never, never>,
|
|
287
|
+
StorageHash extends string | undefined = undefined,
|
|
127
288
|
ExtensionPacks extends Record<string, unknown> | undefined = undefined,
|
|
128
289
|
Capabilities extends Record<string, Record<string, boolean>> | undefined = undefined,
|
|
129
|
-
> extends ContractBuilder<Target, Tables, Models,
|
|
290
|
+
> extends ContractBuilder<Target, Tables, Models, StorageHash, ExtensionPacks, Capabilities> {
|
|
291
|
+
protected declare readonly state: ContractBuilderState<
|
|
292
|
+
Target,
|
|
293
|
+
Tables,
|
|
294
|
+
Models,
|
|
295
|
+
StorageHash,
|
|
296
|
+
ExtensionPacks,
|
|
297
|
+
Capabilities
|
|
298
|
+
> & {
|
|
299
|
+
readonly storageTypes?: Types;
|
|
300
|
+
};
|
|
130
301
|
/**
|
|
131
302
|
* This method is responsible for normalizing the contract IR by setting default values
|
|
132
303
|
* for all required fields:
|
|
@@ -147,7 +318,7 @@ class SqlContractBuilder<
|
|
|
147
318
|
*/
|
|
148
319
|
build(): Target extends string
|
|
149
320
|
? SqlContract<
|
|
150
|
-
BuildStorage<Tables>,
|
|
321
|
+
BuildStorage<Tables, Types>,
|
|
151
322
|
BuildModels<Models>,
|
|
152
323
|
BuildRelations<Models>,
|
|
153
324
|
ContractBuilderMappings<CodecTypes>
|
|
@@ -155,7 +326,7 @@ class SqlContractBuilder<
|
|
|
155
326
|
readonly schemaVersion: '1';
|
|
156
327
|
readonly target: Target;
|
|
157
328
|
readonly targetFamily: 'sql';
|
|
158
|
-
readonly
|
|
329
|
+
readonly storageHash: StorageHash extends string ? StorageHash : string;
|
|
159
330
|
} & (ExtensionPacks extends Record<string, unknown>
|
|
160
331
|
? { readonly extensionPacks: ExtensionPacks }
|
|
161
332
|
: Record<string, never>) &
|
|
@@ -166,7 +337,7 @@ class SqlContractBuilder<
|
|
|
166
337
|
// Type helper to ensure literal types are preserved in return type
|
|
167
338
|
type BuiltContract = Target extends string
|
|
168
339
|
? SqlContract<
|
|
169
|
-
BuildStorage<Tables>,
|
|
340
|
+
BuildStorage<Tables, Types>,
|
|
170
341
|
BuildModels<Models>,
|
|
171
342
|
BuildRelations<Models>,
|
|
172
343
|
ContractBuilderMappings<CodecTypes>
|
|
@@ -174,7 +345,7 @@ class SqlContractBuilder<
|
|
|
174
345
|
readonly schemaVersion: '1';
|
|
175
346
|
readonly target: Target;
|
|
176
347
|
readonly targetFamily: 'sql';
|
|
177
|
-
readonly
|
|
348
|
+
readonly storageHash: StorageHash extends string ? StorageHash : string;
|
|
178
349
|
} & (ExtensionPacks extends Record<string, unknown>
|
|
179
350
|
? { readonly extensionPacks: ExtensionPacks }
|
|
180
351
|
: Record<string, never>) &
|
|
@@ -189,6 +360,7 @@ class SqlContractBuilder<
|
|
|
189
360
|
const target = this.state.target as Target & string;
|
|
190
361
|
|
|
191
362
|
const storageTables = {} as Partial<Mutable<BuildStorageTables<Tables>>>;
|
|
363
|
+
const executionDefaults: ExecutionMutationDefault[] = [];
|
|
192
364
|
|
|
193
365
|
for (const tableName of Object.keys(this.state.tables) as Array<keyof Tables & string>) {
|
|
194
366
|
const tableState = this.state.tables[tableName];
|
|
@@ -210,18 +382,56 @@ class SqlContractBuilder<
|
|
|
210
382
|
if (!columnState) continue;
|
|
211
383
|
const codecId = columnState.type;
|
|
212
384
|
const nativeType = columnState.nativeType;
|
|
385
|
+
const typeRef = columnState.typeRef;
|
|
386
|
+
|
|
387
|
+
const encodedDefault =
|
|
388
|
+
columnState.default !== undefined
|
|
389
|
+
? encodeColumnDefault(columnState.default as ColumnDefault)
|
|
390
|
+
: undefined;
|
|
213
391
|
|
|
214
392
|
columns[columnName as keyof ColumnDefs] = {
|
|
215
393
|
nativeType,
|
|
216
394
|
codecId,
|
|
217
395
|
nullable: (columnState.nullable ?? false) as ColumnDefs[keyof ColumnDefs]['nullable'] &
|
|
218
396
|
boolean,
|
|
397
|
+
...ifDefined('typeParams', columnState.typeParams),
|
|
398
|
+
...ifDefined('default', encodedDefault),
|
|
399
|
+
...ifDefined('typeRef', typeRef),
|
|
219
400
|
} as BuildStorageColumn<
|
|
220
401
|
ColumnDefs[keyof ColumnDefs]['nullable'] & boolean,
|
|
221
402
|
ColumnDefs[keyof ColumnDefs]['type']
|
|
222
403
|
>;
|
|
404
|
+
|
|
405
|
+
if ('executionDefault' in columnState && columnState.executionDefault) {
|
|
406
|
+
executionDefaults.push({
|
|
407
|
+
ref: { table: tableName, column: columnName },
|
|
408
|
+
onCreate: columnState.executionDefault,
|
|
409
|
+
});
|
|
410
|
+
}
|
|
223
411
|
}
|
|
224
412
|
|
|
413
|
+
// Build uniques from table state
|
|
414
|
+
const uniques = (tableState.uniques ?? []).map((u) => ({
|
|
415
|
+
columns: u.columns,
|
|
416
|
+
...(u.name ? { name: u.name } : {}),
|
|
417
|
+
}));
|
|
418
|
+
|
|
419
|
+
// Build indexes from table state
|
|
420
|
+
const indexes = (tableState.indexes ?? []).map((i) => ({
|
|
421
|
+
columns: i.columns,
|
|
422
|
+
...(i.name ? { name: i.name } : {}),
|
|
423
|
+
}));
|
|
424
|
+
|
|
425
|
+
// Build foreign keys from table state, materializing defaults
|
|
426
|
+
const foreignKeys = (tableState.foreignKeys ?? []).map((fk) => ({
|
|
427
|
+
columns: fk.columns,
|
|
428
|
+
references: fk.references,
|
|
429
|
+
...applyFkDefaults(fk, this.state.foreignKeyDefaults),
|
|
430
|
+
...(fk.name ? { name: fk.name } : {}),
|
|
431
|
+
...(fk.onDelete !== undefined ? { onDelete: fk.onDelete } : {}),
|
|
432
|
+
...(fk.onUpdate !== undefined ? { onUpdate: fk.onUpdate } : {}),
|
|
433
|
+
}));
|
|
434
|
+
|
|
225
435
|
const table = {
|
|
226
436
|
columns: columns as {
|
|
227
437
|
[K in keyof ColumnDefs]: BuildStorageColumn<
|
|
@@ -229,13 +439,14 @@ class SqlContractBuilder<
|
|
|
229
439
|
ColumnDefs[K]['type']
|
|
230
440
|
>;
|
|
231
441
|
},
|
|
232
|
-
uniques
|
|
233
|
-
indexes
|
|
234
|
-
foreignKeys
|
|
442
|
+
uniques,
|
|
443
|
+
indexes,
|
|
444
|
+
foreignKeys,
|
|
235
445
|
...(tableState.primaryKey
|
|
236
446
|
? {
|
|
237
447
|
primaryKey: {
|
|
238
448
|
columns: tableState.primaryKey,
|
|
449
|
+
...(tableState.primaryKeyName ? { name: tableState.primaryKeyName } : {}),
|
|
239
450
|
},
|
|
240
451
|
}
|
|
241
452
|
: {}),
|
|
@@ -244,7 +455,26 @@ class SqlContractBuilder<
|
|
|
244
455
|
(storageTables as Mutable<BuildStorageTables<Tables>>)[tableName] = table;
|
|
245
456
|
}
|
|
246
457
|
|
|
247
|
-
const
|
|
458
|
+
const storageTypes = (this.state.storageTypes ?? {}) as Types;
|
|
459
|
+
const storage: BuildStorage<Tables, Types> = {
|
|
460
|
+
tables: storageTables as BuildStorageTables<Tables>,
|
|
461
|
+
types: storageTypes,
|
|
462
|
+
};
|
|
463
|
+
|
|
464
|
+
const execution =
|
|
465
|
+
executionDefaults.length > 0
|
|
466
|
+
? {
|
|
467
|
+
mutations: {
|
|
468
|
+
defaults: executionDefaults.sort((a, b) => {
|
|
469
|
+
const tableCompare = a.ref.table.localeCompare(b.ref.table);
|
|
470
|
+
if (tableCompare !== 0) {
|
|
471
|
+
return tableCompare;
|
|
472
|
+
}
|
|
473
|
+
return a.ref.column.localeCompare(b.ref.column);
|
|
474
|
+
}),
|
|
475
|
+
},
|
|
476
|
+
}
|
|
477
|
+
: undefined;
|
|
248
478
|
|
|
249
479
|
// Build models - construct as partial first, then assert full type
|
|
250
480
|
const modelsPartial: Partial<BuildModels<Models>> = {};
|
|
@@ -348,11 +578,12 @@ class SqlContractBuilder<
|
|
|
348
578
|
schemaVersion: '1' as const,
|
|
349
579
|
target,
|
|
350
580
|
targetFamily: 'sql' as const,
|
|
351
|
-
|
|
581
|
+
storageHash: this.state.storageHash || 'sha256:ts-builder-placeholder',
|
|
352
582
|
models,
|
|
353
583
|
relations: relationsPartial,
|
|
354
584
|
storage,
|
|
355
585
|
mappings,
|
|
586
|
+
...(execution ? { execution } : {}),
|
|
356
587
|
extensionPacks,
|
|
357
588
|
capabilities: this.state.capabilities || {},
|
|
358
589
|
meta: {},
|
|
@@ -365,7 +596,8 @@ class SqlContractBuilder<
|
|
|
365
596
|
Target,
|
|
366
597
|
Tables,
|
|
367
598
|
Models,
|
|
368
|
-
|
|
599
|
+
Types,
|
|
600
|
+
StorageHash,
|
|
369
601
|
ExtensionPacks,
|
|
370
602
|
Capabilities
|
|
371
603
|
>['build']
|
|
@@ -374,13 +606,23 @@ class SqlContractBuilder<
|
|
|
374
606
|
|
|
375
607
|
override target<T extends string>(
|
|
376
608
|
packRef: TargetPackRef<'sql', T>,
|
|
377
|
-
): SqlContractBuilder<
|
|
609
|
+
): SqlContractBuilder<
|
|
610
|
+
CodecTypes,
|
|
611
|
+
T,
|
|
612
|
+
Tables,
|
|
613
|
+
Models,
|
|
614
|
+
Types,
|
|
615
|
+
StorageHash,
|
|
616
|
+
ExtensionPacks,
|
|
617
|
+
Capabilities
|
|
618
|
+
> {
|
|
378
619
|
return new SqlContractBuilder<
|
|
379
620
|
CodecTypes,
|
|
380
621
|
T,
|
|
381
622
|
Tables,
|
|
382
623
|
Models,
|
|
383
|
-
|
|
624
|
+
Types,
|
|
625
|
+
StorageHash,
|
|
384
626
|
ExtensionPacks,
|
|
385
627
|
Capabilities
|
|
386
628
|
>({
|
|
@@ -396,7 +638,8 @@ class SqlContractBuilder<
|
|
|
396
638
|
Target,
|
|
397
639
|
Tables,
|
|
398
640
|
Models,
|
|
399
|
-
|
|
641
|
+
Types,
|
|
642
|
+
StorageHash,
|
|
400
643
|
ExtensionPacks,
|
|
401
644
|
Capabilities
|
|
402
645
|
> {
|
|
@@ -411,19 +654,19 @@ class SqlContractBuilder<
|
|
|
411
654
|
|
|
412
655
|
if (packRef.kind !== 'extension') {
|
|
413
656
|
throw new Error(
|
|
414
|
-
`extensionPacks() only accepts extension pack refs. Received kind
|
|
657
|
+
`extensionPacks() only accepts extension pack refs. Received kind "${packRef.kind}".`,
|
|
415
658
|
);
|
|
416
659
|
}
|
|
417
660
|
|
|
418
661
|
if (packRef.familyId !== 'sql') {
|
|
419
662
|
throw new Error(
|
|
420
|
-
`extension pack
|
|
663
|
+
`extension pack "${packRef.id}" targets family "${packRef.familyId}" but this builder targets "sql".`,
|
|
421
664
|
);
|
|
422
665
|
}
|
|
423
666
|
|
|
424
667
|
if (packRef.targetId && packRef.targetId !== this.state.target) {
|
|
425
668
|
throw new Error(
|
|
426
|
-
`extension pack
|
|
669
|
+
`extension pack "${packRef.id}" targets "${packRef.targetId}" but builder target is "${this.state.target}".`,
|
|
427
670
|
);
|
|
428
671
|
}
|
|
429
672
|
|
|
@@ -435,7 +678,8 @@ class SqlContractBuilder<
|
|
|
435
678
|
Target,
|
|
436
679
|
Tables,
|
|
437
680
|
Models,
|
|
438
|
-
|
|
681
|
+
Types,
|
|
682
|
+
StorageHash,
|
|
439
683
|
ExtensionPacks,
|
|
440
684
|
Capabilities
|
|
441
685
|
>({
|
|
@@ -446,27 +690,46 @@ class SqlContractBuilder<
|
|
|
446
690
|
|
|
447
691
|
override capabilities<C extends Record<string, Record<string, boolean>>>(
|
|
448
692
|
capabilities: C,
|
|
449
|
-
): SqlContractBuilder<CodecTypes, Target, Tables, Models,
|
|
450
|
-
return new SqlContractBuilder<
|
|
693
|
+
): SqlContractBuilder<CodecTypes, Target, Tables, Models, Types, StorageHash, ExtensionPacks, C> {
|
|
694
|
+
return new SqlContractBuilder<
|
|
695
|
+
CodecTypes,
|
|
696
|
+
Target,
|
|
697
|
+
Tables,
|
|
698
|
+
Models,
|
|
699
|
+
Types,
|
|
700
|
+
StorageHash,
|
|
701
|
+
ExtensionPacks,
|
|
702
|
+
C
|
|
703
|
+
>({
|
|
451
704
|
...this.state,
|
|
452
705
|
capabilities,
|
|
453
706
|
});
|
|
454
707
|
}
|
|
455
708
|
|
|
456
|
-
override
|
|
709
|
+
override storageHash<H extends string>(
|
|
457
710
|
hash: H,
|
|
458
|
-
): SqlContractBuilder<
|
|
711
|
+
): SqlContractBuilder<
|
|
712
|
+
CodecTypes,
|
|
713
|
+
Target,
|
|
714
|
+
Tables,
|
|
715
|
+
Models,
|
|
716
|
+
Types,
|
|
717
|
+
H,
|
|
718
|
+
ExtensionPacks,
|
|
719
|
+
Capabilities
|
|
720
|
+
> {
|
|
459
721
|
return new SqlContractBuilder<
|
|
460
722
|
CodecTypes,
|
|
461
723
|
Target,
|
|
462
724
|
Tables,
|
|
463
725
|
Models,
|
|
726
|
+
Types,
|
|
464
727
|
H,
|
|
465
728
|
ExtensionPacks,
|
|
466
729
|
Capabilities
|
|
467
730
|
>({
|
|
468
731
|
...this.state,
|
|
469
|
-
|
|
732
|
+
storageHash: hash,
|
|
470
733
|
});
|
|
471
734
|
}
|
|
472
735
|
|
|
@@ -485,12 +748,18 @@ class SqlContractBuilder<
|
|
|
485
748
|
Target,
|
|
486
749
|
Tables & Record<TableName, ReturnType<T['build']>>,
|
|
487
750
|
Models,
|
|
488
|
-
|
|
751
|
+
Types,
|
|
752
|
+
StorageHash,
|
|
489
753
|
ExtensionPacks,
|
|
490
754
|
Capabilities
|
|
491
755
|
> {
|
|
492
|
-
const tableBuilder =
|
|
493
|
-
const result = callback(
|
|
756
|
+
const tableBuilder = createTable(name);
|
|
757
|
+
const result = callback(
|
|
758
|
+
tableBuilder as unknown as SqlTableBuilder<
|
|
759
|
+
TableName,
|
|
760
|
+
CodecTypes
|
|
761
|
+
> as unknown as TableBuilder<TableName>,
|
|
762
|
+
);
|
|
494
763
|
const finalBuilder = result instanceof TableBuilder ? result : tableBuilder;
|
|
495
764
|
const tableState = finalBuilder.build();
|
|
496
765
|
|
|
@@ -499,7 +768,8 @@ class SqlContractBuilder<
|
|
|
499
768
|
Target,
|
|
500
769
|
Tables & Record<TableName, ReturnType<T['build']>>,
|
|
501
770
|
Models,
|
|
502
|
-
|
|
771
|
+
Types,
|
|
772
|
+
StorageHash,
|
|
503
773
|
ExtensionPacks,
|
|
504
774
|
Capabilities
|
|
505
775
|
>({
|
|
@@ -529,7 +799,8 @@ class SqlContractBuilder<
|
|
|
529
799
|
Target,
|
|
530
800
|
Tables,
|
|
531
801
|
Models & Record<ModelName, ReturnType<M['build']>>,
|
|
532
|
-
|
|
802
|
+
Types,
|
|
803
|
+
StorageHash,
|
|
533
804
|
ExtensionPacks,
|
|
534
805
|
Capabilities
|
|
535
806
|
> {
|
|
@@ -543,7 +814,8 @@ class SqlContractBuilder<
|
|
|
543
814
|
Target,
|
|
544
815
|
Tables,
|
|
545
816
|
Models & Record<ModelName, ReturnType<M['build']>>,
|
|
546
|
-
|
|
817
|
+
Types,
|
|
818
|
+
StorageHash,
|
|
547
819
|
ExtensionPacks,
|
|
548
820
|
Capabilities
|
|
549
821
|
>({
|
|
@@ -552,6 +824,64 @@ class SqlContractBuilder<
|
|
|
552
824
|
Record<ModelName, ReturnType<M['build']>>,
|
|
553
825
|
});
|
|
554
826
|
}
|
|
827
|
+
|
|
828
|
+
override foreignKeyDefaults(
|
|
829
|
+
config: ForeignKeyDefaultsState,
|
|
830
|
+
): SqlContractBuilder<
|
|
831
|
+
CodecTypes,
|
|
832
|
+
Target,
|
|
833
|
+
Tables,
|
|
834
|
+
Models,
|
|
835
|
+
Types,
|
|
836
|
+
StorageHash,
|
|
837
|
+
ExtensionPacks,
|
|
838
|
+
Capabilities
|
|
839
|
+
> {
|
|
840
|
+
return new SqlContractBuilder<
|
|
841
|
+
CodecTypes,
|
|
842
|
+
Target,
|
|
843
|
+
Tables,
|
|
844
|
+
Models,
|
|
845
|
+
Types,
|
|
846
|
+
StorageHash,
|
|
847
|
+
ExtensionPacks,
|
|
848
|
+
Capabilities
|
|
849
|
+
>({
|
|
850
|
+
...this.state,
|
|
851
|
+
foreignKeyDefaults: config,
|
|
852
|
+
});
|
|
853
|
+
}
|
|
854
|
+
|
|
855
|
+
storageType<Name extends string, Type extends StorageTypeInstance>(
|
|
856
|
+
name: Name,
|
|
857
|
+
typeInstance: Type,
|
|
858
|
+
): SqlContractBuilder<
|
|
859
|
+
CodecTypes,
|
|
860
|
+
Target,
|
|
861
|
+
Tables,
|
|
862
|
+
Models,
|
|
863
|
+
Types & Record<Name, Type>,
|
|
864
|
+
StorageHash,
|
|
865
|
+
ExtensionPacks,
|
|
866
|
+
Capabilities
|
|
867
|
+
> {
|
|
868
|
+
return new SqlContractBuilder<
|
|
869
|
+
CodecTypes,
|
|
870
|
+
Target,
|
|
871
|
+
Tables,
|
|
872
|
+
Models,
|
|
873
|
+
Types & Record<Name, Type>,
|
|
874
|
+
StorageHash,
|
|
875
|
+
ExtensionPacks,
|
|
876
|
+
Capabilities
|
|
877
|
+
>({
|
|
878
|
+
...this.state,
|
|
879
|
+
storageTypes: {
|
|
880
|
+
...(this.state.storageTypes ?? {}),
|
|
881
|
+
[name]: typeInstance,
|
|
882
|
+
},
|
|
883
|
+
});
|
|
884
|
+
}
|
|
555
885
|
}
|
|
556
886
|
|
|
557
887
|
export function defineContract<
|