@prisma-next/sql-contract-ts 0.3.0-dev.133 → 0.3.0-dev.135
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 +141 -4
- package/dist/contract-builder.d.mts +732 -15
- package/dist/contract-builder.d.mts.map +1 -1
- package/dist/contract-builder.mjs +1254 -131
- package/dist/contract-builder.mjs.map +1 -1
- package/package.json +7 -7
- package/src/authoring-helper-runtime.ts +139 -0
- package/src/authoring-type-utils.ts +168 -0
- package/src/composed-authoring-helpers.ts +254 -0
- package/src/contract-builder.ts +236 -335
- package/src/contract-ir-builder.ts +475 -0
- package/src/contract.ts +6 -0
- package/src/exports/contract-builder.ts +24 -2
- package/src/semantic-contract.ts +86 -0
- package/src/staged-contract-dsl.ts +1490 -0
- package/src/staged-contract-lowering.ts +705 -0
- package/src/staged-contract-types.ts +494 -0
- package/src/staged-contract-warnings.ts +245 -0
package/src/contract-builder.ts
CHANGED
|
@@ -1,12 +1,9 @@
|
|
|
1
|
-
import type { ExtensionPackRef, TargetPackRef } from '@prisma-next/contract/framework-components';
|
|
2
1
|
import type {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
TaggedRaw,
|
|
9
|
-
} from '@prisma-next/contract/types';
|
|
2
|
+
ExtensionPackRef,
|
|
3
|
+
FamilyPackRef,
|
|
4
|
+
TargetPackRef,
|
|
5
|
+
} from '@prisma-next/contract/framework-components';
|
|
6
|
+
import type { ExecutionMutationDefaultValue } from '@prisma-next/contract/types';
|
|
10
7
|
import type {
|
|
11
8
|
ColumnBuilderState,
|
|
12
9
|
ColumnTypeDescriptor,
|
|
@@ -24,19 +21,48 @@ import {
|
|
|
24
21
|
type ExtractColumns,
|
|
25
22
|
type ExtractPrimaryKey,
|
|
26
23
|
ModelBuilder,
|
|
27
|
-
type Mutable,
|
|
28
24
|
TableBuilder,
|
|
29
25
|
} from '@prisma-next/contract-authoring';
|
|
30
|
-
import {
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
type TypeMaps,
|
|
26
|
+
import type {
|
|
27
|
+
ContractWithTypeMaps,
|
|
28
|
+
Index,
|
|
29
|
+
ReferentialAction,
|
|
30
|
+
SqlContract,
|
|
31
|
+
StorageTypeInstance,
|
|
32
|
+
TypeMaps,
|
|
38
33
|
} from '@prisma-next/sql-contract/types';
|
|
39
|
-
import {
|
|
34
|
+
import {
|
|
35
|
+
type ComposedAuthoringHelpers,
|
|
36
|
+
createComposedAuthoringHelpers,
|
|
37
|
+
} from './composed-authoring-helpers';
|
|
38
|
+
import {
|
|
39
|
+
buildContractIR,
|
|
40
|
+
buildSqlContractFromSemanticDefinition,
|
|
41
|
+
type RuntimeBuilderState,
|
|
42
|
+
} from './contract-ir-builder';
|
|
43
|
+
|
|
44
|
+
export { buildSqlContractFromSemanticDefinition } from './contract-ir-builder';
|
|
45
|
+
|
|
46
|
+
import {
|
|
47
|
+
field,
|
|
48
|
+
isStagedContractInput,
|
|
49
|
+
type ModelAttributesSpec,
|
|
50
|
+
model,
|
|
51
|
+
type RelationBuilder,
|
|
52
|
+
rel,
|
|
53
|
+
type ScalarFieldBuilder,
|
|
54
|
+
type SqlStageSpec,
|
|
55
|
+
type StagedContractInput,
|
|
56
|
+
type StagedModelBuilder,
|
|
57
|
+
type RelationState as StagedRelationState,
|
|
58
|
+
} from './staged-contract-dsl';
|
|
59
|
+
import { buildStagedSemanticContractDefinition } from './staged-contract-lowering';
|
|
60
|
+
import type {
|
|
61
|
+
ExtractCodecTypesFromPack,
|
|
62
|
+
MergeExtensionCodecTypes,
|
|
63
|
+
MergeExtensionPackRefs,
|
|
64
|
+
SqlContractResult,
|
|
65
|
+
} from './staged-contract-types';
|
|
40
66
|
|
|
41
67
|
type ColumnDefaultForCodec<
|
|
42
68
|
CodecTypes extends Record<string, { output: unknown }>,
|
|
@@ -126,24 +152,6 @@ export interface SqlTableBuilder<
|
|
|
126
152
|
>;
|
|
127
153
|
}
|
|
128
154
|
|
|
129
|
-
type ExtractCodecTypesFromPack<P> = P extends { __codecTypes?: infer C }
|
|
130
|
-
? C extends Record<string, { output: unknown }>
|
|
131
|
-
? C
|
|
132
|
-
: Record<string, never>
|
|
133
|
-
: Record<string, never>;
|
|
134
|
-
|
|
135
|
-
type UnionToIntersection<U> = (U extends unknown ? (k: U) => void : never) extends (
|
|
136
|
-
k: infer I,
|
|
137
|
-
) => void
|
|
138
|
-
? I
|
|
139
|
-
: never;
|
|
140
|
-
|
|
141
|
-
type MergeExtensionCodecTypes<Packs extends Record<string, unknown>> = UnionToIntersection<
|
|
142
|
-
{
|
|
143
|
-
[K in keyof Packs]: ExtractCodecTypesFromPack<Packs[K]>;
|
|
144
|
-
}[keyof Packs]
|
|
145
|
-
>;
|
|
146
|
-
|
|
147
155
|
type BuildStorageTable<
|
|
148
156
|
_TableName extends string,
|
|
149
157
|
Columns extends Record<string, ColumnBuilderState<string, boolean, string>>,
|
|
@@ -194,73 +202,30 @@ type BuildStorage<
|
|
|
194
202
|
readonly types: Types;
|
|
195
203
|
};
|
|
196
204
|
|
|
197
|
-
type BuildStorageTables<
|
|
198
|
-
Tables extends Record<
|
|
199
|
-
string,
|
|
200
|
-
TableBuilderState<
|
|
201
|
-
string,
|
|
202
|
-
Record<string, ColumnBuilderState<string, boolean, string>>,
|
|
203
|
-
readonly string[] | undefined
|
|
204
|
-
>
|
|
205
|
-
>,
|
|
206
|
-
> = {
|
|
207
|
-
readonly [K in keyof Tables]: BuildStorageTable<
|
|
208
|
-
K & string,
|
|
209
|
-
ExtractColumns<Tables[K]>,
|
|
210
|
-
ExtractPrimaryKey<Tables[K]>
|
|
211
|
-
>;
|
|
212
|
-
};
|
|
213
|
-
|
|
214
205
|
export interface ColumnBuilder<Name extends string, Nullable extends boolean, Type extends string> {
|
|
215
206
|
nullable<Value extends boolean>(value?: Value): ColumnBuilder<Name, Value, Type>;
|
|
216
207
|
type<Id extends string>(id: Id): ColumnBuilder<Name, Nullable, Id>;
|
|
217
208
|
build(): ColumnBuilderState<Name, Nullable, Type>;
|
|
218
209
|
}
|
|
219
210
|
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
return value.every((item) => isJsonValue(item));
|
|
232
|
-
}
|
|
233
|
-
if (isPlainObject(value)) {
|
|
234
|
-
return Object.values(value).every((item) => isJsonValue(item));
|
|
235
|
-
}
|
|
236
|
-
return false;
|
|
237
|
-
}
|
|
238
|
-
|
|
239
|
-
function encodeDefaultLiteralValue(
|
|
240
|
-
value: ColumnDefaultLiteralInputValue,
|
|
241
|
-
): ColumnDefaultLiteralValue {
|
|
242
|
-
if (typeof value === 'bigint') {
|
|
243
|
-
return { $type: 'bigint', value: value.toString() };
|
|
244
|
-
}
|
|
245
|
-
if (value instanceof Date) {
|
|
246
|
-
return value.toISOString();
|
|
247
|
-
}
|
|
248
|
-
if (isJsonValue(value)) {
|
|
249
|
-
if (isPlainObject(value) && '$type' in value) {
|
|
250
|
-
return { $type: 'raw', value } satisfies TaggedRaw;
|
|
251
|
-
}
|
|
252
|
-
return value;
|
|
253
|
-
}
|
|
254
|
-
throw new Error(
|
|
255
|
-
'Unsupported column default literal value: expected JSON-safe value, bigint, or Date.',
|
|
256
|
-
);
|
|
257
|
-
}
|
|
211
|
+
type StagedModelLike = {
|
|
212
|
+
readonly stageOne: {
|
|
213
|
+
readonly modelName?: string;
|
|
214
|
+
readonly fields: Record<string, ScalarFieldBuilder>;
|
|
215
|
+
readonly relations: Record<string, RelationBuilder<StagedRelationState>>;
|
|
216
|
+
};
|
|
217
|
+
readonly __attributes: ModelAttributesSpec | undefined;
|
|
218
|
+
readonly __sql: SqlStageSpec | undefined;
|
|
219
|
+
buildAttributesSpec(): ModelAttributesSpec | undefined;
|
|
220
|
+
buildSqlSpec(): SqlStageSpec | undefined;
|
|
221
|
+
};
|
|
258
222
|
|
|
259
|
-
function
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
223
|
+
function buildStagedContract<Definition extends StagedContractInput>(
|
|
224
|
+
definition: Definition,
|
|
225
|
+
): SqlContractResult<Definition> {
|
|
226
|
+
return buildSqlContractFromSemanticDefinition(
|
|
227
|
+
buildStagedSemanticContractDefinition(definition),
|
|
228
|
+
) as SqlContractResult<Definition>;
|
|
264
229
|
}
|
|
265
230
|
|
|
266
231
|
class SqlContractBuilder<
|
|
@@ -327,241 +292,7 @@ class SqlContractBuilder<
|
|
|
327
292
|
TypeMaps<CodecTypes, Record<string, never>>
|
|
328
293
|
>
|
|
329
294
|
: never {
|
|
330
|
-
|
|
331
|
-
? ContractWithTypeMaps<
|
|
332
|
-
SqlContract<BuildStorage<Tables, Types>, BuildModels<Models>> & {
|
|
333
|
-
readonly schemaVersion: '1';
|
|
334
|
-
readonly target: Target;
|
|
335
|
-
readonly targetFamily: 'sql';
|
|
336
|
-
readonly storageHash: StorageHash extends string ? StorageHash : string;
|
|
337
|
-
} & (ExtensionPacks extends Record<string, unknown>
|
|
338
|
-
? { readonly extensionPacks: ExtensionPacks }
|
|
339
|
-
: Record<string, never>) &
|
|
340
|
-
(Capabilities extends Record<string, Record<string, boolean>>
|
|
341
|
-
? { readonly capabilities: Capabilities }
|
|
342
|
-
: Record<string, never>),
|
|
343
|
-
TypeMaps<CodecTypes, Record<string, never>>
|
|
344
|
-
>
|
|
345
|
-
: never;
|
|
346
|
-
if (!this.state.target) {
|
|
347
|
-
throw new Error('target is required. Call .target() before .build()');
|
|
348
|
-
}
|
|
349
|
-
|
|
350
|
-
const target = this.state.target as Target & string;
|
|
351
|
-
|
|
352
|
-
const storageTables = {} as Partial<Mutable<BuildStorageTables<Tables>>>;
|
|
353
|
-
const executionDefaults: ExecutionMutationDefault[] = [];
|
|
354
|
-
|
|
355
|
-
for (const tableName of Object.keys(this.state.tables) as Array<keyof Tables & string>) {
|
|
356
|
-
const tableState = this.state.tables[tableName];
|
|
357
|
-
if (!tableState) continue;
|
|
358
|
-
|
|
359
|
-
type TableKey = typeof tableName;
|
|
360
|
-
type ColumnDefs = ExtractColumns<Tables[TableKey]>;
|
|
361
|
-
type PrimaryKey = ExtractPrimaryKey<Tables[TableKey]>;
|
|
362
|
-
|
|
363
|
-
const columns = {} as Partial<{
|
|
364
|
-
[K in keyof ColumnDefs]: BuildStorageColumn<
|
|
365
|
-
ColumnDefs[K]['nullable'] & boolean,
|
|
366
|
-
ColumnDefs[K]['type']
|
|
367
|
-
>;
|
|
368
|
-
}>;
|
|
369
|
-
|
|
370
|
-
for (const columnName in tableState.columns) {
|
|
371
|
-
const columnState = tableState.columns[columnName];
|
|
372
|
-
if (!columnState) continue;
|
|
373
|
-
const codecId = columnState.type;
|
|
374
|
-
const nativeType = columnState.nativeType;
|
|
375
|
-
const typeRef = columnState.typeRef;
|
|
376
|
-
|
|
377
|
-
const encodedDefault =
|
|
378
|
-
columnState.default !== undefined
|
|
379
|
-
? encodeColumnDefault(columnState.default as ColumnDefault)
|
|
380
|
-
: undefined;
|
|
381
|
-
|
|
382
|
-
columns[columnName as keyof ColumnDefs] = {
|
|
383
|
-
nativeType,
|
|
384
|
-
codecId,
|
|
385
|
-
nullable: (columnState.nullable ?? false) as ColumnDefs[keyof ColumnDefs]['nullable'] &
|
|
386
|
-
boolean,
|
|
387
|
-
...ifDefined('typeParams', columnState.typeParams),
|
|
388
|
-
...ifDefined('default', encodedDefault),
|
|
389
|
-
...ifDefined('typeRef', typeRef),
|
|
390
|
-
} as BuildStorageColumn<
|
|
391
|
-
ColumnDefs[keyof ColumnDefs]['nullable'] & boolean,
|
|
392
|
-
ColumnDefs[keyof ColumnDefs]['type']
|
|
393
|
-
>;
|
|
394
|
-
|
|
395
|
-
if ('executionDefault' in columnState && columnState.executionDefault) {
|
|
396
|
-
executionDefaults.push({
|
|
397
|
-
ref: { table: tableName, column: columnName },
|
|
398
|
-
onCreate: columnState.executionDefault,
|
|
399
|
-
});
|
|
400
|
-
}
|
|
401
|
-
}
|
|
402
|
-
|
|
403
|
-
// Build uniques from table state
|
|
404
|
-
const uniques = (tableState.uniques ?? []).map((u) => ({
|
|
405
|
-
columns: u.columns,
|
|
406
|
-
...(u.name ? { name: u.name } : {}),
|
|
407
|
-
}));
|
|
408
|
-
|
|
409
|
-
// Build indexes from table state
|
|
410
|
-
const indexes = (tableState.indexes ?? []).map((i) => ({
|
|
411
|
-
columns: i.columns,
|
|
412
|
-
...(i.name ? { name: i.name } : {}),
|
|
413
|
-
...(i.using ? { using: i.using } : {}),
|
|
414
|
-
...(i.config ? { config: i.config } : {}),
|
|
415
|
-
}));
|
|
416
|
-
|
|
417
|
-
// Build foreign keys from table state, materializing defaults
|
|
418
|
-
const foreignKeys = (tableState.foreignKeys ?? []).map((fk) => ({
|
|
419
|
-
columns: fk.columns,
|
|
420
|
-
references: fk.references,
|
|
421
|
-
...applyFkDefaults(fk, this.state.foreignKeyDefaults),
|
|
422
|
-
...(fk.name ? { name: fk.name } : {}),
|
|
423
|
-
...(fk.onDelete !== undefined ? { onDelete: fk.onDelete } : {}),
|
|
424
|
-
...(fk.onUpdate !== undefined ? { onUpdate: fk.onUpdate } : {}),
|
|
425
|
-
}));
|
|
426
|
-
|
|
427
|
-
const table = {
|
|
428
|
-
columns: columns as {
|
|
429
|
-
[K in keyof ColumnDefs]: BuildStorageColumn<
|
|
430
|
-
ColumnDefs[K]['nullable'] & boolean,
|
|
431
|
-
ColumnDefs[K]['type']
|
|
432
|
-
>;
|
|
433
|
-
},
|
|
434
|
-
uniques,
|
|
435
|
-
indexes,
|
|
436
|
-
foreignKeys,
|
|
437
|
-
...(tableState.primaryKey
|
|
438
|
-
? {
|
|
439
|
-
primaryKey: {
|
|
440
|
-
columns: tableState.primaryKey,
|
|
441
|
-
...(tableState.primaryKeyName ? { name: tableState.primaryKeyName } : {}),
|
|
442
|
-
},
|
|
443
|
-
}
|
|
444
|
-
: {}),
|
|
445
|
-
} as unknown as BuildStorageTable<TableKey & string, ColumnDefs, PrimaryKey>;
|
|
446
|
-
|
|
447
|
-
(storageTables as Mutable<BuildStorageTables<Tables>>)[tableName] = table;
|
|
448
|
-
}
|
|
449
|
-
|
|
450
|
-
const storageTypes = (this.state.storageTypes ?? {}) as Types;
|
|
451
|
-
const storage: BuildStorage<Tables, Types> = {
|
|
452
|
-
tables: storageTables as BuildStorageTables<Tables>,
|
|
453
|
-
types: storageTypes,
|
|
454
|
-
};
|
|
455
|
-
|
|
456
|
-
const execution =
|
|
457
|
-
executionDefaults.length > 0
|
|
458
|
-
? {
|
|
459
|
-
mutations: {
|
|
460
|
-
defaults: executionDefaults.sort((a, b) => {
|
|
461
|
-
const tableCompare = a.ref.table.localeCompare(b.ref.table);
|
|
462
|
-
if (tableCompare !== 0) {
|
|
463
|
-
return tableCompare;
|
|
464
|
-
}
|
|
465
|
-
return a.ref.column.localeCompare(b.ref.column);
|
|
466
|
-
}),
|
|
467
|
-
},
|
|
468
|
-
}
|
|
469
|
-
: undefined;
|
|
470
|
-
|
|
471
|
-
// Build models - construct as partial first, then assert full type
|
|
472
|
-
const modelsPartial: Partial<BuildModels<Models>> = {};
|
|
473
|
-
|
|
474
|
-
for (const modelName in this.state.models) {
|
|
475
|
-
const modelState = this.state.models[modelName];
|
|
476
|
-
if (!modelState) continue;
|
|
477
|
-
|
|
478
|
-
const modelStateTyped = modelState as unknown as {
|
|
479
|
-
name: string;
|
|
480
|
-
table: string;
|
|
481
|
-
fields: Record<string, string>;
|
|
482
|
-
relations: Record<string, RelationDefinition>;
|
|
483
|
-
};
|
|
484
|
-
|
|
485
|
-
const tableName = modelStateTyped.table;
|
|
486
|
-
const tableState = this.state.tables[tableName as keyof Tables];
|
|
487
|
-
const tableColumns = tableState
|
|
488
|
-
? (
|
|
489
|
-
tableState as unknown as {
|
|
490
|
-
columns: Record<string, { type: string; nullable?: boolean }>;
|
|
491
|
-
}
|
|
492
|
-
).columns
|
|
493
|
-
: {};
|
|
494
|
-
|
|
495
|
-
const storageFields: Record<string, { readonly column: string }> = {};
|
|
496
|
-
const domainFields: Record<string, Record<string, unknown>> = {};
|
|
497
|
-
|
|
498
|
-
for (const fieldName in modelStateTyped.fields) {
|
|
499
|
-
const columnName = modelStateTyped.fields[fieldName];
|
|
500
|
-
if (!columnName) continue;
|
|
501
|
-
|
|
502
|
-
storageFields[fieldName] = { column: columnName };
|
|
503
|
-
|
|
504
|
-
const column = tableColumns[columnName];
|
|
505
|
-
if (column) {
|
|
506
|
-
domainFields[fieldName] = {
|
|
507
|
-
codecId: column.type,
|
|
508
|
-
nullable: column.nullable ?? false,
|
|
509
|
-
};
|
|
510
|
-
}
|
|
511
|
-
}
|
|
512
|
-
|
|
513
|
-
const modelRelations: Record<string, Record<string, unknown>> = {};
|
|
514
|
-
if (modelStateTyped.relations) {
|
|
515
|
-
for (const relName in modelStateTyped.relations) {
|
|
516
|
-
const rel = modelStateTyped.relations[relName];
|
|
517
|
-
if (!rel) continue;
|
|
518
|
-
modelRelations[relName] = {
|
|
519
|
-
to: rel.to,
|
|
520
|
-
cardinality: rel.cardinality,
|
|
521
|
-
on: {
|
|
522
|
-
localFields: rel.on.parentCols,
|
|
523
|
-
targetFields: rel.on.childCols,
|
|
524
|
-
},
|
|
525
|
-
};
|
|
526
|
-
}
|
|
527
|
-
}
|
|
528
|
-
|
|
529
|
-
(modelsPartial as unknown as Record<string, Record<string, unknown>>)[modelName] = {
|
|
530
|
-
storage: {
|
|
531
|
-
table: tableName,
|
|
532
|
-
fields: storageFields,
|
|
533
|
-
},
|
|
534
|
-
fields: domainFields,
|
|
535
|
-
relations: modelRelations,
|
|
536
|
-
};
|
|
537
|
-
}
|
|
538
|
-
|
|
539
|
-
const models = modelsPartial as unknown as BuildModels<Models>;
|
|
540
|
-
|
|
541
|
-
const extensionNamespaces = this.state.extensionNamespaces ?? [];
|
|
542
|
-
const extensionPacks: Record<string, unknown> = { ...(this.state.extensionPacks || {}) };
|
|
543
|
-
for (const namespace of extensionNamespaces) {
|
|
544
|
-
if (!Object.hasOwn(extensionPacks, namespace)) {
|
|
545
|
-
extensionPacks[namespace] = {};
|
|
546
|
-
}
|
|
547
|
-
}
|
|
548
|
-
|
|
549
|
-
const contract = {
|
|
550
|
-
schemaVersion: '1' as const,
|
|
551
|
-
target,
|
|
552
|
-
targetFamily: 'sql' as const,
|
|
553
|
-
storageHash: this.state.storageHash || 'sha256:ts-builder-placeholder',
|
|
554
|
-
models,
|
|
555
|
-
roots: {},
|
|
556
|
-
storage,
|
|
557
|
-
...(execution ? { execution } : {}),
|
|
558
|
-
extensionPacks,
|
|
559
|
-
capabilities: this.state.capabilities || {},
|
|
560
|
-
meta: {},
|
|
561
|
-
sources: {},
|
|
562
|
-
} as unknown as BuiltContract;
|
|
563
|
-
|
|
564
|
-
return contract as unknown as ReturnType<
|
|
295
|
+
return buildContractIR(this.state as unknown as RuntimeBuilderState) as unknown as ReturnType<
|
|
565
296
|
SqlContractBuilder<
|
|
566
297
|
CodecTypes,
|
|
567
298
|
Target,
|
|
@@ -629,7 +360,7 @@ class SqlContractBuilder<
|
|
|
629
360
|
Models,
|
|
630
361
|
Types,
|
|
631
362
|
StorageHash,
|
|
632
|
-
ExtensionPacks,
|
|
363
|
+
MergeExtensionPackRefs<ExtensionPacks, Packs>,
|
|
633
364
|
Capabilities
|
|
634
365
|
> {
|
|
635
366
|
if (!this.state.target) {
|
|
@@ -637,8 +368,13 @@ class SqlContractBuilder<
|
|
|
637
368
|
}
|
|
638
369
|
|
|
639
370
|
const namespaces = new Set(this.state.extensionNamespaces ?? []);
|
|
371
|
+
const nextExtensionPacks = {
|
|
372
|
+
...(this.state.extensionPacks ?? {}),
|
|
373
|
+
} as Record<string, unknown>;
|
|
640
374
|
|
|
641
|
-
for (const packRef of Object.
|
|
375
|
+
for (const [name, packRef] of Object.entries(packs) as Array<
|
|
376
|
+
[keyof Packs & string, ExtensionPackRef<'sql', string>]
|
|
377
|
+
>) {
|
|
642
378
|
if (!packRef) continue;
|
|
643
379
|
|
|
644
380
|
if (packRef.kind !== 'extension') {
|
|
@@ -660,6 +396,7 @@ class SqlContractBuilder<
|
|
|
660
396
|
}
|
|
661
397
|
|
|
662
398
|
namespaces.add(packRef.id);
|
|
399
|
+
nextExtensionPacks[name] = packRef;
|
|
663
400
|
}
|
|
664
401
|
|
|
665
402
|
return new SqlContractBuilder<
|
|
@@ -669,10 +406,11 @@ class SqlContractBuilder<
|
|
|
669
406
|
Models,
|
|
670
407
|
Types,
|
|
671
408
|
StorageHash,
|
|
672
|
-
ExtensionPacks,
|
|
409
|
+
MergeExtensionPackRefs<ExtensionPacks, Packs>,
|
|
673
410
|
Capabilities
|
|
674
411
|
>({
|
|
675
412
|
...this.state,
|
|
413
|
+
extensionPacks: nextExtensionPacks as MergeExtensionPackRefs<ExtensionPacks, Packs>,
|
|
676
414
|
extensionNamespaces: [...namespaces],
|
|
677
415
|
});
|
|
678
416
|
}
|
|
@@ -743,6 +481,9 @@ class SqlContractBuilder<
|
|
|
743
481
|
Capabilities
|
|
744
482
|
> {
|
|
745
483
|
const tableBuilder = createTable(name);
|
|
484
|
+
// Double cast: createTable returns an unparameterized builder; we first narrow
|
|
485
|
+
// to SqlTableBuilder with the caller's generic params, then to the public
|
|
486
|
+
// TableBuilder facade that the callback expects.
|
|
746
487
|
const result = callback(
|
|
747
488
|
tableBuilder as unknown as SqlTableBuilder<
|
|
748
489
|
TableName,
|
|
@@ -873,8 +614,168 @@ class SqlContractBuilder<
|
|
|
873
614
|
}
|
|
874
615
|
}
|
|
875
616
|
|
|
617
|
+
type StagedContractDefinition<
|
|
618
|
+
Family extends FamilyPackRef<string>,
|
|
619
|
+
Target extends TargetPackRef<'sql', string>,
|
|
620
|
+
Types extends Record<string, StorageTypeInstance>,
|
|
621
|
+
Models extends Record<string, StagedModelLike>,
|
|
622
|
+
ExtensionPacks extends Record<string, ExtensionPackRef<'sql', string>> | undefined,
|
|
623
|
+
Capabilities extends Record<string, Record<string, boolean>> | undefined,
|
|
624
|
+
Naming extends StagedContractInput['naming'] | undefined,
|
|
625
|
+
StorageHash extends string | undefined,
|
|
626
|
+
ForeignKeyDefaults extends ForeignKeyDefaultsState | undefined,
|
|
627
|
+
> = {
|
|
628
|
+
readonly family: Family;
|
|
629
|
+
readonly target: Target;
|
|
630
|
+
readonly extensionPacks?: ExtensionPacks;
|
|
631
|
+
readonly naming?: Naming;
|
|
632
|
+
readonly storageHash?: StorageHash;
|
|
633
|
+
readonly foreignKeyDefaults?: ForeignKeyDefaults;
|
|
634
|
+
readonly capabilities?: Capabilities;
|
|
635
|
+
readonly types?: Types;
|
|
636
|
+
readonly models?: Models;
|
|
637
|
+
};
|
|
638
|
+
|
|
639
|
+
type StagedContractScaffold<
|
|
640
|
+
Family extends FamilyPackRef<string>,
|
|
641
|
+
Target extends TargetPackRef<'sql', string>,
|
|
642
|
+
ExtensionPacks extends Record<string, ExtensionPackRef<'sql', string>> | undefined,
|
|
643
|
+
Capabilities extends Record<string, Record<string, boolean>> | undefined,
|
|
644
|
+
Naming extends StagedContractInput['naming'] | undefined,
|
|
645
|
+
StorageHash extends string | undefined,
|
|
646
|
+
ForeignKeyDefaults extends ForeignKeyDefaultsState | undefined,
|
|
647
|
+
> = {
|
|
648
|
+
readonly family: Family;
|
|
649
|
+
readonly target: Target;
|
|
650
|
+
readonly extensionPacks?: ExtensionPacks;
|
|
651
|
+
readonly naming?: Naming;
|
|
652
|
+
readonly storageHash?: StorageHash;
|
|
653
|
+
readonly foreignKeyDefaults?: ForeignKeyDefaults;
|
|
654
|
+
readonly capabilities?: Capabilities;
|
|
655
|
+
};
|
|
656
|
+
|
|
657
|
+
type StagedContractFactory<
|
|
658
|
+
Family extends FamilyPackRef<string>,
|
|
659
|
+
Target extends TargetPackRef<'sql', string>,
|
|
660
|
+
Types extends Record<string, StorageTypeInstance>,
|
|
661
|
+
Models extends Record<string, StagedModelLike>,
|
|
662
|
+
ExtensionPacks extends Record<string, ExtensionPackRef<'sql', string>> | undefined,
|
|
663
|
+
> = (helpers: ComposedAuthoringHelpers<Family, Target, ExtensionPacks>) => {
|
|
664
|
+
readonly types?: Types;
|
|
665
|
+
readonly models?: Models;
|
|
666
|
+
};
|
|
667
|
+
|
|
668
|
+
export function defineContract<
|
|
669
|
+
CodecTypes extends Record<string, { output: unknown }> = Record<string, never>,
|
|
670
|
+
>(): SqlContractBuilder<CodecTypes>;
|
|
671
|
+
export function defineContract<
|
|
672
|
+
const Family extends FamilyPackRef<string>,
|
|
673
|
+
const Target extends TargetPackRef<'sql', string>,
|
|
674
|
+
const Types extends Record<string, StorageTypeInstance> = Record<never, never>,
|
|
675
|
+
const Models extends Record<string, StagedModelLike> = Record<never, never>,
|
|
676
|
+
const ExtensionPacks extends
|
|
677
|
+
| Record<string, ExtensionPackRef<'sql', string>>
|
|
678
|
+
| undefined = undefined,
|
|
679
|
+
const Capabilities extends Record<string, Record<string, boolean>> | undefined = undefined,
|
|
680
|
+
const Naming extends StagedContractInput['naming'] | undefined = undefined,
|
|
681
|
+
const StorageHash extends string | undefined = undefined,
|
|
682
|
+
const ForeignKeyDefaults extends ForeignKeyDefaultsState | undefined = undefined,
|
|
683
|
+
>(
|
|
684
|
+
definition: StagedContractDefinition<
|
|
685
|
+
Family,
|
|
686
|
+
Target,
|
|
687
|
+
Types,
|
|
688
|
+
Models,
|
|
689
|
+
ExtensionPacks,
|
|
690
|
+
Capabilities,
|
|
691
|
+
Naming,
|
|
692
|
+
StorageHash,
|
|
693
|
+
ForeignKeyDefaults
|
|
694
|
+
>,
|
|
695
|
+
): SqlContractResult<
|
|
696
|
+
StagedContractDefinition<
|
|
697
|
+
Family,
|
|
698
|
+
Target,
|
|
699
|
+
Types,
|
|
700
|
+
Models,
|
|
701
|
+
ExtensionPacks,
|
|
702
|
+
Capabilities,
|
|
703
|
+
Naming,
|
|
704
|
+
StorageHash,
|
|
705
|
+
ForeignKeyDefaults
|
|
706
|
+
>
|
|
707
|
+
>;
|
|
708
|
+
export function defineContract<
|
|
709
|
+
const Family extends FamilyPackRef<string>,
|
|
710
|
+
const Target extends TargetPackRef<'sql', string>,
|
|
711
|
+
const Types extends Record<string, StorageTypeInstance> = Record<never, never>,
|
|
712
|
+
const Models extends Record<string, StagedModelLike> = Record<never, never>,
|
|
713
|
+
const ExtensionPacks extends
|
|
714
|
+
| Record<string, ExtensionPackRef<'sql', string>>
|
|
715
|
+
| undefined = undefined,
|
|
716
|
+
const Capabilities extends Record<string, Record<string, boolean>> | undefined = undefined,
|
|
717
|
+
const Naming extends StagedContractInput['naming'] | undefined = undefined,
|
|
718
|
+
const StorageHash extends string | undefined = undefined,
|
|
719
|
+
const ForeignKeyDefaults extends ForeignKeyDefaultsState | undefined = undefined,
|
|
720
|
+
>(
|
|
721
|
+
definition: StagedContractScaffold<
|
|
722
|
+
Family,
|
|
723
|
+
Target,
|
|
724
|
+
ExtensionPacks,
|
|
725
|
+
Capabilities,
|
|
726
|
+
Naming,
|
|
727
|
+
StorageHash,
|
|
728
|
+
ForeignKeyDefaults
|
|
729
|
+
>,
|
|
730
|
+
factory: StagedContractFactory<Family, Target, Types, Models, ExtensionPacks>,
|
|
731
|
+
): SqlContractResult<
|
|
732
|
+
StagedContractDefinition<
|
|
733
|
+
Family,
|
|
734
|
+
Target,
|
|
735
|
+
Types,
|
|
736
|
+
Models,
|
|
737
|
+
ExtensionPacks,
|
|
738
|
+
Capabilities,
|
|
739
|
+
Naming,
|
|
740
|
+
StorageHash,
|
|
741
|
+
ForeignKeyDefaults
|
|
742
|
+
>
|
|
743
|
+
>;
|
|
876
744
|
export function defineContract<
|
|
877
745
|
CodecTypes extends Record<string, { output: unknown }> = Record<string, never>,
|
|
878
|
-
>(
|
|
746
|
+
>(
|
|
747
|
+
definition?: StagedContractInput,
|
|
748
|
+
factory?: StagedContractFactory<
|
|
749
|
+
FamilyPackRef<string>,
|
|
750
|
+
TargetPackRef<'sql', string>,
|
|
751
|
+
Record<string, StorageTypeInstance>,
|
|
752
|
+
Record<string, StagedModelLike>,
|
|
753
|
+
Record<string, ExtensionPackRef<'sql', string>> | undefined
|
|
754
|
+
>,
|
|
755
|
+
): SqlContractBuilder<CodecTypes> | SqlContractResult<StagedContractInput> {
|
|
756
|
+
if (definition && isStagedContractInput(definition)) {
|
|
757
|
+
if (factory) {
|
|
758
|
+
const builtDefinition = {
|
|
759
|
+
...definition,
|
|
760
|
+
...factory(
|
|
761
|
+
createComposedAuthoringHelpers({
|
|
762
|
+
family: definition.family,
|
|
763
|
+
target: definition.target,
|
|
764
|
+
extensionPacks: definition.extensionPacks,
|
|
765
|
+
}),
|
|
766
|
+
),
|
|
767
|
+
};
|
|
768
|
+
return buildStagedContract(builtDefinition);
|
|
769
|
+
}
|
|
770
|
+
return buildStagedContract(definition);
|
|
771
|
+
}
|
|
879
772
|
return new SqlContractBuilder<CodecTypes>();
|
|
880
773
|
}
|
|
774
|
+
|
|
775
|
+
export { field, model, rel };
|
|
776
|
+
export type {
|
|
777
|
+
ComposedAuthoringHelpers,
|
|
778
|
+
StagedContractInput,
|
|
779
|
+
StagedModelBuilder,
|
|
780
|
+
ScalarFieldBuilder,
|
|
781
|
+
};
|