@prisma-next/target-postgres 0.14.0-dev.60 → 0.14.0-dev.62
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/{authoring-WkqG_MkU.mjs → authoring-CdIZ0yvD.mjs} +147 -38
- package/dist/authoring-CdIZ0yvD.mjs.map +1 -0
- package/dist/contract-free.d.mts +1 -1
- package/dist/contract-free.d.mts.map +1 -1
- package/dist/contract-free.mjs +2 -2
- package/dist/{control-policy-Co_13Hxa.mjs → control-policy-DKp0HKpY.mjs} +203 -45
- package/dist/control-policy-DKp0HKpY.mjs.map +1 -0
- package/dist/control.mjs +22 -25
- package/dist/control.mjs.map +1 -1
- package/dist/{ddl-B-krEXY1.mjs → ddl-gmxHf68z.mjs} +20 -4
- package/dist/{ddl-B-krEXY1.mjs.map → ddl-gmxHf68z.mjs.map} +1 -1
- package/dist/ddl.d.mts +2 -2
- package/dist/ddl.mjs +2 -2
- package/dist/{descriptor-meta-BOcKPaLE.mjs → descriptor-meta-DEuXJfpR.mjs} +3 -3
- package/dist/{descriptor-meta-BOcKPaLE.mjs.map → descriptor-meta-DEuXJfpR.mjs.map} +1 -1
- package/dist/{diff-database-schema-BOsDnH64.mjs → diff-database-schema-D2sjvMw9.mjs} +55 -19
- package/dist/diff-database-schema-D2sjvMw9.mjs.map +1 -0
- package/dist/diff-database-schema.d.mts +4 -4
- package/dist/diff-database-schema.d.mts.map +1 -1
- package/dist/diff-database-schema.mjs +1 -1
- package/dist/issue-planner.d.mts +1 -1
- package/dist/issue-planner.d.mts.map +1 -1
- package/dist/issue-planner.mjs +1 -1
- package/dist/migration.d.mts +2 -2
- package/dist/migration.mjs +2 -2
- package/dist/{nodes-BtQyZha6.d.mts → nodes-Bc2N3tMy.d.mts} +27 -3
- package/dist/nodes-Bc2N3tMy.d.mts.map +1 -0
- package/dist/{nodes-B815pj_X.mjs → nodes-DJC5B8Id.mjs} +32 -2
- package/dist/nodes-DJC5B8Id.mjs.map +1 -0
- package/dist/{op-factory-call-DxNNKUeZ.mjs → op-factory-call-C4flTtTG.mjs} +105 -6
- package/dist/op-factory-call-C4flTtTG.mjs.map +1 -0
- package/dist/{op-factory-call-D6_7-7Vc.d.mts → op-factory-call-CSIg5XDu.d.mts} +26 -3
- package/dist/{op-factory-call-D6_7-7Vc.d.mts.map → op-factory-call-CSIg5XDu.d.mts.map} +1 -1
- package/dist/op-factory-call.d.mts +2 -2
- package/dist/op-factory-call.mjs +2 -2
- package/dist/pack.d.mts +146 -3
- package/dist/pack.d.mts.map +1 -1
- package/dist/pack.mjs +1 -1
- package/dist/{planner-CNrc1Odu.mjs → planner-BtEd5LMr.mjs} +32 -64
- package/dist/planner-BtEd5LMr.mjs.map +1 -0
- package/dist/{planner-ddl-builders-B8Nn6nHN.mjs → planner-ddl-builders-BKlmGDJl.mjs} +7 -3
- package/dist/planner-ddl-builders-BKlmGDJl.mjs.map +1 -0
- package/dist/planner-ddl-builders.d.mts.map +1 -1
- package/dist/planner-ddl-builders.mjs +1 -1
- package/dist/{planner-produced-postgres-migration-a-tjfKsA.d.mts → planner-produced-postgres-migration-CXue-6M9.d.mts} +2 -2
- package/dist/{planner-produced-postgres-migration-a-tjfKsA.d.mts.map → planner-produced-postgres-migration-CXue-6M9.d.mts.map} +1 -1
- package/dist/{planner-produced-postgres-migration-NI-oGKcw.mjs → planner-produced-postgres-migration-Jat3hg4u.mjs} +2 -2
- package/dist/{planner-produced-postgres-migration-NI-oGKcw.mjs.map → planner-produced-postgres-migration-Jat3hg4u.mjs.map} +1 -1
- package/dist/planner-produced-postgres-migration.d.mts +1 -1
- package/dist/planner-produced-postgres-migration.mjs +1 -1
- package/dist/{planner-sql-checks-AXoxB1Jl.mjs → planner-sql-checks-Br1c_QsH.mjs} +3 -3
- package/dist/{planner-sql-checks-AXoxB1Jl.mjs.map → planner-sql-checks-Br1c_QsH.mjs.map} +1 -1
- package/dist/planner-sql-checks.mjs +1 -1
- package/dist/planner.d.mts +3 -3
- package/dist/planner.d.mts.map +1 -1
- package/dist/planner.mjs +2 -2
- package/dist/{postgres-contract-view-Dg-N7KA7.mjs → postgres-contract-view-BAPW0ec1.mjs} +3 -3
- package/dist/{postgres-contract-view-Dg-N7KA7.mjs.map → postgres-contract-view-BAPW0ec1.mjs.map} +1 -1
- package/dist/{postgres-database-schema-node-CfdTY-Qs.d.mts → postgres-database-schema-node-CJv5bfbs.d.mts} +70 -26
- package/dist/postgres-database-schema-node-CJv5bfbs.d.mts.map +1 -0
- package/dist/{postgres-migration-ChyRsWvE.mjs → postgres-migration-ChLMQRd-.mjs} +19 -3
- package/dist/postgres-migration-ChLMQRd-.mjs.map +1 -0
- package/dist/{postgres-migration-Bzzi0Asr.d.mts → postgres-migration-DkmgGNcv.d.mts} +21 -2
- package/dist/postgres-migration-DkmgGNcv.d.mts.map +1 -0
- package/dist/{postgres-role-schema-node-BiSTCTNg.mjs → postgres-role-schema-node-Cm-j0ZGM.mjs} +20 -25
- package/dist/postgres-role-schema-node-Cm-j0ZGM.mjs.map +1 -0
- package/dist/{postgres-schema-DTLA_aRi.mjs → postgres-schema-DWQ0-CPb.mjs} +32 -4
- package/dist/postgres-schema-DWQ0-CPb.mjs.map +1 -0
- package/dist/{postgres-schema-CU4gF6QZ.d.mts → postgres-schema-DsrtYp2v.d.mts} +13 -1
- package/dist/postgres-schema-DsrtYp2v.d.mts.map +1 -0
- package/dist/{postgres-table-schema-node-9FCtCUz2.mjs → postgres-table-schema-node-D6LvInCe.mjs} +71 -8
- package/dist/postgres-table-schema-node-D6LvInCe.mjs.map +1 -0
- package/dist/{resolve-ddl-schema-Ca88Tg6W.mjs → resolve-ddl-schema-CAza65Iy.mjs} +2 -2
- package/dist/{resolve-ddl-schema-Ca88Tg6W.mjs.map → resolve-ddl-schema-CAza65Iy.mjs.map} +1 -1
- package/dist/runtime.mjs +1 -1
- package/dist/schema-ir-annotations.mjs +1 -1
- package/dist/{sql-utils-DcfMz4MQ.mjs → sql-utils-SU4FDvIV.mjs} +12 -3
- package/dist/{sql-utils-DcfMz4MQ.mjs.map → sql-utils-SU4FDvIV.mjs.map} +1 -1
- package/dist/sql-utils.d.mts +8 -1
- package/dist/sql-utils.d.mts.map +1 -1
- package/dist/sql-utils.mjs +2 -2
- package/dist/types.d.mts +3 -3
- package/dist/types.mjs +4 -4
- package/package.json +20 -20
- package/src/contract-free/ddl.ts +27 -0
- package/src/core/authoring.ts +136 -25
- package/src/core/ddl/nodes.ts +44 -0
- package/src/core/migrations/contract-to-postgres-database-schema-node.ts +12 -1
- package/src/core/migrations/control-policy.ts +172 -45
- package/src/core/migrations/diff-database-schema.ts +48 -13
- package/src/core/migrations/issue-planner.ts +77 -4
- package/src/core/migrations/op-factory-call.ts +84 -0
- package/src/core/migrations/operations/native-enum-types.ts +62 -0
- package/src/core/migrations/planner-ddl-builders.ts +12 -2
- package/src/core/migrations/planner.ts +30 -62
- package/src/core/migrations/postgres-migration.ts +31 -0
- package/src/core/migrations/verify-postgres-namespaces.ts +0 -1
- package/src/core/postgres-role.ts +22 -0
- package/src/core/postgres-schema.ts +22 -1
- package/src/core/postgres-validators.ts +1 -0
- package/src/core/psl-infer/infer-psl-contract.ts +7 -16
- package/src/core/schema-ir/node-storage-coordinate.ts +26 -0
- package/src/core/schema-ir/postgres-database-schema-node.ts +5 -4
- package/src/core/schema-ir/postgres-namespace-schema-node.ts +18 -27
- package/src/core/schema-ir/postgres-native-enum-schema-node.ts +83 -0
- package/src/core/schema-ir/postgres-role-schema-node.ts +4 -2
- package/src/core/schema-ir/schema-node-kinds.ts +19 -3
- package/src/core/sql-utils.ts +15 -2
- package/src/exports/ddl.ts +2 -0
- package/src/exports/op-factory-call.ts +2 -0
- package/src/exports/sql-utils.ts +1 -0
- package/src/exports/types.ts +4 -1
- package/dist/authoring-WkqG_MkU.mjs.map +0 -1
- package/dist/control-policy-Co_13Hxa.mjs.map +0 -1
- package/dist/diff-database-schema-BOsDnH64.mjs.map +0 -1
- package/dist/nodes-B815pj_X.mjs.map +0 -1
- package/dist/nodes-BtQyZha6.d.mts.map +0 -1
- package/dist/op-factory-call-DxNNKUeZ.mjs.map +0 -1
- package/dist/planner-CNrc1Odu.mjs.map +0 -1
- package/dist/planner-ddl-builders-B8Nn6nHN.mjs.map +0 -1
- package/dist/postgres-database-schema-node-CfdTY-Qs.d.mts.map +0 -1
- package/dist/postgres-migration-Bzzi0Asr.d.mts.map +0 -1
- package/dist/postgres-migration-ChyRsWvE.mjs.map +0 -1
- package/dist/postgres-role-schema-node-BiSTCTNg.mjs.map +0 -1
- package/dist/postgres-schema-CU4gF6QZ.d.mts.map +0 -1
- package/dist/postgres-schema-DTLA_aRi.mjs.map +0 -1
- package/dist/postgres-table-schema-node-9FCtCUz2.mjs.map +0 -1
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { r as isPostgresSchema } from "./postgres-schema-
|
|
2
|
-
import { i as quoteIdentifier } from "./sql-utils-
|
|
3
|
-
import { n as PostgresSchemaNodeKind, t as PostgresTableSchemaNode } from "./postgres-table-schema-node-
|
|
4
|
-
import { A as
|
|
5
|
-
import { t as buildExpectedFormatType } from "./planner-sql-checks-
|
|
6
|
-
import { n as buildColumnTypeSql, t as buildColumnDefaultSql } from "./planner-ddl-builders-
|
|
1
|
+
import { r as isPostgresSchema } from "./postgres-schema-DWQ0-CPb.mjs";
|
|
2
|
+
import { i as quoteIdentifier } from "./sql-utils-SU4FDvIV.mjs";
|
|
3
|
+
import { n as PostgresNativeEnumSchemaNode, o as postgresNodeEntityKind, r as PostgresSchemaNodeKind, t as PostgresTableSchemaNode } from "./postgres-table-schema-node-D6LvInCe.mjs";
|
|
4
|
+
import { A as SetNotNullCall, C as DropNotNullCall, D as RawSqlCall, E as EnableRowLevelSecurityCall, M as buildTargetDetails, S as DropNativeEnumTypeCall, T as DropTableCall, _ as DropCheckConstraintCall, a as AddNotNullColumnWithTempDefaultCall, b as DropDefaultCall, c as AlterColumnTypeCall, d as CreateNativeEnumTypeCall, g as DisableRowLevelSecurityCall, h as DataTransformCall, i as AddNotNullColumnDirectCall, j as postgresDefaultToDdlColumnDefault, k as SetDefaultCall, m as CreateTableCall, n as AddColumnCall, o as AddPrimaryKeyCall, p as CreateSchemaCall, r as AddForeignKeyCall, s as AddUniqueCall, t as AddCheckConstraintCall, u as CreateIndexCall, v as DropColumnCall, x as DropIndexCall, y as DropConstraintCall } from "./op-factory-call-C4flTtTG.mjs";
|
|
5
|
+
import { t as buildExpectedFormatType } from "./planner-sql-checks-Br1c_QsH.mjs";
|
|
6
|
+
import { n as buildColumnTypeSql, t as buildColumnDefaultSql } from "./planner-ddl-builders-BKlmGDJl.mjs";
|
|
7
7
|
import { n as resolveIdentityValue } from "./planner-identity-values-CJPha2Sz.mjs";
|
|
8
8
|
import { i as hasUniqueConstraint, n as hasForeignKey, t as buildSchemaLookupMap } from "./planner-schema-lookup-CiVaAQP-.mjs";
|
|
9
9
|
import { UNBOUND_NAMESPACE_ID, entityAt } from "@prisma-next/framework-components/ir";
|
|
@@ -15,6 +15,31 @@ import * as contractFree from "@prisma-next/sql-relational-core/contract-free";
|
|
|
15
15
|
import { RelationalSchemaNodeKind, SqlSchemaIR } from "@prisma-next/sql-schema-ir/types";
|
|
16
16
|
import { defaultIndexName } from "@prisma-next/sql-schema-ir/naming";
|
|
17
17
|
import { notOk, ok } from "@prisma-next/utils/result";
|
|
18
|
+
//#region src/core/schema-ir/node-storage-coordinate.ts
|
|
19
|
+
/**
|
|
20
|
+
* The storage-`entries` coordinate `(entityKind, entityName)` a Postgres diff
|
|
21
|
+
* node addresses — a table by its name, a native enum by its physical type
|
|
22
|
+
* name. `undefined` for a node that is not a whole storage entity (a namespace,
|
|
23
|
+
* a column, a policy). Lets ownership/subject resolution treat every entity kind
|
|
24
|
+
* uniformly, the node self-describing its storage identity.
|
|
25
|
+
*/
|
|
26
|
+
function postgresNodeStorageCoordinate(node) {
|
|
27
|
+
if (PostgresTableSchemaNode.is(node)) {
|
|
28
|
+
const entityKind = postgresNodeEntityKind(node.nodeKind);
|
|
29
|
+
return entityKind === void 0 ? void 0 : {
|
|
30
|
+
entityKind,
|
|
31
|
+
entityName: node.name
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
if (PostgresNativeEnumSchemaNode.is(node)) {
|
|
35
|
+
const entityKind = postgresNodeEntityKind(node.nodeKind);
|
|
36
|
+
return entityKind === void 0 ? void 0 : {
|
|
37
|
+
entityKind,
|
|
38
|
+
entityName: node.typeName
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
//#endregion
|
|
18
43
|
//#region src/core/migrations/column-ddl-rendering.ts
|
|
19
44
|
/**
|
|
20
45
|
* Reconstructs the `StorageColumn`-shaped fields the DDL builder functions
|
|
@@ -542,8 +567,10 @@ function issueConflict(kind, summary, location) {
|
|
|
542
567
|
function classifyCall(call) {
|
|
543
568
|
switch (call.factoryName) {
|
|
544
569
|
case "createExtension":
|
|
545
|
-
case "createSchema":
|
|
570
|
+
case "createSchema":
|
|
571
|
+
case "createNativeEnumType": return "dep";
|
|
546
572
|
case "dropTable":
|
|
573
|
+
case "dropNativeEnumType":
|
|
547
574
|
case "dropColumn":
|
|
548
575
|
case "dropConstraint":
|
|
549
576
|
case "dropCheckConstraint":
|
|
@@ -594,11 +621,16 @@ function conflictKindForCall(call) {
|
|
|
594
621
|
function locationForCall(call) {
|
|
595
622
|
const anyCall = call;
|
|
596
623
|
const location = {};
|
|
597
|
-
if (anyCall.tableName)
|
|
624
|
+
if (anyCall.tableName) {
|
|
625
|
+
location.entityKind = "table";
|
|
626
|
+
location.entityName = anyCall.tableName;
|
|
627
|
+
} else if (anyCall.typeName) {
|
|
628
|
+
location.entityKind = "native_enum";
|
|
629
|
+
location.entityName = anyCall.typeName;
|
|
630
|
+
}
|
|
598
631
|
if (anyCall.columnName) location.column = anyCall.columnName;
|
|
599
632
|
if (anyCall.indexName) location.index = anyCall.indexName;
|
|
600
633
|
if (anyCall.constraintName) location.constraint = anyCall.constraintName;
|
|
601
|
-
if (anyCall.typeName) location.type = anyCall.typeName;
|
|
602
634
|
return Object.keys(location).length > 0 ? location : void 0;
|
|
603
635
|
}
|
|
604
636
|
function conflictForDisallowedCall(call, allowed) {
|
|
@@ -674,6 +706,7 @@ function nodeIssueOrder(issue) {
|
|
|
674
706
|
if (node === void 0) return 99;
|
|
675
707
|
switch (node.nodeKind) {
|
|
676
708
|
case PostgresSchemaNodeKind.namespace: return 1;
|
|
709
|
+
case PostgresSchemaNodeKind.nativeEnum: return issue.reason === "not-expected" ? 17 : 2;
|
|
677
710
|
case RelationalSchemaNodeKind.foreignKey: return issue.reason === "not-expected" ? 10 : 60;
|
|
678
711
|
case RelationalSchemaNodeKind.unique: return issue.reason === "not-expected" ? 11 : 51;
|
|
679
712
|
case RelationalSchemaNodeKind.primaryKey: return issue.reason === "not-expected" ? 12 : 50;
|
|
@@ -759,6 +792,27 @@ function buildCreateTableCallsFromNode(schemaName, ddlSchemaName, table, codecHo
|
|
|
759
792
|
function nodeConflict(kind, message) {
|
|
760
793
|
return issueConflict(kind, message);
|
|
761
794
|
}
|
|
795
|
+
/**
|
|
796
|
+
* Managed native-enum issue -> op lowering. A missing declared type creates
|
|
797
|
+
* it; an unclaimed live type drops it (ownership-scoped upstream by
|
|
798
|
+
* `retainUnownedExtras`, destructiveness gated by the operation-class
|
|
799
|
+
* policy); a paired member-value mismatch is a NAMED unsupported diagnostic
|
|
800
|
+
* — never a silent no-op and never a drop-and-recreate. Slice B replaces the
|
|
801
|
+
* diagnostic with order-aware `ALTER TYPE ... ADD VALUE` / refusal semantics.
|
|
802
|
+
*/
|
|
803
|
+
function mapNativeEnumNodeIssue(issue, ctx) {
|
|
804
|
+
const ddlSchemaName = issueSchemaName(issue);
|
|
805
|
+
if (ddlSchemaName === void 0) return notOk(nodeConflict("unsupportedOperation", `Enum issue has no schema in its path: ${issue.path.join("/")}`));
|
|
806
|
+
const schemaName = emissionSchemaName(ctx, ddlSchemaName);
|
|
807
|
+
if (issue.reason === "not-found") {
|
|
808
|
+
const expected = blindCast(issue.expected);
|
|
809
|
+
return ok([new CreateNativeEnumTypeCall(schemaName, expected.typeName, expected.members)]);
|
|
810
|
+
}
|
|
811
|
+
if (issue.reason === "not-expected") return ok([new DropNativeEnumTypeCall(schemaName, blindCast(issue.actual).typeName)]);
|
|
812
|
+
const expected = blindCast(issue.expected);
|
|
813
|
+
const actualMembers = blindCast(issue.actual).members;
|
|
814
|
+
return notOk(nodeConflict("unsupportedOperation", `Native enum type "${ddlSchemaName}"."${expected.typeName}" member values changed (contract declares [${expected.members.join(", ")}], database has [${actualMembers.join(", ")}]); enum value changes are not auto-migrated yet. Author the change manually with \`migration new\`.`));
|
|
815
|
+
}
|
|
762
816
|
function mapTableNodeIssue(issue, schemaName, ddlSchemaName, codecHooks) {
|
|
763
817
|
if (issue.reason === "not-found") return ok(buildCreateTableCallsFromNode(schemaName, ddlSchemaName, blindCast(issue.expected), codecHooks));
|
|
764
818
|
if (issue.reason === "not-expected") return ok([new DropTableCall(schemaName, blindCast(issue.actual).name)]);
|
|
@@ -853,6 +907,7 @@ function mapNodeIssueToCall(issue, ctx) {
|
|
|
853
907
|
if (issue.reason !== "not-found") return notOk(nodeConflict("unsupportedOperation", `Unexpected namespace drift: ${issue.path.join("/")}`));
|
|
854
908
|
return ok([new CreateSchemaCall(blindCast(issue.expected).schemaName)]);
|
|
855
909
|
}
|
|
910
|
+
if (node.nodeKind === PostgresSchemaNodeKind.nativeEnum) return mapNativeEnumNodeIssue(issue, ctx);
|
|
856
911
|
const ddlSchemaName = issueSchemaName(issue);
|
|
857
912
|
const tableName = issueTableName(issue);
|
|
858
913
|
if (ddlSchemaName === void 0 || tableName === void 0) return notOk(nodeConflict("unsupportedOperation", `Issue has no schema/table in its path: ${issue.path.join("/")}`));
|
|
@@ -972,13 +1027,16 @@ function planIssues(options) {
|
|
|
972
1027
|
* and is fail-closed. Any call not listed here — including future or
|
|
973
1028
|
* extension-contributed factories — is treated as NOT object-creation, so it
|
|
974
1029
|
* is suppressed under `tolerated` rather than permissively emitted.
|
|
1030
|
+
*
|
|
1031
|
+
* Lists the creation factories that actually reach the call-side resolver
|
|
1032
|
+
* (`resolvePostgresCallControlPolicySubject`) — today only RLS policy
|
|
1033
|
+
* creation, from `planPostgresSchemaDiff`. Every other whole-object create
|
|
1034
|
+
* (table, schema, native enum, and RLS enablement) is constructed inside
|
|
1035
|
+
* `planIssues` and graded on the node side by
|
|
1036
|
+
* `resolvePostgresNodeIssueCreationFactoryName`, so none of them are listed
|
|
1037
|
+
* here.
|
|
975
1038
|
*/
|
|
976
|
-
const OBJECT_CREATION_FACTORIES = new Set([
|
|
977
|
-
"createTable",
|
|
978
|
-
"createSchema",
|
|
979
|
-
"createRlsPolicy",
|
|
980
|
-
"enableRowLevelSecurity"
|
|
981
|
-
]);
|
|
1039
|
+
const OBJECT_CREATION_FACTORIES = new Set(["createRlsPolicy"]);
|
|
982
1040
|
function createsNewTopLevelObject(call) {
|
|
983
1041
|
return OBJECT_CREATION_FACTORIES.has(call.factoryName);
|
|
984
1042
|
}
|
|
@@ -986,17 +1044,33 @@ function ddlSchemaNameForNamespace(contract, namespaceId) {
|
|
|
986
1044
|
const namespace = contract.storage.namespaces[namespaceId];
|
|
987
1045
|
return isPostgresSchema(namespace) ? namespace.ddlSchemaName(contract.storage) : namespaceId;
|
|
988
1046
|
}
|
|
989
|
-
|
|
1047
|
+
/**
|
|
1048
|
+
* Resolve the namespace a declared storage entity lives in by walking every
|
|
1049
|
+
* namespace for one whose `entries` map actually contains the coordinate —
|
|
1050
|
+
* a table by its name, a native enum by its physical type name (see
|
|
1051
|
+
* {@link postgresNodeStorageCoordinate}). When `ddlSchemaName` is given, the
|
|
1052
|
+
* match must also land in that DDL schema (disambiguates same-named entities
|
|
1053
|
+
* declared under different namespaces); when omitted, the first namespace
|
|
1054
|
+
* that declares the entity wins. Falls back to {@link UNBOUND_NAMESPACE_ID}
|
|
1055
|
+
* when no namespace declares it — e.g. an extra/dropped entity the contract
|
|
1056
|
+
* doesn't claim at all.
|
|
1057
|
+
*/
|
|
1058
|
+
function resolveNamespaceIdForEntity(contract, coordinate, ddlSchemaName) {
|
|
990
1059
|
for (const namespaceId of Object.keys(contract.storage.namespaces)) {
|
|
991
1060
|
if (!entityAt(contract.storage, {
|
|
992
1061
|
namespaceId,
|
|
993
|
-
|
|
994
|
-
entityName: tableName
|
|
1062
|
+
...coordinate
|
|
995
1063
|
})) continue;
|
|
996
1064
|
if (ddlSchemaName === void 0 || ddlSchemaNameForNamespace(contract, namespaceId) === ddlSchemaName) return namespaceId;
|
|
997
1065
|
}
|
|
998
1066
|
return UNBOUND_NAMESPACE_ID;
|
|
999
1067
|
}
|
|
1068
|
+
function resolveNamespaceIdForTable(contract, tableName, ddlSchemaName) {
|
|
1069
|
+
return resolveNamespaceIdForEntity(contract, {
|
|
1070
|
+
entityKind: "table",
|
|
1071
|
+
entityName: tableName
|
|
1072
|
+
}, ddlSchemaName);
|
|
1073
|
+
}
|
|
1000
1074
|
function resolveNamespaceIdForDdlSchema(contract, ddlSchemaName) {
|
|
1001
1075
|
for (const namespaceId of Object.keys(contract.storage.namespaces)) {
|
|
1002
1076
|
const ns = contract.storage.namespaces[namespaceId];
|
|
@@ -1012,9 +1086,42 @@ function postgresCallFields(call) {
|
|
|
1012
1086
|
...ifDefined("columnName", "columnName" in call ? call.columnName : void 0)
|
|
1013
1087
|
};
|
|
1014
1088
|
}
|
|
1015
|
-
function
|
|
1016
|
-
if (subject
|
|
1017
|
-
|
|
1089
|
+
function formatSuppressionSubjectLabel(subject, contract) {
|
|
1090
|
+
if (subject === void 0) return "unknown";
|
|
1091
|
+
const ddlSchema = ddlSchemaNameForNamespace(contract, subject.namespaceId);
|
|
1092
|
+
if (subject.entityKind !== void 0 && subject.entityName !== void 0) return `${subject.entityKind} "${ddlSchema}.${subject.entityName}"`;
|
|
1093
|
+
return `namespace "${ddlSchema}"`;
|
|
1094
|
+
}
|
|
1095
|
+
function postgresSuppressionSummary(subjectLabel, subject, policy) {
|
|
1096
|
+
const namespace = subject?.namespaceId ?? "unknown";
|
|
1097
|
+
const declared = subject?.explicitNodeControlPolicy;
|
|
1098
|
+
if (policy === "external" && declared === "managed") return `control policy suppressed: ${subjectLabel} — namespace '${namespace}' has effective control 'external' but declared 'managed'`;
|
|
1099
|
+
return `control policy suppressed: ${subjectLabel} — namespace '${namespace}' has effective control '${policy}'${declared ? ` but declared '${declared}'` : ""}`;
|
|
1100
|
+
}
|
|
1101
|
+
/**
|
|
1102
|
+
* Render one family {@link SuppressionRecord} into a target `SqlPlannerConflict`.
|
|
1103
|
+
* The family decides *that* a subject is suppressed and hands over the raw
|
|
1104
|
+
* coordinate + policy; the label, message, and location are rendered here,
|
|
1105
|
+
* driven entirely by the subject's own `(entityKind, entityName)` coordinate
|
|
1106
|
+
* — no target-owned table-vs-enum vocabulary.
|
|
1107
|
+
*/
|
|
1108
|
+
function renderPostgresSuppression(record, contract) {
|
|
1109
|
+
const subject = record.subject;
|
|
1110
|
+
return {
|
|
1111
|
+
kind: "controlPolicySuppressedCall",
|
|
1112
|
+
summary: postgresSuppressionSummary(formatSuppressionSubjectLabel(subject, contract), subject, record.policy),
|
|
1113
|
+
location: {
|
|
1114
|
+
...ifDefined("namespaceId", subject?.namespaceId),
|
|
1115
|
+
...ifDefined("entityKind", subject?.entityKind),
|
|
1116
|
+
...ifDefined("entityName", subject?.entityName),
|
|
1117
|
+
...ifDefined("column", subject?.column)
|
|
1118
|
+
},
|
|
1119
|
+
meta: {
|
|
1120
|
+
controlPolicy: record.policy,
|
|
1121
|
+
...ifDefined("factoryName", record.factoryName),
|
|
1122
|
+
...ifDefined("declaredControlPolicy", subject?.explicitNodeControlPolicy)
|
|
1123
|
+
}
|
|
1124
|
+
};
|
|
1018
1125
|
}
|
|
1019
1126
|
function resolvePostgresCallControlPolicySubject(call, contract) {
|
|
1020
1127
|
const callFields = postgresCallFields(call);
|
|
@@ -1032,9 +1139,10 @@ function resolvePostgresCallControlPolicySubject(call, contract) {
|
|
|
1032
1139
|
})?.control;
|
|
1033
1140
|
return {
|
|
1034
1141
|
namespaceId,
|
|
1035
|
-
|
|
1036
|
-
|
|
1142
|
+
entityKind: "table",
|
|
1143
|
+
entityName: callFields.tableName,
|
|
1037
1144
|
...ifDefined("column", callFields.columnName),
|
|
1145
|
+
...ifDefined("explicitNodeControlPolicy", tableControlPolicy),
|
|
1038
1146
|
createsNewObject
|
|
1039
1147
|
};
|
|
1040
1148
|
}
|
|
@@ -1044,10 +1152,10 @@ function resolvePostgresCallControlPolicySubject(call, contract) {
|
|
|
1044
1152
|
};
|
|
1045
1153
|
}
|
|
1046
1154
|
/**
|
|
1047
|
-
* Node kinds
|
|
1048
|
-
* object
|
|
1049
|
-
*
|
|
1050
|
-
*
|
|
1155
|
+
* Node kinds whose *absence* is the creation of a whole, top-level Postgres
|
|
1156
|
+
* object: a namespace, a table, or a native enum. Used by
|
|
1157
|
+
* {@link resolvePostgresNodeIssueCreationFactoryName} to decide whether a
|
|
1158
|
+
* `tolerated` subject permits the issue to flow into the planner
|
|
1051
1159
|
* (create-if-absent) and to seed the suppressed-subject warning's
|
|
1052
1160
|
* `factoryName` when the planner is skipped. RLS policy creation is not
|
|
1053
1161
|
* listed here — policy issues never reach this issue-based partition (they
|
|
@@ -1056,13 +1164,15 @@ function resolvePostgresCallControlPolicySubject(call, contract) {
|
|
|
1056
1164
|
*/
|
|
1057
1165
|
const POSTGRES_NODE_CREATION_FACTORY = Object.freeze({
|
|
1058
1166
|
[PostgresSchemaNodeKind.namespace]: "createSchema",
|
|
1059
|
-
[PostgresSchemaNodeKind.table]: "createTable"
|
|
1167
|
+
[PostgresSchemaNodeKind.table]: "createTable",
|
|
1168
|
+
[PostgresSchemaNodeKind.nativeEnum]: "createNativeEnumType"
|
|
1060
1169
|
});
|
|
1061
1170
|
/**
|
|
1062
1171
|
* A table `not-equal` issue whose `rlsEnabled` flips OFF→ON (expected on,
|
|
1063
|
-
* actual off) is enablement toward `ENABLE ROW LEVEL SECURITY
|
|
1064
|
-
* creation-class
|
|
1065
|
-
*
|
|
1172
|
+
* actual off) is enablement toward `ENABLE ROW LEVEL SECURITY`. It is
|
|
1173
|
+
* creation-class on the node side because `isEnablementCreationIssue` and
|
|
1174
|
+
* {@link resolvePostgresNodeIssueCreationFactoryName} treat this OFF→ON delta
|
|
1175
|
+
* as a creation: enabling RLS establishes the fail-closed guard the declared
|
|
1066
1176
|
* policy set attaches to, the same grant `tolerated` extends to creating the
|
|
1067
1177
|
* policies themselves. The opposite direction (`DISABLE`) is a modification
|
|
1068
1178
|
* and stays managed-only. Keying on the actual delta (not just the expected
|
|
@@ -1087,15 +1197,36 @@ function resolvePostgresNodeIssueCreationFactoryName(issue) {
|
|
|
1087
1197
|
* {@link SchemaDiffIssue}. Mirrors the resolution
|
|
1088
1198
|
* `resolvePostgresCallControlPolicySubject` performs for a generated DDL
|
|
1089
1199
|
* call, but works *off the issue* — so the planner can partition issues by
|
|
1090
|
-
* effective policy before the diff engine runs.
|
|
1091
|
-
*
|
|
1092
|
-
*
|
|
1200
|
+
* effective policy before the diff engine runs.
|
|
1201
|
+
*
|
|
1202
|
+
* A whole storage entity (table or native enum) resolves generically off
|
|
1203
|
+
* {@link postgresNodeStorageCoordinate} — the node self-describes its
|
|
1204
|
+
* `(entityKind, entityName)`, so table and enum issues share one code path
|
|
1205
|
+
* with no per-kind branch. A sub-entity issue (a column/constraint drift
|
|
1206
|
+
* inside an owned table) carries no such coordinate on its own node, so it
|
|
1207
|
+
* falls back to reading the enclosing table name off the issue path.
|
|
1208
|
+
*
|
|
1209
|
+
* `createsNewObject` is delegated to {@link resolvePostgresNodeIssueCreationFactoryName}
|
|
1210
|
+
* in every branch below — that function already encodes exactly which
|
|
1211
|
+
* node-kind/reason combinations describe a brand-new top-level object
|
|
1212
|
+
* (a `not-found` table/enum, or an RLS-enablement `not-equal`).
|
|
1213
|
+
*
|
|
1214
|
+
* A `not-expected` (extra/dropped) entity carries no contract namespace
|
|
1215
|
+
* coordinate — the live object isn't claimed by any contract namespace — so
|
|
1216
|
+
* the subject's `namespaceId` falls back to {@link UNBOUND_NAMESPACE_ID} via
|
|
1217
|
+
* `resolveNamespaceIdForEntity`'s own fallback, matching how the call-side
|
|
1218
|
+
* resolver treats the `DropTableCall`/`DropNativeEnumTypeCall` it produces.
|
|
1093
1219
|
*
|
|
1094
|
-
* A
|
|
1095
|
-
*
|
|
1096
|
-
*
|
|
1097
|
-
* `
|
|
1098
|
-
*
|
|
1220
|
+
* A role node resolves against the `PostgresRole` contract entity at that
|
|
1221
|
+
* role's name (roles are root-level diff subjects, so the name is the
|
|
1222
|
+
* second path segment after the tree root). A `not-found` role is declared,
|
|
1223
|
+
* so the entity is always found and its `control` read directly — which is
|
|
1224
|
+
* always {@link ROLE_DEFAULT_CONTROL_POLICY} today, since no authoring
|
|
1225
|
+
* surface sets it otherwise. A `not-expected` role has no contract entity
|
|
1226
|
+
* (an undeclared live role, by definition), so the subject falls back to
|
|
1227
|
+
* the same default — roles are referenced but never owned, so an
|
|
1228
|
+
* undeclared role gets exactly the same governance as a declared one.
|
|
1229
|
+
* Never creates a new object: role provisioning is a non-goal.
|
|
1099
1230
|
*/
|
|
1100
1231
|
function resolvePostgresNodeIssueControlPolicySubject(issue, contract) {
|
|
1101
1232
|
const node = issue.expected ?? issue.actual;
|
|
@@ -1104,6 +1235,33 @@ function resolvePostgresNodeIssueControlPolicySubject(issue, contract) {
|
|
|
1104
1235
|
namespaceId: resolveNamespaceIdForDdlSchema(contract, blindCast(node).schemaName),
|
|
1105
1236
|
createsNewObject: issue.reason === "not-found"
|
|
1106
1237
|
};
|
|
1238
|
+
if (node.nodeKind === PostgresSchemaNodeKind.role) {
|
|
1239
|
+
const roleName = issue.path[1];
|
|
1240
|
+
return {
|
|
1241
|
+
namespaceId: UNBOUND_NAMESPACE_ID,
|
|
1242
|
+
explicitNodeControlPolicy: (roleName === void 0 ? void 0 : entityAt(contract.storage, {
|
|
1243
|
+
namespaceId: UNBOUND_NAMESPACE_ID,
|
|
1244
|
+
entityKind: "role",
|
|
1245
|
+
entityName: roleName
|
|
1246
|
+
}))?.control ?? "external",
|
|
1247
|
+
createsNewObject: false
|
|
1248
|
+
};
|
|
1249
|
+
}
|
|
1250
|
+
const coordinate = postgresNodeStorageCoordinate(node);
|
|
1251
|
+
if (coordinate !== void 0) {
|
|
1252
|
+
const namespaceId = resolveNamespaceIdForEntity(contract, coordinate, issue.path[1]);
|
|
1253
|
+
const entityControl = entityAt(contract.storage, {
|
|
1254
|
+
namespaceId,
|
|
1255
|
+
...coordinate
|
|
1256
|
+
})?.control;
|
|
1257
|
+
return {
|
|
1258
|
+
namespaceId,
|
|
1259
|
+
...coordinate,
|
|
1260
|
+
...ifDefined("column", issueColumnName(issue)),
|
|
1261
|
+
...ifDefined("explicitNodeControlPolicy", entityControl),
|
|
1262
|
+
createsNewObject: resolvePostgresNodeIssueCreationFactoryName(issue) !== void 0
|
|
1263
|
+
};
|
|
1264
|
+
}
|
|
1107
1265
|
const tableName = issue.path[2];
|
|
1108
1266
|
if (tableName === void 0) return void 0;
|
|
1109
1267
|
const ddlSchemaName = issue.path[1];
|
|
@@ -1113,16 +1271,16 @@ function resolvePostgresNodeIssueControlPolicySubject(issue, contract) {
|
|
|
1113
1271
|
entityKind: "table",
|
|
1114
1272
|
entityName: tableName
|
|
1115
1273
|
});
|
|
1116
|
-
const createsNewObject = node.nodeKind === PostgresSchemaNodeKind.table && issue.reason === "not-found" || isEnablementCreationIssue(issue);
|
|
1117
1274
|
return {
|
|
1118
1275
|
namespaceId,
|
|
1119
|
-
|
|
1120
|
-
|
|
1276
|
+
entityKind: "table",
|
|
1277
|
+
entityName: tableName,
|
|
1121
1278
|
...ifDefined("column", issueColumnName(issue)),
|
|
1122
|
-
|
|
1279
|
+
...ifDefined("explicitNodeControlPolicy", table?.control),
|
|
1280
|
+
createsNewObject: resolvePostgresNodeIssueCreationFactoryName(issue) !== void 0
|
|
1123
1281
|
};
|
|
1124
1282
|
}
|
|
1125
1283
|
//#endregion
|
|
1126
|
-
export { resolvePostgresNodeIssueCreationFactoryName as a, issueSchemaName as c,
|
|
1284
|
+
export { resolvePostgresNodeIssueCreationFactoryName as a, issueSchemaName as c, postgresNodeStorageCoordinate as d, resolvePostgresNodeIssueControlPolicySubject as i, planIssues as l, resolveNamespaceIdForDdlSchema as n, coalesceSubtreeIssues as o, resolvePostgresCallControlPolicySubject as r, issueNode as s, renderPostgresSuppression as t, postgresPlannerStrategies as u };
|
|
1127
1285
|
|
|
1128
|
-
//# sourceMappingURL=control-policy-
|
|
1286
|
+
//# sourceMappingURL=control-policy-DKp0HKpY.mjs.map
|