@prisma-next/family-sql 0.16.0-dev.3 → 0.16.0-dev.31
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 +1 -1
- package/dist/control.d.mts +1 -1
- package/dist/control.d.mts.map +1 -1
- package/dist/control.mjs +108 -33
- package/dist/control.mjs.map +1 -1
- package/dist/diff.d.mts +1 -1
- package/dist/errors-ZGKTAYsm.mjs +9 -0
- package/dist/errors-ZGKTAYsm.mjs.map +1 -0
- package/dist/ir.d.mts.map +1 -1
- package/dist/ir.mjs +1 -1
- package/dist/migration.d.mts +1 -1
- package/dist/psl-infer.d.mts +3 -5
- package/dist/psl-infer.d.mts.map +1 -1
- package/dist/psl-infer.mjs +11 -8
- package/dist/psl-infer.mjs.map +1 -1
- package/dist/{sql-contract-serializer-C75cfMSS.mjs → sql-contract-serializer-othnJUZ_.mjs} +7 -2
- package/dist/sql-contract-serializer-othnJUZ_.mjs.map +1 -0
- package/dist/{types-6JMCRorL.d.mts → types-DhAmOoxA.d.mts} +11 -4
- package/dist/{types-6JMCRorL.d.mts.map → types-DhAmOoxA.d.mts.map} +1 -1
- package/dist/{verify-C-G0obRm.mjs → verify-DuuJFiTm.mjs} +7 -2
- package/dist/verify-DuuJFiTm.mjs.map +1 -0
- package/dist/verify.d.mts.map +1 -1
- package/dist/verify.mjs +1 -1
- package/package.json +21 -21
- package/src/core/control-instance.ts +50 -24
- package/src/core/errors.ts +22 -0
- package/src/core/ir/sql-contract-serializer-base.ts +8 -1
- package/src/core/migrations/contract-to-schema-ir.ts +78 -17
- package/src/core/migrations/types.ts +10 -3
- package/src/core/psl-contract-infer/name-transforms.ts +0 -12
- package/src/core/psl-contract-infer/printer-config.ts +2 -3
- package/src/core/psl-contract-infer/relation-inference.ts +23 -1
- package/src/core/verify.ts +10 -1
- package/src/exports/psl-infer.ts +1 -2
- package/dist/sql-contract-serializer-C75cfMSS.mjs.map +0 -1
- package/dist/verify-C-G0obRm.mjs.map +0 -1
package/README.md
CHANGED
|
@@ -44,7 +44,7 @@ const stack = createControlStack({
|
|
|
44
44
|
target: postgresTargetDescriptor,
|
|
45
45
|
adapter: postgresAdapterDescriptor,
|
|
46
46
|
driver: postgresDriverDescriptor,
|
|
47
|
-
|
|
47
|
+
extensions: [pgVectorExtensionDescriptor],
|
|
48
48
|
});
|
|
49
49
|
|
|
50
50
|
// Create a family instance for control-plane operations
|
package/dist/control.d.mts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { r as SqlControlAdapter } from "./control-adapter-CW7FdxeS.mjs";
|
|
2
|
-
import { A as SqlPlannerSuccessResult, C as SqlMigrationRunnerSuccessValue, D as SqlPlannerConflictLocation, E as SqlPlannerConflictKind, O as SqlPlannerFailureResult, S as SqlMigrationRunnerResult, T as SqlPlannerConflict, _ as SqlMigrationRunner, a as FieldEvent, b as SqlMigrationRunnerExecuteOptions, c as SqlControlAdapterDescriptor, d as SqlMigrationPlanContractInfo, f as SqlMigrationPlanOperation, g as SqlMigrationPlannerPlanOptions, h as SqlMigrationPlanner, i as ExpandNativeTypeInput, j as StorageTypePlanResult, k as SqlPlannerResult, l as SqlControlExtensionDescriptor, m as SqlMigrationPlanOperationTarget, n as CodecControlHooks, o as FieldEventContext, p as SqlMigrationPlanOperationStep, r as CreateSqlMigrationPlanOptions, s as ResolveIdentityValueInput, t as AnyRecord, u as SqlMigrationPlan, v as SqlMigrationRunnerErrorCode, w as SqlPlanTargetDetails, x as SqlMigrationRunnerFailure, y as SqlMigrationRunnerExecuteCallbacks } from "./types-
|
|
2
|
+
import { A as SqlPlannerSuccessResult, C as SqlMigrationRunnerSuccessValue, D as SqlPlannerConflictLocation, E as SqlPlannerConflictKind, O as SqlPlannerFailureResult, S as SqlMigrationRunnerResult, T as SqlPlannerConflict, _ as SqlMigrationRunner, a as FieldEvent, b as SqlMigrationRunnerExecuteOptions, c as SqlControlAdapterDescriptor, d as SqlMigrationPlanContractInfo, f as SqlMigrationPlanOperation, g as SqlMigrationPlannerPlanOptions, h as SqlMigrationPlanner, i as ExpandNativeTypeInput, j as StorageTypePlanResult, k as SqlPlannerResult, l as SqlControlExtensionDescriptor, m as SqlMigrationPlanOperationTarget, n as CodecControlHooks, o as FieldEventContext, p as SqlMigrationPlanOperationStep, r as CreateSqlMigrationPlanOptions, s as ResolveIdentityValueInput, t as AnyRecord, u as SqlMigrationPlan, v as SqlMigrationRunnerErrorCode, w as SqlPlanTargetDetails, x as SqlMigrationRunnerFailure, y as SqlMigrationRunnerExecuteCallbacks } from "./types-DhAmOoxA.mjs";
|
|
3
3
|
import { n as SqlSchemaDiffInput, r as SqlSchemaDiffResult, t as SqlSchemaDiffFn } from "./schema-differ-C8OHo1V5.mjs";
|
|
4
4
|
import { ContractSerializer, ControlFamilyDescriptor, ControlFamilyInstance, ControlStack, DiffSubjectGranularity, MigratableTargetDescriptor, MigrationOperationClass, MigrationOperationPolicy, MigrationOperationPolicy as MigrationOperationPolicy$1, MigrationPlan, MigrationPlanOperation, MigrationPlanOperation as MigrationPlanOperation$1, MigrationPlanner, MigrationPlannerConflict, MigrationPlannerConflict as MigrationPlannerConflict$1, MigrationPlannerResult, MutationDefaultGeneratorDescriptor, OpFactoryCall, OperationPreview, OperationPreviewCapable, PslContractInferCapable, SchemaDiffIssue, SchemaVerifier, SchemaViewCapable, SignDatabaseResult, TargetMigrationsCapability, VerifyDatabaseResult, VerifyDatabaseSchemaResult, assembleAuthoringContributions } from "@prisma-next/framework-components/control";
|
|
5
5
|
import { ColumnDefault, Contract, ControlPolicy } from "@prisma-next/contract/types";
|
package/dist/control.d.mts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"control.d.mts","names":[],"sources":["../src/core/control-instance.ts","../src/core/control-descriptor.ts","../src/core/assembly.ts","../src/core/control-target-descriptor.ts","../src/core/migrations/contract-to-schema-ir.ts","../src/core/migrations/control-policy.ts","../src/core/migrations/field-event-planner.ts","../src/core/migrations/native-type-expander.ts","../src/core/migrations/plan-helpers.ts","../src/core/migrations/policies.ts","../src/core/timestamp-now-generator.ts","../src/exports/control.ts"],"mappings":";;;;;;;;;;;;;;
|
|
1
|
+
{"version":3,"file":"control.d.mts","names":[],"sources":["../src/core/control-instance.ts","../src/core/control-descriptor.ts","../src/core/assembly.ts","../src/core/control-target-descriptor.ts","../src/core/migrations/contract-to-schema-ir.ts","../src/core/migrations/control-policy.ts","../src/core/migrations/field-event-planner.ts","../src/core/migrations/native-type-expander.ts","../src/core/migrations/plan-helpers.ts","../src/core/migrations/policies.ts","../src/core/timestamp-now-generator.ts","../src/exports/control.ts"],"mappings":"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"}
|
package/dist/control.mjs
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { i as sqlFamilyPslBlockDescriptors, n as sqlFamilyAuthoringFieldPresets, r as sqlFamilyEntityTypes, t as sqlFamilyAuthoringTypes } from "./authoring-type-constructors-CXd-8ydc.mjs";
|
|
2
2
|
import { n as classifyDiffSubjectGranularity, o as verifySqlSchemaByDiff, s as extractCodecControlHooks, t as classifyDiffEntityKind } from "./schema-verify-DY21bMwy.mjs";
|
|
3
|
-
import { t as
|
|
4
|
-
import { t as
|
|
3
|
+
import { t as sqlFamilyError } from "./errors-ZGKTAYsm.mjs";
|
|
4
|
+
import { t as SqlContractSerializer } from "./sql-contract-serializer-othnJUZ_.mjs";
|
|
5
|
+
import { t as collectSupportedCodecTypeIds } from "./verify-DuuJFiTm.mjs";
|
|
5
6
|
import { a as timestampNowControlDescriptor, i as temporalCodecPresetWithPrecision, n as temporalAuthoringPresets, r as temporalCodecPreset } from "./timestamp-now-generator-DRXygu32.mjs";
|
|
6
7
|
import { sqlEmission } from "@prisma-next/sql-contract-emitter";
|
|
7
8
|
import { blindCast } from "@prisma-next/utils/casts";
|
|
@@ -9,8 +10,8 @@ import { APP_SPACE_ID, SchemaTreeNode, VERIFY_CODE_HASH_MISMATCH, VERIFY_CODE_MA
|
|
|
9
10
|
import { isPlainRecord } from "@prisma-next/framework-components/ir";
|
|
10
11
|
import { assertDescriptorSelfConsistency } from "@prisma-next/migration-tools/spaces";
|
|
11
12
|
import { sqlContractCanonicalizationHooks } from "@prisma-next/sql-contract/canonicalization-hooks";
|
|
12
|
-
import { defaultIndexName } from "@prisma-next/sql-schema-ir/naming";
|
|
13
13
|
import { ifDefined } from "@prisma-next/utils/defined";
|
|
14
|
+
import { InternalError } from "@prisma-next/utils/internal-error";
|
|
14
15
|
import { effectiveControlPolicy } from "@prisma-next/contract/types";
|
|
15
16
|
import { StorageTable, isStorageTypeInstance } from "@prisma-next/sql-contract/types";
|
|
16
17
|
import { RelationalSchemaNodeKind, SqlSchemaIR, SqlTableIR } from "@prisma-next/sql-schema-ir/types";
|
|
@@ -49,6 +50,16 @@ function sqlOperationsToPreview(operations) {
|
|
|
49
50
|
}
|
|
50
51
|
//#endregion
|
|
51
52
|
//#region src/core/control-instance.ts
|
|
53
|
+
function missingDescriptorOperationError(targetId, operation) {
|
|
54
|
+
return sqlFamilyError("CONTRACT.PACK_CONTRIBUTION_INVALID", `SQL target "${targetId}" is missing the required ${operation} descriptor operation`, {
|
|
55
|
+
why: `The target descriptor does not contribute the ${operation} operation the SQL family requires for this call.`,
|
|
56
|
+
fix: `Use a target package whose control descriptor implements ${operation}.`,
|
|
57
|
+
meta: {
|
|
58
|
+
targetId,
|
|
59
|
+
operation
|
|
60
|
+
}
|
|
61
|
+
});
|
|
62
|
+
}
|
|
52
63
|
function extractCodecTypeIdsFromContract(contract) {
|
|
53
64
|
const typeIds = /* @__PURE__ */ new Set();
|
|
54
65
|
if (typeof contract === "object" && contract !== null && "storage" in contract && typeof contract.storage === "object" && contract.storage !== null && "namespaces" in contract.storage && typeof contract.storage.namespaces === "object" && contract.storage.namespaces !== null) {
|
|
@@ -89,7 +100,7 @@ function createVerifyResult(options) {
|
|
|
89
100
|
return result;
|
|
90
101
|
}
|
|
91
102
|
function buildSqlTypeMetadataRegistry(options) {
|
|
92
|
-
const { target, adapter,
|
|
103
|
+
const { target, adapter, extensions } = options;
|
|
93
104
|
const registry = /* @__PURE__ */ new Map();
|
|
94
105
|
const targetId = adapter.targetId;
|
|
95
106
|
const descriptors = [
|
|
@@ -117,7 +128,7 @@ function buildSqlTypeMetadataRegistry(options) {
|
|
|
117
128
|
function buildTransitiveDependsOnMap(extensions) {
|
|
118
129
|
const directDeps = /* @__PURE__ */ new Map();
|
|
119
130
|
for (const ext of extensions) {
|
|
120
|
-
const packs = ext.contractSpace?.contractJson?.
|
|
131
|
+
const packs = ext.contractSpace?.contractJson?.extensions;
|
|
121
132
|
const deps = packs !== null && typeof packs === "object" ? Object.keys(packs) : [];
|
|
122
133
|
directDeps.set(ext.id, deps);
|
|
123
134
|
}
|
|
@@ -177,7 +188,14 @@ function assertNoCrossSpaceFkReverseReferences(extensions) {
|
|
|
177
188
|
if (target["spaceId"] === void 0) continue;
|
|
178
189
|
const targetSpaceId = target["spaceId"];
|
|
179
190
|
if (typeof targetSpaceId !== "string") continue;
|
|
180
|
-
if (dependsOnMap.get(targetSpaceId)?.has(ext.id)) throw
|
|
191
|
+
if (dependsOnMap.get(targetSpaceId)?.has(ext.id)) throw sqlFamilyError("CONTRACT.FOREIGN_KEY_INVALID", `Cross-space FK reverse-reference detected: extension "${ext.id}" has a cross-space FK targeting space "${targetSpaceId}", but "${targetSpaceId}" depends on "${ext.id}". Cross-space FKs must follow the dependency direction (a space can only reference spaces it depends on, not spaces that depend on it).`, {
|
|
192
|
+
why: "The foreign key points against the contract-space dependency direction.",
|
|
193
|
+
fix: "Move the foreign key to the depending space, or restructure the extension dependencies so the referencing space depends on the referenced one.",
|
|
194
|
+
meta: {
|
|
195
|
+
extensionId: ext.id,
|
|
196
|
+
targetSpaceId
|
|
197
|
+
}
|
|
198
|
+
});
|
|
181
199
|
}
|
|
182
200
|
}
|
|
183
201
|
}
|
|
@@ -185,10 +203,10 @@ function assertNoCrossSpaceFkReverseReferences(extensions) {
|
|
|
185
203
|
}
|
|
186
204
|
}
|
|
187
205
|
function createSqlFamilyInstance(stack) {
|
|
188
|
-
if (!stack.adapter) throw new
|
|
206
|
+
if (!stack.adapter) throw new InternalError("SQL family requires an adapter descriptor in ControlStack");
|
|
189
207
|
const target = stack.target;
|
|
190
208
|
const adapter = stack.adapter;
|
|
191
|
-
const extensions = stack.
|
|
209
|
+
const extensions = stack.extensions;
|
|
192
210
|
for (const extension of extensions) if (extension.contractSpace) {
|
|
193
211
|
const { contractJson, headRef } = extension.contractSpace;
|
|
194
212
|
assertDescriptorSelfConsistency({
|
|
@@ -205,7 +223,7 @@ function createSqlFamilyInstance(stack) {
|
|
|
205
223
|
const typeMetadataRegistry = buildSqlTypeMetadataRegistry({
|
|
206
224
|
target,
|
|
207
225
|
adapter,
|
|
208
|
-
|
|
226
|
+
extensions
|
|
209
227
|
});
|
|
210
228
|
let controlAdapter;
|
|
211
229
|
const getControlAdapter = () => controlAdapter ??= adapter.create(stack);
|
|
@@ -324,8 +342,8 @@ function createSqlFamilyInstance(stack) {
|
|
|
324
342
|
},
|
|
325
343
|
verifySchema(options) {
|
|
326
344
|
const contract = deserializeWithTargetSerializer(options.contract);
|
|
327
|
-
if (!diffSchema) throw
|
|
328
|
-
if (!targetGranularityOf) throw
|
|
345
|
+
if (!diffSchema) throw missingDescriptorOperationError(target.targetId, "diffSchema");
|
|
346
|
+
if (!targetGranularityOf) throw missingDescriptorOperationError(target.targetId, "classifySubjectGranularity");
|
|
329
347
|
return verifySqlSchemaByDiff({
|
|
330
348
|
contract,
|
|
331
349
|
schema: options.schema,
|
|
@@ -345,7 +363,7 @@ function createSqlFamilyInstance(stack) {
|
|
|
345
363
|
* cannot read; nothing is stamped on the issue or the node.
|
|
346
364
|
*/
|
|
347
365
|
classifySubjectGranularity(issue) {
|
|
348
|
-
if (!targetGranularityOf) throw
|
|
366
|
+
if (!targetGranularityOf) throw missingDescriptorOperationError(target.targetId, "classifySubjectGranularity");
|
|
349
367
|
return classifyDiffSubjectGranularity(issue, targetGranularityOf);
|
|
350
368
|
},
|
|
351
369
|
/**
|
|
@@ -356,7 +374,7 @@ function createSqlFamilyInstance(stack) {
|
|
|
356
374
|
* capability.
|
|
357
375
|
*/
|
|
358
376
|
classifyEntityKind(issue) {
|
|
359
|
-
if (!targetEntityKindOf) throw
|
|
377
|
+
if (!targetEntityKindOf) throw missingDescriptorOperationError(target.targetId, "classifyEntityKind");
|
|
360
378
|
return classifyDiffEntityKind(issue, targetEntityKindOf);
|
|
361
379
|
},
|
|
362
380
|
async sign(options) {
|
|
@@ -393,7 +411,11 @@ function createSqlFamilyInstance(stack) {
|
|
|
393
411
|
if (!await controlAdapter.updateMarker(driver, APP_SPACE_ID, existingStorageHash, {
|
|
394
412
|
storageHash: contractStorageHash,
|
|
395
413
|
profileHash: contractProfileHash
|
|
396
|
-
})) throw
|
|
414
|
+
})) throw sqlFamilyError("MIGRATION.MARKER_CAS_FAILURE", "CAS conflict: marker was modified by another process during sign", {
|
|
415
|
+
why: "Another process updated the contract marker between the read and the compare-and-swap write.",
|
|
416
|
+
fix: "Re-run the sign command; if it keeps failing, make sure only one migration process runs at a time.",
|
|
417
|
+
meta: { space: APP_SPACE_ID }
|
|
418
|
+
});
|
|
397
419
|
markerUpdated = true;
|
|
398
420
|
}
|
|
399
421
|
}
|
|
@@ -447,7 +469,11 @@ function createSqlFamilyInstance(stack) {
|
|
|
447
469
|
return getControlAdapter().introspect(options.driver, options.contract);
|
|
448
470
|
},
|
|
449
471
|
inferPslContract(schemaIR) {
|
|
450
|
-
if (!targetInferPslContract) throw
|
|
472
|
+
if (!targetInferPslContract) throw sqlFamilyError("CONTRACT.INFER_UNSUPPORTED", `Target "${target.targetId}" does not support contract infer (no inferPslContract on its descriptor).`, {
|
|
473
|
+
why: "The target descriptor does not provide the inferPslContract hook, so a PSL contract cannot be inferred from the database schema.",
|
|
474
|
+
fix: "Use a target package that supports contract infer, or author the contract instead of inferring it.",
|
|
475
|
+
meta: { targetId: target.targetId }
|
|
476
|
+
});
|
|
451
477
|
return targetInferPslContract(schemaIR, describedContracts);
|
|
452
478
|
},
|
|
453
479
|
lowerAst(ast, context) {
|
|
@@ -515,7 +541,7 @@ function createSqlFamilyInstance(stack) {
|
|
|
515
541
|
}));
|
|
516
542
|
}
|
|
517
543
|
for (const index of table.indexes) {
|
|
518
|
-
const name = index.name
|
|
544
|
+
const name = index.name;
|
|
519
545
|
const label = index.unique ? `unique index ${name}` : `index ${name}`;
|
|
520
546
|
children.push(new SchemaTreeNode({
|
|
521
547
|
kind: "index",
|
|
@@ -614,13 +640,17 @@ function buildColumnCodecRef(resolved, many) {
|
|
|
614
640
|
function resolveColumnTypeMetadata(column, storageTypes) {
|
|
615
641
|
if (!column.typeRef) return column;
|
|
616
642
|
const referenced = storageTypes[column.typeRef];
|
|
617
|
-
if (!referenced) throw
|
|
643
|
+
if (!referenced) throw sqlFamilyError("CONTRACT.TYPE_UNKNOWN", `Column references storage type "${column.typeRef}" but it is not defined in storage.types.`, {
|
|
644
|
+
why: "The column typeRef does not resolve to any entry in the contract storage.types map.",
|
|
645
|
+
fix: "Regenerate the contract from its authoring source; do not hand-edit contract JSON.",
|
|
646
|
+
meta: { typeRef: column.typeRef }
|
|
647
|
+
});
|
|
618
648
|
if (isStorageTypeInstance(referenced)) return {
|
|
619
649
|
codecId: referenced.codecId,
|
|
620
650
|
nativeType: referenced.nativeType,
|
|
621
651
|
typeParams: referenced.typeParams
|
|
622
652
|
};
|
|
623
|
-
throw new
|
|
653
|
+
throw new InternalError(`Storage type "${column.typeRef}" has an unknown polymorphic kind; expected a codec-typed StorageTypeInstance.`);
|
|
624
654
|
}
|
|
625
655
|
/**
|
|
626
656
|
* Resolves a `ValueSetRef` to its permitted values from the contract storage.
|
|
@@ -637,11 +667,34 @@ function allStrings(values) {
|
|
|
637
667
|
}
|
|
638
668
|
function resolveValueSetValues(ref, storage, contextLabel) {
|
|
639
669
|
const ns = storage.namespaces[ref.namespaceId];
|
|
640
|
-
if (!ns) throw
|
|
670
|
+
if (!ns) throw sqlFamilyError("CONTRACT.NAMESPACE_UNKNOWN", `resolveValueSetValues: namespace "${ref.namespaceId}" not found in storage (${contextLabel})`, {
|
|
671
|
+
why: "A value-set reference names a namespace the contract storage does not declare.",
|
|
672
|
+
fix: "Regenerate the contract from its authoring source; do not hand-edit contract JSON.",
|
|
673
|
+
meta: {
|
|
674
|
+
namespaceId: ref.namespaceId,
|
|
675
|
+
context: contextLabel
|
|
676
|
+
}
|
|
677
|
+
});
|
|
641
678
|
const valueSet = ns.entries.valueSet?.[ref.entityName];
|
|
642
|
-
if (!valueSet) throw
|
|
679
|
+
if (!valueSet) throw sqlFamilyError("CONTRACT.ENUM_UNKNOWN", `resolveValueSetValues: value-set "${ref.entityName}" not found in namespace "${ref.namespaceId}" (${contextLabel})`, {
|
|
680
|
+
why: "A value-set reference names an entry its namespace does not declare.",
|
|
681
|
+
fix: "Regenerate the contract from its authoring source; do not hand-edit contract JSON.",
|
|
682
|
+
meta: {
|
|
683
|
+
valueSet: ref.entityName,
|
|
684
|
+
namespaceId: ref.namespaceId,
|
|
685
|
+
context: contextLabel
|
|
686
|
+
}
|
|
687
|
+
});
|
|
643
688
|
const values = valueSet.values;
|
|
644
|
-
if (!allStrings(values)) throw
|
|
689
|
+
if (!allStrings(values)) throw sqlFamilyError("CONTRACT.ENUM_INVALID", `resolveValueSetValues: value-set "${ref.entityName}" in namespace "${ref.namespaceId}" has a non-string value; numeric-enum CHECK constraints are not yet supported (${contextLabel})`, {
|
|
690
|
+
why: "Only string value-sets can be rendered as CHECK constraints; this value-set carries a non-string value.",
|
|
691
|
+
fix: "Use string enum values, or drop the CHECK-constrained enum until numeric enums are supported.",
|
|
692
|
+
meta: {
|
|
693
|
+
valueSet: ref.entityName,
|
|
694
|
+
namespaceId: ref.namespaceId,
|
|
695
|
+
context: contextLabel
|
|
696
|
+
}
|
|
697
|
+
});
|
|
645
698
|
return values;
|
|
646
699
|
}
|
|
647
700
|
/**
|
|
@@ -672,14 +725,24 @@ function convertUnique(unique, tableName) {
|
|
|
672
725
|
dependsOn: flatColumnDependsOn(tableName, unique.columns)
|
|
673
726
|
};
|
|
674
727
|
}
|
|
675
|
-
function convertIndex(index, tableName) {
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
728
|
+
function convertIndex(index, tableName, tableColumns) {
|
|
729
|
+
const base = {
|
|
730
|
+
name: index.name,
|
|
731
|
+
prefix: index.prefix,
|
|
732
|
+
where: index.where,
|
|
733
|
+
unique: index.unique,
|
|
734
|
+
partial: index.where !== void 0,
|
|
735
|
+
type: index.type,
|
|
736
|
+
options: index.options,
|
|
737
|
+
annotations: void 0,
|
|
738
|
+
dependsOn: flatColumnDependsOn(tableName, index.columns ?? tableColumns)
|
|
739
|
+
};
|
|
740
|
+
return index.expression !== void 0 ? {
|
|
741
|
+
...base,
|
|
742
|
+
expression: index.expression
|
|
743
|
+
} : {
|
|
744
|
+
...base,
|
|
745
|
+
columns: index.columns ?? []
|
|
683
746
|
};
|
|
684
747
|
}
|
|
685
748
|
/**
|
|
@@ -762,7 +825,7 @@ function convertTable(name, table, storageTypes, expandNativeType, renderDefault
|
|
|
762
825
|
} : void 0),
|
|
763
826
|
foreignKeys: table.foreignKeys.map((fk) => convertForeignKey(fk, storage)),
|
|
764
827
|
uniques: table.uniques.map((u) => convertUnique(u, name)),
|
|
765
|
-
indexes: table.indexes.map((i) => convertIndex(i, name)),
|
|
828
|
+
indexes: table.indexes.map((i) => convertIndex(i, name, Object.keys(table.columns))),
|
|
766
829
|
...ifDefined("checks", checks)
|
|
767
830
|
});
|
|
768
831
|
}
|
|
@@ -835,7 +898,11 @@ function detectDestructiveChanges(from, to) {
|
|
|
835
898
|
* per-table fields.
|
|
836
899
|
*/
|
|
837
900
|
function contractNamespaceToSchemaIR(storage, namespaceId, options) {
|
|
838
|
-
if (options.annotationNamespace.length === 0) throw
|
|
901
|
+
if (options.annotationNamespace.length === 0) throw sqlFamilyError("CONTRACT.PACK_CONTRIBUTION_INVALID", "annotationNamespace must be a non-empty string", {
|
|
902
|
+
why: "The calling target pack passed an empty annotationNamespace to the contract-to-schema-IR projection.",
|
|
903
|
+
fix: "Fix the target pack to pass its non-empty annotation namespace (e.g. \"pg\").",
|
|
904
|
+
meta: { option: "annotationNamespace" }
|
|
905
|
+
});
|
|
839
906
|
const namespace = storage.namespaces[namespaceId];
|
|
840
907
|
if (!namespace) return new SqlSchemaIR({ tables: {} });
|
|
841
908
|
const storageTypes = { ...storage.types ?? {} };
|
|
@@ -847,7 +914,11 @@ function contractNamespaceToSchemaIR(storage, namespaceId, options) {
|
|
|
847
914
|
return new SqlSchemaIR({ tables });
|
|
848
915
|
}
|
|
849
916
|
function contractToSchemaIR(contract, options) {
|
|
850
|
-
if (options.annotationNamespace.length === 0) throw
|
|
917
|
+
if (options.annotationNamespace.length === 0) throw sqlFamilyError("CONTRACT.PACK_CONTRIBUTION_INVALID", "annotationNamespace must be a non-empty string", {
|
|
918
|
+
why: "The calling target pack passed an empty annotationNamespace to the contract-to-schema-IR projection.",
|
|
919
|
+
fix: "Fix the target pack to pass its non-empty annotation namespace (e.g. \"pg\").",
|
|
920
|
+
meta: { option: "annotationNamespace" }
|
|
921
|
+
});
|
|
851
922
|
if (!contract) return new SqlSchemaIR({ tables: {} });
|
|
852
923
|
const storage = contract.storage;
|
|
853
924
|
const storageTypes = { ...storage.types ?? {} };
|
|
@@ -855,7 +926,11 @@ function contractToSchemaIR(contract, options) {
|
|
|
855
926
|
for (const ns of Object.values(storage.namespaces)) for (const [tableName, tableDefRaw] of Object.entries(ns.entries.table ?? {})) {
|
|
856
927
|
StorageTable.assert(tableDefRaw, `namespaces.${ns.id}.entries.table.${tableName}`);
|
|
857
928
|
const tableDef = tableDefRaw;
|
|
858
|
-
if (tables[tableName] !== void 0) throw
|
|
929
|
+
if (tables[tableName] !== void 0) throw sqlFamilyError("CONTRACT.TABLE_AMBIGUOUS", `contractToSchemaIR: duplicate SQL table name "${tableName}" across namespaces (ambiguous for flat SqlSchemaIR.tables).`, {
|
|
930
|
+
why: "Two namespaces declare a table with the same name, which is ambiguous for the flat schema-IR table map.",
|
|
931
|
+
fix: "Rename one of the tables so every table name is unique across namespaces.",
|
|
932
|
+
meta: { table: tableName }
|
|
933
|
+
});
|
|
859
934
|
tables[tableName] = convertTable(tableName, tableDef, storageTypes, options.expandNativeType, options.renderDefault, options.resolveDefault, storage);
|
|
860
935
|
}
|
|
861
936
|
return new SqlSchemaIR({
|