@prisma-next/sql-contract-ts 0.14.0-dev.80 → 0.14.0-dev.82
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/dist/{build-contract-C07F2P2K.mjs → build-contract-BzAyIu0y.mjs} +42 -40
- package/dist/build-contract-BzAyIu0y.mjs.map +1 -0
- package/dist/config-types.mjs +1 -1
- package/dist/contract-builder.d.mts +205 -196
- package/dist/contract-builder.d.mts.map +1 -1
- package/dist/contract-builder.mjs +118 -29
- package/dist/contract-builder.mjs.map +1 -1
- package/package.json +10 -10
- package/src/build-contract.ts +52 -53
- package/src/contract-builder.ts +9 -63
- package/src/contract-definition.ts +17 -12
- package/src/contract-dsl.ts +8 -8
- package/src/contract-lowering.ts +153 -3
- package/src/exports/contract-builder.ts +2 -0
- package/dist/build-contract-C07F2P2K.mjs.map +0 -1
|
@@ -1,10 +1,11 @@
|
|
|
1
|
-
import { t as buildSqlContractFromDefinition } from "./build-contract-
|
|
1
|
+
import { t as buildSqlContractFromDefinition } from "./build-contract-BzAyIu0y.mjs";
|
|
2
2
|
import { blindCast } from "@prisma-next/utils/casts";
|
|
3
3
|
import { ifDefined } from "@prisma-next/utils/defined";
|
|
4
4
|
import { isColumnDefault } from "@prisma-next/contract/types";
|
|
5
5
|
import { bindEnumType, createEntityHelpersFromNamespace, enumType, isEnumTypeHandle, member } from "@prisma-next/contract-authoring";
|
|
6
|
-
import { assertNoCrossRegistryCollisions, instantiateAuthoringFieldPreset, instantiateAuthoringTypeConstructor, isAuthoringFieldPresetDescriptor, isAuthoringTypeConstructorDescriptor, mergeAuthoringNamespaces, validateAuthoringHelperArguments } from "@prisma-next/framework-components/authoring";
|
|
6
|
+
import { assertNoCrossRegistryCollisions, instantiateAuthoringFieldPreset, instantiateAuthoringTypeConstructor, isAuthoringEntityTypeDescriptor, isAuthoringFieldPresetDescriptor, isAuthoringTypeConstructorDescriptor, mergeAuthoringNamespaces, validateAuthoringHelperArguments } from "@prisma-next/framework-components/authoring";
|
|
7
7
|
import { toStorageTypeInstance } from "@prisma-next/sql-contract/types";
|
|
8
|
+
import { providesEntityHandleLowering } from "@prisma-next/sql-contract/entity-handle-lowering-hook";
|
|
8
9
|
//#region src/authoring-helper-runtime.ts
|
|
9
10
|
function isNamedConstraintOptionsLike(value) {
|
|
10
11
|
if (typeof value !== "object" || value === null || Array.isArray(value)) return false;
|
|
@@ -1190,9 +1191,120 @@ function lowerModels(collection, extensionPacks) {
|
|
|
1190
1191
|
const storageTypeReverseLookup = buildStorageTypeReverseLookup(collection.storageTypes);
|
|
1191
1192
|
return Array.from(collection.modelSpecs.values()).map((spec) => resolveModelNode(spec, collection.modelSpecs, collection.storageTypes, storageTypeReverseLookup, extensionPacks));
|
|
1192
1193
|
}
|
|
1194
|
+
/**
|
|
1195
|
+
* Kind-agnostic walk over the author-declared `entities` handle list:
|
|
1196
|
+
*
|
|
1197
|
+
* 1. Index the bound packs' `entityTypes` contributions by discriminator so
|
|
1198
|
+
* each handle's `entityKind` maps to the pack that registered it; a
|
|
1199
|
+
* handle whose kind no composed pack registers is an error naming the
|
|
1200
|
+
* kind.
|
|
1201
|
+
* 2. Resolve each handle's declared model refs (`handle.refs`, actual
|
|
1202
|
+
* model-handle objects) to storage table coordinates — identity against
|
|
1203
|
+
* the contract's `models` record first, then the handle's declared model
|
|
1204
|
+
* name against the build's model specs; never by re-deriving a table
|
|
1205
|
+
* name. A cross-space (extensionModel) handle resolves to its own
|
|
1206
|
+
* coordinate annotated with `spaceId`.
|
|
1207
|
+
* 3. Call each owning pack's batch lowering hook once with all of its
|
|
1208
|
+
* claimed handles, and fold the returned rows into the namespace-scoped
|
|
1209
|
+
* attachments (namespace → kind → key), rejecting two different entities
|
|
1210
|
+
* in one slot. The result becomes `ContractDefinition.attachedEntities`.
|
|
1211
|
+
*
|
|
1212
|
+
* No entity kind is named anywhere in this walk.
|
|
1213
|
+
*/
|
|
1214
|
+
function lowerPackEntityHandles(definition, modelSpecs) {
|
|
1215
|
+
const entities = definition.entities;
|
|
1216
|
+
if (entities === void 0 || entities.length === 0) return void 0;
|
|
1217
|
+
const components = [definition.target, ...Object.values(definition.extensionPacks ?? {})];
|
|
1218
|
+
const owningComponent = /* @__PURE__ */ new Map();
|
|
1219
|
+
const walkEntityTypes = (namespace, component) => {
|
|
1220
|
+
for (const value of Object.values(namespace)) if (isAuthoringEntityTypeDescriptor(value)) owningComponent.set(value.discriminator, component);
|
|
1221
|
+
else walkEntityTypes(value, component);
|
|
1222
|
+
};
|
|
1223
|
+
for (const component of components) {
|
|
1224
|
+
const entityTypes = component.authoring?.entityTypes;
|
|
1225
|
+
if (entityTypes !== void 0) walkEntityTypes(entityTypes, component);
|
|
1226
|
+
}
|
|
1227
|
+
const defaultNamespaceId = definition.target.defaultNamespaceId;
|
|
1228
|
+
const modelNamesByIdentity = /* @__PURE__ */ new Map();
|
|
1229
|
+
for (const [modelName, modelBuilder] of Object.entries(definition.models ?? {})) modelNamesByIdentity.set(modelBuilder, modelName);
|
|
1230
|
+
const coordinateOf = (modelName) => {
|
|
1231
|
+
const spec = modelSpecs.get(modelName);
|
|
1232
|
+
if (spec === void 0) return void 0;
|
|
1233
|
+
return {
|
|
1234
|
+
kind: "resolved",
|
|
1235
|
+
namespaceId: spec.namespace ?? defaultNamespaceId,
|
|
1236
|
+
tableName: spec.tableName,
|
|
1237
|
+
modelName
|
|
1238
|
+
};
|
|
1239
|
+
};
|
|
1240
|
+
const declaredModelName = (value) => {
|
|
1241
|
+
if (typeof value !== "object" || value === null || !("stageOne" in value)) return void 0;
|
|
1242
|
+
const stageOne = value.stageOne;
|
|
1243
|
+
if (typeof stageOne !== "object" || stageOne === null || !("modelName" in stageOne)) return;
|
|
1244
|
+
return typeof stageOne.modelName === "string" ? stageOne.modelName : void 0;
|
|
1245
|
+
};
|
|
1246
|
+
const resolveRef = (value) => {
|
|
1247
|
+
const modelName = declaredModelName(value);
|
|
1248
|
+
if (isCrossSpaceHandle(value)) {
|
|
1249
|
+
const tableName = value.tableName;
|
|
1250
|
+
const namespaceId = value.stageOne.namespace;
|
|
1251
|
+
if (tableName !== void 0 && namespaceId !== void 0) return {
|
|
1252
|
+
kind: "cross-space",
|
|
1253
|
+
spaceId: value.spaceId,
|
|
1254
|
+
namespaceId,
|
|
1255
|
+
tableName,
|
|
1256
|
+
...ifDefined("modelName", modelName)
|
|
1257
|
+
};
|
|
1258
|
+
return {
|
|
1259
|
+
kind: "unresolved",
|
|
1260
|
+
...ifDefined("modelName", modelName)
|
|
1261
|
+
};
|
|
1262
|
+
}
|
|
1263
|
+
const identityName = modelNamesByIdentity.get(value);
|
|
1264
|
+
return (identityName !== void 0 ? coordinateOf(identityName) : void 0) ?? (modelName !== void 0 ? coordinateOf(modelName) : void 0) ?? {
|
|
1265
|
+
kind: "unresolved",
|
|
1266
|
+
...ifDefined("modelName", modelName)
|
|
1267
|
+
};
|
|
1268
|
+
};
|
|
1269
|
+
const claimed = /* @__PURE__ */ new Map();
|
|
1270
|
+
for (const handle of entities) {
|
|
1271
|
+
const component = owningComponent.get(handle.entityKind);
|
|
1272
|
+
if (component === void 0) throw new Error(`defineContract: entities contains a handle with entityKind "${handle.entityKind}", which no composed pack registers. Compose a pack whose entityTypes contribution claims "${handle.entityKind}", or remove the handle.`);
|
|
1273
|
+
const refs = {};
|
|
1274
|
+
for (const [refName, refValue] of Object.entries(handle.refs ?? {})) refs[refName] = resolveRef(refValue);
|
|
1275
|
+
const forComponent = claimed.get(component) ?? [];
|
|
1276
|
+
forComponent.push({
|
|
1277
|
+
handle,
|
|
1278
|
+
refs
|
|
1279
|
+
});
|
|
1280
|
+
claimed.set(component, forComponent);
|
|
1281
|
+
}
|
|
1282
|
+
const pack = {};
|
|
1283
|
+
for (const [component, handles] of claimed) {
|
|
1284
|
+
const authoring = component.authoring;
|
|
1285
|
+
if (!providesEntityHandleLowering(authoring)) {
|
|
1286
|
+
const kinds = [...new Set(handles.map((entry) => entry.handle.entityKind))].sort();
|
|
1287
|
+
throw new Error(`defineContract: entityKind(s) ${kinds.map((kind) => `"${kind}"`).join(", ")} are registered by a pack that does not implement entity-handle lowering (no lowerEntityHandles on its authoring contributions).`);
|
|
1288
|
+
}
|
|
1289
|
+
for (const row of authoring.lowerEntityHandles({
|
|
1290
|
+
handles,
|
|
1291
|
+
defaultNamespaceId
|
|
1292
|
+
})) {
|
|
1293
|
+
const forNamespace = pack[row.namespaceId] ?? {};
|
|
1294
|
+
pack[row.namespaceId] = forNamespace;
|
|
1295
|
+
const forKind = forNamespace[row.entityKind] ?? {};
|
|
1296
|
+
forNamespace[row.entityKind] = forKind;
|
|
1297
|
+
const existing = forKind[row.key];
|
|
1298
|
+
if (existing !== void 0 && existing !== row.entity) throw new Error(`defineContract: two different "${row.entityKind}" entities named "${row.key}" in namespace "${row.namespaceId}" — pack-entity names must be unique per namespace.`);
|
|
1299
|
+
forKind[row.key] = row.entity;
|
|
1300
|
+
}
|
|
1301
|
+
}
|
|
1302
|
+
return pack;
|
|
1303
|
+
}
|
|
1193
1304
|
function buildContractDefinition(definition) {
|
|
1194
1305
|
const collection = collectRuntimeModelSpecs(definition);
|
|
1195
1306
|
const models = lowerModels(collection, definition.extensionPacks);
|
|
1307
|
+
const attachedEntities = lowerPackEntityHandles(definition, collection.modelSpecs);
|
|
1196
1308
|
return {
|
|
1197
1309
|
target: definition.target,
|
|
1198
1310
|
...ifDefined("defaultControlPolicy", definition.defaultControlPolicy),
|
|
@@ -1203,7 +1315,7 @@ function buildContractDefinition(definition) {
|
|
|
1203
1315
|
...definition.namespaces ? { namespaces: definition.namespaces } : {},
|
|
1204
1316
|
createNamespace: definition.createNamespace,
|
|
1205
1317
|
...definition.enums && Object.keys(definition.enums).length > 0 ? { enums: definition.enums } : {},
|
|
1206
|
-
...
|
|
1318
|
+
...attachedEntities && Object.keys(attachedEntities).length > 0 ? { attachedEntities } : {},
|
|
1207
1319
|
models
|
|
1208
1320
|
};
|
|
1209
1321
|
}
|
|
@@ -1291,29 +1403,6 @@ function buildContractFromDsl(definition) {
|
|
|
1291
1403
|
validatePerModelNamespaces(definition.target, definition.namespaces, definition.models ?? {});
|
|
1292
1404
|
return blindCast(buildSqlContractFromDefinition(buildContractDefinition(definition), definition.codecLookup));
|
|
1293
1405
|
}
|
|
1294
|
-
function mergePackEntityNames(namespaceId, kind, a, b) {
|
|
1295
|
-
if (a !== void 0 && b !== void 0) for (const [name, entity] of Object.entries(b)) {
|
|
1296
|
-
const existing = a[name];
|
|
1297
|
-
if (existing !== void 0 && existing !== entity) throw new Error(`defineContract: two different "${kind}" entities named "${name}" in namespace "${namespaceId}" — a factory-returned pack entity conflicts with a scaffold-declared one; pack-entity names must be unique per namespace.`);
|
|
1298
|
-
}
|
|
1299
|
-
return {
|
|
1300
|
-
...a ?? {},
|
|
1301
|
-
...b ?? {}
|
|
1302
|
-
};
|
|
1303
|
-
}
|
|
1304
|
-
function mergePackEntityKinds(namespaceId, a, b) {
|
|
1305
|
-
const kinds = /* @__PURE__ */ new Set([...Object.keys(a ?? {}), ...Object.keys(b ?? {})]);
|
|
1306
|
-
const result = {};
|
|
1307
|
-
for (const kind of kinds) result[kind] = mergePackEntityNames(namespaceId, kind, a?.[kind], b?.[kind]);
|
|
1308
|
-
return result;
|
|
1309
|
-
}
|
|
1310
|
-
function mergePackEntities(a, b) {
|
|
1311
|
-
if (a === void 0 && b === void 0) return void 0;
|
|
1312
|
-
const namespaces = /* @__PURE__ */ new Set([...Object.keys(a ?? {}), ...Object.keys(b ?? {})]);
|
|
1313
|
-
const result = {};
|
|
1314
|
-
for (const namespaceId of namespaces) result[namespaceId] = mergePackEntityKinds(namespaceId, a?.[namespaceId], b?.[namespaceId]);
|
|
1315
|
-
return result;
|
|
1316
|
-
}
|
|
1317
1406
|
/** Implementation. */
|
|
1318
1407
|
function buildBoundContract(family, target, definition, factory) {
|
|
1319
1408
|
const full = {
|
|
@@ -1331,13 +1420,13 @@ function buildBoundContract(family, target, definition, factory) {
|
|
|
1331
1420
|
...definition.enums ?? {},
|
|
1332
1421
|
...built.enums
|
|
1333
1422
|
};
|
|
1334
|
-
const
|
|
1423
|
+
const mergedEntities = [...definition.entities ?? [], ...built.entities ?? []];
|
|
1335
1424
|
return buildContractFromDsl({
|
|
1336
1425
|
...full,
|
|
1337
1426
|
...ifDefined("types", built.types),
|
|
1338
1427
|
...ifDefined("models", built.models),
|
|
1339
1428
|
...ifDefined("enums", Object.keys(mergedEnums).length > 0 ? mergedEnums : void 0),
|
|
1340
|
-
...ifDefined("
|
|
1429
|
+
...ifDefined("entities", mergedEntities.length > 0 ? mergedEntities : void 0)
|
|
1341
1430
|
});
|
|
1342
1431
|
}
|
|
1343
1432
|
return buildContractFromDsl(full);
|
|
@@ -1348,6 +1437,6 @@ function defineContract(definition, factory) {
|
|
|
1348
1437
|
return buildBoundContract(definition.family, definition.target, definition);
|
|
1349
1438
|
}
|
|
1350
1439
|
//#endregion
|
|
1351
|
-
export { bindEnumType, buildBoundContract, buildSqlContractFromDefinition, defineContract, enumType, extensionModel, field, member, model, rel };
|
|
1440
|
+
export { bindEnumType, buildBoundContract, buildContractDefinition, buildSqlContractFromDefinition, defineContract, enumType, extensionModel, field, member, model, rel };
|
|
1352
1441
|
|
|
1353
1442
|
//# sourceMappingURL=contract-builder.mjs.map
|