@prisma-next/sql-contract-ts 0.3.0-dev.135 → 0.3.0-dev.146
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 +107 -154
- package/dist/config-types.d.mts +2 -2
- package/dist/config-types.d.mts.map +1 -1
- package/dist/config-types.mjs +2 -2
- package/dist/config-types.mjs.map +1 -1
- package/dist/contract-builder.d.mts +192 -236
- package/dist/contract-builder.d.mts.map +1 -1
- package/dist/contract-builder.mjs +317 -422
- package/dist/contract-builder.mjs.map +1 -1
- package/package.json +8 -6
- package/schemas/data-contract-sql-v1.json +6 -6
- package/src/authoring-helper-runtime.ts +2 -2
- package/src/authoring-type-utils.ts +2 -2
- package/src/build-contract.ts +463 -0
- package/src/composed-authoring-helpers.ts +8 -6
- package/src/config-types.ts +3 -3
- package/src/contract-builder.ts +122 -636
- package/src/{semantic-contract.ts → contract-definition.ts} +33 -16
- package/src/{staged-contract-dsl.ts → contract-dsl.ts} +30 -28
- package/src/{staged-contract-lowering.ts → contract-lowering.ts} +46 -48
- package/src/{staged-contract-types.ts → contract-types.ts} +185 -145
- package/src/{staged-contract-warnings.ts → contract-warnings.ts} +18 -21
- package/src/exports/contract-builder.ts +12 -13
- package/src/contract-ir-builder.ts +0 -475
- package/src/contract.ts +0 -475
|
@@ -1,38 +1,39 @@
|
|
|
1
|
-
import type { ExtensionPackRef, TargetPackRef } from '@prisma-next/contract/framework-components';
|
|
2
1
|
import type { ColumnDefault, ExecutionMutationDefaultValue } from '@prisma-next/contract/types';
|
|
3
2
|
import type {
|
|
4
3
|
ColumnTypeDescriptor,
|
|
5
4
|
ForeignKeyDefaultsState,
|
|
6
5
|
} from '@prisma-next/contract-authoring';
|
|
6
|
+
import type { ExtensionPackRef, TargetPackRef } from '@prisma-next/framework-components/components';
|
|
7
7
|
import type { ReferentialAction, StorageTypeInstance } from '@prisma-next/sql-contract/types';
|
|
8
8
|
|
|
9
|
-
export interface
|
|
9
|
+
export interface FieldNode {
|
|
10
10
|
readonly fieldName: string;
|
|
11
11
|
readonly columnName: string;
|
|
12
12
|
readonly descriptor: ColumnTypeDescriptor;
|
|
13
13
|
readonly nullable: boolean;
|
|
14
14
|
readonly default?: ColumnDefault;
|
|
15
15
|
readonly executionDefault?: ExecutionMutationDefaultValue;
|
|
16
|
+
readonly many?: boolean;
|
|
16
17
|
}
|
|
17
18
|
|
|
18
|
-
export interface
|
|
19
|
+
export interface PrimaryKeyNode {
|
|
19
20
|
readonly columns: readonly string[];
|
|
20
21
|
readonly name?: string;
|
|
21
22
|
}
|
|
22
23
|
|
|
23
|
-
export interface
|
|
24
|
+
export interface UniqueConstraintNode {
|
|
24
25
|
readonly columns: readonly string[];
|
|
25
26
|
readonly name?: string;
|
|
26
27
|
}
|
|
27
28
|
|
|
28
|
-
export interface
|
|
29
|
+
export interface IndexNode {
|
|
29
30
|
readonly columns: readonly string[];
|
|
30
31
|
readonly name?: string;
|
|
31
32
|
readonly using?: string;
|
|
32
33
|
readonly config?: Record<string, unknown>;
|
|
33
34
|
}
|
|
34
35
|
|
|
35
|
-
export interface
|
|
36
|
+
export interface ForeignKeyNode {
|
|
36
37
|
readonly columns: readonly string[];
|
|
37
38
|
readonly references: {
|
|
38
39
|
readonly model: string;
|
|
@@ -46,7 +47,7 @@ export interface SqlSemanticForeignKeyNode {
|
|
|
46
47
|
readonly index?: boolean;
|
|
47
48
|
}
|
|
48
49
|
|
|
49
|
-
export interface
|
|
50
|
+
export interface RelationNode {
|
|
50
51
|
readonly fieldName: string;
|
|
51
52
|
readonly toModel: string;
|
|
52
53
|
readonly toTable: string;
|
|
@@ -64,23 +65,39 @@ export interface SqlSemanticRelationNode {
|
|
|
64
65
|
};
|
|
65
66
|
}
|
|
66
67
|
|
|
67
|
-
export interface
|
|
68
|
+
export interface ValueObjectFieldNode {
|
|
69
|
+
readonly fieldName: string;
|
|
70
|
+
readonly columnName: string;
|
|
71
|
+
readonly valueObjectName: string;
|
|
72
|
+
readonly nullable: boolean;
|
|
73
|
+
readonly default?: ColumnDefault;
|
|
74
|
+
readonly executionDefault?: ExecutionMutationDefaultValue;
|
|
75
|
+
readonly many?: boolean;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
export interface ValueObjectNode {
|
|
79
|
+
readonly name: string;
|
|
80
|
+
readonly fields: readonly (FieldNode | ValueObjectFieldNode)[];
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
export interface ModelNode {
|
|
68
84
|
readonly modelName: string;
|
|
69
85
|
readonly tableName: string;
|
|
70
|
-
readonly fields: readonly
|
|
71
|
-
readonly id?:
|
|
72
|
-
readonly uniques?: readonly
|
|
73
|
-
readonly indexes?: readonly
|
|
74
|
-
readonly foreignKeys?: readonly
|
|
75
|
-
readonly relations?: readonly
|
|
86
|
+
readonly fields: readonly (FieldNode | ValueObjectFieldNode)[];
|
|
87
|
+
readonly id?: PrimaryKeyNode;
|
|
88
|
+
readonly uniques?: readonly UniqueConstraintNode[];
|
|
89
|
+
readonly indexes?: readonly IndexNode[];
|
|
90
|
+
readonly foreignKeys?: readonly ForeignKeyNode[];
|
|
91
|
+
readonly relations?: readonly RelationNode[];
|
|
76
92
|
}
|
|
77
93
|
|
|
78
|
-
export interface
|
|
94
|
+
export interface ContractDefinition {
|
|
79
95
|
readonly target: TargetPackRef<'sql', string>;
|
|
80
96
|
readonly extensionPacks?: Record<string, ExtensionPackRef<'sql', string>>;
|
|
81
97
|
readonly capabilities?: Record<string, Record<string, boolean>>;
|
|
82
98
|
readonly storageHash?: string;
|
|
83
99
|
readonly foreignKeyDefaults?: ForeignKeyDefaultsState;
|
|
84
100
|
readonly storageTypes?: Record<string, StorageTypeInstance>;
|
|
85
|
-
readonly models: readonly
|
|
101
|
+
readonly models: readonly ModelNode[];
|
|
102
|
+
readonly valueObjects?: readonly ValueObjectNode[];
|
|
86
103
|
}
|
|
@@ -1,10 +1,3 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
AuthoringFieldPresetDescriptor,
|
|
3
|
-
ExtensionPackRef,
|
|
4
|
-
FamilyPackRef,
|
|
5
|
-
TargetPackRef,
|
|
6
|
-
} from '@prisma-next/contract/framework-components';
|
|
7
|
-
import { instantiateAuthoringFieldPreset } from '@prisma-next/contract/framework-components';
|
|
8
1
|
import type {
|
|
9
2
|
ColumnDefault,
|
|
10
3
|
ColumnDefaultLiteralInputValue,
|
|
@@ -14,6 +7,14 @@ import type {
|
|
|
14
7
|
ColumnTypeDescriptor,
|
|
15
8
|
ForeignKeyDefaultsState,
|
|
16
9
|
} from '@prisma-next/contract-authoring';
|
|
10
|
+
import type { AuthoringFieldPresetDescriptor } from '@prisma-next/framework-components/authoring';
|
|
11
|
+
import { instantiateAuthoringFieldPreset } from '@prisma-next/framework-components/authoring';
|
|
12
|
+
import type { CodecLookup } from '@prisma-next/framework-components/codec';
|
|
13
|
+
import type {
|
|
14
|
+
ExtensionPackRef,
|
|
15
|
+
FamilyPackRef,
|
|
16
|
+
TargetPackRef,
|
|
17
|
+
} from '@prisma-next/framework-components/components';
|
|
17
18
|
import type { StorageTypeInstance } from '@prisma-next/sql-contract/types';
|
|
18
19
|
import { ifDefined } from '@prisma-next/utils/defined';
|
|
19
20
|
import type { NamedConstraintSpec } from './authoring-type-utils';
|
|
@@ -952,7 +953,7 @@ function findDuplicateRelationName(
|
|
|
952
953
|
);
|
|
953
954
|
}
|
|
954
955
|
|
|
955
|
-
export class
|
|
956
|
+
export class ContractModelBuilder<
|
|
956
957
|
ModelName extends string | undefined,
|
|
957
958
|
Fields extends Record<string, ScalarFieldBuilder>,
|
|
958
959
|
Relations extends Record<string, AnyRelationBuilder> = Record<never, never>,
|
|
@@ -982,7 +983,7 @@ export class StagedModelBuilder<
|
|
|
982
983
|
|
|
983
984
|
ref<FieldName extends keyof Fields & string>(
|
|
984
985
|
this: ModelName extends string
|
|
985
|
-
?
|
|
986
|
+
? ContractModelBuilder<ModelName, Fields, Relations, AttributesSpec, SqlSpec>
|
|
986
987
|
: never,
|
|
987
988
|
fieldName: FieldName,
|
|
988
989
|
): TargetFieldRef<ModelName & string, FieldName> {
|
|
@@ -1001,7 +1002,7 @@ export class StagedModelBuilder<
|
|
|
1001
1002
|
|
|
1002
1003
|
relations<const NextRelations extends Record<string, AnyRelationBuilder>>(
|
|
1003
1004
|
relations: NextRelations,
|
|
1004
|
-
):
|
|
1005
|
+
): ContractModelBuilder<ModelName, Fields, Relations & NextRelations, AttributesSpec, SqlSpec> {
|
|
1005
1006
|
const duplicateRelationName = findDuplicateRelationName(this.stageOne.relations, relations);
|
|
1006
1007
|
if (duplicateRelationName) {
|
|
1007
1008
|
throw new Error(
|
|
@@ -1009,7 +1010,7 @@ export class StagedModelBuilder<
|
|
|
1009
1010
|
);
|
|
1010
1011
|
}
|
|
1011
1012
|
|
|
1012
|
-
return new
|
|
1013
|
+
return new ContractModelBuilder(
|
|
1013
1014
|
{
|
|
1014
1015
|
...this.stageOne,
|
|
1015
1016
|
relations: {
|
|
@@ -1027,19 +1028,19 @@ export class StagedModelBuilder<
|
|
|
1027
1028
|
AttributeContext<Fields>,
|
|
1028
1029
|
ValidateAttributesStageSpec<Fields, SqlSpec, NextAttributesSpec>
|
|
1029
1030
|
>,
|
|
1030
|
-
):
|
|
1031
|
-
return new
|
|
1031
|
+
): ContractModelBuilder<ModelName, Fields, Relations, NextAttributesSpec, SqlSpec> {
|
|
1032
|
+
return new ContractModelBuilder(this.stageOne, specOrFactory, this.sqlFactory);
|
|
1032
1033
|
}
|
|
1033
1034
|
|
|
1034
1035
|
sql<const NextSqlSpec extends SqlStageSpec>(
|
|
1035
1036
|
specOrFactory: StageInput<SqlContext<Fields>, NextSqlSpec>,
|
|
1036
1037
|
): [ValidateSqlStageSpec<Fields, AttributesSpec, NextSqlSpec>] extends [never]
|
|
1037
|
-
?
|
|
1038
|
-
:
|
|
1038
|
+
? ContractModelBuilder<ModelName, Fields, Relations, AttributesSpec, never>
|
|
1039
|
+
: ContractModelBuilder<ModelName, Fields, Relations, AttributesSpec, NextSqlSpec> {
|
|
1039
1040
|
// Conditional return type cannot be verified by the implementation; the
|
|
1040
|
-
// runtime value is always a valid
|
|
1041
|
+
// runtime value is always a valid ContractModelBuilder regardless of the
|
|
1041
1042
|
// validation outcome (validation is type-level only).
|
|
1042
|
-
return new
|
|
1043
|
+
return new ContractModelBuilder(this.stageOne, this.attributesFactory, specOrFactory) as never;
|
|
1043
1044
|
}
|
|
1044
1045
|
|
|
1045
1046
|
buildAttributesSpec(): AttributesSpec {
|
|
@@ -1157,13 +1158,13 @@ function normalizeRelationModelSource(
|
|
|
1157
1158
|
};
|
|
1158
1159
|
}
|
|
1159
1160
|
|
|
1160
|
-
export type
|
|
1161
|
+
export type ContractInput<
|
|
1161
1162
|
Family extends FamilyPackRef<string> = FamilyPackRef<string>,
|
|
1162
1163
|
Target extends TargetPackRef<'sql', string> = TargetPackRef<'sql', string>,
|
|
1163
1164
|
Types extends Record<string, StorageTypeInstance> = Record<never, never>,
|
|
1164
1165
|
Models extends Record<
|
|
1165
1166
|
string,
|
|
1166
|
-
|
|
1167
|
+
ContractModelBuilder<
|
|
1167
1168
|
string | undefined,
|
|
1168
1169
|
Record<string, ScalarFieldBuilder>,
|
|
1169
1170
|
Record<string, AnyRelationBuilder>,
|
|
@@ -1183,6 +1184,7 @@ export type StagedContractInput<
|
|
|
1183
1184
|
readonly capabilities?: Capabilities;
|
|
1184
1185
|
readonly types?: Types;
|
|
1185
1186
|
readonly models?: Models;
|
|
1187
|
+
readonly codecLookup?: CodecLookup;
|
|
1186
1188
|
};
|
|
1187
1189
|
|
|
1188
1190
|
export function model<
|
|
@@ -1195,7 +1197,7 @@ export function model<
|
|
|
1195
1197
|
readonly fields: Fields;
|
|
1196
1198
|
readonly relations?: Relations;
|
|
1197
1199
|
},
|
|
1198
|
-
):
|
|
1200
|
+
): ContractModelBuilder<ModelName, Fields, Relations>;
|
|
1199
1201
|
|
|
1200
1202
|
export function model<
|
|
1201
1203
|
Fields extends Record<string, ScalarFieldBuilder>,
|
|
@@ -1203,7 +1205,7 @@ export function model<
|
|
|
1203
1205
|
>(input: {
|
|
1204
1206
|
readonly fields: Fields;
|
|
1205
1207
|
readonly relations?: Relations;
|
|
1206
|
-
}):
|
|
1208
|
+
}): ContractModelBuilder<undefined, Fields, Relations>;
|
|
1207
1209
|
|
|
1208
1210
|
export function model<
|
|
1209
1211
|
const ModelName extends string,
|
|
@@ -1220,14 +1222,14 @@ export function model<
|
|
|
1220
1222
|
readonly fields: Fields;
|
|
1221
1223
|
readonly relations?: Relations;
|
|
1222
1224
|
},
|
|
1223
|
-
):
|
|
1225
|
+
): ContractModelBuilder<ModelName | undefined, Fields, Relations> {
|
|
1224
1226
|
const input = typeof modelNameOrInput === 'string' ? maybeInput : modelNameOrInput;
|
|
1225
1227
|
|
|
1226
1228
|
if (!input) {
|
|
1227
1229
|
throw new Error('model("ModelName", ...) requires a model definition.');
|
|
1228
1230
|
}
|
|
1229
1231
|
|
|
1230
|
-
return new
|
|
1232
|
+
return new ContractModelBuilder({
|
|
1231
1233
|
...(typeof modelNameOrInput === 'string' ? { modelName: modelNameOrInput } : {}),
|
|
1232
1234
|
fields: input.fields,
|
|
1233
1235
|
relations: (input.relations ?? {}) as Relations,
|
|
@@ -1372,7 +1374,7 @@ export const field = {
|
|
|
1372
1374
|
namedType: namedTypeField,
|
|
1373
1375
|
};
|
|
1374
1376
|
|
|
1375
|
-
export function
|
|
1377
|
+
export function isContractInput(value: unknown): value is ContractInput {
|
|
1376
1378
|
if (typeof value !== 'object' || value === null || !('target' in value) || !('family' in value)) {
|
|
1377
1379
|
return false;
|
|
1378
1380
|
}
|
|
@@ -1437,7 +1439,7 @@ export type FieldStateOf<T> = T extends ScalarFieldBuilder<infer State> ? State
|
|
|
1437
1439
|
export type RelationStateOf<T> = T extends RelationBuilder<infer State> ? State : never;
|
|
1438
1440
|
|
|
1439
1441
|
export type ModelFieldsOf<T> =
|
|
1440
|
-
T extends
|
|
1442
|
+
T extends ContractModelBuilder<
|
|
1441
1443
|
string | undefined,
|
|
1442
1444
|
infer Fields,
|
|
1443
1445
|
Record<string, AnyRelationBuilder>,
|
|
@@ -1448,7 +1450,7 @@ export type ModelFieldsOf<T> =
|
|
|
1448
1450
|
: never;
|
|
1449
1451
|
|
|
1450
1452
|
export type ModelRelationsOf<T> =
|
|
1451
|
-
T extends
|
|
1453
|
+
T extends ContractModelBuilder<
|
|
1452
1454
|
string | undefined,
|
|
1453
1455
|
Record<string, ScalarFieldBuilder>,
|
|
1454
1456
|
infer Relations,
|
|
@@ -1459,7 +1461,7 @@ export type ModelRelationsOf<T> =
|
|
|
1459
1461
|
: never;
|
|
1460
1462
|
|
|
1461
1463
|
export type ModelAttributesOf<T> =
|
|
1462
|
-
T extends
|
|
1464
|
+
T extends ContractModelBuilder<
|
|
1463
1465
|
string | undefined,
|
|
1464
1466
|
Record<string, ScalarFieldBuilder>,
|
|
1465
1467
|
Record<string, AnyRelationBuilder>,
|
|
@@ -1470,7 +1472,7 @@ export type ModelAttributesOf<T> =
|
|
|
1470
1472
|
: undefined;
|
|
1471
1473
|
|
|
1472
1474
|
export type ModelSqlOf<T> =
|
|
1473
|
-
T extends
|
|
1475
|
+
T extends ContractModelBuilder<
|
|
1474
1476
|
string | undefined,
|
|
1475
1477
|
Record<string, ScalarFieldBuilder>,
|
|
1476
1478
|
Record<string, AnyRelationBuilder>,
|
|
@@ -1,40 +1,40 @@
|
|
|
1
1
|
import type { ColumnTypeDescriptor } from '@prisma-next/contract-authoring';
|
|
2
2
|
import type { StorageTypeInstance } from '@prisma-next/sql-contract/types';
|
|
3
3
|
import type {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
} from './
|
|
4
|
+
ContractDefinition,
|
|
5
|
+
FieldNode,
|
|
6
|
+
ForeignKeyNode,
|
|
7
|
+
IndexNode,
|
|
8
|
+
ModelNode,
|
|
9
|
+
PrimaryKeyNode,
|
|
10
|
+
RelationNode,
|
|
11
|
+
UniqueConstraintNode,
|
|
12
|
+
} from './contract-definition';
|
|
13
13
|
import {
|
|
14
14
|
applyNaming,
|
|
15
|
+
type ContractInput,
|
|
16
|
+
type ContractModelBuilder,
|
|
15
17
|
type FieldStateOf,
|
|
16
18
|
type ForeignKeyConstraint,
|
|
17
19
|
type IdConstraint,
|
|
18
20
|
type ModelAttributesSpec,
|
|
19
21
|
normalizeRelationFieldNames,
|
|
20
22
|
type RelationBuilder,
|
|
23
|
+
type RelationState,
|
|
21
24
|
resolveRelationModelName,
|
|
22
25
|
type ScalarFieldBuilder,
|
|
23
26
|
type SqlStageSpec,
|
|
24
|
-
type StagedContractInput,
|
|
25
|
-
type StagedModelBuilder,
|
|
26
|
-
type RelationState as StagedRelationState,
|
|
27
27
|
type UniqueConstraint,
|
|
28
|
-
} from './
|
|
28
|
+
} from './contract-dsl';
|
|
29
29
|
import {
|
|
30
30
|
emitTypedCrossModelFallbackWarnings,
|
|
31
31
|
emitTypedNamedTypeFallbackWarnings,
|
|
32
|
-
} from './
|
|
32
|
+
} from './contract-warnings';
|
|
33
33
|
|
|
34
|
-
type
|
|
34
|
+
type RuntimeModel = ContractModelBuilder<
|
|
35
35
|
string | undefined,
|
|
36
36
|
Record<string, ScalarFieldBuilder>,
|
|
37
|
-
Record<string, RelationBuilder<
|
|
37
|
+
Record<string, RelationBuilder<RelationState>>,
|
|
38
38
|
ModelAttributesSpec | undefined,
|
|
39
39
|
SqlStageSpec | undefined
|
|
40
40
|
>;
|
|
@@ -44,15 +44,15 @@ type RuntimeModelSpec = {
|
|
|
44
44
|
readonly tableName: string;
|
|
45
45
|
readonly fieldBuilders: Record<string, ScalarFieldBuilder>;
|
|
46
46
|
readonly fieldToColumn: Record<string, string>;
|
|
47
|
-
readonly relations: Record<string, RelationBuilder<
|
|
47
|
+
readonly relations: Record<string, RelationBuilder<RelationState>>;
|
|
48
48
|
readonly attributesSpec: ModelAttributesSpec | undefined;
|
|
49
49
|
readonly sqlSpec: SqlStageSpec | undefined;
|
|
50
50
|
readonly idConstraint: IdConstraint | undefined;
|
|
51
51
|
};
|
|
52
52
|
|
|
53
|
-
type
|
|
53
|
+
type RuntimeCollection = {
|
|
54
54
|
readonly storageTypes: Record<string, StorageTypeInstance>;
|
|
55
|
-
readonly models: Record<string,
|
|
55
|
+
readonly models: Record<string, RuntimeModel>;
|
|
56
56
|
readonly modelSpecs: ReadonlyMap<string, RuntimeModelSpec>;
|
|
57
57
|
};
|
|
58
58
|
|
|
@@ -114,7 +114,7 @@ function mapFieldNamesToColumnNames(
|
|
|
114
114
|
return fieldNames.map((fieldName) => {
|
|
115
115
|
const columnName = fieldToColumn[fieldName];
|
|
116
116
|
if (!columnName) {
|
|
117
|
-
throw new Error(`Unknown field "${modelName}.${fieldName}" in
|
|
117
|
+
throw new Error(`Unknown field "${modelName}.${fieldName}" in contract definition`);
|
|
118
118
|
}
|
|
119
119
|
return columnName;
|
|
120
120
|
});
|
|
@@ -294,10 +294,10 @@ function resolveRelationAnchorFields(spec: RuntimeModelSpec): readonly string[]
|
|
|
294
294
|
|
|
295
295
|
function lowerBelongsToRelation(
|
|
296
296
|
relationName: string,
|
|
297
|
-
relation: Extract<
|
|
297
|
+
relation: Extract<RelationState, { kind: 'belongsTo' }>,
|
|
298
298
|
currentSpec: RuntimeModelSpec,
|
|
299
299
|
allSpecs: ReadonlyMap<string, RuntimeModelSpec>,
|
|
300
|
-
):
|
|
300
|
+
): RelationNode {
|
|
301
301
|
const targetModelName = resolveRelationModelName(relation.toModel);
|
|
302
302
|
const targetSpec = allSpecs.get(targetModelName);
|
|
303
303
|
if (!targetSpec) {
|
|
@@ -341,10 +341,10 @@ function lowerBelongsToRelation(
|
|
|
341
341
|
|
|
342
342
|
function lowerHasOwnershipRelation(
|
|
343
343
|
relationName: string,
|
|
344
|
-
relation: Extract<
|
|
344
|
+
relation: Extract<RelationState, { kind: 'hasMany' | 'hasOne' }>,
|
|
345
345
|
currentSpec: RuntimeModelSpec,
|
|
346
346
|
allSpecs: ReadonlyMap<string, RuntimeModelSpec>,
|
|
347
|
-
):
|
|
347
|
+
): RelationNode {
|
|
348
348
|
const targetModelName = resolveRelationModelName(relation.toModel);
|
|
349
349
|
const targetSpec = allSpecs.get(targetModelName);
|
|
350
350
|
if (!targetSpec) {
|
|
@@ -388,10 +388,10 @@ function lowerHasOwnershipRelation(
|
|
|
388
388
|
|
|
389
389
|
function lowerManyToManyRelation(
|
|
390
390
|
relationName: string,
|
|
391
|
-
relation: Extract<
|
|
391
|
+
relation: Extract<RelationState, { kind: 'manyToMany' }>,
|
|
392
392
|
currentSpec: RuntimeModelSpec,
|
|
393
393
|
allSpecs: ReadonlyMap<string, RuntimeModelSpec>,
|
|
394
|
-
):
|
|
394
|
+
): RelationNode {
|
|
395
395
|
const targetModelName = resolveRelationModelName(relation.toModel);
|
|
396
396
|
const targetSpec = allSpecs.get(targetModelName);
|
|
397
397
|
if (!targetSpec) {
|
|
@@ -456,12 +456,12 @@ function lowerManyToManyRelation(
|
|
|
456
456
|
};
|
|
457
457
|
}
|
|
458
458
|
|
|
459
|
-
function
|
|
459
|
+
function resolveRelationNode(
|
|
460
460
|
relationName: string,
|
|
461
|
-
relation:
|
|
461
|
+
relation: RelationState,
|
|
462
462
|
currentSpec: RuntimeModelSpec,
|
|
463
463
|
allSpecs: ReadonlyMap<string, RuntimeModelSpec>,
|
|
464
|
-
):
|
|
464
|
+
): RelationNode {
|
|
465
465
|
if (relation.kind === 'belongsTo') {
|
|
466
466
|
return lowerBelongsToRelation(relationName, relation, currentSpec, allSpecs);
|
|
467
467
|
}
|
|
@@ -485,7 +485,7 @@ function lowerForeignKeyNode(
|
|
|
485
485
|
readonly constraint?: boolean | undefined;
|
|
486
486
|
readonly index?: boolean | undefined;
|
|
487
487
|
},
|
|
488
|
-
):
|
|
488
|
+
): ForeignKeyNode {
|
|
489
489
|
return {
|
|
490
490
|
columns: mapFieldNamesToColumnNames(spec.modelName, foreignKey.fields, spec.fieldToColumn),
|
|
491
491
|
references: {
|
|
@@ -505,10 +505,10 @@ function lowerForeignKeyNode(
|
|
|
505
505
|
};
|
|
506
506
|
}
|
|
507
507
|
|
|
508
|
-
function
|
|
508
|
+
function resolveForeignKeyNodes(
|
|
509
509
|
spec: RuntimeModelSpec,
|
|
510
510
|
allSpecs: ReadonlyMap<string, RuntimeModelSpec>,
|
|
511
|
-
): readonly
|
|
511
|
+
): readonly ForeignKeyNode[] {
|
|
512
512
|
const relationForeignKeys = resolveRelationForeignKeys(spec, allSpecs).map((foreignKey) => {
|
|
513
513
|
const targetSpec = allSpecs.get(foreignKey.targetModel);
|
|
514
514
|
if (!targetSpec) {
|
|
@@ -534,13 +534,13 @@ function resolveSemanticForeignKeyNodes(
|
|
|
534
534
|
return [...relationForeignKeys, ...sqlForeignKeys];
|
|
535
535
|
}
|
|
536
536
|
|
|
537
|
-
function
|
|
537
|
+
function resolveModelNode(
|
|
538
538
|
spec: RuntimeModelSpec,
|
|
539
539
|
allSpecs: ReadonlyMap<string, RuntimeModelSpec>,
|
|
540
540
|
storageTypes: Record<string, StorageTypeInstance>,
|
|
541
541
|
storageTypeReverseLookup: ReadonlyMap<StorageTypeInstance, string>,
|
|
542
|
-
):
|
|
543
|
-
const fields:
|
|
542
|
+
): ModelNode {
|
|
543
|
+
const fields: FieldNode[] = [];
|
|
544
544
|
|
|
545
545
|
for (const [fieldName, fieldBuilder] of Object.entries(spec.fieldBuilders)) {
|
|
546
546
|
const fieldState = fieldBuilder.build();
|
|
@@ -570,16 +570,16 @@ function resolveSemanticModelNode(
|
|
|
570
570
|
const uniques = resolveModelUniqueConstraints(spec).map((unique) => ({
|
|
571
571
|
columns: mapFieldNamesToColumnNames(spec.modelName, unique.fields, spec.fieldToColumn),
|
|
572
572
|
...(unique.name ? { name: unique.name } : {}),
|
|
573
|
-
})) satisfies readonly
|
|
573
|
+
})) satisfies readonly UniqueConstraintNode[];
|
|
574
574
|
const indexes = (spec.sqlSpec?.indexes ?? []).map((index) => ({
|
|
575
575
|
columns: mapFieldNamesToColumnNames(spec.modelName, index.fields, spec.fieldToColumn),
|
|
576
576
|
...(index.name ? { name: index.name } : {}),
|
|
577
577
|
...(index.using ? { using: index.using } : {}),
|
|
578
578
|
...(index.config ? { config: index.config } : {}),
|
|
579
|
-
})) satisfies readonly
|
|
580
|
-
const foreignKeys =
|
|
579
|
+
})) satisfies readonly IndexNode[];
|
|
580
|
+
const foreignKeys = resolveForeignKeyNodes(spec, allSpecs);
|
|
581
581
|
const relations = Object.entries(spec.relations).map(([relationName, relationBuilder]) =>
|
|
582
|
-
|
|
582
|
+
resolveRelationNode(relationName, relationBuilder.build(), spec, allSpecs),
|
|
583
583
|
);
|
|
584
584
|
|
|
585
585
|
return {
|
|
@@ -595,7 +595,7 @@ function resolveSemanticModelNode(
|
|
|
595
595
|
spec.fieldToColumn,
|
|
596
596
|
),
|
|
597
597
|
...(idConstraint.name ? { name: idConstraint.name } : {}),
|
|
598
|
-
} satisfies
|
|
598
|
+
} satisfies PrimaryKeyNode,
|
|
599
599
|
}
|
|
600
600
|
: {}),
|
|
601
601
|
...(uniques.length > 0 ? { uniques } : {}),
|
|
@@ -605,9 +605,9 @@ function resolveSemanticModelNode(
|
|
|
605
605
|
};
|
|
606
606
|
}
|
|
607
607
|
|
|
608
|
-
function collectRuntimeModelSpecs(definition:
|
|
608
|
+
function collectRuntimeModelSpecs(definition: ContractInput): RuntimeCollection {
|
|
609
609
|
const storageTypes = { ...(definition.types ?? {}) } as Record<string, StorageTypeInstance>;
|
|
610
|
-
const models = { ...(definition.models ?? {}) } as Record<string,
|
|
610
|
+
const models = { ...(definition.models ?? {}) } as Record<string, RuntimeModel>;
|
|
611
611
|
|
|
612
612
|
emitTypedNamedTypeFallbackWarnings(models, storageTypes);
|
|
613
613
|
|
|
@@ -671,12 +671,12 @@ function collectRuntimeModelSpecs(definition: StagedContractInput): RuntimeStage
|
|
|
671
671
|
};
|
|
672
672
|
}
|
|
673
673
|
|
|
674
|
-
function
|
|
674
|
+
function lowerModels(collection: RuntimeCollection): readonly ModelNode[] {
|
|
675
675
|
emitTypedCrossModelFallbackWarnings(collection);
|
|
676
676
|
|
|
677
677
|
const storageTypeReverseLookup = buildStorageTypeReverseLookup(collection.storageTypes);
|
|
678
678
|
return Array.from(collection.modelSpecs.values()).map((spec) =>
|
|
679
|
-
|
|
679
|
+
resolveModelNode(
|
|
680
680
|
spec,
|
|
681
681
|
collection.modelSpecs,
|
|
682
682
|
collection.storageTypes,
|
|
@@ -685,11 +685,9 @@ function lowerSemanticModels(collection: RuntimeStagedCollection): readonly SqlS
|
|
|
685
685
|
);
|
|
686
686
|
}
|
|
687
687
|
|
|
688
|
-
export function
|
|
689
|
-
definition: StagedContractInput,
|
|
690
|
-
): SqlSemanticContractDefinition {
|
|
688
|
+
export function buildContractDefinition(definition: ContractInput): ContractDefinition {
|
|
691
689
|
const collection = collectRuntimeModelSpecs(definition);
|
|
692
|
-
const models =
|
|
690
|
+
const models = lowerModels(collection);
|
|
693
691
|
|
|
694
692
|
return {
|
|
695
693
|
target: definition.target,
|