@prisma-next/target-postgres 0.14.0-dev.22 → 0.14.0-dev.24

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.
Files changed (96) hide show
  1. package/dist/contract-free.mjs +2 -2
  2. package/dist/control.d.mts.map +1 -1
  3. package/dist/control.mjs +8 -7
  4. package/dist/control.mjs.map +1 -1
  5. package/dist/{ddl-BJPdPsT3.mjs → ddl-CGf6UABz.mjs} +2 -2
  6. package/dist/{ddl-BJPdPsT3.mjs.map → ddl-CGf6UABz.mjs.map} +1 -1
  7. package/dist/{descriptor-meta-CKpjK2Nv.mjs → descriptor-meta-Dvvpu_jU.mjs} +3 -3
  8. package/dist/{descriptor-meta-CKpjK2Nv.mjs.map → descriptor-meta-Dvvpu_jU.mjs.map} +1 -1
  9. package/dist/{descriptor-meta-runtime-DiVla56r.mjs → descriptor-meta-runtime-D5zHFKUz.mjs} +2 -2
  10. package/dist/descriptor-meta-runtime-D5zHFKUz.mjs.map +1 -0
  11. package/dist/{issue-planner-YwXUKGZ1.mjs → issue-planner-D5H1VuVP.mjs} +4 -4
  12. package/dist/{issue-planner-YwXUKGZ1.mjs.map → issue-planner-D5H1VuVP.mjs.map} +1 -1
  13. package/dist/issue-planner.d.mts +2 -2
  14. package/dist/issue-planner.mjs +1 -1
  15. package/dist/migration.d.mts +2 -2
  16. package/dist/migration.mjs +2 -2
  17. package/dist/{op-factory-call-DcY4BHNh.mjs → op-factory-call-DIdBDwmO.mjs} +3 -3
  18. package/dist/op-factory-call-DIdBDwmO.mjs.map +1 -0
  19. package/dist/{op-factory-call-CQ4P40QC.d.mts → op-factory-call-DPJR7tJc.d.mts} +3 -3
  20. package/dist/{op-factory-call-CQ4P40QC.d.mts.map → op-factory-call-DPJR7tJc.d.mts.map} +1 -1
  21. package/dist/op-factory-call.d.mts +1 -1
  22. package/dist/op-factory-call.mjs +1 -1
  23. package/dist/pack.d.mts +2 -3
  24. package/dist/pack.d.mts.map +1 -1
  25. package/dist/pack.mjs +1 -1
  26. package/dist/{planner-_ZHpIQ1-.mjs → planner-BnNEtGYM.mjs} +116 -76
  27. package/dist/planner-BnNEtGYM.mjs.map +1 -0
  28. package/dist/{planner-produced-postgres-migration-CNTSCMl7.d.mts → planner-produced-postgres-migration-BO-frvvN.d.mts} +2 -2
  29. package/dist/{planner-produced-postgres-migration-CNTSCMl7.d.mts.map → planner-produced-postgres-migration-BO-frvvN.d.mts.map} +1 -1
  30. package/dist/{planner-produced-postgres-migration-Dv5ZAvHt.mjs → planner-produced-postgres-migration-DzvdQ-7K.mjs} +2 -2
  31. package/dist/{planner-produced-postgres-migration-Dv5ZAvHt.mjs.map → planner-produced-postgres-migration-DzvdQ-7K.mjs.map} +1 -1
  32. package/dist/planner-produced-postgres-migration.d.mts +1 -1
  33. package/dist/planner-produced-postgres-migration.mjs +1 -1
  34. package/dist/{planner-sql-checks-C7nLjabn.mjs → planner-sql-checks-CyjaoKhm.mjs} +2 -2
  35. package/dist/{planner-sql-checks-C7nLjabn.mjs.map → planner-sql-checks-CyjaoKhm.mjs.map} +1 -1
  36. package/dist/planner-sql-checks.mjs +1 -1
  37. package/dist/planner.d.mts +30 -35
  38. package/dist/planner.d.mts.map +1 -1
  39. package/dist/planner.mjs +2 -2
  40. package/dist/{postgres-contract-serializer-DJDGaS0q.mjs → postgres-contract-serializer-tGMiJcl4.mjs} +3 -3
  41. package/dist/{postgres-contract-serializer-DJDGaS0q.mjs.map → postgres-contract-serializer-tGMiJcl4.mjs.map} +1 -1
  42. package/dist/{postgres-migration-Bj0olfl3.mjs → postgres-migration-C8JZyTSJ.mjs} +2 -2
  43. package/dist/{postgres-migration-Bj0olfl3.mjs.map → postgres-migration-C8JZyTSJ.mjs.map} +1 -1
  44. package/dist/{postgres-migration-DJNJHcdP.d.mts → postgres-migration-Cs7zMOe1.d.mts} +3 -3
  45. package/dist/{postgres-migration-DJNJHcdP.d.mts.map → postgres-migration-Cs7zMOe1.d.mts.map} +1 -1
  46. package/dist/{postgres-rls-policy-D_z1osEq.d.mts → postgres-rls-policy-12wAEQhs.d.mts} +4 -4
  47. package/dist/postgres-rls-policy-12wAEQhs.d.mts.map +1 -0
  48. package/dist/{postgres-schema-Bn4tsMuo.d.mts → postgres-schema-DJUEkWg-.d.mts} +38 -5
  49. package/dist/postgres-schema-DJUEkWg-.d.mts.map +1 -0
  50. package/dist/{postgres-schema-DfuJq-q_.mjs → postgres-schema-DLcc3W2-.mjs} +37 -40
  51. package/dist/postgres-schema-DLcc3W2-.mjs.map +1 -0
  52. package/dist/postgres-schema-ir-BJl_a3J7.d.mts +102 -0
  53. package/dist/postgres-schema-ir-BJl_a3J7.d.mts.map +1 -0
  54. package/dist/postgres-schema-ir-I_FiUndw.mjs +133 -0
  55. package/dist/postgres-schema-ir-I_FiUndw.mjs.map +1 -0
  56. package/dist/{postgres-schema-ir-annotations-CWHQ-H9Y.mjs → postgres-schema-ir-annotations-BbDSiwx2.mjs} +4 -4
  57. package/dist/postgres-schema-ir-annotations-BbDSiwx2.mjs.map +1 -0
  58. package/dist/runtime.mjs +2 -2
  59. package/dist/schema-ir-annotations.d.mts +1 -1
  60. package/dist/schema-ir-annotations.d.mts.map +1 -1
  61. package/dist/schema-ir-annotations.mjs +1 -1
  62. package/dist/types.d.mts +4 -5
  63. package/dist/types.mjs +3 -3
  64. package/package.json +19 -19
  65. package/src/core/authoring.ts +2 -2
  66. package/src/core/entity-kinds.ts +2 -2
  67. package/src/core/migrations/contract-to-postgres-schema-ir.ts +91 -0
  68. package/src/core/migrations/diff-postgres-schema.ts +55 -0
  69. package/src/core/migrations/op-factory-call.ts +1 -1
  70. package/src/core/migrations/operations/rls.ts +1 -1
  71. package/src/core/migrations/planner.ts +44 -59
  72. package/src/core/migrations/verify-postgres-namespaces.ts +1 -1
  73. package/src/core/postgres-schema.ts +6 -2
  74. package/src/core/{postgres-rls-policy.ts → schema-ir/postgres-rls-policy.ts} +8 -10
  75. package/src/core/{postgres-role.ts → schema-ir/postgres-role.ts} +8 -9
  76. package/src/core/{postgres-schema-ir-annotations.ts → schema-ir/postgres-schema-ir-annotations.ts} +1 -1
  77. package/src/core/{postgres-schema-ir.ts → schema-ir/postgres-schema-ir.ts} +53 -16
  78. package/src/core/schema-ir/postgres-table-ir.ts +96 -0
  79. package/src/exports/control.ts +11 -12
  80. package/src/exports/planner.ts +5 -1
  81. package/src/exports/schema-ir-annotations.ts +1 -1
  82. package/src/exports/types.ts +15 -7
  83. package/dist/descriptor-meta-runtime-DiVla56r.mjs.map +0 -1
  84. package/dist/op-factory-call-DcY4BHNh.mjs.map +0 -1
  85. package/dist/planner-_ZHpIQ1-.mjs.map +0 -1
  86. package/dist/postgres-rls-policy-D_z1osEq.d.mts.map +0 -1
  87. package/dist/postgres-role-_CCuyPCQ.d.mts +0 -33
  88. package/dist/postgres-role-_CCuyPCQ.d.mts.map +0 -1
  89. package/dist/postgres-schema-Bn4tsMuo.d.mts.map +0 -1
  90. package/dist/postgres-schema-DfuJq-q_.mjs.map +0 -1
  91. package/dist/postgres-schema-ir-BF0X8jit.mjs +0 -66
  92. package/dist/postgres-schema-ir-BF0X8jit.mjs.map +0 -1
  93. package/dist/postgres-schema-ir-BQ3RpZMz.d.mts +0 -60
  94. package/dist/postgres-schema-ir-BQ3RpZMz.d.mts.map +0 -1
  95. package/dist/postgres-schema-ir-annotations-CWHQ-H9Y.mjs.map +0 -1
  96. package/src/core/migrations/verify-postgres-rls-policies.ts +0 -62
@@ -1 +0,0 @@
1
- {"version":3,"file":"postgres-schema-ir-BF0X8jit.mjs","names":[],"sources":["../src/core/postgres-schema-ir.ts"],"sourcesContent":["import { freezeNode } from '@prisma-next/framework-components/ir';\nimport {\n type SqlAnnotations,\n type SqlSchemaIR,\n SqlSchemaIRNode,\n type SqlSchemaTarget,\n SqlTableIR,\n type SqlTableIRInput,\n} from '@prisma-next/sql-schema-ir/types';\nimport type { PostgresRlsPolicy } from './postgres-rls-policy';\nimport type { PostgresRole } from './postgres-role';\n\nexport interface PostgresSchemaIRInput {\n readonly tables: Record<string, SqlTableIR | SqlTableIRInput>;\n readonly pgSchemaName: string;\n readonly pgVersion: string;\n readonly rlsPolicies: readonly PostgresRlsPolicy[];\n readonly roles: readonly PostgresRole[];\n readonly existingSchemas: readonly string[];\n readonly nativeEnumTypeNames: readonly string[];\n}\n\n/**\n * Postgres-specific schema IR. Mirrors the structure of `SqlSchemaIR`\n * (same `tables` + optional `annotations` fields) and adds typed fields for\n * data the postgres adapter collects during introspection.\n *\n * Extends `SqlSchemaIRNode` directly rather than `SqlSchemaIR` because\n * `SqlSchemaIR` calls `freezeNode` in its constructor, which prevents\n * subclass field initialisation. `PostgresSchemaIR` replicates the minimal\n * `SqlSchemaIR` structure and freezes itself at the end of its own\n * constructor.\n *\n * RLS-specific fields (`rlsPolicies`, `roles`) are typed top-level fields on\n * this class — no `Reflect.get`, no untyped annotation bag access. The\n * `annotations.pg` bag is populated with only the subset the family layer\n * reads (`nativeEnumTypeNames`, `existingSchemas`, `schema`) so family-layer\n * PSL inference and namespace verification continue to work without knowing\n * about RLS.\n *\n * Nothing RLS-specific leaks into the sql-family layer.\n */\nexport class PostgresSchemaIR extends SqlSchemaIRNode {\n readonly nodeTarget: SqlSchemaTarget = 'postgres';\n readonly tables: Readonly<Record<string, SqlTableIR>>;\n declare readonly annotations?: SqlAnnotations;\n readonly pgSchemaName: string;\n readonly pgVersion: string;\n readonly rlsPolicies: readonly PostgresRlsPolicy[];\n readonly roles: readonly PostgresRole[];\n readonly existingSchemas: readonly string[];\n readonly nativeEnumTypeNames: readonly string[];\n\n constructor(input: PostgresSchemaIRInput) {\n super();\n this.tables = Object.freeze(\n Object.fromEntries(\n Object.entries(input.tables).map(([key, t]) => [\n key,\n t instanceof SqlTableIR ? t : new SqlTableIR(t),\n ]),\n ),\n );\n this.pgSchemaName = input.pgSchemaName;\n this.pgVersion = input.pgVersion;\n this.rlsPolicies = Object.freeze([...input.rlsPolicies]);\n this.roles = Object.freeze([...input.roles]);\n this.existingSchemas = Object.freeze([...input.existingSchemas]);\n this.nativeEnumTypeNames = Object.freeze([...input.nativeEnumTypeNames]);\n // Populate the annotations.pg bag with only the subset the family layer\n // reads (nativeEnumTypeNames for PSL inference, existingSchemas for\n // namespace presence checks). rlsPolicies and roles are NOT placed here\n // — they are consumed directly via typed fields on this class.\n this.annotations = {\n pg: {\n schema: input.pgSchemaName,\n ...(input.nativeEnumTypeNames.length > 0 && {\n nativeEnumTypeNames: input.nativeEnumTypeNames,\n }),\n ...(input.existingSchemas.length > 0 && {\n existingSchemas: input.existingSchemas,\n }),\n },\n };\n freezeNode(this);\n }\n}\n\n/**\n * Structural guard for `PostgresSchemaIR`, narrowing on the `nodeTarget`\n * discriminant rather than `instanceof`. `nodeTarget` is an enumerable own field\n * (a plain class-field initializer), so it survives the `{ ...schema, tables }`\n * spread the multi-space verify path (`projectSchemaToSpace`) produces — that\n * projected object is not a class instance but retains every enumerable own\n * property. The family-level `kind = 'sql-schema-ir'` discriminator is unusable\n * here: it is shared by every SQL schema-IR node and is non-enumerable (dropped\n * by the spread).\n */\nexport function isPostgresSchemaIR(schema: SqlSchemaIR): schema is PostgresSchemaIR {\n return schema.nodeTarget === 'postgres';\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;AA0CA,IAAa,mBAAb,cAAsC,gBAAgB;CACpD,aAAuC;CACvC;CAEA;CACA;CACA;CACA;CACA;CACA;CAEA,YAAY,OAA8B;EACxC,MAAM;EACN,KAAK,SAAS,OAAO,OACnB,OAAO,YACL,OAAO,QAAQ,MAAM,MAAM,CAAC,CAAC,KAAK,CAAC,KAAK,OAAO,CAC7C,KACA,aAAa,aAAa,IAAI,IAAI,WAAW,CAAC,CAChD,CAAC,CACH,CACF;EACA,KAAK,eAAe,MAAM;EAC1B,KAAK,YAAY,MAAM;EACvB,KAAK,cAAc,OAAO,OAAO,CAAC,GAAG,MAAM,WAAW,CAAC;EACvD,KAAK,QAAQ,OAAO,OAAO,CAAC,GAAG,MAAM,KAAK,CAAC;EAC3C,KAAK,kBAAkB,OAAO,OAAO,CAAC,GAAG,MAAM,eAAe,CAAC;EAC/D,KAAK,sBAAsB,OAAO,OAAO,CAAC,GAAG,MAAM,mBAAmB,CAAC;EAKvE,KAAK,cAAc,EACjB,IAAI;GACF,QAAQ,MAAM;GACd,GAAI,MAAM,oBAAoB,SAAS,KAAK,EAC1C,qBAAqB,MAAM,oBAC7B;GACA,GAAI,MAAM,gBAAgB,SAAS,KAAK,EACtC,iBAAiB,MAAM,gBACzB;EACF,EACF;EACA,WAAW,IAAI;CACjB;AACF;;;;;;;;;;;AAYA,SAAgB,mBAAmB,QAAiD;CAClF,OAAO,OAAO,eAAe;AAC/B"}
@@ -1,60 +0,0 @@
1
- import { t as PostgresRlsPolicy } from "./postgres-rls-policy-D_z1osEq.mjs";
2
- import { t as PostgresRole } from "./postgres-role-_CCuyPCQ.mjs";
3
- import { SqlAnnotations, SqlSchemaIR, SqlSchemaIRNode, SqlSchemaTarget, SqlTableIR, SqlTableIRInput } from "@prisma-next/sql-schema-ir/types";
4
-
5
- //#region src/core/postgres-schema-ir.d.ts
6
- interface PostgresSchemaIRInput {
7
- readonly tables: Record<string, SqlTableIR | SqlTableIRInput>;
8
- readonly pgSchemaName: string;
9
- readonly pgVersion: string;
10
- readonly rlsPolicies: readonly PostgresRlsPolicy[];
11
- readonly roles: readonly PostgresRole[];
12
- readonly existingSchemas: readonly string[];
13
- readonly nativeEnumTypeNames: readonly string[];
14
- }
15
- /**
16
- * Postgres-specific schema IR. Mirrors the structure of `SqlSchemaIR`
17
- * (same `tables` + optional `annotations` fields) and adds typed fields for
18
- * data the postgres adapter collects during introspection.
19
- *
20
- * Extends `SqlSchemaIRNode` directly rather than `SqlSchemaIR` because
21
- * `SqlSchemaIR` calls `freezeNode` in its constructor, which prevents
22
- * subclass field initialisation. `PostgresSchemaIR` replicates the minimal
23
- * `SqlSchemaIR` structure and freezes itself at the end of its own
24
- * constructor.
25
- *
26
- * RLS-specific fields (`rlsPolicies`, `roles`) are typed top-level fields on
27
- * this class — no `Reflect.get`, no untyped annotation bag access. The
28
- * `annotations.pg` bag is populated with only the subset the family layer
29
- * reads (`nativeEnumTypeNames`, `existingSchemas`, `schema`) so family-layer
30
- * PSL inference and namespace verification continue to work without knowing
31
- * about RLS.
32
- *
33
- * Nothing RLS-specific leaks into the sql-family layer.
34
- */
35
- declare class PostgresSchemaIR extends SqlSchemaIRNode {
36
- readonly nodeTarget: SqlSchemaTarget;
37
- readonly tables: Readonly<Record<string, SqlTableIR>>;
38
- readonly annotations?: SqlAnnotations;
39
- readonly pgSchemaName: string;
40
- readonly pgVersion: string;
41
- readonly rlsPolicies: readonly PostgresRlsPolicy[];
42
- readonly roles: readonly PostgresRole[];
43
- readonly existingSchemas: readonly string[];
44
- readonly nativeEnumTypeNames: readonly string[];
45
- constructor(input: PostgresSchemaIRInput);
46
- }
47
- /**
48
- * Structural guard for `PostgresSchemaIR`, narrowing on the `nodeTarget`
49
- * discriminant rather than `instanceof`. `nodeTarget` is an enumerable own field
50
- * (a plain class-field initializer), so it survives the `{ ...schema, tables }`
51
- * spread the multi-space verify path (`projectSchemaToSpace`) produces — that
52
- * projected object is not a class instance but retains every enumerable own
53
- * property. The family-level `kind = 'sql-schema-ir'` discriminator is unusable
54
- * here: it is shared by every SQL schema-IR node and is non-enumerable (dropped
55
- * by the spread).
56
- */
57
- declare function isPostgresSchemaIR(schema: SqlSchemaIR): schema is PostgresSchemaIR;
58
- //#endregion
59
- export { PostgresSchemaIRInput as n, isPostgresSchemaIR as r, PostgresSchemaIR as t };
60
- //# sourceMappingURL=postgres-schema-ir-BQ3RpZMz.d.mts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"postgres-schema-ir-BQ3RpZMz.d.mts","names":[],"sources":["../src/core/postgres-schema-ir.ts"],"mappings":";;;;;UAYiB,qBAAA;EAAA,SACN,MAAA,EAAQ,MAAA,SAAe,UAAA,GAAa,eAAA;EAAA,SACpC,YAAA;EAAA,SACA,SAAA;EAAA,SACA,WAAA,WAAsB,iBAAA;EAAA,SACtB,KAAA,WAAgB,YAAA;EAAA,SAChB,eAAA;EAAA,SACA,mBAAA;AAAA;;;;;;;;;;;;;;;;;AAAmB;AAuB9B;;;cAAa,gBAAA,SAAyB,eAAA;EAAA,SAC3B,UAAA,EAAY,eAAA;EAAA,SACZ,MAAA,EAAQ,QAAA,CAAS,MAAA,SAAe,UAAA;EAAA,SACxB,WAAA,GAAc,cAAA;EAAA,SACtB,YAAA;EAAA,SACA,SAAA;EAAA,SACA,WAAA,WAAsB,iBAAA;EAAA,SACtB,KAAA,WAAgB,YAAA;EAAA,SAChB,eAAA;EAAA,SACA,mBAAA;cAEG,KAAA,EAAO,qBAAA;AAAA;;;;;;;;;;;iBA6CL,kBAAA,CAAmB,MAAA,EAAQ,WAAA,GAAc,MAAA,IAAU,gBAAgB"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"postgres-schema-ir-annotations-CWHQ-H9Y.mjs","names":[],"sources":["../src/core/postgres-schema-ir-annotations.ts"],"sourcesContent":["import { UNBOUND_NAMESPACE_ID } from '@prisma-next/framework-components/ir';\nimport type { SqlStorage } from '@prisma-next/sql-contract/types';\nimport type { SqlSchemaIR } from '@prisma-next/sql-schema-ir/types';\nimport { isPostgresSchema } from './postgres-schema';\nimport { isPostgresSchemaIR } from './postgres-schema-ir';\n\nexport function resolveDdlSchemaForNamespaceStorage(\n storage: SqlStorage,\n namespaceId: string,\n schemaIr?: SqlSchemaIR,\n): string {\n if (namespaceId === UNBOUND_NAMESPACE_ID) {\n return (\n (schemaIr && isPostgresSchemaIR(schemaIr) ? schemaIr.pgSchemaName : undefined) ?? 'public'\n );\n }\n const namespace = storage.namespaces[namespaceId];\n if (namespace && isPostgresSchema(namespace)) {\n return namespace.ddlSchemaName(storage);\n }\n return namespaceId;\n}\n"],"mappings":";;;;AAMA,SAAgB,oCACd,SACA,aACA,UACQ;CACR,IAAI,gBAAgB,sBAClB,QACG,YAAY,mBAAmB,QAAQ,IAAI,SAAS,eAAe,KAAA,MAAc;CAGtF,MAAM,YAAY,QAAQ,WAAW;CACrC,IAAI,aAAa,iBAAiB,SAAS,GACzC,OAAO,UAAU,cAAc,OAAO;CAExC,OAAO;AACT"}
@@ -1,62 +0,0 @@
1
- import type { Contract } from '@prisma-next/contract/types';
2
- import type { SchemaDiffIssue } from '@prisma-next/framework-components/control';
3
- import { diffNodes } from '@prisma-next/framework-components/control';
4
- import { UNBOUND_NAMESPACE_ID } from '@prisma-next/framework-components/ir';
5
- import type { SqlStorage } from '@prisma-next/sql-contract/types';
6
- import { isPostgresSchema } from '../postgres-schema';
7
- import type { PostgresSchemaIR } from '../postgres-schema-ir';
8
-
9
- // Postgres binds the late-bound (`__unbound__`) namespace to the `public`
10
- // schema, so an unbound contract owns `public` in the live database. Both the
11
- // contract slot ids and the introspected policy coordinates can carry either
12
- // form depending on how the schema was lowered, so normalize both sides to the
13
- // same id before comparing ownership.
14
- const POSTGRES_DEFAULT_NAMESPACE_ID = 'public';
15
-
16
- function resolveNamespaceId(namespaceId: string): string {
17
- return namespaceId === UNBOUND_NAMESPACE_ID ? POSTGRES_DEFAULT_NAMESPACE_ID : namespaceId;
18
- }
19
-
20
- /**
21
- * Computes RLS policy drift between the contract and the live DB schema using
22
- * the generic {@link diffNodes} differ. Returns `SchemaDiffIssue[]` keyed by
23
- * the full `EntityCoordinate` (plane + namespaceId + entityKind + entityName).
24
- *
25
- * Both sides supply `PostgresRlsPolicy` nodes that implement `DiffableNode`
26
- * with a concrete namespace coordinate — the contract carries explicit
27
- * `namespaceId` set during lowering (e.g. `'public'`); the introspected schema
28
- * carries the resolved DDL schema name. The differ matches purely on coordinate
29
- * identity; no namespace interpretation happens here.
30
- *
31
- * The diff is scoped to the namespaces the verified contract owns. The live
32
- * schema introspection returns every policy across all DB schemas, but a policy
33
- * in a namespace this contract does not own belongs to another contract space
34
- * (or is external) and must not be reported as extra. Without this scope a space
35
- * that owns only `auth`/`storage` (e.g. the supabase extension space) would flag
36
- * the application space's `public.*` policies as extra during verify.
37
- *
38
- * Ownership is the set of namespaces the contract declares (its
39
- * `storage.namespaces` slot keys), with the late-bound `__unbound__` slot
40
- * resolved to the Postgres default `public` so a single-namespace contract still
41
- * owns — and diffs — its `public` policies.
42
- */
43
- export function diffPostgresRlsPolicies(input: {
44
- readonly contract: Contract<SqlStorage>;
45
- readonly schema: PostgresSchemaIR;
46
- }): readonly SchemaDiffIssue[] {
47
- const { contract, schema } = input;
48
-
49
- const ownedNamespaceIds = new Set(
50
- Object.keys(contract.storage.namespaces).map(resolveNamespaceId),
51
- );
52
-
53
- const expected = Object.values(contract.storage.namespaces).flatMap((ns) =>
54
- isPostgresSchema(ns) ? Object.values(ns.policy) : [],
55
- );
56
-
57
- const actual = schema.rlsPolicies.filter((policy) =>
58
- ownedNamespaceIds.has(resolveNamespaceId(policy.namespaceId)),
59
- );
60
-
61
- return diffNodes(expected, actual);
62
- }