@prisma-next/target-postgres 0.14.0-dev.69 → 0.14.0-dev.70

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 (37) hide show
  1. package/dist/{authoring-CI40w7qe.mjs → authoring-Bi9aa8zG.mjs} +55 -9
  2. package/dist/authoring-Bi9aa8zG.mjs.map +1 -0
  3. package/dist/{control-policy-SqhTdh7B.mjs → control-policy-5_5odTg9.mjs} +7 -35
  4. package/dist/{control-policy-SqhTdh7B.mjs.map → control-policy-5_5odTg9.mjs.map} +1 -1
  5. package/dist/control.mjs +4 -4
  6. package/dist/{descriptor-meta-D9P2X_vH.mjs → descriptor-meta-UugzVM-U.mjs} +2 -2
  7. package/dist/{descriptor-meta-D9P2X_vH.mjs.map → descriptor-meta-UugzVM-U.mjs.map} +1 -1
  8. package/dist/{diff-database-schema-DgPjvCFL.mjs → diff-database-schema-Dis8SMoT.mjs} +9 -6
  9. package/dist/diff-database-schema-Dis8SMoT.mjs.map +1 -0
  10. package/dist/diff-database-schema.mjs +1 -1
  11. package/dist/issue-planner.mjs +1 -1
  12. package/dist/migration.mjs +1 -1
  13. package/dist/pack.d.mts +15 -2
  14. package/dist/pack.d.mts.map +1 -1
  15. package/dist/pack.mjs +1 -1
  16. package/dist/{planner-mfrnbA0y.mjs → planner-BXlWpNsT.mjs} +4 -4
  17. package/dist/{planner-mfrnbA0y.mjs.map → planner-BXlWpNsT.mjs.map} +1 -1
  18. package/dist/{planner-produced-postgres-migration-Bff3t-CR.mjs → planner-produced-postgres-migration-C8vSaHku.mjs} +2 -2
  19. package/dist/{planner-produced-postgres-migration-Bff3t-CR.mjs.map → planner-produced-postgres-migration-C8vSaHku.mjs.map} +1 -1
  20. package/dist/planner-produced-postgres-migration.mjs +1 -1
  21. package/dist/planner.d.mts +1 -1
  22. package/dist/planner.mjs +2 -2
  23. package/dist/{postgres-contract-view-DdVPr1hY.mjs → postgres-contract-view-C3LPCLP_.mjs} +2 -2
  24. package/dist/{postgres-contract-view-DdVPr1hY.mjs.map → postgres-contract-view-C3LPCLP_.mjs.map} +1 -1
  25. package/dist/{postgres-migration-BCQa4N1k.mjs → postgres-migration-B3u0erMT.mjs} +2 -2
  26. package/dist/{postgres-migration-BCQa4N1k.mjs.map → postgres-migration-B3u0erMT.mjs.map} +1 -1
  27. package/dist/{postgres-schema-ChzFbyAs.d.mts → postgres-schema-DKq6s1P3.d.mts} +59 -59
  28. package/dist/postgres-schema-DKq6s1P3.d.mts.map +1 -0
  29. package/dist/runtime.mjs +1 -1
  30. package/dist/types.d.mts +1 -1
  31. package/package.json +20 -20
  32. package/src/core/authoring.ts +44 -2
  33. package/src/core/migrations/contract-to-postgres-database-schema-node.ts +22 -4
  34. package/src/core/migrations/control-policy.ts +6 -34
  35. package/dist/authoring-CI40w7qe.mjs.map +0 -1
  36. package/dist/diff-database-schema-DgPjvCFL.mjs.map +0 -1
  37. package/dist/postgres-schema-ChzFbyAs.d.mts.map +0 -1
@@ -2,6 +2,7 @@ import { a as PG_ENUM_CODEC_ID } from "./codec-ids-C_-Hj6bL.mjs";
2
2
  import { t as PostgresNativeEnum } from "./postgres-native-enum-BwVNf0Ku.mjs";
3
3
  import { _ as PostgresRlsEnablement, d as PostgresRlsEnablementSchema, f as PostgresRlsPolicySchema, g as PostgresRlsPolicy, m as PostgresRole, p as PostgresRoleSchema, u as PostgresNativeEnumSchema } from "./postgres-schema-DYATroNx.mjs";
4
4
  import { i as normalizePredicate, r as computeContentHash, t as formatRlsPolicyWireName } from "./wire-name-rHHtr1h0.mjs";
5
+ import { UNBOUND_NAMESPACE_ID } from "@prisma-next/framework-components/ir";
5
6
  import { temporalAuthoringPresets } from "@prisma-next/family-sql/control";
6
7
  import { ifDefined } from "@prisma-next/utils/defined";
7
8
  import { modelAttribute } from "@prisma-next/psl-parser";
@@ -236,12 +237,50 @@ function lowerNativeEnumFromBlock(block, ctx) {
236
237
  members
237
238
  });
238
239
  }
240
+ /**
241
+ * `native_enum`'s entity-type factory output, checked separately from the assembled
242
+ * `postgresAuthoringEntityTypes` map below: `deriveValueSet` is SQL-family surface
243
+ * ({@link SqlValueSetDerivingEntityTypeOutput}), not part of the framework
244
+ * `AuthoringEntityTypeFactoryOutput` shape, so folding it directly into the map's single
245
+ * `satisfies AuthoringEntityTypeNamespace` check would trip an excess-property error. Checking it
246
+ * here against the intersection of both shapes keeps it structurally valid against each without
247
+ * widening the map's own check.
248
+ */
249
+ const nativeEnumEntityTypeOutput = {
250
+ factory: lowerNativeEnumFromBlock,
251
+ deriveValueSet: (entity) => ({
252
+ kind: "valueSet",
253
+ values: [...entity.members]
254
+ })
255
+ };
256
+ /**
257
+ * Lowers a `role <name> {}` block into a {@link PostgresRole}. Roles are
258
+ * cluster-scoped in Postgres, so the block must be declared inside
259
+ * `namespace unbound { … }` — any other lexical namespace (a named schema,
260
+ * or the default bucket top-level declarations resolve to) is a load-time
261
+ * diagnostic. The lowered entity carries the unbound coordinate.
262
+ */
263
+ function lowerRoleFromBlock(block, ctx) {
264
+ if (block.namespaceId !== UNBOUND_NAMESPACE_ID) {
265
+ ctx.diagnostics?.push({
266
+ code: "PSL_ROLE_BLOCK_OUTSIDE_UNBOUND_NAMESPACE",
267
+ message: `\`role\` block "${block.name}" must be declared inside \`namespace unbound { }\`, not in namespace "${block.namespaceId}"`,
268
+ sourceId: ctx.sourceId ?? "unknown",
269
+ span: block.span
270
+ });
271
+ return;
272
+ }
273
+ return new PostgresRole({
274
+ name: block.name,
275
+ namespaceId: UNBOUND_NAMESPACE_ID
276
+ });
277
+ }
239
278
  const postgresAuthoringEntityTypes = {
240
279
  role: {
241
280
  kind: "entity",
242
281
  discriminator: "role",
243
282
  validatorSchema: PostgresRoleSchema,
244
- output: { factory: (input) => new PostgresRole(input) }
283
+ output: { factory: lowerRoleFromBlock }
245
284
  },
246
285
  rls: {
247
286
  kind: "entity",
@@ -259,13 +298,7 @@ const postgresAuthoringEntityTypes = {
259
298
  kind: "entity",
260
299
  discriminator: "native_enum",
261
300
  validatorSchema: PostgresNativeEnumSchema,
262
- output: {
263
- factory: lowerNativeEnumFromBlock,
264
- deriveValueSet: (entity) => ({
265
- kind: "valueSet",
266
- values: [...entity.members]
267
- })
268
- }
301
+ output: nativeEnumEntityTypeOutput
269
302
  }
270
303
  };
271
304
  /**
@@ -397,6 +430,19 @@ const postgresAuthoringPslBlockDescriptors = {
397
430
  name: { required: true },
398
431
  parameters: {},
399
432
  variadicParameters: true
433
+ },
434
+ /**
435
+ * PSL block descriptor for `role` (e.g. `role anon {}`). Name-only, no
436
+ * parameters and no body content. Declared inside `namespace unbound { }`
437
+ * — see {@link lowerRoleFromBlock} for the placement check and the
438
+ * coordinate the lowered entity carries.
439
+ */
440
+ role: {
441
+ kind: "pslBlock",
442
+ keyword: "role",
443
+ discriminator: "role",
444
+ name: { required: true },
445
+ parameters: {}
400
446
  }
401
447
  };
402
448
  /**
@@ -525,4 +571,4 @@ const postgresAuthoringFieldPresets = {
525
571
  //#endregion
526
572
  export { postgresAuthoringTypes as a, postgresAuthoringPslBlockDescriptors as i, postgresAuthoringFieldPresets as n, postgresAuthoringModelAttributes as r, postgresAuthoringEntityTypes as t };
527
573
 
528
- //# sourceMappingURL=authoring-CI40w7qe.mjs.map
574
+ //# sourceMappingURL=authoring-Bi9aa8zG.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"authoring-Bi9aa8zG.mjs","names":[],"sources":["../src/core/authoring.ts"],"sourcesContent":["import { temporalAuthoringPresets } from '@prisma-next/family-sql/control';\nimport type {\n AuthoringEntityContext,\n AuthoringEntityTypeFactoryOutput,\n AuthoringEntityTypeNamespace,\n AuthoringFieldNamespace,\n AuthoringModelAttributeContext,\n AuthoringModelAttributeDescriptorNamespace,\n AuthoringPslBlockDescriptorNamespace,\n AuthoringTypeNamespace,\n PslExtensionBlock,\n} from '@prisma-next/framework-components/authoring';\nimport { UNBOUND_NAMESPACE_ID } from '@prisma-next/framework-components/ir';\nimport { modelAttribute } from '@prisma-next/psl-parser';\nimport type { SqlValueSetDerivingEntityTypeOutput } from '@prisma-next/sql-contract/value-set-derivation-hook';\nimport { ifDefined } from '@prisma-next/utils/defined';\nimport { PG_ENUM_CODEC_ID } from './codec-ids';\nimport { PostgresNativeEnum } from './postgres-native-enum';\nimport { PostgresRlsEnablement, type PostgresRlsEnablementInput } from './postgres-rls-enablement';\nimport { PostgresRlsPolicy, type RlsPolicyOperation } from './postgres-rls-policy';\nimport { PostgresRole } from './postgres-role';\nimport {\n PostgresNativeEnumSchema,\n PostgresRlsEnablementSchema,\n PostgresRlsPolicySchema,\n PostgresRoleSchema,\n} from './postgres-validators';\nimport { computeContentHash, normalizePredicate } from './rls/canonicalize';\nimport { formatRlsPolicyWireName } from './rls/wire-name';\n\n/**\n * `pg.enum(<ref>)` registers as an ordinary type constructor whose sole\n * positional argument names a `native_enum` entity instead of carrying a\n * literal value. The interpreter resolves the ref to the `native_enum`\n * entity generically (driven by `entityRefArg`); the `pg/enum@1` codec\n * descriptor's `columnFromEntity` hook (see `codecs.ts`) converts that\n * entity into the column's `typeParams` and native type.\n */\nexport const postgresAuthoringTypes = {\n pg: {\n enum: {\n kind: 'typeConstructor',\n entityRefArg: { index: 0, entityKind: 'native_enum' },\n output: {\n codecId: PG_ENUM_CODEC_ID,\n },\n },\n },\n} as const satisfies AuthoringTypeNamespace;\n\nexport interface RlsPolicyExtensionBlock extends PslExtensionBlock {\n readonly namespaceId: string;\n}\n\n/** A parsed `role` block annotated with its lexical namespace id by the interpreter. */\nexport interface RoleExtensionBlock extends PslExtensionBlock {\n readonly namespaceId: string;\n}\n\n/**\n * Maps a `policy_<op>` keyword to the RLS operation it authors. The keyword\n * IS the operation (per the project's rejection of a `policy { operation = … }`\n * conditional block).\n */\nconst POLICY_KEYWORD_OPERATION: Readonly<Record<string, RlsPolicyOperation>> = {\n policy_select: 'select',\n policy_insert: 'insert',\n policy_update: 'update',\n policy_delete: 'delete',\n policy_all: 'all',\n};\n\n/**\n * Which predicate each RLS operation admits, mirroring Postgres: SELECT and\n * DELETE decide row visibility/eligibility with `USING` only; INSERT validates\n * the new row with `WITH CHECK` only; UPDATE and ALL take both. A predicate\n * outside this set is a load-time error (see {@link lowerRlsPolicyFromBlock}).\n */\nconst POLICY_OPERATION_PREDICATES: Readonly<\n Record<RlsPolicyOperation, { readonly using: boolean; readonly withCheck: boolean }>\n> = {\n select: { using: true, withCheck: false },\n insert: { using: false, withCheck: true },\n update: { using: true, withCheck: true },\n delete: { using: true, withCheck: false },\n all: { using: true, withCheck: true },\n};\n\nfunction readRefParam(block: PslExtensionBlock, key: string): string | undefined {\n const param = block.parameters[key];\n return param?.kind === 'ref' ? param.identifier : undefined;\n}\n\nfunction readValueParam(block: PslExtensionBlock, key: string): string | undefined {\n const param = block.parameters[key];\n return param?.kind === 'value' ? param.raw : undefined;\n}\n\nfunction readListRefParams(block: PslExtensionBlock, key: string): string[] {\n const param = block.parameters[key];\n if (param?.kind !== 'list') return [];\n return param.items.flatMap((item) => (item.kind === 'ref' ? [item.identifier] : []));\n}\n\n/**\n * Unwraps a quoted PSL string argument, inverting the printer's\n * `escapePslString` escapes (`\\\\`, `\\\"`, `\\n`, `\\r`). An unknown escape\n * sequence is kept verbatim, matching the printer-side `unescapePslString`\n * convention.\n */\nfunction unwrapQuotedString(raw: string): string {\n if (!(raw.startsWith('\"') && raw.endsWith('\"') && raw.length >= 2)) {\n return raw;\n }\n const inner = raw.slice(1, -1);\n let result = '';\n for (let i = 0; i < inner.length; i++) {\n if (inner[i] !== '\\\\' || i + 1 >= inner.length) {\n result += inner[i];\n continue;\n }\n const next = inner[i + 1];\n if (next === '\\\\' || next === '\"') {\n result += next;\n } else if (next === 'n') {\n result += '\\n';\n } else if (next === 'r') {\n result += '\\r';\n } else {\n result += '\\\\';\n result += next;\n }\n i++;\n }\n return result;\n}\n\nfunction lowerRlsPolicyFromBlock(\n block: RlsPolicyExtensionBlock,\n ctx: AuthoringEntityContext,\n): PostgresRlsPolicy | undefined {\n const prefix = block.name;\n const operation = POLICY_KEYWORD_OPERATION[block.keyword] ?? 'select';\n const targetModelName = readRefParam(block, 'target') ?? '';\n const tableName = targetModelName.charAt(0).toLowerCase() + targetModelName.slice(1);\n const roles = [...readListRefParams(block, 'roles')].sort();\n\n const usingRaw = readValueParam(block, 'using');\n const withCheckRaw = readValueParam(block, 'withCheck');\n\n // Reject a predicate the operation does not take (e.g. `using` on INSERT, or\n // `withCheck` on SELECT/DELETE). The descriptor's param set already omits it,\n // but the generic descriptor validator is not wired into the SQL-family\n // interpreter, so the lowering enforces the per-operation predicate matrix\n // directly — a wrong predicate is a load-time diagnostic, not a silent drop.\n const support = POLICY_OPERATION_PREDICATES[operation];\n const rejectPredicate = (predicate: 'using' | 'withCheck'): undefined => {\n ctx.diagnostics?.push({\n code: 'PSL_RLS_PREDICATE_NOT_FOR_OPERATION',\n message: `\\`${block.keyword}\\` policy \"${block.name}\" does not take a \\`${predicate}\\` predicate; the ${operation.toUpperCase()} operation uses ${support.using ? '`using`' : '`withCheck`'}${support.using && support.withCheck ? ' and `withCheck`' : ' only'}.`,\n sourceId: ctx.sourceId ?? 'unknown',\n span: block.parameters[predicate]?.span ?? block.span,\n });\n return undefined;\n };\n if (usingRaw !== undefined && !support.using) return rejectPredicate('using');\n if (withCheckRaw !== undefined && !support.withCheck) return rejectPredicate('withCheck');\n\n const using = usingRaw !== undefined ? unwrapQuotedString(usingRaw) : undefined;\n const withCheck = withCheckRaw !== undefined ? unwrapQuotedString(withCheckRaw) : undefined;\n\n const wireHash = computeContentHash({\n ...ifDefined('using', using !== undefined ? normalizePredicate(using) : undefined),\n ...ifDefined('withCheck', withCheck !== undefined ? normalizePredicate(withCheck) : undefined),\n roles,\n operation,\n permissive: true,\n });\n const wireName = formatRlsPolicyWireName(prefix, wireHash);\n\n return new PostgresRlsPolicy({\n name: wireName,\n prefix,\n tableName,\n namespaceId: block.namespaceId,\n operation,\n roles,\n ...ifDefined('using', using),\n ...ifDefined('withCheck', withCheck),\n permissive: true,\n });\n}\n\n/**\n * Lowers a `native_enum { memberName = \"value\" … @@map(\"type_name\") }` block\n * into a {@link PostgresNativeEnum}. Members must be authored as explicit\n * `key = \"value\"` pairs — a bare (value-less) member is a diagnostic, not\n * accepted (authoring-design.md §2.1). The parsed `memberName` is only used\n * to duplicate-check and report diagnostics; the lowered entity carries just\n * the member values (a native enum is value-only — the member \"name\" isn't\n * a separate authoring concept from the value). `typeName` comes from\n * `@@map` or defaults to the block name verbatim.\n */\nfunction lowerNativeEnumFromBlock(\n block: PslExtensionBlock,\n ctx: AuthoringEntityContext,\n): PostgresNativeEnum | undefined {\n const sourceId = ctx.sourceId ?? 'unknown';\n const diagnostics = ctx.diagnostics;\n\n const mapAttr = block.blockAttributes.find((a) => a.name === 'map');\n let typeName = block.name;\n if (mapAttr) {\n const rawArg = mapAttr.args[0]?.value;\n const mapped = rawArg !== undefined ? unwrapQuotedString(rawArg) : undefined;\n if (mapped === undefined) {\n diagnostics?.push({\n code: 'PSL_NATIVE_ENUM_INVALID_MAP',\n message: `native_enum \"${block.name}\" @@map attribute must have a quoted type-name argument`,\n sourceId,\n span: mapAttr.span,\n });\n return undefined;\n }\n typeName = mapped;\n }\n\n let memberError = false;\n const seenValues = new Set<string>();\n const members: string[] = [];\n for (const [memberName, paramValue] of Object.entries(block.parameters)) {\n if (paramValue.kind === 'bare') {\n diagnostics?.push({\n code: 'PSL_NATIVE_ENUM_BARE_MEMBER',\n message: `native_enum \"${block.name}\" member \"${memberName}\" has no value; members must be authored as \"${memberName} = \\\\\"value\\\\\"\"`,\n sourceId,\n span: paramValue.span,\n });\n memberError = true;\n continue;\n }\n if (paramValue.kind !== 'value') continue;\n\n let jsonValue: unknown;\n try {\n jsonValue = JSON.parse(paramValue.raw);\n } catch {\n diagnostics?.push({\n code: 'PSL_EXTENSION_INVALID_VALUE',\n message: `native_enum \"${block.name}\" member \"${memberName}\" value \"${paramValue.raw}\" is not valid JSON`,\n sourceId,\n span: paramValue.span,\n });\n memberError = true;\n continue;\n }\n if (typeof jsonValue !== 'string') {\n diagnostics?.push({\n code: 'PSL_EXTENSION_INVALID_VALUE',\n message: `native_enum \"${block.name}\" member \"${memberName}\" value must be a string`,\n sourceId,\n span: paramValue.span,\n });\n memberError = true;\n continue;\n }\n if (seenValues.has(jsonValue)) {\n diagnostics?.push({\n code: 'PSL_NATIVE_ENUM_DUPLICATE_MEMBER_VALUE',\n message: `native_enum \"${block.name}\": duplicate member value \"${jsonValue}\"`,\n sourceId,\n span: paramValue.span,\n });\n memberError = true;\n continue;\n }\n seenValues.add(jsonValue);\n members.push(jsonValue);\n }\n\n if (memberError) return undefined;\n\n if (members.length === 0) {\n diagnostics?.push({\n code: 'PSL_NATIVE_ENUM_MISSING_MEMBERS',\n message: `native_enum \"${block.name}\" must have at least one member`,\n sourceId,\n span: block.span,\n });\n return undefined;\n }\n\n // `control` stays unset — the effective grade is resolved at read time via `effectiveControlPolicy`, like `StorageTable`/`StorageColumn`.\n return new PostgresNativeEnum({ typeName, members });\n}\n\n/**\n * `native_enum`'s entity-type factory output, checked separately from the assembled\n * `postgresAuthoringEntityTypes` map below: `deriveValueSet` is SQL-family surface\n * ({@link SqlValueSetDerivingEntityTypeOutput}), not part of the framework\n * `AuthoringEntityTypeFactoryOutput` shape, so folding it directly into the map's single\n * `satisfies AuthoringEntityTypeNamespace` check would trip an excess-property error. Checking it\n * here against the intersection of both shapes keeps it structurally valid against each without\n * widening the map's own check.\n */\nconst nativeEnumEntityTypeOutput = {\n factory: lowerNativeEnumFromBlock,\n deriveValueSet: (entity: PostgresNativeEnum) => ({\n kind: 'valueSet' as const,\n values: [...entity.members],\n }),\n} satisfies AuthoringEntityTypeFactoryOutput<PslExtensionBlock, PostgresNativeEnum | undefined> &\n SqlValueSetDerivingEntityTypeOutput;\n\n/**\n * Lowers a `role <name> {}` block into a {@link PostgresRole}. Roles are\n * cluster-scoped in Postgres, so the block must be declared inside\n * `namespace unbound { … }` — any other lexical namespace (a named schema,\n * or the default bucket top-level declarations resolve to) is a load-time\n * diagnostic. The lowered entity carries the unbound coordinate.\n */\nfunction lowerRoleFromBlock(\n block: RoleExtensionBlock,\n ctx: AuthoringEntityContext,\n): PostgresRole | undefined {\n if (block.namespaceId !== UNBOUND_NAMESPACE_ID) {\n ctx.diagnostics?.push({\n code: 'PSL_ROLE_BLOCK_OUTSIDE_UNBOUND_NAMESPACE',\n message: `\\`role\\` block \"${block.name}\" must be declared inside \\`namespace unbound { }\\`, not in namespace \"${block.namespaceId}\"`,\n sourceId: ctx.sourceId ?? 'unknown',\n span: block.span,\n });\n return undefined;\n }\n return new PostgresRole({ name: block.name, namespaceId: UNBOUND_NAMESPACE_ID });\n}\n\nexport const postgresAuthoringEntityTypes = {\n role: {\n kind: 'entity',\n discriminator: 'role',\n validatorSchema: PostgresRoleSchema,\n output: {\n factory: lowerRoleFromBlock,\n },\n },\n rls: {\n kind: 'entity',\n discriminator: 'rls',\n validatorSchema: PostgresRlsEnablementSchema,\n output: {\n factory: (input: PostgresRlsEnablementInput): PostgresRlsEnablement =>\n new PostgresRlsEnablement(input),\n },\n },\n policy: {\n kind: 'entity',\n discriminator: 'policy',\n validatorSchema: PostgresRlsPolicySchema,\n output: {\n factory: lowerRlsPolicyFromBlock,\n },\n },\n native_enum: {\n kind: 'entity',\n discriminator: 'native_enum',\n validatorSchema: PostgresNativeEnumSchema,\n output: nativeEnumEntityTypeOutput,\n },\n} as const satisfies AuthoringEntityTypeNamespace;\n\n/**\n * Field presets contributed by the Postgres target pack.\n *\n * These mirror the PSL scalar-to-codec mapping used by the Postgres adapter\n * (see `createPostgresPslScalarTypeDescriptors`), so that authoring a field\n * via the TS callback surface (e.g. `field.int()`) and via the PSL scalar\n * surface (e.g. `Int`) lowers to byte-identical contracts.\n *\n * The `uuidNative` / `id.uuidv4Native` / `id.uuidv7Native` presets use the\n * native Postgres `uuid` type (codecId `pg/uuid@1`). For cross-target\n * portability use `uuidString` / `id.uuidv4String` / `id.uuidv7String` from\n * the family pack instead.\n */\n/**\n * Shared parameter descriptors for the five `policy_<op>` PSL block\n * keywords. All five share the `policy` discriminator — the parser\n * dispatches by keyword (see the framework's PSL-block SPI), and every\n * keyword's factory lowers to `PostgresRlsPolicy` via `lowerRlsPolicyFromBlock`.\n *\n * The `roles` list uses `scope:'cross-space'` because same-namespace\n * role ref resolution requires PSL namespace entries keyed by `refKind`\n * (i.e. `'role'`), which in turn requires the role block discriminator to\n * equal `'role'`. Aligning discriminator with refKind is tracked for\n * slice 4 (cross-space roles). Until then cross-space passes validation\n * unconditionally and the authored role names flow through unchanged.\n */\nconst policyTargetParam = {\n kind: 'ref',\n refKind: 'model',\n scope: 'same-namespace',\n required: true,\n} as const;\nconst policyRolesParam = {\n kind: 'list',\n of: { kind: 'ref', refKind: 'role', scope: 'cross-space' },\n} as const;\nconst policyPredicateParam = { kind: 'value', codecId: 'pg/text@1', required: true } as const;\n// A policy may only target an RLS-controlled model: the model named by\n// `target` must declare `@@rls`, or the load fails with a diagnostic naming\n// the model and the policy prefix.\nconst policyRequiresRls = { parameter: 'target', attribute: 'rls' } as const;\n\nexport const postgresAuthoringPslBlockDescriptors = {\n // The predicate param set per keyword mirrors Postgres: SELECT/DELETE take\n // USING only; INSERT takes WITH CHECK only; UPDATE/ALL take both. The\n // per-operation predicate matrix is enforced in `lowerRlsPolicyFromBlock`\n // (a wrong predicate for the operation is a load-time diagnostic there),\n // since the generic descriptor validator is not wired into the SQL-family\n // interpreter.\n policy_select: {\n kind: 'pslBlock',\n keyword: 'policy_select',\n discriminator: 'policy',\n name: { required: true },\n parameters: { target: policyTargetParam, roles: policyRolesParam, using: policyPredicateParam },\n requiresModelAttribute: policyRequiresRls,\n },\n policy_delete: {\n kind: 'pslBlock',\n keyword: 'policy_delete',\n discriminator: 'policy',\n name: { required: true },\n parameters: { target: policyTargetParam, roles: policyRolesParam, using: policyPredicateParam },\n requiresModelAttribute: policyRequiresRls,\n },\n policy_insert: {\n kind: 'pslBlock',\n keyword: 'policy_insert',\n discriminator: 'policy',\n name: { required: true },\n parameters: {\n target: policyTargetParam,\n roles: policyRolesParam,\n withCheck: policyPredicateParam,\n },\n requiresModelAttribute: policyRequiresRls,\n },\n policy_update: {\n kind: 'pslBlock',\n keyword: 'policy_update',\n discriminator: 'policy',\n name: { required: true },\n parameters: {\n target: policyTargetParam,\n roles: policyRolesParam,\n using: policyPredicateParam,\n withCheck: policyPredicateParam,\n },\n requiresModelAttribute: policyRequiresRls,\n },\n policy_all: {\n kind: 'pslBlock',\n keyword: 'policy_all',\n discriminator: 'policy',\n name: { required: true },\n parameters: {\n target: policyTargetParam,\n roles: policyRolesParam,\n using: policyPredicateParam,\n withCheck: policyPredicateParam,\n },\n requiresModelAttribute: policyRequiresRls,\n },\n /**\n * PSL block descriptor for `native_enum`.\n *\n * Reuses the existing variadic-block mechanism (the same shape the SQL\n * family's `enum` block ships): the body is an open `memberName = \"value\"`\n * list. `variadicParameters: true` opens the block to arbitrary keys\n * beyond the declared (empty) `parameters` set — the lowering factory\n * (`lowerNativeEnumFromBlock`) turns the variadic entries into ordered\n * members and rejects a bare (value-less) member.\n */\n native_enum: {\n kind: 'pslBlock',\n keyword: 'native_enum',\n discriminator: 'native_enum',\n name: { required: true },\n parameters: {},\n variadicParameters: true,\n },\n /**\n * PSL block descriptor for `role` (e.g. `role anon {}`). Name-only, no\n * parameters and no body content. Declared inside `namespace unbound { }`\n * — see {@link lowerRoleFromBlock} for the placement check and the\n * coordinate the lowered entity carries.\n */\n role: {\n kind: 'pslBlock',\n keyword: 'role',\n discriminator: 'role',\n name: { required: true },\n parameters: {},\n },\n} as const satisfies AuthoringPslBlockDescriptorNamespace;\n\n/**\n * `@@` model attributes contributed by the Postgres target pack.\n *\n * `@@rls` is argument-less: presence marks the model's table\n * RLS-controlled. It lowers to a {@link PostgresRlsEnablement} marker in\n * the namespace's `entries.rls`, keyed by the model's table name — the\n * marker (never the policy set) is what drives\n * `ENABLE`/`DISABLE ROW LEVEL SECURITY` planning.\n */\nexport const postgresAuthoringModelAttributes = {\n rls: {\n kind: 'modelAttribute',\n attribute: 'rls',\n spec: modelAttribute('rls', {}),\n lower: (_parsed: Record<never, never>, ctx: AuthoringModelAttributeContext) => ({\n key: ctx.storageName,\n entity: new PostgresRlsEnablement({\n tableName: ctx.storageName,\n namespaceId: ctx.namespaceId,\n }),\n }),\n },\n} as const satisfies AuthoringModelAttributeDescriptorNamespace;\n\nexport const postgresAuthoringFieldPresets = {\n text: {\n kind: 'fieldPreset',\n output: {\n codecId: 'pg/text@1',\n nativeType: 'text',\n },\n },\n int: {\n kind: 'fieldPreset',\n output: {\n codecId: 'pg/int4@1',\n nativeType: 'int4',\n },\n },\n bigint: {\n kind: 'fieldPreset',\n output: {\n codecId: 'pg/int8@1',\n nativeType: 'int8',\n },\n },\n float: {\n kind: 'fieldPreset',\n output: {\n codecId: 'pg/float8@1',\n nativeType: 'float8',\n },\n },\n decimal: {\n kind: 'fieldPreset',\n output: {\n codecId: 'pg/numeric@1',\n nativeType: 'numeric',\n },\n },\n boolean: {\n kind: 'fieldPreset',\n output: {\n codecId: 'pg/bool@1',\n nativeType: 'bool',\n },\n },\n json: {\n kind: 'fieldPreset',\n output: {\n codecId: 'pg/jsonb@1',\n nativeType: 'jsonb',\n },\n },\n bytes: {\n kind: 'fieldPreset',\n output: {\n codecId: 'pg/bytea@1',\n nativeType: 'bytea',\n },\n },\n dateTime: {\n kind: 'fieldPreset',\n output: {\n codecId: 'pg/timestamptz@1',\n nativeType: 'timestamptz',\n },\n },\n temporal: /* @__PURE__ */ temporalAuthoringPresets({\n codecId: 'pg/timestamptz@1',\n nativeType: 'timestamptz',\n }),\n uuidNative: {\n kind: 'fieldPreset',\n output: {\n codecId: 'pg/uuid@1',\n nativeType: 'uuid',\n },\n },\n id: {\n uuidv4Native: {\n kind: 'fieldPreset',\n output: {\n codecId: 'pg/uuid@1',\n nativeType: 'uuid',\n executionDefaults: {\n onCreate: {\n kind: 'generator',\n id: 'uuidv4',\n },\n },\n id: true,\n },\n },\n uuidv7Native: {\n kind: 'fieldPreset',\n output: {\n codecId: 'pg/uuid@1',\n nativeType: 'uuid',\n executionDefaults: {\n onCreate: {\n kind: 'generator',\n id: 'uuidv7',\n },\n },\n id: true,\n },\n },\n },\n} as const satisfies AuthoringFieldNamespace;\n"],"mappings":";;;;;;;;;;;;;;;;;AAsCA,MAAa,yBAAyB,EACpC,IAAI,EACF,MAAM;CACJ,MAAM;CACN,cAAc;EAAE,OAAO;EAAG,YAAY;CAAc;CACpD,QAAQ,EACN,SAAS,iBACX;AACF,EACF,EACF;;;;;;AAgBA,MAAM,2BAAyE;CAC7E,eAAe;CACf,eAAe;CACf,eAAe;CACf,eAAe;CACf,YAAY;AACd;;;;;;;AAQA,MAAM,8BAEF;CACF,QAAQ;EAAE,OAAO;EAAM,WAAW;CAAM;CACxC,QAAQ;EAAE,OAAO;EAAO,WAAW;CAAK;CACxC,QAAQ;EAAE,OAAO;EAAM,WAAW;CAAK;CACvC,QAAQ;EAAE,OAAO;EAAM,WAAW;CAAM;CACxC,KAAK;EAAE,OAAO;EAAM,WAAW;CAAK;AACtC;AAEA,SAAS,aAAa,OAA0B,KAAiC;CAC/E,MAAM,QAAQ,MAAM,WAAW;CAC/B,OAAO,OAAO,SAAS,QAAQ,MAAM,aAAa,KAAA;AACpD;AAEA,SAAS,eAAe,OAA0B,KAAiC;CACjF,MAAM,QAAQ,MAAM,WAAW;CAC/B,OAAO,OAAO,SAAS,UAAU,MAAM,MAAM,KAAA;AAC/C;AAEA,SAAS,kBAAkB,OAA0B,KAAuB;CAC1E,MAAM,QAAQ,MAAM,WAAW;CAC/B,IAAI,OAAO,SAAS,QAAQ,OAAO,CAAC;CACpC,OAAO,MAAM,MAAM,SAAS,SAAU,KAAK,SAAS,QAAQ,CAAC,KAAK,UAAU,IAAI,CAAC,CAAE;AACrF;;;;;;;AAQA,SAAS,mBAAmB,KAAqB;CAC/C,IAAI,EAAE,IAAI,WAAW,IAAG,KAAK,IAAI,SAAS,IAAG,KAAK,IAAI,UAAU,IAC9D,OAAO;CAET,MAAM,QAAQ,IAAI,MAAM,GAAG,EAAE;CAC7B,IAAI,SAAS;CACb,KAAK,IAAI,IAAI,GAAG,IAAI,MAAM,QAAQ,KAAK;EACrC,IAAI,MAAM,OAAO,QAAQ,IAAI,KAAK,MAAM,QAAQ;GAC9C,UAAU,MAAM;GAChB;EACF;EACA,MAAM,OAAO,MAAM,IAAI;EACvB,IAAI,SAAS,QAAQ,SAAS,MAC5B,UAAU;OACL,IAAI,SAAS,KAClB,UAAU;OACL,IAAI,SAAS,KAClB,UAAU;OACL;GACL,UAAU;GACV,UAAU;EACZ;EACA;CACF;CACA,OAAO;AACT;AAEA,SAAS,wBACP,OACA,KAC+B;CAC/B,MAAM,SAAS,MAAM;CACrB,MAAM,YAAY,yBAAyB,MAAM,YAAY;CAC7D,MAAM,kBAAkB,aAAa,OAAO,QAAQ,KAAK;CACzD,MAAM,YAAY,gBAAgB,OAAO,CAAC,CAAC,CAAC,YAAY,IAAI,gBAAgB,MAAM,CAAC;CACnF,MAAM,QAAQ,CAAC,GAAG,kBAAkB,OAAO,OAAO,CAAC,CAAC,CAAC,KAAK;CAE1D,MAAM,WAAW,eAAe,OAAO,OAAO;CAC9C,MAAM,eAAe,eAAe,OAAO,WAAW;CAOtD,MAAM,UAAU,4BAA4B;CAC5C,MAAM,mBAAmB,cAAgD;EACvE,IAAI,aAAa,KAAK;GACpB,MAAM;GACN,SAAS,KAAK,MAAM,QAAQ,aAAa,MAAM,KAAK,sBAAsB,UAAU,oBAAoB,UAAU,YAAY,EAAE,kBAAkB,QAAQ,QAAQ,YAAY,gBAAgB,QAAQ,SAAS,QAAQ,YAAY,qBAAqB,QAAQ;GAChQ,UAAU,IAAI,YAAY;GAC1B,MAAM,MAAM,WAAW,UAAU,EAAE,QAAQ,MAAM;EACnD,CAAC;CAEH;CACA,IAAI,aAAa,KAAA,KAAa,CAAC,QAAQ,OAAO,OAAO,gBAAgB,OAAO;CAC5E,IAAI,iBAAiB,KAAA,KAAa,CAAC,QAAQ,WAAW,OAAO,gBAAgB,WAAW;CAExF,MAAM,QAAQ,aAAa,KAAA,IAAY,mBAAmB,QAAQ,IAAI,KAAA;CACtE,MAAM,YAAY,iBAAiB,KAAA,IAAY,mBAAmB,YAAY,IAAI,KAAA;CAWlF,OAAO,IAAI,kBAAkB;EAC3B,MAHe,wBAAwB,QAPxB,mBAAmB;GAClC,GAAG,UAAU,SAAS,UAAU,KAAA,IAAY,mBAAmB,KAAK,IAAI,KAAA,CAAS;GACjF,GAAG,UAAU,aAAa,cAAc,KAAA,IAAY,mBAAmB,SAAS,IAAI,KAAA,CAAS;GAC7F;GACA;GACA,YAAY;EACd,CACwD,CAGzC;EACb;EACA;EACA,aAAa,MAAM;EACnB;EACA;EACA,GAAG,UAAU,SAAS,KAAK;EAC3B,GAAG,UAAU,aAAa,SAAS;EACnC,YAAY;CACd,CAAC;AACH;;;;;;;;;;;AAYA,SAAS,yBACP,OACA,KACgC;CAChC,MAAM,WAAW,IAAI,YAAY;CACjC,MAAM,cAAc,IAAI;CAExB,MAAM,UAAU,MAAM,gBAAgB,MAAM,MAAM,EAAE,SAAS,KAAK;CAClE,IAAI,WAAW,MAAM;CACrB,IAAI,SAAS;EACX,MAAM,SAAS,QAAQ,KAAK,EAAE,EAAE;EAChC,MAAM,SAAS,WAAW,KAAA,IAAY,mBAAmB,MAAM,IAAI,KAAA;EACnE,IAAI,WAAW,KAAA,GAAW;GACxB,aAAa,KAAK;IAChB,MAAM;IACN,SAAS,gBAAgB,MAAM,KAAK;IACpC;IACA,MAAM,QAAQ;GAChB,CAAC;GACD;EACF;EACA,WAAW;CACb;CAEA,IAAI,cAAc;CAClB,MAAM,6BAAa,IAAI,IAAY;CACnC,MAAM,UAAoB,CAAC;CAC3B,KAAK,MAAM,CAAC,YAAY,eAAe,OAAO,QAAQ,MAAM,UAAU,GAAG;EACvE,IAAI,WAAW,SAAS,QAAQ;GAC9B,aAAa,KAAK;IAChB,MAAM;IACN,SAAS,gBAAgB,MAAM,KAAK,YAAY,WAAW,+CAA+C,WAAW;IACrH;IACA,MAAM,WAAW;GACnB,CAAC;GACD,cAAc;GACd;EACF;EACA,IAAI,WAAW,SAAS,SAAS;EAEjC,IAAI;EACJ,IAAI;GACF,YAAY,KAAK,MAAM,WAAW,GAAG;EACvC,QAAQ;GACN,aAAa,KAAK;IAChB,MAAM;IACN,SAAS,gBAAgB,MAAM,KAAK,YAAY,WAAW,WAAW,WAAW,IAAI;IACrF;IACA,MAAM,WAAW;GACnB,CAAC;GACD,cAAc;GACd;EACF;EACA,IAAI,OAAO,cAAc,UAAU;GACjC,aAAa,KAAK;IAChB,MAAM;IACN,SAAS,gBAAgB,MAAM,KAAK,YAAY,WAAW;IAC3D;IACA,MAAM,WAAW;GACnB,CAAC;GACD,cAAc;GACd;EACF;EACA,IAAI,WAAW,IAAI,SAAS,GAAG;GAC7B,aAAa,KAAK;IAChB,MAAM;IACN,SAAS,gBAAgB,MAAM,KAAK,6BAA6B,UAAU;IAC3E;IACA,MAAM,WAAW;GACnB,CAAC;GACD,cAAc;GACd;EACF;EACA,WAAW,IAAI,SAAS;EACxB,QAAQ,KAAK,SAAS;CACxB;CAEA,IAAI,aAAa,OAAO,KAAA;CAExB,IAAI,QAAQ,WAAW,GAAG;EACxB,aAAa,KAAK;GAChB,MAAM;GACN,SAAS,gBAAgB,MAAM,KAAK;GACpC;GACA,MAAM,MAAM;EACd,CAAC;EACD;CACF;CAGA,OAAO,IAAI,mBAAmB;EAAE;EAAU;CAAQ,CAAC;AACrD;;;;;;;;;;AAWA,MAAM,6BAA6B;CACjC,SAAS;CACT,iBAAiB,YAAgC;EAC/C,MAAM;EACN,QAAQ,CAAC,GAAG,OAAO,OAAO;CAC5B;AACF;;;;;;;;AAUA,SAAS,mBACP,OACA,KAC0B;CAC1B,IAAI,MAAM,gBAAgB,sBAAsB;EAC9C,IAAI,aAAa,KAAK;GACpB,MAAM;GACN,SAAS,mBAAmB,MAAM,KAAK,yEAAyE,MAAM,YAAY;GAClI,UAAU,IAAI,YAAY;GAC1B,MAAM,MAAM;EACd,CAAC;EACD;CACF;CACA,OAAO,IAAI,aAAa;EAAE,MAAM,MAAM;EAAM,aAAa;CAAqB,CAAC;AACjF;AAEA,MAAa,+BAA+B;CAC1C,MAAM;EACJ,MAAM;EACN,eAAe;EACf,iBAAiB;EACjB,QAAQ,EACN,SAAS,mBACX;CACF;CACA,KAAK;EACH,MAAM;EACN,eAAe;EACf,iBAAiB;EACjB,QAAQ,EACN,UAAU,UACR,IAAI,sBAAsB,KAAK,EACnC;CACF;CACA,QAAQ;EACN,MAAM;EACN,eAAe;EACf,iBAAiB;EACjB,QAAQ,EACN,SAAS,wBACX;CACF;CACA,aAAa;EACX,MAAM;EACN,eAAe;EACf,iBAAiB;EACjB,QAAQ;CACV;AACF;;;;;;;;;;;;;;;;;;;;;;;;;;;AA4BA,MAAM,oBAAoB;CACxB,MAAM;CACN,SAAS;CACT,OAAO;CACP,UAAU;AACZ;AACA,MAAM,mBAAmB;CACvB,MAAM;CACN,IAAI;EAAE,MAAM;EAAO,SAAS;EAAQ,OAAO;CAAc;AAC3D;AACA,MAAM,uBAAuB;CAAE,MAAM;CAAS,SAAS;CAAa,UAAU;AAAK;AAInF,MAAM,oBAAoB;CAAE,WAAW;CAAU,WAAW;AAAM;AAElE,MAAa,uCAAuC;CAOlD,eAAe;EACb,MAAM;EACN,SAAS;EACT,eAAe;EACf,MAAM,EAAE,UAAU,KAAK;EACvB,YAAY;GAAE,QAAQ;GAAmB,OAAO;GAAkB,OAAO;EAAqB;EAC9F,wBAAwB;CAC1B;CACA,eAAe;EACb,MAAM;EACN,SAAS;EACT,eAAe;EACf,MAAM,EAAE,UAAU,KAAK;EACvB,YAAY;GAAE,QAAQ;GAAmB,OAAO;GAAkB,OAAO;EAAqB;EAC9F,wBAAwB;CAC1B;CACA,eAAe;EACb,MAAM;EACN,SAAS;EACT,eAAe;EACf,MAAM,EAAE,UAAU,KAAK;EACvB,YAAY;GACV,QAAQ;GACR,OAAO;GACP,WAAW;EACb;EACA,wBAAwB;CAC1B;CACA,eAAe;EACb,MAAM;EACN,SAAS;EACT,eAAe;EACf,MAAM,EAAE,UAAU,KAAK;EACvB,YAAY;GACV,QAAQ;GACR,OAAO;GACP,OAAO;GACP,WAAW;EACb;EACA,wBAAwB;CAC1B;CACA,YAAY;EACV,MAAM;EACN,SAAS;EACT,eAAe;EACf,MAAM,EAAE,UAAU,KAAK;EACvB,YAAY;GACV,QAAQ;GACR,OAAO;GACP,OAAO;GACP,WAAW;EACb;EACA,wBAAwB;CAC1B;;;;;;;;;;;CAWA,aAAa;EACX,MAAM;EACN,SAAS;EACT,eAAe;EACf,MAAM,EAAE,UAAU,KAAK;EACvB,YAAY,CAAC;EACb,oBAAoB;CACtB;;;;;;;CAOA,MAAM;EACJ,MAAM;EACN,SAAS;EACT,eAAe;EACf,MAAM,EAAE,UAAU,KAAK;EACvB,YAAY,CAAC;CACf;AACF;;;;;;;;;;AAWA,MAAa,mCAAmC,EAC9C,KAAK;CACH,MAAM;CACN,WAAW;CACX,MAAM,eAAe,OAAO,CAAC,CAAC;CAC9B,QAAQ,SAA+B,SAAyC;EAC9E,KAAK,IAAI;EACT,QAAQ,IAAI,sBAAsB;GAChC,WAAW,IAAI;GACf,aAAa,IAAI;EACnB,CAAC;CACH;AACF,EACF;AAEA,MAAa,gCAAgC;CAC3C,MAAM;EACJ,MAAM;EACN,QAAQ;GACN,SAAS;GACT,YAAY;EACd;CACF;CACA,KAAK;EACH,MAAM;EACN,QAAQ;GACN,SAAS;GACT,YAAY;EACd;CACF;CACA,QAAQ;EACN,MAAM;EACN,QAAQ;GACN,SAAS;GACT,YAAY;EACd;CACF;CACA,OAAO;EACL,MAAM;EACN,QAAQ;GACN,SAAS;GACT,YAAY;EACd;CACF;CACA,SAAS;EACP,MAAM;EACN,QAAQ;GACN,SAAS;GACT,YAAY;EACd;CACF;CACA,SAAS;EACP,MAAM;EACN,QAAQ;GACN,SAAS;GACT,YAAY;EACd;CACF;CACA,MAAM;EACJ,MAAM;EACN,QAAQ;GACN,SAAS;GACT,YAAY;EACd;CACF;CACA,OAAO;EACL,MAAM;EACN,QAAQ;GACN,SAAS;GACT,YAAY;EACd;CACF;CACA,UAAU;EACR,MAAM;EACN,QAAQ;GACN,SAAS;GACT,YAAY;EACd;CACF;CACA,UAA0B,yCAAyB;EACjD,SAAS;EACT,YAAY;CACd,CAAC;CACD,YAAY;EACV,MAAM;EACN,QAAQ;GACN,SAAS;GACT,YAAY;EACd;CACF;CACA,IAAI;EACF,cAAc;GACZ,MAAM;GACN,QAAQ;IACN,SAAS;IACT,YAAY;IACZ,mBAAmB,EACjB,UAAU;KACR,MAAM;KACN,IAAI;IACN,EACF;IACA,IAAI;GACN;EACF;EACA,cAAc;GACZ,MAAM;GACN,QAAQ;IACN,SAAS;IACT,YAAY;IACZ,mBAAmB,EACjB,UAAU;KACR,MAAM;KACN,IAAI;IACN,EACF;IACA,IAAI;GACN;EACF;CACF;AACF"}
@@ -1193,40 +1193,12 @@ function resolvePostgresNodeIssueCreationFactoryName(issue) {
1193
1193
  return POSTGRES_NODE_CREATION_FACTORY[node.nodeKind];
1194
1194
  }
1195
1195
  /**
1196
- * Resolve the control-policy subject coordinate for a single node-typed
1197
- * {@link SchemaDiffIssue}. Mirrors the resolution
1198
- * `resolvePostgresCallControlPolicySubject` performs for a generated DDL
1199
- * call, but works *off the issue* so the planner can partition issues by
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.
1219
- *
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.
1196
+ * Resolves the control-policy subject for a node-typed {@link SchemaDiffIssue}
1197
+ * (the issue-side mirror of `resolvePostgresCallControlPolicySubject`).
1198
+ * Storage entities resolve off their node coordinate; a sub-entity issue
1199
+ * resolves off the enclosing table read from the issue path; an unclaimed
1200
+ * extra falls back to the unbound coordinate. A role always resolves
1201
+ * `'external'` — roles are referenced, never owned.
1230
1202
  */
1231
1203
  function resolvePostgresNodeIssueControlPolicySubject(issue, contract) {
1232
1204
  const node = issue.expected ?? issue.actual;
@@ -1283,4 +1255,4 @@ function resolvePostgresNodeIssueControlPolicySubject(issue, contract) {
1283
1255
  //#endregion
1284
1256
  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 };
1285
1257
 
1286
- //# sourceMappingURL=control-policy-SqhTdh7B.mjs.map
1258
+ //# sourceMappingURL=control-policy-5_5odTg9.mjs.map