@prisma-next/target-postgres 0.15.0-dev.12 → 0.15.0-dev.14
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-BtsOWgI3.mjs → authoring-CGe-7Yr9.mjs} +16 -6
- package/dist/authoring-CGe-7Yr9.mjs.map +1 -0
- package/dist/control.mjs +3 -3
- package/dist/{descriptor-meta-CFQKLXl_.mjs → descriptor-meta-Bxw2GNog.mjs} +2 -2
- package/dist/{descriptor-meta-CFQKLXl_.mjs.map → descriptor-meta-Bxw2GNog.mjs.map} +1 -1
- package/dist/migration.mjs +1 -1
- package/dist/pack.d.mts +105 -1
- package/dist/pack.d.mts.map +1 -1
- package/dist/pack.mjs +1 -1
- package/dist/{planner-ootbxGty.mjs → planner-BWmH0NqM.mjs} +2 -2
- package/dist/{planner-ootbxGty.mjs.map → planner-BWmH0NqM.mjs.map} +1 -1
- package/dist/{planner-produced-postgres-migration-DVsaobdV.mjs → planner-produced-postgres-migration-BV3WLLXl.mjs} +2 -2
- package/dist/{planner-produced-postgres-migration-DVsaobdV.mjs.map → planner-produced-postgres-migration-BV3WLLXl.mjs.map} +1 -1
- package/dist/planner-produced-postgres-migration.mjs +1 -1
- package/dist/planner.mjs +1 -1
- package/dist/{postgres-contract-view-DM8sN1Ot.mjs → postgres-contract-view-CWsxTdoA.mjs} +2 -2
- package/dist/{postgres-contract-view-DM8sN1Ot.mjs.map → postgres-contract-view-CWsxTdoA.mjs.map} +1 -1
- package/dist/{postgres-migration-Bt3sXoID.mjs → postgres-migration-1_ZoswMV.mjs} +2 -2
- package/dist/{postgres-migration-Bt3sXoID.mjs.map → postgres-migration-1_ZoswMV.mjs.map} +1 -1
- package/dist/runtime.mjs +1 -1
- package/package.json +20 -20
- package/src/core/authoring.ts +18 -5
- package/dist/authoring-BtsOWgI3.mjs.map +0 -1
|
@@ -4,7 +4,7 @@ import { _ as PostgresRlsEnablement, d as PostgresRlsEnablementSchema, f as Post
|
|
|
4
4
|
import { a as normalizePredicate, i as computeContentHash, r as POLICY_OPERATION_PREDICATES, t as formatRlsPolicyWireName } from "./wire-name-DbQ9-2RC.mjs";
|
|
5
5
|
import { UNBOUND_NAMESPACE_ID } from "@prisma-next/framework-components/ir";
|
|
6
6
|
import { blindCast } from "@prisma-next/utils/casts";
|
|
7
|
-
import { temporalAuthoringPresets } from "@prisma-next/family-sql/control";
|
|
7
|
+
import { temporalAuthoringPresets, temporalCodecPresetWithPrecision } from "@prisma-next/family-sql/control";
|
|
8
8
|
import { ifDefined } from "@prisma-next/utils/defined";
|
|
9
9
|
import { modelAttribute } from "@prisma-next/psl-parser";
|
|
10
10
|
import { assertDefined } from "@prisma-next/utils/assertions";
|
|
@@ -519,10 +519,20 @@ const postgresAuthoringFieldPresets = {
|
|
|
519
519
|
nativeType: "timestamptz"
|
|
520
520
|
}
|
|
521
521
|
},
|
|
522
|
-
temporal:
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
522
|
+
temporal: {
|
|
523
|
+
.../* @__PURE__ */ temporalAuthoringPresets({
|
|
524
|
+
codecId: "pg/timestamptz@1",
|
|
525
|
+
nativeType: "timestamptz"
|
|
526
|
+
}),
|
|
527
|
+
timestamp: /* @__PURE__ */ temporalCodecPresetWithPrecision({
|
|
528
|
+
codecId: "pg/timestamp@1",
|
|
529
|
+
nativeType: "timestamp"
|
|
530
|
+
}),
|
|
531
|
+
timestamptz: /* @__PURE__ */ temporalCodecPresetWithPrecision({
|
|
532
|
+
codecId: "pg/timestamptz@1",
|
|
533
|
+
nativeType: "timestamptz"
|
|
534
|
+
})
|
|
535
|
+
},
|
|
526
536
|
uuidNative: {
|
|
527
537
|
kind: "fieldPreset",
|
|
528
538
|
output: {
|
|
@@ -671,4 +681,4 @@ function postgresLowerEntityHandles(input) {
|
|
|
671
681
|
//#endregion
|
|
672
682
|
export { postgresAuthoringTypes as a, postgresAuthoringPslBlockDescriptors as i, postgresAuthoringFieldPresets as n, postgresLowerEntityHandles as o, postgresAuthoringModelAttributes as r, postgresAuthoringEntityTypes as t };
|
|
673
683
|
|
|
674
|
-
//# sourceMappingURL=authoring-
|
|
684
|
+
//# sourceMappingURL=authoring-CGe-7Yr9.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"authoring-CGe-7Yr9.mjs","names":[],"sources":["../src/core/authoring.ts"],"sourcesContent":["import {\n temporalAuthoringPresets,\n temporalCodecPresetWithPrecision,\n} 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 {\n EntityHandleLoweringInput,\n LoweredPackEntity,\n ResolvedEntityHandleRef,\n ResolvedPslModelRefs,\n} from '@prisma-next/sql-contract/entity-handle-lowering-hook';\nimport type { SqlValueSetDerivingEntityTypeOutput } from '@prisma-next/sql-contract/value-set-derivation-hook';\nimport { assertDefined } from '@prisma-next/utils/assertions';\nimport { blindCast } from '@prisma-next/utils/casts';\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 {\n computeContentHash,\n normalizePredicate,\n POLICY_OPERATION_PREDICATES,\n} 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 * Model refs the family interpreter resolved from the block's descriptor-\n * declared `refKind: 'model'` parameters before invoking this factory\n * (keyed by parameter name). An unresolved required ref is the\n * interpreter's diagnostic; the factory is never called with one missing.\n */\n readonly resolvedModelRefs?: ResolvedPslModelRefs;\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\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\n/**\n * Assembles a {@link PostgresRlsPolicy} from lowered inputs: normalizes the\n * predicates, computes the content-hash wire name, and constructs the frozen\n * entity. The single hash-assembly body shared by the PSL block lowering\n * ({@link lowerRlsPolicyFromBlock}) and the TS entity-handle lowering\n * ({@link postgresLowerEntityHandles}) so the two surfaces cannot drift.\n */\nfunction buildRlsPolicyEntity(input: {\n readonly prefix: string;\n readonly tableName: string;\n readonly namespaceId: string;\n readonly operation: RlsPolicyOperation;\n readonly roles: readonly string[];\n readonly using?: string;\n readonly withCheck?: string;\n}): PostgresRlsPolicy {\n const wireHash = computeContentHash({\n ...ifDefined('using', input.using !== undefined ? normalizePredicate(input.using) : undefined),\n ...ifDefined(\n 'withCheck',\n input.withCheck !== undefined ? normalizePredicate(input.withCheck) : undefined,\n ),\n roles: input.roles,\n operation: input.operation,\n permissive: true,\n });\n\n return new PostgresRlsPolicy({\n name: formatRlsPolicyWireName(input.prefix, wireHash),\n prefix: input.prefix,\n tableName: input.tableName,\n namespaceId: input.namespaceId,\n operation: input.operation,\n roles: input.roles,\n ...ifDefined('using', input.using),\n ...ifDefined('withCheck', input.withCheck),\n permissive: true,\n });\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 // The interpreter resolves the descriptor-declared `target` model ref to\n // its storage table name before invoking this factory (an unresolved or\n // missing required ref is the interpreter's diagnostic), so a lookup miss\n // here is structurally impossible.\n const tableName = block.resolvedModelRefs?.['target']?.tableName;\n assertDefined(\n tableName,\n `lowerRlsPolicyFromBlock: policy \"${block.name}\" reached the factory without a resolved \\`target\\` ref; the interpreter resolves same-namespace model refs before invoking entity factories.`,\n );\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 return buildRlsPolicyEntity({\n prefix,\n tableName,\n namespaceId: block.namespaceId,\n operation,\n roles,\n ...ifDefined('using', using),\n ...ifDefined('withCheck', withCheck),\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: {\n .../* @__PURE__ */ temporalAuthoringPresets({\n codecId: 'pg/timestamptz@1',\n nativeType: 'timestamptz',\n }),\n timestamp: /* @__PURE__ */ temporalCodecPresetWithPrecision({\n codecId: 'pg/timestamp@1',\n nativeType: 'timestamp',\n }),\n timestamptz: /* @__PURE__ */ temporalCodecPresetWithPrecision({\n codecId: 'pg/timestamptz@1',\n nativeType: 'timestamptz',\n }),\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\n/**\n * Postgres identifiers cap at 63 characters and the wire name appends a\n * 9-character `_<8hex>` suffix, so the authored prefix is bounded at 54.\n */\nconst RLS_POLICY_PREFIX_MAX_LENGTH = 54;\n\ninterface RlsRoleHandleShape {\n readonly entityKind: 'role';\n readonly name: string;\n}\n\ninterface RlsPolicyHandleShape {\n readonly entityKind: 'policy';\n readonly operation: RlsPolicyOperation;\n readonly name: string;\n readonly roles: readonly { readonly name: string }[];\n readonly using?: string;\n readonly withCheck?: string;\n}\n\ninterface RlsTargetCoordinate {\n readonly namespaceId: string;\n readonly tableName: string;\n}\n\n/**\n * Resolves an entity handle's `target` ref to a table coordinate of this\n * contract, or throws the load-time diagnostic naming the handle: a\n * cross-space target is rejected (you cannot CREATE POLICY on a table\n * another space owns) and an unresolved target names the model.\n */\nfunction requireLocalTarget(\n refs: Readonly<Record<string, ResolvedEntityHandleRef>>,\n subject: string,\n): RlsTargetCoordinate {\n const target = refs['target'];\n if (target !== undefined && target.kind === 'resolved') {\n return { namespaceId: target.namespaceId, tableName: target.tableName };\n }\n if (target !== undefined && target.kind === 'cross-space') {\n throw new Error(\n `defineContract: ${subject} targets model \"${target.modelName ?? target.tableName}\", which lives in another contract space. Policies and rlsEnabled entries must target a model declared in this contract.`,\n );\n }\n throw new Error(\n `defineContract: ${subject} targets model \"${target?.modelName ?? '<anonymous>'}\", which is not in the contract's models. Add the model to \\`models\\`.`,\n );\n}\n\n/**\n * The SQL-family entity-handle batch lowering hook for the Postgres pack\n * (`SqlEntityHandleLoweringContribution`). Receives every `entities` handle\n * whose kind this pack registered — batch, so the cross-entity diagnostics\n * (duplicate prefix, policy without rlsEnabled, duplicate role) can see\n * sibling handles — and lowers them with the same keying and hash assembly\n * as the PSL path: `policy` keyed by prefix (wire name via\n * {@link buildRlsPolicyEntity}), `rls` keyed by table name, `role` keyed by\n * name and filed under the default namespace (roles are declared\n * contract-wide; PSL has no role block to set a precedent).\n */\nexport function postgresLowerEntityHandles(\n input: EntityHandleLoweringInput,\n): readonly LoweredPackEntity[] {\n const enablements = new Map<\n string,\n { coordinate: RlsTargetCoordinate; entity: PostgresRlsEnablement }\n >();\n const roles = new Map<string, PostgresRole>();\n const policies: {\n readonly handle: RlsPolicyHandleShape;\n readonly refs: Readonly<Record<string, ResolvedEntityHandleRef>>;\n }[] = [];\n const coordinateKey = (coordinate: RlsTargetCoordinate): string =>\n `${coordinate.namespaceId} ${coordinate.tableName}`;\n\n for (const { handle, refs } of input.handles) {\n switch (handle.entityKind) {\n case 'rls': {\n const coordinate = requireLocalTarget(refs, 'an rlsEnabled entry');\n const key = coordinateKey(coordinate);\n if (!enablements.has(key)) {\n enablements.set(key, {\n coordinate,\n entity: new PostgresRlsEnablement({\n tableName: coordinate.tableName,\n namespaceId: coordinate.namespaceId,\n }),\n });\n }\n break;\n }\n case 'role': {\n const roleHandle = blindCast<\n RlsRoleHandleShape,\n 'role handles are constructed only by the postgres contract-builder role() constructor, which enforces this shape'\n >(handle);\n if (roles.has(roleHandle.name)) {\n throw new Error(\n `defineContract: role \"${roleHandle.name}\" is declared more than once in the entities list.`,\n );\n }\n // Roles are cluster-scoped in Postgres, so they always land in the\n // `__unbound__` namespace — identical to a PSL `role` block\n // (`lowerRoleFromBlock`) and matching the `PostgresRole` class's own\n // contract. The declaring surface (TS entities vs PSL) does not move\n // the slot.\n roles.set(\n roleHandle.name,\n new PostgresRole({ name: roleHandle.name, namespaceId: UNBOUND_NAMESPACE_ID }),\n );\n break;\n }\n case 'policy': {\n const policyHandle = blindCast<\n RlsPolicyHandleShape,\n 'policy handles are constructed only by the postgres contract-builder policy*() constructors, which enforce this shape'\n >(handle);\n policies.push({ handle: policyHandle, refs });\n break;\n }\n default:\n throw new Error(\n `defineContract: the postgres pack does not lower \"${handle.entityKind}\" handles from the entities list.`,\n );\n }\n }\n\n const rows: LoweredPackEntity[] = [];\n const seenPrefixes = new Set<string>();\n\n for (const { handle: policy, refs } of policies) {\n const prefix = policy.name;\n if (prefix.length > RLS_POLICY_PREFIX_MAX_LENGTH) {\n throw new Error(\n `defineContract: policy prefix \"${prefix}\" exceeds the ${RLS_POLICY_PREFIX_MAX_LENGTH}-character maximum (Postgres identifiers cap at 63 characters and the wire name appends a 9-character hash suffix).`,\n );\n }\n const coordinate = requireLocalTarget(refs, `policy \"${prefix}\"`);\n if (!enablements.has(coordinateKey(coordinate))) {\n const target = refs['target'];\n throw new Error(\n `defineContract: policy \"${prefix}\" targets model \"${target?.modelName ?? coordinate.tableName}\", whose table is not RLS-enabled. Add rlsEnabled(<model>) to the entities list.`,\n );\n }\n const prefixKey = `${coordinate.namespaceId} ${prefix}`;\n if (seenPrefixes.has(prefixKey)) {\n throw new Error(\n `defineContract: policy prefix \"${prefix}\" is declared more than once in namespace \"${coordinate.namespaceId}\". Policy prefixes must be unique per namespace.`,\n );\n }\n seenPrefixes.add(prefixKey);\n\n const roleNames = [...new Set(policy.roles.map((roleHandle) => roleHandle.name))].sort();\n rows.push({\n namespaceId: coordinate.namespaceId,\n entityKind: 'policy',\n key: prefix,\n entity: buildRlsPolicyEntity({\n prefix,\n tableName: coordinate.tableName,\n namespaceId: coordinate.namespaceId,\n operation: policy.operation,\n roles: roleNames,\n ...ifDefined('using', policy.using),\n ...ifDefined('withCheck', policy.withCheck),\n }),\n });\n }\n\n for (const { coordinate, entity } of enablements.values()) {\n rows.push({\n namespaceId: coordinate.namespaceId,\n entityKind: 'rls',\n key: coordinate.tableName,\n entity,\n });\n }\n for (const [name, entity] of roles) {\n rows.push({ namespaceId: UNBOUND_NAMESPACE_ID, entityKind: 'role', key: name, entity });\n }\n return rows;\n}\n"],"mappings":"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"}
|
package/dist/control.mjs
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import { t as postgresTargetDescriptorMeta } from "./descriptor-meta-
|
|
1
|
+
import { t as postgresTargetDescriptorMeta } from "./descriptor-meta-Bxw2GNog.mjs";
|
|
2
2
|
import { a as postgresDiffSubjectGranularity, i as postgresDiffSubjectEntityKind } from "./postgres-table-schema-node-D6LvInCe.mjs";
|
|
3
3
|
import { i as PostgresDatabaseSchemaNode } from "./postgres-role-schema-node-bg32e7I-.mjs";
|
|
4
4
|
import { n as diffPostgresSchema, r as contractToPostgresDatabaseSchemaNode } from "./diff-database-schema-oY3brcLj.mjs";
|
|
5
5
|
import { r as renderDefaultLiteral } from "./planner-ddl-builders-BKlmGDJl.mjs";
|
|
6
|
-
import { n as PostgresContractSerializer } from "./postgres-contract-view-
|
|
7
|
-
import { t as createPostgresMigrationPlanner } from "./planner-
|
|
6
|
+
import { n as PostgresContractSerializer } from "./postgres-contract-view-CWsxTdoA.mjs";
|
|
7
|
+
import { t as createPostgresMigrationPlanner } from "./planner-BWmH0NqM.mjs";
|
|
8
8
|
import { UNBOUND_NAMESPACE_ID, coordinateKey, elementCoordinates } from "@prisma-next/framework-components/ir";
|
|
9
9
|
import { blindCast } from "@prisma-next/utils/casts";
|
|
10
10
|
import { buildNativeTypeExpander, runnerFailure, runnerSuccess } from "@prisma-next/family-sql/control";
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { E as postgresQualifyColumnType } from "./codecs-DRbb26Or.mjs";
|
|
2
2
|
import { t as DEFAULT_NAMESPACE_ID } from "./namespace-ids-xtp_ZY86.mjs";
|
|
3
3
|
import { i as postgresCreateNamespace } from "./postgres-schema-Cm4DtiGA.mjs";
|
|
4
|
-
import { a as postgresAuthoringTypes, i as postgresAuthoringPslBlockDescriptors, n as postgresAuthoringFieldPresets, o as postgresLowerEntityHandles, r as postgresAuthoringModelAttributes, t as postgresAuthoringEntityTypes } from "./authoring-
|
|
4
|
+
import { a as postgresAuthoringTypes, i as postgresAuthoringPslBlockDescriptors, n as postgresAuthoringFieldPresets, o as postgresLowerEntityHandles, r as postgresAuthoringModelAttributes, t as postgresAuthoringEntityTypes } from "./authoring-CGe-7Yr9.mjs";
|
|
5
5
|
import { t as postgresTargetDescriptorMetaRuntime } from "./descriptor-meta-runtime-UwYdV8fD.mjs";
|
|
6
6
|
const postgresTargetDescriptorMeta = {
|
|
7
7
|
...postgresTargetDescriptorMetaRuntime,
|
|
@@ -20,4 +20,4 @@ const postgresTargetDescriptorMeta = {
|
|
|
20
20
|
//#endregion
|
|
21
21
|
export { postgresTargetDescriptorMeta as t };
|
|
22
22
|
|
|
23
|
-
//# sourceMappingURL=descriptor-meta-
|
|
23
|
+
//# sourceMappingURL=descriptor-meta-Bxw2GNog.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"descriptor-meta-
|
|
1
|
+
{"version":3,"file":"descriptor-meta-Bxw2GNog.mjs","names":[],"sources":["../src/core/descriptor-meta.ts"],"sourcesContent":["import type { CodecTypes } from '../exports/codec-types';\nimport {\n postgresAuthoringEntityTypes,\n postgresAuthoringFieldPresets,\n postgresAuthoringModelAttributes,\n postgresAuthoringPslBlockDescriptors,\n postgresAuthoringTypes,\n postgresLowerEntityHandles,\n} from './authoring';\nimport { postgresQualifyColumnType } from './codecs';\nimport { postgresTargetDescriptorMetaRuntime } from './descriptor-meta-runtime';\nimport { DEFAULT_NAMESPACE_ID } from './namespace-ids';\nimport { postgresCreateNamespace } from './postgres-schema';\n\nconst postgresTargetDescriptorMetaBase = {\n ...postgresTargetDescriptorMetaRuntime,\n defaultNamespaceId: DEFAULT_NAMESPACE_ID,\n authoring: {\n type: postgresAuthoringTypes,\n field: postgresAuthoringFieldPresets,\n entityTypes: postgresAuthoringEntityTypes,\n pslBlockDescriptors: postgresAuthoringPslBlockDescriptors,\n modelAttributes: postgresAuthoringModelAttributes,\n createNamespace: postgresCreateNamespace,\n qualifyColumnType: postgresQualifyColumnType,\n lowerEntityHandles: postgresLowerEntityHandles,\n },\n} as const;\n\nexport const postgresTargetDescriptorMeta: typeof postgresTargetDescriptorMetaBase & {\n readonly __codecTypes?: CodecTypes;\n} = postgresTargetDescriptorMetaBase;\n"],"mappings":";;;;;AA6BA,MAAa,+BAET;CAhBF,GAAG;CACH,oBAAoB;CACpB,WAAW;EACT,MAAM;EACN,OAAO;EACP,aAAa;EACb,qBAAqB;EACrB,iBAAiB;EACjB,iBAAiB;EACjB,mBAAmB;EACnB,oBAAoB;CACtB;AAKE"}
|
package/dist/migration.mjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { P as createExtension } from "./op-factory-call-tBcLo_B8.mjs";
|
|
2
2
|
import { t as dataTransform } from "./data-transform-BOWpliq8.mjs";
|
|
3
|
-
import { t as PostgresMigration } from "./postgres-migration-
|
|
3
|
+
import { t as PostgresMigration } from "./postgres-migration-1_ZoswMV.mjs";
|
|
4
4
|
import { checkExpression, col, fn, foreignKey, lit, primaryKey, unique } from "@prisma-next/sql-relational-core/contract-free";
|
|
5
5
|
import { placeholder } from "@prisma-next/errors/migration";
|
|
6
6
|
import { MigrationCLI } from "@prisma-next/cli/migration-cli";
|
package/dist/pack.d.mts
CHANGED
|
@@ -116,6 +116,110 @@ declare const postgresTargetDescriptorMetaBase: {
|
|
|
116
116
|
};
|
|
117
117
|
};
|
|
118
118
|
readonly temporal: {
|
|
119
|
+
readonly timestamp: {
|
|
120
|
+
readonly kind: "fieldPreset";
|
|
121
|
+
readonly args: readonly [{
|
|
122
|
+
readonly name: "precision";
|
|
123
|
+
readonly kind: "number";
|
|
124
|
+
readonly optional: true;
|
|
125
|
+
readonly integer: true;
|
|
126
|
+
readonly minimum: 0;
|
|
127
|
+
}, {
|
|
128
|
+
readonly name: "onCreate";
|
|
129
|
+
readonly kind: "option";
|
|
130
|
+
readonly values: readonly ["now"];
|
|
131
|
+
readonly optional: true;
|
|
132
|
+
}, {
|
|
133
|
+
readonly name: "onUpdate";
|
|
134
|
+
readonly kind: "option";
|
|
135
|
+
readonly values: readonly ["now"];
|
|
136
|
+
readonly optional: true;
|
|
137
|
+
}];
|
|
138
|
+
readonly output: {
|
|
139
|
+
readonly codecId: "pg/timestamp@1";
|
|
140
|
+
readonly nativeType: "timestamp";
|
|
141
|
+
readonly typeParams: {
|
|
142
|
+
readonly precision: {
|
|
143
|
+
readonly kind: "arg";
|
|
144
|
+
readonly index: 0;
|
|
145
|
+
};
|
|
146
|
+
};
|
|
147
|
+
readonly executionDefaults: {
|
|
148
|
+
readonly onCreate: {
|
|
149
|
+
readonly kind: "select";
|
|
150
|
+
readonly index: 1;
|
|
151
|
+
readonly cases: {
|
|
152
|
+
readonly now: {
|
|
153
|
+
readonly kind: "generator";
|
|
154
|
+
readonly id: "timestampNow";
|
|
155
|
+
};
|
|
156
|
+
};
|
|
157
|
+
};
|
|
158
|
+
readonly onUpdate: {
|
|
159
|
+
readonly kind: "select";
|
|
160
|
+
readonly index: 2;
|
|
161
|
+
readonly cases: {
|
|
162
|
+
readonly now: {
|
|
163
|
+
readonly kind: "generator";
|
|
164
|
+
readonly id: "timestampNow";
|
|
165
|
+
};
|
|
166
|
+
};
|
|
167
|
+
};
|
|
168
|
+
};
|
|
169
|
+
};
|
|
170
|
+
};
|
|
171
|
+
readonly timestamptz: {
|
|
172
|
+
readonly kind: "fieldPreset";
|
|
173
|
+
readonly args: readonly [{
|
|
174
|
+
readonly name: "precision";
|
|
175
|
+
readonly kind: "number";
|
|
176
|
+
readonly optional: true;
|
|
177
|
+
readonly integer: true;
|
|
178
|
+
readonly minimum: 0;
|
|
179
|
+
}, {
|
|
180
|
+
readonly name: "onCreate";
|
|
181
|
+
readonly kind: "option";
|
|
182
|
+
readonly values: readonly ["now"];
|
|
183
|
+
readonly optional: true;
|
|
184
|
+
}, {
|
|
185
|
+
readonly name: "onUpdate";
|
|
186
|
+
readonly kind: "option";
|
|
187
|
+
readonly values: readonly ["now"];
|
|
188
|
+
readonly optional: true;
|
|
189
|
+
}];
|
|
190
|
+
readonly output: {
|
|
191
|
+
readonly codecId: "pg/timestamptz@1";
|
|
192
|
+
readonly nativeType: "timestamptz";
|
|
193
|
+
readonly typeParams: {
|
|
194
|
+
readonly precision: {
|
|
195
|
+
readonly kind: "arg";
|
|
196
|
+
readonly index: 0;
|
|
197
|
+
};
|
|
198
|
+
};
|
|
199
|
+
readonly executionDefaults: {
|
|
200
|
+
readonly onCreate: {
|
|
201
|
+
readonly kind: "select";
|
|
202
|
+
readonly index: 1;
|
|
203
|
+
readonly cases: {
|
|
204
|
+
readonly now: {
|
|
205
|
+
readonly kind: "generator";
|
|
206
|
+
readonly id: "timestampNow";
|
|
207
|
+
};
|
|
208
|
+
};
|
|
209
|
+
};
|
|
210
|
+
readonly onUpdate: {
|
|
211
|
+
readonly kind: "select";
|
|
212
|
+
readonly index: 2;
|
|
213
|
+
readonly cases: {
|
|
214
|
+
readonly now: {
|
|
215
|
+
readonly kind: "generator";
|
|
216
|
+
readonly id: "timestampNow";
|
|
217
|
+
};
|
|
218
|
+
};
|
|
219
|
+
};
|
|
220
|
+
};
|
|
221
|
+
};
|
|
222
|
+
};
|
|
119
223
|
readonly createdAt: {
|
|
120
224
|
readonly kind: "fieldPreset";
|
|
121
225
|
readonly output: {
|
|
@@ -218,7 +322,7 @@ declare const postgresTargetDescriptorMetaBase: {
|
|
|
218
322
|
prefix: string;
|
|
219
323
|
tableName: string;
|
|
220
324
|
namespaceId: string;
|
|
221
|
-
operation: "
|
|
325
|
+
operation: "select" | "delete" | "insert" | "update" | "all";
|
|
222
326
|
roles: readonly string[];
|
|
223
327
|
permissive: boolean;
|
|
224
328
|
using?: string;
|
package/dist/pack.d.mts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pack.d.mts","names":[],"sources":["../src/core/authoring.ts","../src/core/descriptor-meta.ts"],"mappings":";;;;;;;;
|
|
1
|
+
{"version":3,"file":"pack.d.mts","names":[],"sources":["../src/core/authoring.ts","../src/core/descriptor-meta.ts"],"mappings":";;;;;;;;UAiEiB,uBAAA,SAAgC,iBAAiB;EAAA,SACvD,WAAA;EAyqBkB;AAAA;;;;AC/tB+B;ED+tB/B,SAlqBlB,iBAAA,GAAoB,oBAAA;AAAA;;UAId,kBAAA,SAA2B,iBAAiB;EAAA,SAClD,WAAW;AAAA;;;;;;;;;;;;iBA2pBN,0BAAA,CACd,KAAA,EAAO,yBAAA,YACG,iBAAiB;;;cC7tBvB,gCAAA;EAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;oCAaI,kBAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;cAEG,4BAAA,SAAqC,gCAAA;EAAA,SACvC,YAAA,GAAe,UAAU;AAAA"}
|
package/dist/pack.mjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { t as postgresTargetDescriptorMeta } from "./descriptor-meta-
|
|
1
|
+
import { t as postgresTargetDescriptorMeta } from "./descriptor-meta-Bxw2GNog.mjs";
|
|
2
2
|
export { postgresTargetDescriptorMeta as default };
|
|
@@ -6,7 +6,7 @@ import { t as resolveDdlSchemaForNamespaceStorage } from "./resolve-ddl-schema-X
|
|
|
6
6
|
import { t as buildPostgresPlanDiff } from "./diff-database-schema-oY3brcLj.mjs";
|
|
7
7
|
import { a as resolvePostgresNodeIssueCreationFactoryName, c as issueSchemaName, d as postgresNodeStorageCoordinate, i as resolvePostgresNodeIssueControlPolicySubject, l as planIssues, n as resolveNamespaceIdForDdlSchema, o as coalesceSubtreeIssues, r as resolvePostgresCallControlPolicySubject, s as issueNode, t as renderPostgresSuppression, u as postgresPlannerStrategies } from "./control-policy-DaLdbcYE.mjs";
|
|
8
8
|
import { T as DropPostgresRlsPolicyCall, k as RenamePostgresRlsPolicyCall, p as CreatePostgresRlsPolicyCall } from "./op-factory-call-tBcLo_B8.mjs";
|
|
9
|
-
import { t as TypeScriptRenderablePostgresMigration } from "./planner-produced-postgres-migration-
|
|
9
|
+
import { t as TypeScriptRenderablePostgresMigration } from "./planner-produced-postgres-migration-BV3WLLXl.mjs";
|
|
10
10
|
import { UNBOUND_NAMESPACE_ID } from "@prisma-next/framework-components/ir";
|
|
11
11
|
import { blindCast } from "@prisma-next/utils/casts";
|
|
12
12
|
import { extractCodecControlHooks, partitionCallsByControlPolicy, partitionIssuesByControlPolicy, planFieldEventOperations, plannerFailure } from "@prisma-next/family-sql/control";
|
|
@@ -387,4 +387,4 @@ function policyNodeToContractPolicy(node) {
|
|
|
387
387
|
//#endregion
|
|
388
388
|
export { createPostgresMigrationPlanner as t };
|
|
389
389
|
|
|
390
|
-
//# sourceMappingURL=planner-
|
|
390
|
+
//# sourceMappingURL=planner-BWmH0NqM.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"planner-ootbxGty.mjs","names":["#lowerer"],"sources":["../src/core/migrations/verify-postgres-namespaces.ts","../src/core/migrations/planner.ts"],"sourcesContent":["import type { Contract } from '@prisma-next/contract/types';\nimport type { SchemaDiffIssue } from '@prisma-next/framework-components/control';\nimport { UNBOUND_NAMESPACE_ID } from '@prisma-next/framework-components/ir';\nimport type { SqlStorage } from '@prisma-next/sql-contract/types';\nimport type { SqlSchemaIRNode } from '@prisma-next/sql-schema-ir/types';\nimport { DEFAULT_NAMESPACE_ID } from '../namespace-ids';\nimport { isPostgresSchema } from '../postgres-schema';\nimport { PostgresDatabaseSchemaNode } from '../schema-ir/postgres-database-schema-node';\nimport { PostgresNamespaceSchemaNode } from '../schema-ir/postgres-namespace-schema-node';\nimport type { SqlSchemaDiffNode } from '../schema-ir/schema-node-kinds';\n\n/**\n * Resolves the live-database schema name for a given namespace\n * coordinate. Mirrors `resolveDdlSchemaForNamespace` in\n * `planner-strategies.ts` so the verifier's projection and the\n * planner's projection always agree — Postgres-aware namespaces (the\n * production path) dispatch to `ddlSchemaName(storage)`, and bare\n * object payloads (used by some tests) fall back to the coordinate\n * itself.\n */\nfunction resolveDdlSchemaName(storage: SqlStorage, namespaceId: string): string {\n const namespace = storage.namespaces[namespaceId];\n if (isPostgresSchema(namespace)) {\n return namespace.ddlSchemaName(storage);\n }\n return namespaceId;\n}\n\n/**\n * Reads the introspected list of schema names from the database-root schema\n * node. `existingSchemas` is database-level, so it lives on the\n * `PostgresDatabaseSchemaNode` root — not on the per-schema namespace nodes.\n *\n * Defaults to the always-present `public` schema when the node is not the\n * database root — a fresh Postgres database always carries `public` (unless an\n * operator dropped it manually), so any verifier path that runs without an\n * enriched introspection still suppresses the redundant `CREATE SCHEMA\n * \"public\"`.\n *\n * Production introspection (`PostgresControlAdapter.introspect`) is the\n * authoritative source: it queries `pg_namespace` and sets `existingSchemas`\n * on the returned root. Tests that want to assert against a richer initial\n * state construct a `PostgresDatabaseSchemaNode` explicitly.\n */\nfunction existingSchemasFromSchema(schema: SqlSchemaIRNode): readonly string[] {\n if (PostgresDatabaseSchemaNode.is(schema)) {\n return schema.existingSchemas;\n }\n return [DEFAULT_NAMESPACE_ID];\n}\n\n/**\n * Emits a `postgres-namespace` `not-found` diff issue for every\n * contract-declared Postgres namespace whose live container does not yet\n * exist. The planner prepends these (node-typed, synthesized) to the\n * relational diff issues so a multi-schema plan emits `CREATE SCHEMA`\n * before the tables that need it — a planner-only concern (verify already\n * rejects via the `not-found` table issues a missing schema already\n * produces), so this is not part of the shared diff.\n *\n * A namespace's live container is the schema returned by its\n * polymorphic `ddlSchemaName(storage)` method — named schemas resolve\n * to their own id; the unbound singleton returns `UNBOUND_NAMESPACE_ID`\n * and is skipped explicitly (late-bound namespaces have no fixed DDL\n * schema). Issues are emitted only when the resolved name is a real,\n * creatable schema (not the unbound sentinel) and is missing from the\n * introspected list. `public` is suppressed implicitly because the\n * introspection (or its sensible default) always carries it.\n *\n * Each emitted issue's path is `['database', ddlName]` — an ancestor of\n * every table path under that schema, so it must never be run through\n * `coalesceSubtreeIssues` alongside the table diff (it would swallow the\n * table-level `not-found` issues that drive `CREATE TABLE`); the planner\n * adds these AFTER coalescing the relational issues, and they are not\n * subject to sibling-space ownership scoping (mirrors the retired\n * coordinate walk, which prepended namespace issues after that filter).\n */\nexport function verifyPostgresNamespacePresence(input: {\n readonly contract: Contract<SqlStorage>;\n readonly schema: SqlSchemaIRNode;\n}): readonly SchemaDiffIssue<SqlSchemaDiffNode>[] {\n const { contract, schema } = input;\n const existing = new Set(existingSchemasFromSchema(schema));\n const issues: SchemaDiffIssue<SqlSchemaDiffNode>[] = [];\n const namespaceIds = Object.keys(contract.storage.namespaces).sort();\n for (const namespaceId of namespaceIds) {\n if (namespaceId === UNBOUND_NAMESPACE_ID) continue;\n const ddlName = resolveDdlSchemaName(contract.storage, namespaceId);\n if (ddlName === UNBOUND_NAMESPACE_ID) continue;\n if (existing.has(ddlName)) continue;\n const namespace = new PostgresNamespaceSchemaNode({\n schemaName: ddlName,\n tables: {},\n });\n issues.push({\n path: ['database', ddlName],\n expected: namespace,\n });\n }\n return issues;\n}\n","import type { Contract } from '@prisma-next/contract/types';\nimport type {\n MigrationOperationPolicy,\n SqlMigrationPlannerPlanOptions,\n SqlPlannerConflict,\n SqlPlannerFailureResult,\n} from '@prisma-next/family-sql/control';\nimport {\n extractCodecControlHooks,\n partitionCallsByControlPolicy,\n partitionIssuesByControlPolicy,\n planFieldEventOperations,\n plannerFailure,\n} from '@prisma-next/family-sql/control';\nimport type { ExecuteRequestLowerer } from '@prisma-next/family-sql/control-adapter';\nimport type { TargetBoundComponentDescriptor } from '@prisma-next/framework-components/components';\nimport type {\n MigrationPlanner,\n MigrationPlanWithAuthoringSurface,\n MigrationScaffoldContext,\n SchemaDiffIssue,\n SchemaOwnership,\n} from '@prisma-next/framework-components/control';\nimport { issueOutcome } from '@prisma-next/framework-components/control';\nimport { 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 { blindCast } from '@prisma-next/utils/casts';\nimport { ifDefined } from '@prisma-next/utils/defined';\nimport { PostgresRlsPolicy } from '../postgres-rls-policy';\nimport { parseRlsPolicyWireName } from '../rls/wire-name';\nimport { postgresNodeStorageCoordinate } from '../schema-ir/node-storage-coordinate';\nimport { PostgresDatabaseSchemaNode } from '../schema-ir/postgres-database-schema-node';\nimport { PostgresPolicySchemaNode } from '../schema-ir/postgres-policy-schema-node';\nimport type { SqlSchemaDiffNode } from '../schema-ir/schema-node-kinds';\nimport {\n renderPostgresSuppression,\n resolveNamespaceIdForDdlSchema,\n resolvePostgresCallControlPolicySubject,\n resolvePostgresNodeIssueControlPolicySubject,\n resolvePostgresNodeIssueCreationFactoryName,\n} from './control-policy';\nimport { buildPostgresPlanDiff } from './diff-database-schema';\nimport { coalesceSubtreeIssues, issueNode, issueSchemaName, planIssues } from './issue-planner';\nimport type { PostgresOpFactoryCall } from './op-factory-call';\nimport {\n CreatePostgresRlsPolicyCall,\n DropPostgresRlsPolicyCall,\n RenamePostgresRlsPolicyCall,\n} from './op-factory-call';\nimport { TypeScriptRenderablePostgresMigration } from './planner-produced-postgres-migration';\nimport { postgresPlannerStrategies } from './planner-strategies';\nimport { resolveDdlSchemaForNamespaceStorage } from './resolve-ddl-schema';\nimport { verifyPostgresNamespacePresence } from './verify-postgres-namespaces';\n\ntype PlannerFrameworkComponents = SqlMigrationPlannerPlanOptions extends {\n readonly frameworkComponents: infer T;\n}\n ? T\n : ReadonlyArray<unknown>;\n\ntype PlannerOptionsWithComponents = SqlMigrationPlannerPlanOptions & {\n readonly frameworkComponents: PlannerFrameworkComponents;\n};\n\nexport function createPostgresMigrationPlanner(\n lowerer: ExecuteRequestLowerer,\n): PostgresMigrationPlanner {\n return new PostgresMigrationPlanner(lowerer);\n}\n\n/**\n * Result of `PostgresMigrationPlanner.plan()`. A discriminated union whose\n * success variant carries a `TypeScriptRenderablePostgresMigration` — a\n * migration object that both the CLI (via `renderTypeScript()`) and the\n * SQL-typed callers (via `operations`, `describe()`, etc.) consume\n * uniformly.\n */\nexport type PostgresPlanResult =\n | {\n readonly kind: 'success';\n readonly plan: TypeScriptRenderablePostgresMigration;\n readonly warnings?: readonly SqlPlannerConflict[];\n }\n | SqlPlannerFailureResult;\n\n/**\n * Postgres migration planner — a thin wrapper over `planIssues`.\n *\n * `plan()` diffs the target contract against the live schema via the one\n * differ (`buildPostgresPlanDiff`, producing node-typed `SchemaDiffIssue[]`)\n * and delegates to `planIssues` with the unified `postgresPlannerStrategies`\n * list: NOT-NULL backfill, type-change, nullable-tightening, codec-hook\n * storage types, component-declared dependency installs, and\n * shared-temp-default / empty-table-guarded NOT-NULL add-column. The same\n * strategy list runs for `migration plan`, `db update`, and `db init`;\n * behavior diverges purely on `policy.allowedOperationClasses` (the\n * data-safe strategies short-circuit when `'data'` is excluded). The issue\n * planner applies operation-class policy gates and emits a single\n * `PostgresOpFactoryCall[]` that drives both the runtime-ops view (via\n * `renderOps`) and the `renderTypeScript()` authoring surface. RLS policy\n * drift (the structural half of the same one-differ tree) is handled\n * separately via `planPostgresSchemaDiff`.\n */\nexport class PostgresMigrationPlanner implements MigrationPlanner<'sql', 'postgres'> {\n readonly #lowerer: ExecuteRequestLowerer | undefined;\n\n constructor(lowerer?: ExecuteRequestLowerer) {\n this.#lowerer = lowerer;\n }\n\n plan(options: {\n readonly contract: unknown;\n readonly schema: unknown;\n readonly policy: MigrationOperationPolicy;\n /**\n * The \"from\" contract (state the planner assumes the database starts\n * at), or `null` for reconciliation flows. Only `migration plan` ever\n * supplies a non-null value; `db update` / `db init` reconcile against\n * the live schema and pass `null`. When present alongside the\n * `'data'` operation class, strategies that need from/to column-shape\n * comparisons (unsafe type change, nullability tightening) activate.\n *\n * Typed as the framework `Contract | null` to satisfy the\n * `MigrationPlanner` interface contract; `planSql` narrows to the SQL\n * shape via `SqlMigrationPlannerPlanOptions`. Used to populate\n * `describe().from` on the produced plan as\n * `fromContract?.storage.storageHash ?? null`.\n */\n readonly fromContract: Contract | null;\n readonly schemaName?: string;\n readonly frameworkComponents: ReadonlyArray<TargetBoundComponentDescriptor<'sql', string>>;\n /**\n * Contract space this plan applies to. Stamped onto the produced\n * {@link TypeScriptRenderablePostgresMigration.spaceId} so the runner keys\n * the marker row by the right space.\n */\n readonly spaceId: string;\n /**\n * Ownership oracle over the contract-space composition — see\n * {@link SqlMigrationPlannerPlanOptions.ownership}.\n */\n readonly ownership?: SchemaOwnership;\n }): PostgresPlanResult {\n return this.planSql(options as SqlMigrationPlannerPlanOptions);\n }\n\n emptyMigration(\n context: MigrationScaffoldContext,\n spaceId: string,\n ): MigrationPlanWithAuthoringSurface {\n return new TypeScriptRenderablePostgresMigration(\n [],\n {\n from: context.fromHash,\n to: context.toHash,\n },\n spaceId,\n this.#lowerer,\n );\n }\n\n private planSql(options: SqlMigrationPlannerPlanOptions): PostgresPlanResult {\n const schemaName =\n options.schemaName ??\n Object.keys(options.contract.storage.namespaces).find((id) => id !== UNBOUND_NAMESPACE_ID) ??\n UNBOUND_NAMESPACE_ID;\n const policyResult = this.ensureAdditivePolicy(options.policy);\n if (policyResult) {\n return policyResult;\n }\n\n // The one combined tree diff drives the whole plan: relational findings\n // become structural DDL via `planIssues`, policy findings become RLS ops\n // via `planPostgresSchemaDiff`. Verify runs its own full-tree node diff\n // (`diffSchema`) over the same schema and rejects on a\n // surviving failure.\n PostgresDatabaseSchemaNode.assert(options.schema);\n const { issues: rawIssues } = buildPostgresPlanDiff({\n contract: options.contract,\n actualSchema: options.schema,\n frameworkComponents: options.frameworkComponents,\n });\n const policyDiffIssues = rawIssues.filter((issue) => isPolicyDiffIssue(issue));\n // Role diff issues resolve to the `external` control policy (see\n // `resolvePostgresNodeIssueControlPolicySubject`'s role branch), so the\n // control-policy partition below suppresses them to zero ops on its own,\n // before `mapNodeIssueToCall` ever sees them — no separate exclusion\n // needed here.\n const relationalDiffIssues = rawIssues.filter((issue) => !isPolicyDiffIssue(issue));\n\n // The generic differ is total and un-gated: strict-mode extras filtering\n // (dropping `not-expected` findings outside strict mode, mirroring the\n // retired coordinate walk's `if (strict) { ...extra_* } }` guards),\n // subtree coalescing (a missing/extra table also emits an issue for\n // every child under it — redundant once the table-level Create/Drop call\n // already accounts for the whole subtree), and ownership are all post-diff\n // planner steps.\n //\n // Ownership: a live extra is only this plan's to drop when no contract\n // space owns it. The differ ran against THIS space's contract, so a table\n // a sibling space owns surfaces here as `not-expected`; the planner asks\n // the ownership oracle (the passive aggregate) whether any space declares\n // it and, if so, leaves it alone — it is a sibling's table, not an orphan.\n // A table no space owns stays a genuine extra to drop under a destructive\n // policy. Ownership lives in the aggregate; the planner only asks. Absent\n // oracle (single-space, none handed) keeps every extra. Coalescing MUST\n // run before this so a sibling-owned table's child issues have already\n // collapsed into the one table-level issue that carries the table name.\n const strict =\n options.policy.allowedOperationClasses.includes('widening') ||\n options.policy.allowedOperationClasses.includes('destructive');\n const coalesced = coalesceSubtreeIssues(relationalDiffIssues);\n const owned = retainUnownedExtras(coalesced, options.ownership, options.contract);\n const gated = strict ? owned : owned.filter((issue) => issueOutcome(issue) !== 'not-expected');\n\n // Namespace presence (`CREATE SCHEMA`) is a planner-only op-generation\n // concern stitched in here rather than inside the shared diff — verify\n // never needs it (a missing schema already surfaces as a `not-found`\n // table in the relational findings). These synthesized issues are added\n // AFTER coalescing/scoping (never coalesced against the table diff —\n // their path is an ancestor of every table path under that schema, so\n // running them through the same coalesce would swallow the table-level\n // `not-found` issues that drive `CREATE TABLE`) and are NOT subject to\n // sibling-space scoping, matching the retired coordinate walk exactly.\n const namespaceIssues = verifyPostgresNamespacePresence({\n contract: options.contract,\n schema: options.schema,\n });\n const schemaIssues = [...namespaceIssues, ...gated];\n\n const codecHooks = extractCodecControlHooks(options.frameworkComponents);\n const storageTypes = options.contract.storage.types ?? {};\n // The strategy layer reads the live schema by bare table name for existence\n // checks (shared-temp-default safety, FK/unique probes), so it takes one\n // per-schema namespace node — never the whole tree root, and never a flat\n // merge of every namespace (which would collide same-named tables across\n // schemas). Probing more than one namespace at once is future work.\n const relationalSchema = relationalNamespaceNode(options.schema, schemaName);\n\n // Input-side control-policy partition. `external` / `observed` subjects\n // — and non-creation issues for `tolerated` subjects — are dropped from\n // the planner's input entirely; the planner never observes them, never\n // diffs them, never generates DDL for them. Suppression warnings are\n // built directly from the suppressed partition (one per subject), so the\n // user-visible message survives even when the planner would have failed\n // to model the subject's live shape.\n const issuePartition = partitionIssuesByControlPolicy({\n issues: schemaIssues,\n contract: options.contract,\n resolveControlPolicySubject: (issue) =>\n resolvePostgresNodeIssueControlPolicySubject(issue, options.contract),\n resolveCreationFactoryName: resolvePostgresNodeIssueCreationFactoryName,\n });\n\n const result = planIssues({\n issues: issuePartition.plannable,\n toContract: options.contract,\n // `fromContract` is only supplied by `migration plan`. It is `null` for\n // `db update` / `db init`, which means data-safety strategies needing\n // from/to comparisons (unsafe type change, nullable tightening) are\n // inapplicable there — reconciliation falls through to\n // `mapNodeIssueToCall`'s direct destructive handlers.\n fromContract: options.fromContract,\n schemaName,\n codecHooks,\n storageTypes,\n ...ifDefined('schema', relationalSchema),\n policy: options.policy,\n frameworkComponents: options.frameworkComponents,\n strategies: postgresPlannerStrategies,\n });\n\n if (!result.ok) {\n return plannerFailure(result.failure);\n }\n\n const schemaDiffCalls = this.planPostgresSchemaDiff(options, policyDiffIssues);\n const schemaDiffPartition = partitionCallsByControlPolicy({\n calls: schemaDiffCalls,\n contract: options.contract,\n resolveControlPolicySubject: (call) =>\n resolvePostgresCallControlPolicySubject(call, options.contract),\n resolveFactoryName: (call) => call.factoryName,\n });\n\n // Inline `onFieldEvent`-emitted ops after structural DDL. The fixed\n // ordering is `structural → added → dropped → altered`, with\n // within-group sorting by `(tableName, fieldName)` so re-emits are\n // byte-stable. The hook fires only at the application emitter —\n // extension-space planning never reaches this helper.\n const fieldEventOps = planFieldEventOperations({\n priorContract: options.fromContract,\n newContract: options.contract,\n codecHooks,\n });\n // Codec hook ops are target-agnostic `OpFactoryCall`; Postgres planning\n // lifts them at this integration boundary (see field-event-planner JSDoc).\n const fieldEventPostgresCalls = blindCast<\n readonly PostgresOpFactoryCall[],\n 'Codec hook ops conform to PostgresOpFactoryCall at the app emitter boundary'\n >(fieldEventOps);\n const fieldEventPartition = partitionCallsByControlPolicy({\n calls: fieldEventPostgresCalls,\n contract: options.contract,\n resolveControlPolicySubject: (call) =>\n resolvePostgresCallControlPolicySubject(call, options.contract),\n resolveFactoryName: (call) => call.factoryName,\n });\n const calls = [...result.value.calls, ...schemaDiffPartition.kept, ...fieldEventPartition.kept];\n const warnings: SqlPlannerConflict[] = [\n ...issuePartition.suppressions,\n ...schemaDiffPartition.suppressions,\n ...fieldEventPartition.suppressions,\n ].map((record) => renderPostgresSuppression(record, options.contract));\n\n return Object.freeze({\n kind: 'success' as const,\n plan: new TypeScriptRenderablePostgresMigration(\n calls,\n {\n from: options.fromContract?.storage.storageHash ?? null,\n to: options.contract.storage.storageHash,\n },\n options.spaceId,\n this.#lowerer,\n ),\n ...(warnings.length > 0 ? { warnings: Object.freeze(warnings) } : {}),\n });\n }\n\n /**\n * Maps the RLS policy presence findings of the one combined tree diff\n * (`buildPostgresPlanDiff`, already ownership-filtered) into\n * `CREATE POLICY` / `DROP POLICY` / `ALTER POLICY … RENAME TO` ops. It\n * does not re-diff — it consumes exactly the policy-node subset of the\n * shared diff's issues. Enablement is NOT decided here: `ENABLE`/`DISABLE\n * ROW LEVEL SECURITY` derive from the table's marker-driven `rlsEnabled`\n * attribute diff on the relational side.\n *\n * Rename post-pass: a `not-found` and a `not-expected` policy on the SAME\n * table whose wire-name content hashes match but prefixes differ are one\n * prefix-only rename, collapsed into a single non-destructive\n * `RenamePostgresRlsPolicyCall`. Multi-candidate hash groups pair\n * deterministically by sorted wire name; leftovers proceed as\n * create/drop. Unparseable wire names never pair.\n *\n * The pairing runs only when the policy allows `widening` (rename's\n * class). Without it (db-init's additive-only set), pairing degrades\n * deliberately to the additive half: the new name is CREATEd and the old\n * policy survives live until a widening/destructive-allowed plan runs —\n * emitting an ungated widening rename would only fail at the runner's\n * class re-enforcement.\n */\n private planPostgresSchemaDiff(\n options: PlannerOptionsWithComponents,\n filteredDiffIssues: readonly SchemaDiffIssue<SqlSchemaDiffNode>[],\n ): readonly PostgresOpFactoryCall[] {\n const allowsDestructive = options.policy.allowedOperationClasses.includes('destructive');\n const allowsWidening = options.policy.allowedOperationClasses.includes('widening');\n\n interface PolicyFinding {\n readonly node: PostgresPolicySchemaNode;\n readonly schemaForTable: string;\n }\n const missing: PolicyFinding[] = [];\n const extra: PolicyFinding[] = [];\n\n for (const issue of filteredDiffIssues) {\n // 'not-equal' is unreachable for content-addressed policies: the wire name\n // encodes the body hash, so two policies sharing a local key (same name)\n // are always equal and isEqualTo never returns false.\n if (issueOutcome(issue) === 'not-found') {\n const expected = issue.expected;\n PostgresPolicySchemaNode.assert(expected);\n // expected.namespaceId is the DDL schema name (resolved during projection);\n // this re-resolution is a no-op as long as PostgresSchema.ddlSchemaName() returns this.id.\n missing.push({\n node: expected,\n schemaForTable: resolveDdlSchemaForNamespaceStorage(\n options.contract.storage,\n expected.namespaceId,\n ),\n });\n } else if (issueOutcome(issue) === 'not-expected') {\n const actual = issue.actual;\n PostgresPolicySchemaNode.assert(actual);\n extra.push({\n node: actual,\n schemaForTable: resolveDdlSchemaForNamespaceStorage(\n options.contract.storage,\n actual.namespaceId,\n ),\n });\n }\n }\n\n const calls: PostgresOpFactoryCall[] = [];\n const renamedExtras = new Set<PolicyFinding>();\n const renamedMissing = new Set<PolicyFinding>();\n const pairingKey = (finding: PolicyFinding, hash: string): string =>\n JSON.stringify([finding.schemaForTable, finding.node.tableName, hash]);\n\n if (allowsWidening) {\n const extrasByGroup = new Map<string, PolicyFinding[]>();\n for (const finding of extra) {\n const parsed = parseRlsPolicyWireName(finding.node.name);\n if (parsed === undefined) continue;\n const key = pairingKey(finding, parsed.hash);\n const group = extrasByGroup.get(key) ?? [];\n group.push(finding);\n extrasByGroup.set(key, group);\n }\n for (const group of extrasByGroup.values()) {\n group.sort((a, b) => (a.node.name < b.node.name ? -1 : a.node.name > b.node.name ? 1 : 0));\n }\n\n const sortedMissing = [...missing].sort((a, b) =>\n a.node.name < b.node.name ? -1 : a.node.name > b.node.name ? 1 : 0,\n );\n for (const missingFinding of sortedMissing) {\n const parsed = parseRlsPolicyWireName(missingFinding.node.name);\n if (parsed === undefined) continue;\n const candidates = extrasByGroup.get(pairingKey(missingFinding, parsed.hash));\n const candidate = candidates?.shift();\n if (candidate === undefined) continue;\n // Same name would never surface as missing+extra (the differ pairs by\n // name), so a matched candidate always differs in prefix only.\n renamedExtras.add(candidate);\n renamedMissing.add(missingFinding);\n calls.push(\n new RenamePostgresRlsPolicyCall(\n missingFinding.schemaForTable,\n missingFinding.node.tableName,\n candidate.node.name,\n missingFinding.node.name,\n ),\n );\n }\n }\n\n for (const finding of missing) {\n if (renamedMissing.has(finding)) continue;\n calls.push(\n new CreatePostgresRlsPolicyCall(\n finding.schemaForTable,\n finding.node.tableName,\n policyNodeToContractPolicy(finding.node),\n ),\n );\n }\n if (allowsDestructive) {\n for (const finding of extra) {\n if (renamedExtras.has(finding)) continue;\n calls.push(\n new DropPostgresRlsPolicyCall(\n finding.schemaForTable,\n finding.node.tableName,\n finding.node.name,\n ),\n );\n }\n }\n\n return calls;\n }\n\n private ensureAdditivePolicy(policy: MigrationOperationPolicy) {\n if (!policy.allowedOperationClasses.includes('additive')) {\n return plannerFailure([\n {\n kind: 'unsupportedOperation',\n summary: 'Migration planner requires additive operations be allowed',\n why: 'The planner requires the \"additive\" operation class to be allowed in the policy.',\n },\n ]);\n }\n return null;\n }\n}\n\n/**\n * A diff issue whose node is an RLS policy — the structural half of the one\n * combined tree diff, routed to `planPostgresSchemaDiff` instead of\n * `planIssues`.\n */\nfunction isPolicyDiffIssue(issue: SchemaDiffIssue<SqlSchemaDiffNode>): boolean {\n const node = issue.expected ?? issue.actual;\n return node !== undefined && PostgresPolicySchemaNode.is(node);\n}\n\n/**\n * Drops a `not-expected` issue when it is a whole extra storage entity (a table\n * or a native enum) that some space in the composition owns. Each such node\n * yields its own storage coordinate (see {@link postgresNodeStorageCoordinate}),\n * so `declaresEntity` answers over the whole composition on one uniform\n * coordinate: a positive answer means a sibling owns this entity here — leave\n * it; a negative answer means a genuine orphan — drop it. A node with no storage\n * coordinate (a namespace, or a deeper column/constraint drift on an owned\n * table) is this space's own and is always kept. No oracle ⇒ keep everything.\n */\nfunction retainUnownedExtras(\n issues: readonly SchemaDiffIssue<SqlSchemaDiffNode>[],\n ownership: SchemaOwnership | undefined,\n contract: Contract<SqlStorage>,\n): readonly SchemaDiffIssue<SqlSchemaDiffNode>[] {\n if (ownership === undefined) return issues;\n return issues.filter((issue) => {\n if (issueOutcome(issue) !== 'not-expected') return true;\n const node = issueNode(issue);\n if (node === undefined) return true;\n const coordinate = postgresNodeStorageCoordinate(node);\n if (coordinate === undefined) return true;\n const ddlSchemaName = issueSchemaName(issue);\n if (ddlSchemaName === undefined) return true;\n const namespaceId = resolveNamespaceIdForDdlSchema(contract, ddlSchemaName);\n return !ownership.declaresEntity({ namespaceId, ...coordinate });\n });\n}\n\n/**\n * Returns the one namespace node the relational strategy layer probes for\n * live-table existence and reads codec-hook context off — the namespace\n * matching the planner's resolved schema name, or the first namespace when\n * none matches. `undefined` when the tree has no namespaces, so the strategy\n * context uses its empty-schema default.\n *\n * The relational strategies key tables by bare name, so they can only probe one\n * namespace at a time; probing across every namespace at once is future work.\n *\n * Returns the real `PostgresNamespaceSchemaNode` reference rather than a\n * projection: `storageTypePlanCallStrategy` hands this same value to codec\n * `planTypeOperations` hooks as `schema`, and hooks read the Postgres-specific\n * `nativeEnums` field off it (via `PostgresNamespaceSchemaNode.is`) to decide\n * whether a native enum type already exists — a projection that only copies\n * `tables` would silently drop that signal. `StrategyContext.schema`'s\n * declared type (`SqlSchemaIR`, shared with SQLite's flat shape) doesn't\n * capture this, so the return is `blindCast` the same way `namespaceSchemaNodes`\n * in the family's relational walk already treats a namespace node as a\n * structurally-`SqlSchemaIR`-shaped value.\n */\nfunction relationalNamespaceNode(\n schema: PostgresDatabaseSchemaNode,\n schemaName: string,\n): SqlSchemaIR | undefined {\n const namespaceNodes = Object.values(schema.namespaces);\n const namespaceNode =\n namespaceNodes.find((node) => node.schemaName === schemaName) ?? namespaceNodes[0];\n if (namespaceNode === undefined) return undefined;\n return blindCast<\n SqlSchemaIR,\n 'PostgresNamespaceSchemaNode carries tables (+ nativeEnums, read by codec hooks via PostgresNamespaceSchemaNode.is) structurally compatible with the SqlSchemaIR shape the strategy layer declares'\n >(namespaceNode);\n}\n\n/**\n * Rebuilds the `PostgresRlsPolicy` contract entity `CreatePostgresRlsPolicyCall`\n * carries (its `renderTypeScript`/`createRlsPolicy` paths serialize the whole\n * entity, `namespaceId` included). This reconstructs rather than looking the\n * original up in the contract on purpose: the diff node's `namespaceId` is the\n * *resolved DDL schema* (set when the expected tree was built), which is the\n * value the emitted op must carry; the contract-stored entity holds the raw,\n * pre-resolution coordinate, so a lookup would change the migration output.\n */\nfunction policyNodeToContractPolicy(node: PostgresPolicySchemaNode): PostgresRlsPolicy {\n return new PostgresRlsPolicy({\n name: node.name,\n prefix: node.prefix,\n tableName: node.tableName,\n namespaceId: node.namespaceId,\n operation: node.operation,\n roles: [...node.roles],\n ...ifDefined('using', node.using),\n ...ifDefined('withCheck', node.withCheck),\n permissive: node.permissive,\n });\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"planner-BWmH0NqM.mjs","names":["#lowerer"],"sources":["../src/core/migrations/verify-postgres-namespaces.ts","../src/core/migrations/planner.ts"],"sourcesContent":["import type { Contract } from '@prisma-next/contract/types';\nimport type { SchemaDiffIssue } from '@prisma-next/framework-components/control';\nimport { UNBOUND_NAMESPACE_ID } from '@prisma-next/framework-components/ir';\nimport type { SqlStorage } from '@prisma-next/sql-contract/types';\nimport type { SqlSchemaIRNode } from '@prisma-next/sql-schema-ir/types';\nimport { DEFAULT_NAMESPACE_ID } from '../namespace-ids';\nimport { isPostgresSchema } from '../postgres-schema';\nimport { PostgresDatabaseSchemaNode } from '../schema-ir/postgres-database-schema-node';\nimport { PostgresNamespaceSchemaNode } from '../schema-ir/postgres-namespace-schema-node';\nimport type { SqlSchemaDiffNode } from '../schema-ir/schema-node-kinds';\n\n/**\n * Resolves the live-database schema name for a given namespace\n * coordinate. Mirrors `resolveDdlSchemaForNamespace` in\n * `planner-strategies.ts` so the verifier's projection and the\n * planner's projection always agree — Postgres-aware namespaces (the\n * production path) dispatch to `ddlSchemaName(storage)`, and bare\n * object payloads (used by some tests) fall back to the coordinate\n * itself.\n */\nfunction resolveDdlSchemaName(storage: SqlStorage, namespaceId: string): string {\n const namespace = storage.namespaces[namespaceId];\n if (isPostgresSchema(namespace)) {\n return namespace.ddlSchemaName(storage);\n }\n return namespaceId;\n}\n\n/**\n * Reads the introspected list of schema names from the database-root schema\n * node. `existingSchemas` is database-level, so it lives on the\n * `PostgresDatabaseSchemaNode` root — not on the per-schema namespace nodes.\n *\n * Defaults to the always-present `public` schema when the node is not the\n * database root — a fresh Postgres database always carries `public` (unless an\n * operator dropped it manually), so any verifier path that runs without an\n * enriched introspection still suppresses the redundant `CREATE SCHEMA\n * \"public\"`.\n *\n * Production introspection (`PostgresControlAdapter.introspect`) is the\n * authoritative source: it queries `pg_namespace` and sets `existingSchemas`\n * on the returned root. Tests that want to assert against a richer initial\n * state construct a `PostgresDatabaseSchemaNode` explicitly.\n */\nfunction existingSchemasFromSchema(schema: SqlSchemaIRNode): readonly string[] {\n if (PostgresDatabaseSchemaNode.is(schema)) {\n return schema.existingSchemas;\n }\n return [DEFAULT_NAMESPACE_ID];\n}\n\n/**\n * Emits a `postgres-namespace` `not-found` diff issue for every\n * contract-declared Postgres namespace whose live container does not yet\n * exist. The planner prepends these (node-typed, synthesized) to the\n * relational diff issues so a multi-schema plan emits `CREATE SCHEMA`\n * before the tables that need it — a planner-only concern (verify already\n * rejects via the `not-found` table issues a missing schema already\n * produces), so this is not part of the shared diff.\n *\n * A namespace's live container is the schema returned by its\n * polymorphic `ddlSchemaName(storage)` method — named schemas resolve\n * to their own id; the unbound singleton returns `UNBOUND_NAMESPACE_ID`\n * and is skipped explicitly (late-bound namespaces have no fixed DDL\n * schema). Issues are emitted only when the resolved name is a real,\n * creatable schema (not the unbound sentinel) and is missing from the\n * introspected list. `public` is suppressed implicitly because the\n * introspection (or its sensible default) always carries it.\n *\n * Each emitted issue's path is `['database', ddlName]` — an ancestor of\n * every table path under that schema, so it must never be run through\n * `coalesceSubtreeIssues` alongside the table diff (it would swallow the\n * table-level `not-found` issues that drive `CREATE TABLE`); the planner\n * adds these AFTER coalescing the relational issues, and they are not\n * subject to sibling-space ownership scoping (mirrors the retired\n * coordinate walk, which prepended namespace issues after that filter).\n */\nexport function verifyPostgresNamespacePresence(input: {\n readonly contract: Contract<SqlStorage>;\n readonly schema: SqlSchemaIRNode;\n}): readonly SchemaDiffIssue<SqlSchemaDiffNode>[] {\n const { contract, schema } = input;\n const existing = new Set(existingSchemasFromSchema(schema));\n const issues: SchemaDiffIssue<SqlSchemaDiffNode>[] = [];\n const namespaceIds = Object.keys(contract.storage.namespaces).sort();\n for (const namespaceId of namespaceIds) {\n if (namespaceId === UNBOUND_NAMESPACE_ID) continue;\n const ddlName = resolveDdlSchemaName(contract.storage, namespaceId);\n if (ddlName === UNBOUND_NAMESPACE_ID) continue;\n if (existing.has(ddlName)) continue;\n const namespace = new PostgresNamespaceSchemaNode({\n schemaName: ddlName,\n tables: {},\n });\n issues.push({\n path: ['database', ddlName],\n expected: namespace,\n });\n }\n return issues;\n}\n","import type { Contract } from '@prisma-next/contract/types';\nimport type {\n MigrationOperationPolicy,\n SqlMigrationPlannerPlanOptions,\n SqlPlannerConflict,\n SqlPlannerFailureResult,\n} from '@prisma-next/family-sql/control';\nimport {\n extractCodecControlHooks,\n partitionCallsByControlPolicy,\n partitionIssuesByControlPolicy,\n planFieldEventOperations,\n plannerFailure,\n} from '@prisma-next/family-sql/control';\nimport type { ExecuteRequestLowerer } from '@prisma-next/family-sql/control-adapter';\nimport type { TargetBoundComponentDescriptor } from '@prisma-next/framework-components/components';\nimport type {\n MigrationPlanner,\n MigrationPlanWithAuthoringSurface,\n MigrationScaffoldContext,\n SchemaDiffIssue,\n SchemaOwnership,\n} from '@prisma-next/framework-components/control';\nimport { issueOutcome } from '@prisma-next/framework-components/control';\nimport { 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 { blindCast } from '@prisma-next/utils/casts';\nimport { ifDefined } from '@prisma-next/utils/defined';\nimport { PostgresRlsPolicy } from '../postgres-rls-policy';\nimport { parseRlsPolicyWireName } from '../rls/wire-name';\nimport { postgresNodeStorageCoordinate } from '../schema-ir/node-storage-coordinate';\nimport { PostgresDatabaseSchemaNode } from '../schema-ir/postgres-database-schema-node';\nimport { PostgresPolicySchemaNode } from '../schema-ir/postgres-policy-schema-node';\nimport type { SqlSchemaDiffNode } from '../schema-ir/schema-node-kinds';\nimport {\n renderPostgresSuppression,\n resolveNamespaceIdForDdlSchema,\n resolvePostgresCallControlPolicySubject,\n resolvePostgresNodeIssueControlPolicySubject,\n resolvePostgresNodeIssueCreationFactoryName,\n} from './control-policy';\nimport { buildPostgresPlanDiff } from './diff-database-schema';\nimport { coalesceSubtreeIssues, issueNode, issueSchemaName, planIssues } from './issue-planner';\nimport type { PostgresOpFactoryCall } from './op-factory-call';\nimport {\n CreatePostgresRlsPolicyCall,\n DropPostgresRlsPolicyCall,\n RenamePostgresRlsPolicyCall,\n} from './op-factory-call';\nimport { TypeScriptRenderablePostgresMigration } from './planner-produced-postgres-migration';\nimport { postgresPlannerStrategies } from './planner-strategies';\nimport { resolveDdlSchemaForNamespaceStorage } from './resolve-ddl-schema';\nimport { verifyPostgresNamespacePresence } from './verify-postgres-namespaces';\n\ntype PlannerFrameworkComponents = SqlMigrationPlannerPlanOptions extends {\n readonly frameworkComponents: infer T;\n}\n ? T\n : ReadonlyArray<unknown>;\n\ntype PlannerOptionsWithComponents = SqlMigrationPlannerPlanOptions & {\n readonly frameworkComponents: PlannerFrameworkComponents;\n};\n\nexport function createPostgresMigrationPlanner(\n lowerer: ExecuteRequestLowerer,\n): PostgresMigrationPlanner {\n return new PostgresMigrationPlanner(lowerer);\n}\n\n/**\n * Result of `PostgresMigrationPlanner.plan()`. A discriminated union whose\n * success variant carries a `TypeScriptRenderablePostgresMigration` — a\n * migration object that both the CLI (via `renderTypeScript()`) and the\n * SQL-typed callers (via `operations`, `describe()`, etc.) consume\n * uniformly.\n */\nexport type PostgresPlanResult =\n | {\n readonly kind: 'success';\n readonly plan: TypeScriptRenderablePostgresMigration;\n readonly warnings?: readonly SqlPlannerConflict[];\n }\n | SqlPlannerFailureResult;\n\n/**\n * Postgres migration planner — a thin wrapper over `planIssues`.\n *\n * `plan()` diffs the target contract against the live schema via the one\n * differ (`buildPostgresPlanDiff`, producing node-typed `SchemaDiffIssue[]`)\n * and delegates to `planIssues` with the unified `postgresPlannerStrategies`\n * list: NOT-NULL backfill, type-change, nullable-tightening, codec-hook\n * storage types, component-declared dependency installs, and\n * shared-temp-default / empty-table-guarded NOT-NULL add-column. The same\n * strategy list runs for `migration plan`, `db update`, and `db init`;\n * behavior diverges purely on `policy.allowedOperationClasses` (the\n * data-safe strategies short-circuit when `'data'` is excluded). The issue\n * planner applies operation-class policy gates and emits a single\n * `PostgresOpFactoryCall[]` that drives both the runtime-ops view (via\n * `renderOps`) and the `renderTypeScript()` authoring surface. RLS policy\n * drift (the structural half of the same one-differ tree) is handled\n * separately via `planPostgresSchemaDiff`.\n */\nexport class PostgresMigrationPlanner implements MigrationPlanner<'sql', 'postgres'> {\n readonly #lowerer: ExecuteRequestLowerer | undefined;\n\n constructor(lowerer?: ExecuteRequestLowerer) {\n this.#lowerer = lowerer;\n }\n\n plan(options: {\n readonly contract: unknown;\n readonly schema: unknown;\n readonly policy: MigrationOperationPolicy;\n /**\n * The \"from\" contract (state the planner assumes the database starts\n * at), or `null` for reconciliation flows. Only `migration plan` ever\n * supplies a non-null value; `db update` / `db init` reconcile against\n * the live schema and pass `null`. When present alongside the\n * `'data'` operation class, strategies that need from/to column-shape\n * comparisons (unsafe type change, nullability tightening) activate.\n *\n * Typed as the framework `Contract | null` to satisfy the\n * `MigrationPlanner` interface contract; `planSql` narrows to the SQL\n * shape via `SqlMigrationPlannerPlanOptions`. Used to populate\n * `describe().from` on the produced plan as\n * `fromContract?.storage.storageHash ?? null`.\n */\n readonly fromContract: Contract | null;\n readonly schemaName?: string;\n readonly frameworkComponents: ReadonlyArray<TargetBoundComponentDescriptor<'sql', string>>;\n /**\n * Contract space this plan applies to. Stamped onto the produced\n * {@link TypeScriptRenderablePostgresMigration.spaceId} so the runner keys\n * the marker row by the right space.\n */\n readonly spaceId: string;\n /**\n * Ownership oracle over the contract-space composition — see\n * {@link SqlMigrationPlannerPlanOptions.ownership}.\n */\n readonly ownership?: SchemaOwnership;\n }): PostgresPlanResult {\n return this.planSql(options as SqlMigrationPlannerPlanOptions);\n }\n\n emptyMigration(\n context: MigrationScaffoldContext,\n spaceId: string,\n ): MigrationPlanWithAuthoringSurface {\n return new TypeScriptRenderablePostgresMigration(\n [],\n {\n from: context.fromHash,\n to: context.toHash,\n },\n spaceId,\n this.#lowerer,\n );\n }\n\n private planSql(options: SqlMigrationPlannerPlanOptions): PostgresPlanResult {\n const schemaName =\n options.schemaName ??\n Object.keys(options.contract.storage.namespaces).find((id) => id !== UNBOUND_NAMESPACE_ID) ??\n UNBOUND_NAMESPACE_ID;\n const policyResult = this.ensureAdditivePolicy(options.policy);\n if (policyResult) {\n return policyResult;\n }\n\n // The one combined tree diff drives the whole plan: relational findings\n // become structural DDL via `planIssues`, policy findings become RLS ops\n // via `planPostgresSchemaDiff`. Verify runs its own full-tree node diff\n // (`diffSchema`) over the same schema and rejects on a\n // surviving failure.\n PostgresDatabaseSchemaNode.assert(options.schema);\n const { issues: rawIssues } = buildPostgresPlanDiff({\n contract: options.contract,\n actualSchema: options.schema,\n frameworkComponents: options.frameworkComponents,\n });\n const policyDiffIssues = rawIssues.filter((issue) => isPolicyDiffIssue(issue));\n // Role diff issues resolve to the `external` control policy (see\n // `resolvePostgresNodeIssueControlPolicySubject`'s role branch), so the\n // control-policy partition below suppresses them to zero ops on its own,\n // before `mapNodeIssueToCall` ever sees them — no separate exclusion\n // needed here.\n const relationalDiffIssues = rawIssues.filter((issue) => !isPolicyDiffIssue(issue));\n\n // The generic differ is total and un-gated: strict-mode extras filtering\n // (dropping `not-expected` findings outside strict mode, mirroring the\n // retired coordinate walk's `if (strict) { ...extra_* } }` guards),\n // subtree coalescing (a missing/extra table also emits an issue for\n // every child under it — redundant once the table-level Create/Drop call\n // already accounts for the whole subtree), and ownership are all post-diff\n // planner steps.\n //\n // Ownership: a live extra is only this plan's to drop when no contract\n // space owns it. The differ ran against THIS space's contract, so a table\n // a sibling space owns surfaces here as `not-expected`; the planner asks\n // the ownership oracle (the passive aggregate) whether any space declares\n // it and, if so, leaves it alone — it is a sibling's table, not an orphan.\n // A table no space owns stays a genuine extra to drop under a destructive\n // policy. Ownership lives in the aggregate; the planner only asks. Absent\n // oracle (single-space, none handed) keeps every extra. Coalescing MUST\n // run before this so a sibling-owned table's child issues have already\n // collapsed into the one table-level issue that carries the table name.\n const strict =\n options.policy.allowedOperationClasses.includes('widening') ||\n options.policy.allowedOperationClasses.includes('destructive');\n const coalesced = coalesceSubtreeIssues(relationalDiffIssues);\n const owned = retainUnownedExtras(coalesced, options.ownership, options.contract);\n const gated = strict ? owned : owned.filter((issue) => issueOutcome(issue) !== 'not-expected');\n\n // Namespace presence (`CREATE SCHEMA`) is a planner-only op-generation\n // concern stitched in here rather than inside the shared diff — verify\n // never needs it (a missing schema already surfaces as a `not-found`\n // table in the relational findings). These synthesized issues are added\n // AFTER coalescing/scoping (never coalesced against the table diff —\n // their path is an ancestor of every table path under that schema, so\n // running them through the same coalesce would swallow the table-level\n // `not-found` issues that drive `CREATE TABLE`) and are NOT subject to\n // sibling-space scoping, matching the retired coordinate walk exactly.\n const namespaceIssues = verifyPostgresNamespacePresence({\n contract: options.contract,\n schema: options.schema,\n });\n const schemaIssues = [...namespaceIssues, ...gated];\n\n const codecHooks = extractCodecControlHooks(options.frameworkComponents);\n const storageTypes = options.contract.storage.types ?? {};\n // The strategy layer reads the live schema by bare table name for existence\n // checks (shared-temp-default safety, FK/unique probes), so it takes one\n // per-schema namespace node — never the whole tree root, and never a flat\n // merge of every namespace (which would collide same-named tables across\n // schemas). Probing more than one namespace at once is future work.\n const relationalSchema = relationalNamespaceNode(options.schema, schemaName);\n\n // Input-side control-policy partition. `external` / `observed` subjects\n // — and non-creation issues for `tolerated` subjects — are dropped from\n // the planner's input entirely; the planner never observes them, never\n // diffs them, never generates DDL for them. Suppression warnings are\n // built directly from the suppressed partition (one per subject), so the\n // user-visible message survives even when the planner would have failed\n // to model the subject's live shape.\n const issuePartition = partitionIssuesByControlPolicy({\n issues: schemaIssues,\n contract: options.contract,\n resolveControlPolicySubject: (issue) =>\n resolvePostgresNodeIssueControlPolicySubject(issue, options.contract),\n resolveCreationFactoryName: resolvePostgresNodeIssueCreationFactoryName,\n });\n\n const result = planIssues({\n issues: issuePartition.plannable,\n toContract: options.contract,\n // `fromContract` is only supplied by `migration plan`. It is `null` for\n // `db update` / `db init`, which means data-safety strategies needing\n // from/to comparisons (unsafe type change, nullable tightening) are\n // inapplicable there — reconciliation falls through to\n // `mapNodeIssueToCall`'s direct destructive handlers.\n fromContract: options.fromContract,\n schemaName,\n codecHooks,\n storageTypes,\n ...ifDefined('schema', relationalSchema),\n policy: options.policy,\n frameworkComponents: options.frameworkComponents,\n strategies: postgresPlannerStrategies,\n });\n\n if (!result.ok) {\n return plannerFailure(result.failure);\n }\n\n const schemaDiffCalls = this.planPostgresSchemaDiff(options, policyDiffIssues);\n const schemaDiffPartition = partitionCallsByControlPolicy({\n calls: schemaDiffCalls,\n contract: options.contract,\n resolveControlPolicySubject: (call) =>\n resolvePostgresCallControlPolicySubject(call, options.contract),\n resolveFactoryName: (call) => call.factoryName,\n });\n\n // Inline `onFieldEvent`-emitted ops after structural DDL. The fixed\n // ordering is `structural → added → dropped → altered`, with\n // within-group sorting by `(tableName, fieldName)` so re-emits are\n // byte-stable. The hook fires only at the application emitter —\n // extension-space planning never reaches this helper.\n const fieldEventOps = planFieldEventOperations({\n priorContract: options.fromContract,\n newContract: options.contract,\n codecHooks,\n });\n // Codec hook ops are target-agnostic `OpFactoryCall`; Postgres planning\n // lifts them at this integration boundary (see field-event-planner JSDoc).\n const fieldEventPostgresCalls = blindCast<\n readonly PostgresOpFactoryCall[],\n 'Codec hook ops conform to PostgresOpFactoryCall at the app emitter boundary'\n >(fieldEventOps);\n const fieldEventPartition = partitionCallsByControlPolicy({\n calls: fieldEventPostgresCalls,\n contract: options.contract,\n resolveControlPolicySubject: (call) =>\n resolvePostgresCallControlPolicySubject(call, options.contract),\n resolveFactoryName: (call) => call.factoryName,\n });\n const calls = [...result.value.calls, ...schemaDiffPartition.kept, ...fieldEventPartition.kept];\n const warnings: SqlPlannerConflict[] = [\n ...issuePartition.suppressions,\n ...schemaDiffPartition.suppressions,\n ...fieldEventPartition.suppressions,\n ].map((record) => renderPostgresSuppression(record, options.contract));\n\n return Object.freeze({\n kind: 'success' as const,\n plan: new TypeScriptRenderablePostgresMigration(\n calls,\n {\n from: options.fromContract?.storage.storageHash ?? null,\n to: options.contract.storage.storageHash,\n },\n options.spaceId,\n this.#lowerer,\n ),\n ...(warnings.length > 0 ? { warnings: Object.freeze(warnings) } : {}),\n });\n }\n\n /**\n * Maps the RLS policy presence findings of the one combined tree diff\n * (`buildPostgresPlanDiff`, already ownership-filtered) into\n * `CREATE POLICY` / `DROP POLICY` / `ALTER POLICY … RENAME TO` ops. It\n * does not re-diff — it consumes exactly the policy-node subset of the\n * shared diff's issues. Enablement is NOT decided here: `ENABLE`/`DISABLE\n * ROW LEVEL SECURITY` derive from the table's marker-driven `rlsEnabled`\n * attribute diff on the relational side.\n *\n * Rename post-pass: a `not-found` and a `not-expected` policy on the SAME\n * table whose wire-name content hashes match but prefixes differ are one\n * prefix-only rename, collapsed into a single non-destructive\n * `RenamePostgresRlsPolicyCall`. Multi-candidate hash groups pair\n * deterministically by sorted wire name; leftovers proceed as\n * create/drop. Unparseable wire names never pair.\n *\n * The pairing runs only when the policy allows `widening` (rename's\n * class). Without it (db-init's additive-only set), pairing degrades\n * deliberately to the additive half: the new name is CREATEd and the old\n * policy survives live until a widening/destructive-allowed plan runs —\n * emitting an ungated widening rename would only fail at the runner's\n * class re-enforcement.\n */\n private planPostgresSchemaDiff(\n options: PlannerOptionsWithComponents,\n filteredDiffIssues: readonly SchemaDiffIssue<SqlSchemaDiffNode>[],\n ): readonly PostgresOpFactoryCall[] {\n const allowsDestructive = options.policy.allowedOperationClasses.includes('destructive');\n const allowsWidening = options.policy.allowedOperationClasses.includes('widening');\n\n interface PolicyFinding {\n readonly node: PostgresPolicySchemaNode;\n readonly schemaForTable: string;\n }\n const missing: PolicyFinding[] = [];\n const extra: PolicyFinding[] = [];\n\n for (const issue of filteredDiffIssues) {\n // 'not-equal' is unreachable for content-addressed policies: the wire name\n // encodes the body hash, so two policies sharing a local key (same name)\n // are always equal and isEqualTo never returns false.\n if (issueOutcome(issue) === 'not-found') {\n const expected = issue.expected;\n PostgresPolicySchemaNode.assert(expected);\n // expected.namespaceId is the DDL schema name (resolved during projection);\n // this re-resolution is a no-op as long as PostgresSchema.ddlSchemaName() returns this.id.\n missing.push({\n node: expected,\n schemaForTable: resolveDdlSchemaForNamespaceStorage(\n options.contract.storage,\n expected.namespaceId,\n ),\n });\n } else if (issueOutcome(issue) === 'not-expected') {\n const actual = issue.actual;\n PostgresPolicySchemaNode.assert(actual);\n extra.push({\n node: actual,\n schemaForTable: resolveDdlSchemaForNamespaceStorage(\n options.contract.storage,\n actual.namespaceId,\n ),\n });\n }\n }\n\n const calls: PostgresOpFactoryCall[] = [];\n const renamedExtras = new Set<PolicyFinding>();\n const renamedMissing = new Set<PolicyFinding>();\n const pairingKey = (finding: PolicyFinding, hash: string): string =>\n JSON.stringify([finding.schemaForTable, finding.node.tableName, hash]);\n\n if (allowsWidening) {\n const extrasByGroup = new Map<string, PolicyFinding[]>();\n for (const finding of extra) {\n const parsed = parseRlsPolicyWireName(finding.node.name);\n if (parsed === undefined) continue;\n const key = pairingKey(finding, parsed.hash);\n const group = extrasByGroup.get(key) ?? [];\n group.push(finding);\n extrasByGroup.set(key, group);\n }\n for (const group of extrasByGroup.values()) {\n group.sort((a, b) => (a.node.name < b.node.name ? -1 : a.node.name > b.node.name ? 1 : 0));\n }\n\n const sortedMissing = [...missing].sort((a, b) =>\n a.node.name < b.node.name ? -1 : a.node.name > b.node.name ? 1 : 0,\n );\n for (const missingFinding of sortedMissing) {\n const parsed = parseRlsPolicyWireName(missingFinding.node.name);\n if (parsed === undefined) continue;\n const candidates = extrasByGroup.get(pairingKey(missingFinding, parsed.hash));\n const candidate = candidates?.shift();\n if (candidate === undefined) continue;\n // Same name would never surface as missing+extra (the differ pairs by\n // name), so a matched candidate always differs in prefix only.\n renamedExtras.add(candidate);\n renamedMissing.add(missingFinding);\n calls.push(\n new RenamePostgresRlsPolicyCall(\n missingFinding.schemaForTable,\n missingFinding.node.tableName,\n candidate.node.name,\n missingFinding.node.name,\n ),\n );\n }\n }\n\n for (const finding of missing) {\n if (renamedMissing.has(finding)) continue;\n calls.push(\n new CreatePostgresRlsPolicyCall(\n finding.schemaForTable,\n finding.node.tableName,\n policyNodeToContractPolicy(finding.node),\n ),\n );\n }\n if (allowsDestructive) {\n for (const finding of extra) {\n if (renamedExtras.has(finding)) continue;\n calls.push(\n new DropPostgresRlsPolicyCall(\n finding.schemaForTable,\n finding.node.tableName,\n finding.node.name,\n ),\n );\n }\n }\n\n return calls;\n }\n\n private ensureAdditivePolicy(policy: MigrationOperationPolicy) {\n if (!policy.allowedOperationClasses.includes('additive')) {\n return plannerFailure([\n {\n kind: 'unsupportedOperation',\n summary: 'Migration planner requires additive operations be allowed',\n why: 'The planner requires the \"additive\" operation class to be allowed in the policy.',\n },\n ]);\n }\n return null;\n }\n}\n\n/**\n * A diff issue whose node is an RLS policy — the structural half of the one\n * combined tree diff, routed to `planPostgresSchemaDiff` instead of\n * `planIssues`.\n */\nfunction isPolicyDiffIssue(issue: SchemaDiffIssue<SqlSchemaDiffNode>): boolean {\n const node = issue.expected ?? issue.actual;\n return node !== undefined && PostgresPolicySchemaNode.is(node);\n}\n\n/**\n * Drops a `not-expected` issue when it is a whole extra storage entity (a table\n * or a native enum) that some space in the composition owns. Each such node\n * yields its own storage coordinate (see {@link postgresNodeStorageCoordinate}),\n * so `declaresEntity` answers over the whole composition on one uniform\n * coordinate: a positive answer means a sibling owns this entity here — leave\n * it; a negative answer means a genuine orphan — drop it. A node with no storage\n * coordinate (a namespace, or a deeper column/constraint drift on an owned\n * table) is this space's own and is always kept. No oracle ⇒ keep everything.\n */\nfunction retainUnownedExtras(\n issues: readonly SchemaDiffIssue<SqlSchemaDiffNode>[],\n ownership: SchemaOwnership | undefined,\n contract: Contract<SqlStorage>,\n): readonly SchemaDiffIssue<SqlSchemaDiffNode>[] {\n if (ownership === undefined) return issues;\n return issues.filter((issue) => {\n if (issueOutcome(issue) !== 'not-expected') return true;\n const node = issueNode(issue);\n if (node === undefined) return true;\n const coordinate = postgresNodeStorageCoordinate(node);\n if (coordinate === undefined) return true;\n const ddlSchemaName = issueSchemaName(issue);\n if (ddlSchemaName === undefined) return true;\n const namespaceId = resolveNamespaceIdForDdlSchema(contract, ddlSchemaName);\n return !ownership.declaresEntity({ namespaceId, ...coordinate });\n });\n}\n\n/**\n * Returns the one namespace node the relational strategy layer probes for\n * live-table existence and reads codec-hook context off — the namespace\n * matching the planner's resolved schema name, or the first namespace when\n * none matches. `undefined` when the tree has no namespaces, so the strategy\n * context uses its empty-schema default.\n *\n * The relational strategies key tables by bare name, so they can only probe one\n * namespace at a time; probing across every namespace at once is future work.\n *\n * Returns the real `PostgresNamespaceSchemaNode` reference rather than a\n * projection: `storageTypePlanCallStrategy` hands this same value to codec\n * `planTypeOperations` hooks as `schema`, and hooks read the Postgres-specific\n * `nativeEnums` field off it (via `PostgresNamespaceSchemaNode.is`) to decide\n * whether a native enum type already exists — a projection that only copies\n * `tables` would silently drop that signal. `StrategyContext.schema`'s\n * declared type (`SqlSchemaIR`, shared with SQLite's flat shape) doesn't\n * capture this, so the return is `blindCast` the same way `namespaceSchemaNodes`\n * in the family's relational walk already treats a namespace node as a\n * structurally-`SqlSchemaIR`-shaped value.\n */\nfunction relationalNamespaceNode(\n schema: PostgresDatabaseSchemaNode,\n schemaName: string,\n): SqlSchemaIR | undefined {\n const namespaceNodes = Object.values(schema.namespaces);\n const namespaceNode =\n namespaceNodes.find((node) => node.schemaName === schemaName) ?? namespaceNodes[0];\n if (namespaceNode === undefined) return undefined;\n return blindCast<\n SqlSchemaIR,\n 'PostgresNamespaceSchemaNode carries tables (+ nativeEnums, read by codec hooks via PostgresNamespaceSchemaNode.is) structurally compatible with the SqlSchemaIR shape the strategy layer declares'\n >(namespaceNode);\n}\n\n/**\n * Rebuilds the `PostgresRlsPolicy` contract entity `CreatePostgresRlsPolicyCall`\n * carries (its `renderTypeScript`/`createRlsPolicy` paths serialize the whole\n * entity, `namespaceId` included). This reconstructs rather than looking the\n * original up in the contract on purpose: the diff node's `namespaceId` is the\n * *resolved DDL schema* (set when the expected tree was built), which is the\n * value the emitted op must carry; the contract-stored entity holds the raw,\n * pre-resolution coordinate, so a lookup would change the migration output.\n */\nfunction policyNodeToContractPolicy(node: PostgresPolicySchemaNode): PostgresRlsPolicy {\n return new PostgresRlsPolicy({\n name: node.name,\n prefix: node.prefix,\n tableName: node.tableName,\n namespaceId: node.namespaceId,\n operation: node.operation,\n roles: [...node.roles],\n ...ifDefined('using', node.using),\n ...ifDefined('withCheck', node.withCheck),\n permissive: node.permissive,\n });\n}\n"],"mappings":"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"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { t as PostgresMigration } from "./postgres-migration-
|
|
1
|
+
import { t as PostgresMigration } from "./postgres-migration-1_ZoswMV.mjs";
|
|
2
2
|
import { t as renderOps } from "./render-ops-BREh1kHe.mjs";
|
|
3
3
|
import { t as renderCallsToTypeScript } from "./render-typescript-7yqILcwr.mjs";
|
|
4
4
|
//#region src/core/migrations/planner-produced-postgres-migration.ts
|
|
@@ -40,4 +40,4 @@ var TypeScriptRenderablePostgresMigration = class extends PostgresMigration {
|
|
|
40
40
|
//#endregion
|
|
41
41
|
export { TypeScriptRenderablePostgresMigration as t };
|
|
42
42
|
|
|
43
|
-
//# sourceMappingURL=planner-produced-postgres-migration-
|
|
43
|
+
//# sourceMappingURL=planner-produced-postgres-migration-BV3WLLXl.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"planner-produced-postgres-migration-
|
|
1
|
+
{"version":3,"file":"planner-produced-postgres-migration-BV3WLLXl.mjs","names":["#calls","#meta","#spaceId","#lowerer","#operationsCache"],"sources":["../src/core/migrations/planner-produced-postgres-migration.ts"],"sourcesContent":["/**\n * Planner-produced Postgres migration.\n *\n * Returned by `PostgresMigrationPlanner.plan(...)` and `emptyMigration(...)`.\n * Holds the migration IR (`PostgresOpFactoryCall[]`) alongside\n * `MigrationMeta` and exposes both the runtime-ops view (`get operations`)\n * and the TypeScript authoring view (`renderTypeScript()`). Satisfies\n * `MigrationPlanWithAuthoringSurface` so the CLI can uniformly serialize any\n * planner result back to `migration.ts`.\n *\n * Extends the family-level `SqlMigration` alias rather than the target-local\n * migration base directly — mirrors Mongo's `PlannerProducedMongoMigration`\n * shape and keeps CLI wiring one step removed from target internals.\n *\n * Placeholder-bearing plans: `renderTypeScript()` always succeeds and embeds\n * `() => placeholder(\"slot\")` at each stub. `operations`, in contrast, is\n * _not safe to enumerate_ on a stub-bearing plan — `DataTransformCall.toOp()`\n * throws `PN-MIG-2001` because a planner-stubbed closure cannot be lowered\n * to a runtime op. Callers that know a plan may carry stubs must render to\n * `migration.ts`, let the user fill the slots, and re-load the edited\n * migration before enumerating ops. The walk-schema planner does not emit\n * `DataTransformCall`s today, so this asymmetry is invisible until the\n * issue-planner integration lands in Phase 2.\n */\n\nimport type { SqlMigrationPlanOperation } from '@prisma-next/family-sql/control';\nimport type { ExecuteRequestLowerer } from '@prisma-next/family-sql/control-adapter';\nimport type {\n MigrationPlanWithAuthoringSurface,\n OpFactoryCall,\n} from '@prisma-next/framework-components/control';\nimport type { MigrationMeta } from '@prisma-next/migration-tools/migration';\nimport type { PostgresPlanTargetDetails } from './planner-target-details';\nimport { PostgresMigration } from './postgres-migration';\nimport { renderOps } from './render-ops';\nimport { renderCallsToTypeScript } from './render-typescript';\n\nexport class TypeScriptRenderablePostgresMigration\n extends PostgresMigration\n implements MigrationPlanWithAuthoringSurface\n{\n readonly #calls: readonly OpFactoryCall[];\n readonly #meta: MigrationMeta;\n readonly #spaceId: string;\n readonly #lowerer: ExecuteRequestLowerer | undefined;\n #operationsCache:\n | readonly (\n | SqlMigrationPlanOperation<PostgresPlanTargetDetails>\n | Promise<SqlMigrationPlanOperation<PostgresPlanTargetDetails>>\n )[]\n | undefined;\n\n constructor(\n calls: readonly OpFactoryCall[],\n meta: MigrationMeta,\n spaceId: string,\n lowerer?: ExecuteRequestLowerer,\n ) {\n super();\n this.#calls = calls;\n this.#meta = meta;\n this.#spaceId = spaceId;\n this.#lowerer = lowerer;\n }\n\n override get operations(): readonly (\n | SqlMigrationPlanOperation<PostgresPlanTargetDetails>\n | Promise<SqlMigrationPlanOperation<PostgresPlanTargetDetails>>\n )[] {\n this.#operationsCache ??= renderOps(this.#calls, this.#lowerer);\n return this.#operationsCache;\n }\n\n override describe(): MigrationMeta {\n return this.#meta;\n }\n\n /**\n * Contract space this planner-produced plan applies to. Threaded\n * from the planner options so the runner keys the marker row by\n * the right space when executing the plan.\n */\n get spaceId(): string {\n return this.#spaceId;\n }\n\n renderTypeScript(): string {\n return renderCallsToTypeScript(this.#calls, { from: this.#meta.from, to: this.#meta.to });\n }\n}\n"],"mappings":";;;;AAqCA,IAAa,wCAAb,cACU,kBAEV;CACE;CACA;CACA;CACA;CACA;CAOA,YACE,OACA,MACA,SACA,SACA;EACA,MAAM;EACN,KAAKA,SAAS;EACd,KAAKC,QAAQ;EACb,KAAKC,WAAW;EAChB,KAAKC,WAAW;CAClB;CAEA,IAAa,aAGT;EACF,KAAKC,qBAAqB,UAAU,KAAKJ,QAAQ,KAAKG,QAAQ;EAC9D,OAAO,KAAKC;CACd;CAEA,WAAmC;EACjC,OAAO,KAAKH;CACd;;;;;;CAOA,IAAI,UAAkB;EACpB,OAAO,KAAKC;CACd;CAEA,mBAA2B;EACzB,OAAO,wBAAwB,KAAKF,QAAQ;GAAE,MAAM,KAAKC,MAAM;GAAM,IAAI,KAAKA,MAAM;EAAG,CAAC;CAC1F;AACF"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { t as TypeScriptRenderablePostgresMigration } from "./planner-produced-postgres-migration-
|
|
1
|
+
import { t as TypeScriptRenderablePostgresMigration } from "./planner-produced-postgres-migration-BV3WLLXl.mjs";
|
|
2
2
|
export { TypeScriptRenderablePostgresMigration };
|
package/dist/planner.mjs
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
import { r as contractToPostgresDatabaseSchemaNode } from "./diff-database-schema-oY3brcLj.mjs";
|
|
2
|
-
import { t as createPostgresMigrationPlanner } from "./planner-
|
|
2
|
+
import { t as createPostgresMigrationPlanner } from "./planner-BWmH0NqM.mjs";
|
|
3
3
|
export { contractToPostgresDatabaseSchemaNode, createPostgresMigrationPlanner };
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { m as PG_INT_CODEC_ID, y as PG_TEXT_CODEC_ID } from "./codec-ids-B10ZZHzw.mjs";
|
|
2
2
|
import { a as nativeEnumEntityKind, c as roleEntityKind, o as policyEntityKind, s as rlsEnablementEntityKind, t as PostgresSchema } from "./postgres-schema-Cm4DtiGA.mjs";
|
|
3
|
-
import { t as postgresAuthoringEntityTypes } from "./authoring-
|
|
3
|
+
import { t as postgresAuthoringEntityTypes } from "./authoring-CGe-7Yr9.mjs";
|
|
4
4
|
import { UNBOUND_NAMESPACE_ID } from "@prisma-next/framework-components/ir";
|
|
5
5
|
import { blindCast } from "@prisma-next/utils/casts";
|
|
6
6
|
import { buildSqlSchemaQualifiedView } from "@prisma-next/sql-contract/contract-view";
|
|
@@ -108,4 +108,4 @@ const PostgresContractView = {
|
|
|
108
108
|
//#endregion
|
|
109
109
|
export { PostgresContractSerializer as n, PostgresContractView as t };
|
|
110
110
|
|
|
111
|
-
//# sourceMappingURL=postgres-contract-view-
|
|
111
|
+
//# sourceMappingURL=postgres-contract-view-CWsxTdoA.mjs.map
|
package/dist/{postgres-contract-view-DM8sN1Ot.mjs.map → postgres-contract-view-CWsxTdoA.mjs.map}
RENAMED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"postgres-contract-view-
|
|
1
|
+
{"version":3,"file":"postgres-contract-view-CWsxTdoA.mjs","names":[],"sources":["../src/core/postgres-contract-serializer.ts","../src/core/postgres-contract-view.ts"],"sourcesContent":["import type { Contract } from '@prisma-next/contract/types';\nimport {\n SqlContractSerializerBase,\n type SqlEntityHydrationFactory,\n} from '@prisma-next/family-sql/ir';\nimport {\n type AuthoringEntityContext,\n type AuthoringEntityTypeFactoryOutput,\n type AuthoringEntityTypeNamespace,\n isAuthoringEntityTypeDescriptor,\n} from '@prisma-next/framework-components/authoring';\nimport {\n type AnyEntityKindDescriptor,\n type Namespace,\n UNBOUND_NAMESPACE_ID,\n} from '@prisma-next/framework-components/ir';\nimport type { SqlNamespaceInput, SqlStorage } from '@prisma-next/sql-contract/types';\nimport { blindCast } from '@prisma-next/utils/casts';\nimport type { JsonObject } from '@prisma-next/utils/json';\nimport { postgresAuthoringEntityTypes } from './authoring';\nimport { PG_INT_CODEC_ID, PG_TEXT_CODEC_ID } from './codec-ids';\nimport {\n nativeEnumEntityKind,\n policyEntityKind,\n rlsEnablementEntityKind,\n roleEntityKind,\n} from './entity-kinds';\nimport { PostgresSchema } from './postgres-schema';\n\nconst POSTGRES_AUTHORING_CTX: AuthoringEntityContext = {\n family: 'sql',\n target: 'postgres',\n enumInferenceCodecs: { text: PG_TEXT_CODEC_ID, int: PG_INT_CODEC_ID },\n};\n\nfunction isAuthoringEntityTypeFactoryOutput(\n output: unknown,\n): output is AuthoringEntityTypeFactoryOutput<unknown, unknown> {\n return (\n typeof output === 'object' &&\n output !== null &&\n 'factory' in output &&\n typeof output.factory === 'function'\n );\n}\n\n/**\n * Walks a pack's entity-type namespace tree and emits hydration factories\n * keyed by the descriptor's `discriminator`. Used for `storage.types`\n * (codec-triple hydration). Namespace entries hydration dispatches by\n * entries key, not discriminator — handled by `hydrateNamespaceEntities`.\n */\nfunction collectStorageTypesHydrators(\n namespace: AuthoringEntityTypeNamespace,\n): ReadonlyMap<string, SqlEntityHydrationFactory> {\n const registry = new Map<string, SqlEntityHydrationFactory>();\n const walk = (node: AuthoringEntityTypeNamespace): void => {\n for (const value of Object.values(node)) {\n if (isAuthoringEntityTypeDescriptor(value)) {\n if (isAuthoringEntityTypeFactoryOutput(value.output)) {\n const { factory } = value.output;\n registry.set(value.discriminator, (raw) => factory(raw, POSTGRES_AUTHORING_CTX));\n }\n continue;\n }\n if (typeof value === 'object' && value !== null) {\n walk(value);\n }\n }\n };\n walk(namespace);\n return registry;\n}\n\nexport class PostgresContractSerializer extends SqlContractSerializerBase<Contract<SqlStorage>> {\n constructor(extraPackEntityKinds: readonly AnyEntityKindDescriptor[] = []) {\n const storageTypesHydrators = collectStorageTypesHydrators(postgresAuthoringEntityTypes);\n super(storageTypesHydrators, [\n policyEntityKind,\n roleEntityKind,\n rlsEnablementEntityKind,\n nativeEnumEntityKind,\n ...extraPackEntityKinds,\n ]);\n }\n\n protected override hydrateSqlNamespaceEntry(\n nsId: string,\n raw: Record<string, unknown>,\n ): Namespace | SqlNamespaceInput {\n const hydrated = blindCast<\n SqlNamespaceInput,\n 'raw is always plain JSON, so super.hydrateSqlNamespaceEntry returns SqlNamespaceInput'\n >(super.hydrateSqlNamespaceEntry(nsId, raw));\n const { id, entries } = hydrated;\n\n const allSlotsEmpty = Object.values(entries).every(\n (slot) => slot === undefined || Object.keys(slot).length === 0,\n );\n if (id === UNBOUND_NAMESPACE_ID && allSlotsEmpty) {\n return PostgresSchema.unbound;\n }\n const valueSetSlot = entries['valueSet'];\n const hasValueSets = valueSetSlot !== undefined && Object.keys(valueSetSlot).length > 0;\n return new PostgresSchema({\n id,\n entries: {\n ...entries,\n table: entries['table'] ?? {},\n ...(hasValueSets ? { valueSet: valueSetSlot } : {}),\n },\n });\n }\n\n override serializeContract(contract: Contract<SqlStorage>): JsonObject {\n const { storage, ...rest } = contract;\n const namespacesJson: Record<string, JsonObject> = {};\n // Each namespace serializes to its id, its schema-kind tag, and the\n // base's generic entries walk — every enumerable kind on\n // `PostgresSchema.entries`, including `native_enum`.\n for (const [nsId, ns] of Object.entries(storage.namespaces)) {\n const isUnboundSlot = ns.id === UNBOUND_NAMESPACE_ID;\n namespacesJson[nsId] = {\n id: ns.id,\n kind: isUnboundSlot ? 'postgres-unbound-schema' : 'postgres-schema',\n entries: this.serializeNamespaceEntries(ns.entries),\n };\n }\n const storageOut: Record<string, unknown> = {\n storageHash: String(storage.storageHash),\n namespaces: namespacesJson,\n };\n if (storage.types !== undefined) {\n const typesOut: Record<string, JsonObject> = {};\n for (const [name, entry] of Object.entries(storage.types)) {\n typesOut[name] = this.serializeJsonObject(entry);\n }\n storageOut['types'] = typesOut;\n }\n return blindCast<\n JsonObject,\n 'contract minus storage plus a JSON-shaped storageOut is a JsonObject'\n >({\n ...rest,\n storage: storageOut,\n });\n }\n}\n","import type { Contract } from '@prisma-next/contract/types';\nimport {\n buildSqlSchemaQualifiedView,\n type SqlSchemaQualifiedView,\n} from '@prisma-next/sql-contract/contract-view';\nimport type { SqlStorage } from '@prisma-next/sql-contract/types';\nimport { PostgresContractSerializer } from './postgres-contract-serializer';\n\n/**\n * A schema-qualified Postgres contract view: the deserialized contract\n * intersected with a single `namespace` member holding every schema by id. It is\n * substitutable for `Contract` (carries `storage`, `domain`, …) and reaches each\n * schema's entities through `view.namespace.<schema>`:\n *\n * ```ts\n * const view = PostgresContractView.fromJson<Contract>(contractJson);\n * view.namespace.public.table.users // typed table leaf in the public schema\n * view.namespace.auth.table.users // the auth schema's own users table\n * view.namespace.public.entries.policy.X // pack-contributed kind (RLS / #771 path)\n * view.namespace.__unbound__.table.X // default schema, keyed by its raw id\n * view.storage // the full contract is still present\n * ```\n *\n * This mirrors the runtime `db.enums.<ns>` keying exactly (the default schema\n * keeps its literal `__unbound__` id). Schema names are NOT promoted to the\n * contract root, so there is no collision with contract envelope fields — a\n * schema named `storage` is `view.namespace.storage`, while `view.storage`\n * stays the contract's `storage`.\n */\nexport type PostgresContractView<TContract extends Contract<SqlStorage> = Contract<SqlStorage>> =\n SqlSchemaQualifiedView<TContract>;\n\nexport const PostgresContractView = {\n /** Wrap an already-deserialized Postgres contract in a schema-qualified view. */\n from<TContract extends Contract<SqlStorage>>(\n contract: TContract,\n ): PostgresContractView<TContract> {\n return buildSqlSchemaQualifiedView(contract);\n },\n\n /** Deserialize a Postgres contract JSON envelope and wrap it in a view. */\n fromJson<TContract extends Contract<SqlStorage> = Contract<SqlStorage>>(\n json: unknown,\n ): PostgresContractView<TContract> {\n const contract = new PostgresContractSerializer().deserializeContract<TContract>(json);\n return buildSqlSchemaQualifiedView(contract);\n },\n};\n"],"mappings":";;;;;;;;;AA6BA,MAAM,yBAAiD;CACrD,QAAQ;CACR,QAAQ;CACR,qBAAqB;EAAE,MAAM;EAAkB,KAAK;CAAgB;AACtE;AAEA,SAAS,mCACP,QAC8D;CAC9D,OACE,OAAO,WAAW,YAClB,WAAW,QACX,aAAa,UACb,OAAO,OAAO,YAAY;AAE9B;;;;;;;AAQA,SAAS,6BACP,WACgD;CAChD,MAAM,2BAAW,IAAI,IAAuC;CAC5D,MAAM,QAAQ,SAA6C;EACzD,KAAK,MAAM,SAAS,OAAO,OAAO,IAAI,GAAG;GACvC,IAAI,gCAAgC,KAAK,GAAG;IAC1C,IAAI,mCAAmC,MAAM,MAAM,GAAG;KACpD,MAAM,EAAE,YAAY,MAAM;KAC1B,SAAS,IAAI,MAAM,gBAAgB,QAAQ,QAAQ,KAAK,sBAAsB,CAAC;IACjF;IACA;GACF;GACA,IAAI,OAAO,UAAU,YAAY,UAAU,MACzC,KAAK,KAAK;EAEd;CACF;CACA,KAAK,SAAS;CACd,OAAO;AACT;AAEA,IAAa,6BAAb,cAAgD,0BAAgD;CAC9F,YAAY,uBAA2D,CAAC,GAAG;EACzE,MAAM,wBAAwB,6BAA6B,4BAA4B;EACvF,MAAM,uBAAuB;GAC3B;GACA;GACA;GACA;GACA,GAAG;EACL,CAAC;CACH;CAEA,yBACE,MACA,KAC+B;EAK/B,MAAM,EAAE,IAAI,YAJK,UAGf,MAAM,yBAAyB,MAAM,GAAG,CACX;EAE/B,MAAM,gBAAgB,OAAO,OAAO,OAAO,CAAC,CAAC,OAC1C,SAAS,SAAS,KAAA,KAAa,OAAO,KAAK,IAAI,CAAC,CAAC,WAAW,CAC/D;EACA,IAAI,OAAO,wBAAwB,eACjC,OAAO,eAAe;EAExB,MAAM,eAAe,QAAQ;EAC7B,MAAM,eAAe,iBAAiB,KAAA,KAAa,OAAO,KAAK,YAAY,CAAC,CAAC,SAAS;EACtF,OAAO,IAAI,eAAe;GACxB;GACA,SAAS;IACP,GAAG;IACH,OAAO,QAAQ,YAAY,CAAC;IAC5B,GAAI,eAAe,EAAE,UAAU,aAAa,IAAI,CAAC;GACnD;EACF,CAAC;CACH;CAEA,kBAA2B,UAA4C;EACrE,MAAM,EAAE,SAAS,GAAG,SAAS;EAC7B,MAAM,iBAA6C,CAAC;EAIpD,KAAK,MAAM,CAAC,MAAM,OAAO,OAAO,QAAQ,QAAQ,UAAU,GAAG;GAC3D,MAAM,gBAAgB,GAAG,OAAO;GAChC,eAAe,QAAQ;IACrB,IAAI,GAAG;IACP,MAAM,gBAAgB,4BAA4B;IAClD,SAAS,KAAK,0BAA0B,GAAG,OAAO;GACpD;EACF;EACA,MAAM,aAAsC;GAC1C,aAAa,OAAO,QAAQ,WAAW;GACvC,YAAY;EACd;EACA,IAAI,QAAQ,UAAU,KAAA,GAAW;GAC/B,MAAM,WAAuC,CAAC;GAC9C,KAAK,MAAM,CAAC,MAAM,UAAU,OAAO,QAAQ,QAAQ,KAAK,GACtD,SAAS,QAAQ,KAAK,oBAAoB,KAAK;GAEjD,WAAW,WAAW;EACxB;EACA,OAAO,UAGL;GACA,GAAG;GACH,SAAS;EACX,CAAC;CACH;AACF;;;ACnHA,MAAa,uBAAuB;;CAElC,KACE,UACiC;EACjC,OAAO,4BAA4B,QAAQ;CAC7C;;CAGA,SACE,MACiC;EAEjC,OAAO,4BADU,IAAI,2BAA2B,CAAC,CAAC,oBAA+B,IACvC,CAAC;CAC7C;AACF"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { g as PostgresRlsPolicy } from "./postgres-schema-Cm4DtiGA.mjs";
|
|
2
2
|
import { A as SetDefaultCall, C as DropNativeEnumTypeCall, D as EnableRowLevelSecurityCall, E as DropTableCall, F as installExtension, S as DropIndexCall, T as DropPostgresRlsPolicyCall, _ as DisableRowLevelSecurityCall, b as DropConstraintCall, c as AddUniqueCall, d as CreateIndexCall, f as CreateNativeEnumTypeCall, h as CreateTableCall, i as AddNativeEnumValueCall, j as SetNotNullCall, k as RenamePostgresRlsPolicyCall, l as AlterColumnTypeCall, m as CreateSchemaCall, n as AddColumnCall, p as CreatePostgresRlsPolicyCall, r as AddForeignKeyCall, s as AddPrimaryKeyCall, t as AddCheckConstraintCall, v as DropCheckConstraintCall, w as DropNotNullCall, x as DropDefaultCall, y as DropColumnCall } from "./op-factory-call-tBcLo_B8.mjs";
|
|
3
3
|
import { t as errorPostgresMigrationStackMissing } from "./errors-DO-w0EUS.mjs";
|
|
4
|
-
import { t as PostgresContractView } from "./postgres-contract-view-
|
|
4
|
+
import { t as PostgresContractView } from "./postgres-contract-view-CWsxTdoA.mjs";
|
|
5
5
|
import { t as dataTransform } from "./data-transform-BOWpliq8.mjs";
|
|
6
6
|
import { Migration } from "@prisma-next/family-sql/migration";
|
|
7
7
|
import { MigrationContractViews } from "@prisma-next/migration-tools/migration";
|
|
@@ -191,4 +191,4 @@ var PostgresMigration = class extends Migration {
|
|
|
191
191
|
//#endregion
|
|
192
192
|
export { PostgresMigration as t };
|
|
193
193
|
|
|
194
|
-
//# sourceMappingURL=postgres-migration-
|
|
194
|
+
//# sourceMappingURL=postgres-migration-1_ZoswMV.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"postgres-migration-Bt3sXoID.mjs","names":["SqlMigration","#endView","#startView"],"sources":["../src/core/migrations/postgres-migration.ts"],"sourcesContent":["import type { Contract } from '@prisma-next/contract/types';\nimport type { SqlMigrationPlanOperation } from '@prisma-next/family-sql/control';\nimport type { SqlControlAdapter } from '@prisma-next/family-sql/control-adapter';\nimport { Migration as SqlMigration } from '@prisma-next/family-sql/migration';\nimport type { ControlStack } from '@prisma-next/framework-components/control';\nimport { MigrationContractViews } from '@prisma-next/migration-tools/migration';\nimport type { SqlStorage } from '@prisma-next/sql-contract/types';\nimport type { DdlColumn, DdlTableConstraint } from '@prisma-next/sql-relational-core/ast';\nimport { errorPostgresMigrationStackMissing } from '../errors';\nimport { PostgresContractView } from '../postgres-contract-view';\nimport { PostgresRlsPolicy, type PostgresRlsPolicyInput } from '../postgres-rls-policy';\nimport {\n AddCheckConstraintCall,\n AddColumnCall,\n AddForeignKeyCall,\n AddNativeEnumValueCall,\n AddPrimaryKeyCall,\n AddUniqueCall,\n AlterColumnTypeCall,\n type AlterColumnTypeOptions,\n CreateIndexCall,\n CreateNativeEnumTypeCall,\n CreatePostgresRlsPolicyCall,\n CreateSchemaCall,\n CreateTableCall,\n DisableRowLevelSecurityCall,\n DropCheckConstraintCall,\n DropColumnCall,\n DropConstraintCall,\n DropDefaultCall,\n DropIndexCall,\n DropNativeEnumTypeCall,\n DropNotNullCall,\n DropPostgresRlsPolicyCall,\n DropTableCall,\n EnableRowLevelSecurityCall,\n RenamePostgresRlsPolicyCall,\n SetDefaultCall,\n SetNotNullCall,\n} from './op-factory-call';\nimport { type DataTransformOptions, dataTransform } from './operations/data-transform';\nimport { installExtension } from './operations/dependencies';\nimport type { CreateIndexExtras } from './operations/indexes';\nimport type { ForeignKeySpec } from './operations/shared';\nimport type { PostgresPlanTargetDetails } from './planner-target-details';\n\n/**\n * Target-owned base class for Postgres migrations.\n *\n * Fixes the `SqlMigration` generic to `PostgresPlanTargetDetails` and the\n * abstract `targetId` to the Postgres target-id string literal, so both\n * user-authored migrations and renderer-generated scaffolds (the output of\n * `renderCallsToTypeScript`) can extend `PostgresMigration` directly without\n * redeclaring target-local identity.\n *\n * Mirrors `MongoMigration` in `@prisma-next/family-mongo`: the renderer\n * emits `extends Migration` against a facade re-export of this class\n * from `@prisma-next/postgres/migration`, keeping the authoring surface\n * target-scoped rather than family-scoped.\n *\n * The constructor materializes a single Postgres `SqlControlAdapter` from\n * `stack.adapter.create(stack)` and stores it; the protected `dataTransform`\n * instance method forwards to the free `dataTransform` factory with that\n * stored adapter, so user migrations can write `this.dataTransform(...)`\n * without threading the adapter through every call.\n *\n * Every method requires an explicit `schema`. Postgres migrations name their\n * schema deliberately — there is no default and no `search_path`-relative\n * option. A migration that left the schema unspecified would resolve against\n * whatever `search_path` the connection happened to carry, and that ambiguity\n * is an antipattern in a migration. (The unbound/unspecified namespace concept\n * remains for SQLite, which has no schemas, and for Mongo's connection `db`.)\n */\nexport abstract class PostgresMigration<\n Start extends Contract<SqlStorage> = Contract<SqlStorage>,\n End extends Contract<SqlStorage> = Contract<SqlStorage>,\n> extends SqlMigration<PostgresPlanTargetDetails, 'postgres', Start, End> {\n readonly targetId = 'postgres' as const;\n\n /**\n * Materialized Postgres control adapter, created once per migration\n * instance from the injected stack. `undefined` only when the migration\n * was instantiated without a stack (test fixtures); `controlAdapterFor`\n * throws a PN-MIG-2007 in that case to surface the misuse.\n */\n protected readonly controlAdapter: SqlControlAdapter<'postgres'> | undefined;\n\n #endView = new MigrationContractViews<PostgresContractView<End>>(\n this,\n 'PostgresMigration',\n (json) => PostgresContractView.fromJson<End>(json),\n );\n #startView = new MigrationContractViews<PostgresContractView<Start>>(\n this,\n 'PostgresMigration',\n (json) => PostgresContractView.fromJson<Start>(json),\n );\n\n constructor(stack?: ControlStack<'sql', 'postgres'>) {\n super(stack);\n // The descriptor `create()` is typed as the wider `ControlAdapterInstance`;\n // the Postgres descriptor concretely returns a `SqlControlAdapter<'postgres'>`,\n // so the cast holds for any Postgres-target stack assembled at runtime.\n this.controlAdapter = stack?.adapter\n ? (stack.adapter.create(stack) as SqlControlAdapter<'postgres'>)\n : undefined;\n }\n\n /**\n * Returns the materialized control adapter, or throws a PN-MIG-2007 naming\n * `operation` when the migration was constructed without a `ControlStack`.\n * Single home for the null-check that every DDL/DML method shares.\n */\n private controlAdapterFor(operation: string): SqlControlAdapter<'postgres'> {\n if (!this.controlAdapter) {\n throw errorPostgresMigrationStackMissing(operation);\n }\n return this.controlAdapter;\n }\n\n /**\n * The typed, schema-qualified Postgres view over this migration's end-state\n * contract — `this.endContract.namespace.<schema>.table.<name>`, etc. Throws\n * if no `endContractJson` was provided.\n */\n get endContract(): PostgresContractView<End> {\n return this.#endView.endContract;\n }\n\n /**\n * The typed Postgres view over this migration's start-state contract, or\n * `null` for a baseline migration (no `startContractJson`).\n */\n get startContract(): PostgresContractView<Start> | null {\n return this.#startView.startContract;\n }\n\n /**\n * Instance-method wrapper around the free `dataTransform` factory that\n * supplies the stored control adapter. Authors call this from inside\n * `get operations()`; the adapter argument is hidden from the call site.\n */\n protected dataTransform<TContract extends Contract<SqlStorage>>(\n contract: TContract,\n name: string,\n options: DataTransformOptions,\n ): Promise<SqlMigrationPlanOperation<PostgresPlanTargetDetails>> {\n return dataTransform(contract, name, options, this.controlAdapterFor('dataTransform'));\n }\n\n /**\n * Emit a `CREATE TABLE` migration operation. Builds a typed DDL node from\n * the supplied options and lowers it through the stored control adapter.\n * Throws if no adapter is present (i.e. migration instantiated without a stack).\n */\n protected createTable(options: {\n readonly schema: string;\n readonly table: string;\n readonly ifNotExists?: boolean;\n readonly columns: readonly DdlColumn[];\n readonly constraints?: readonly DdlTableConstraint[];\n }): Promise<SqlMigrationPlanOperation<PostgresPlanTargetDetails>> {\n return new CreateTableCall(\n options.schema,\n options.table,\n options.columns,\n options.constraints,\n ).toOp(this.controlAdapterFor('createTable'));\n }\n\n /**\n * Emit a `CREATE SCHEMA` migration operation. Builds a typed DDL node from\n * the supplied options and lowers it through the stored control adapter.\n * Throws if no adapter is present (i.e. migration instantiated without a stack).\n */\n protected createSchema(options: {\n readonly schema: string;\n readonly ifNotExists?: boolean;\n }): Promise<SqlMigrationPlanOperation<PostgresPlanTargetDetails>> {\n return new CreateSchemaCall(options.schema).toOp(this.controlAdapterFor('createSchema'));\n }\n\n /**\n * Emit a `CREATE TYPE ... AS ENUM (...)` migration operation for a managed\n * native enum. Builds a typed DDL node and lowers it through the stored\n * control adapter (members render in declaration order). Throws if no adapter\n * is present.\n */\n protected createNativeEnumType(options: {\n readonly schema: string;\n readonly typeName: string;\n readonly members: readonly string[];\n }): Promise<SqlMigrationPlanOperation<PostgresPlanTargetDetails>> {\n return new CreateNativeEnumTypeCall(options.schema, options.typeName, options.members).toOp(\n this.controlAdapterFor('createNativeEnumType'),\n );\n }\n\n /**\n * Emit a `DROP TYPE` migration operation for a managed native enum, lowered\n * through the stored control adapter. Throws if no adapter is present.\n */\n protected dropNativeEnumType(options: {\n readonly schema: string;\n readonly typeName: string;\n }): Promise<SqlMigrationPlanOperation<PostgresPlanTargetDetails>> {\n return new DropNativeEnumTypeCall(options.schema, options.typeName).toOp(\n this.controlAdapterFor('dropNativeEnumType'),\n );\n }\n\n /**\n * Emit an `ALTER TYPE ... ADD VALUE` migration operation appending one\n * member to a managed native enum, lowered through the stored control\n * adapter. Throws if no adapter is present. Every appended value is its\n * own operation — call this once per value to append more than one.\n */\n protected addNativeEnumValue(options: {\n readonly schema: string;\n readonly typeName: string;\n readonly value: string;\n }): Promise<SqlMigrationPlanOperation<PostgresPlanTargetDetails>> {\n return new AddNativeEnumValueCall(options.schema, options.typeName, options.value).toOp(\n this.controlAdapterFor('addNativeEnumValue'),\n );\n }\n\n protected addColumn(options: {\n readonly schema: string;\n readonly table: string;\n readonly column: DdlColumn;\n }): Promise<SqlMigrationPlanOperation<PostgresPlanTargetDetails>> {\n return new AddColumnCall(options.schema, options.table, options.column).toOp(\n this.controlAdapterFor('addColumn'),\n );\n }\n\n protected addPrimaryKey(options: {\n readonly schema: string;\n readonly table: string;\n readonly constraint: string;\n readonly columns: readonly string[];\n }): Promise<SqlMigrationPlanOperation<PostgresPlanTargetDetails>> {\n return new AddPrimaryKeyCall(\n options.schema,\n options.table,\n options.constraint,\n options.columns,\n ).toOp(this.controlAdapterFor('addPrimaryKey'));\n }\n\n protected addUnique(options: {\n readonly schema: string;\n readonly table: string;\n readonly constraint: string;\n readonly columns: readonly string[];\n }): Promise<SqlMigrationPlanOperation<PostgresPlanTargetDetails>> {\n return new AddUniqueCall(\n options.schema,\n options.table,\n options.constraint,\n options.columns,\n ).toOp(this.controlAdapterFor('addUnique'));\n }\n\n protected addForeignKey(options: {\n readonly schema: string;\n readonly table: string;\n readonly foreignKey: ForeignKeySpec;\n }): Promise<SqlMigrationPlanOperation<PostgresPlanTargetDetails>> {\n return new AddForeignKeyCall(options.schema, options.table, options.foreignKey).toOp(\n this.controlAdapterFor('addForeignKey'),\n );\n }\n\n protected addCheckConstraint(options: {\n readonly schema: string;\n readonly table: string;\n readonly constraint: string;\n readonly column: string;\n readonly values: readonly string[];\n }): Promise<SqlMigrationPlanOperation<PostgresPlanTargetDetails>> {\n return new AddCheckConstraintCall(\n options.schema,\n options.table,\n options.constraint,\n options.column,\n options.values,\n ).toOp(this.controlAdapterFor('addCheckConstraint'));\n }\n\n protected dropCheckConstraint(options: {\n readonly schema: string;\n readonly table: string;\n readonly constraint: string;\n }): Promise<SqlMigrationPlanOperation<PostgresPlanTargetDetails>> {\n return new DropCheckConstraintCall(options.schema, options.table, options.constraint).toOp(\n this.controlAdapterFor('dropCheckConstraint'),\n );\n }\n\n protected dropConstraint(options: {\n readonly schema: string;\n readonly table: string;\n readonly constraint: string;\n readonly kind?: 'foreignKey' | 'unique' | 'primaryKey';\n }): Promise<SqlMigrationPlanOperation<PostgresPlanTargetDetails>> {\n return new DropConstraintCall(\n options.schema,\n options.table,\n options.constraint,\n options.kind ?? 'unique',\n ).toOp(this.controlAdapterFor('dropConstraint'));\n }\n\n protected dropTable(options: {\n readonly schema: string;\n readonly table: string;\n }): Promise<SqlMigrationPlanOperation<PostgresPlanTargetDetails>> {\n return new DropTableCall(options.schema, options.table).toOp(\n this.controlAdapterFor('dropTable'),\n );\n }\n\n protected dropColumn(options: {\n readonly schema: string;\n readonly table: string;\n readonly column: string;\n }): Promise<SqlMigrationPlanOperation<PostgresPlanTargetDetails>> {\n return new DropColumnCall(options.schema, options.table, options.column).toOp(\n this.controlAdapterFor('dropColumn'),\n );\n }\n\n protected alterColumnType(options: {\n readonly schema: string;\n readonly table: string;\n readonly column: string;\n readonly options: AlterColumnTypeOptions;\n }): Promise<SqlMigrationPlanOperation<PostgresPlanTargetDetails>> {\n return new AlterColumnTypeCall(\n options.schema,\n options.table,\n options.column,\n options.options,\n ).toOp(this.controlAdapterFor('alterColumnType'));\n }\n\n protected setNotNull(options: {\n readonly schema: string;\n readonly table: string;\n readonly column: string;\n }): Promise<SqlMigrationPlanOperation<PostgresPlanTargetDetails>> {\n return new SetNotNullCall(options.schema, options.table, options.column).toOp(\n this.controlAdapterFor('setNotNull'),\n );\n }\n\n protected dropNotNull(options: {\n readonly schema: string;\n readonly table: string;\n readonly column: string;\n }): Promise<SqlMigrationPlanOperation<PostgresPlanTargetDetails>> {\n return new DropNotNullCall(options.schema, options.table, options.column).toOp(\n this.controlAdapterFor('dropNotNull'),\n );\n }\n\n protected setDefault(options: {\n readonly schema: string;\n readonly table: string;\n readonly column: string;\n readonly defaultSql: string;\n readonly operationClass?: 'additive' | 'widening';\n }): Promise<SqlMigrationPlanOperation<PostgresPlanTargetDetails>> {\n return new SetDefaultCall(\n options.schema,\n options.table,\n options.column,\n options.defaultSql,\n options.operationClass,\n ).toOp(this.controlAdapterFor('setDefault'));\n }\n\n protected dropDefault(options: {\n readonly schema: string;\n readonly table: string;\n readonly column: string;\n }): Promise<SqlMigrationPlanOperation<PostgresPlanTargetDetails>> {\n return new DropDefaultCall(options.schema, options.table, options.column).toOp(\n this.controlAdapterFor('dropDefault'),\n );\n }\n\n protected createIndex(options: {\n readonly schema: string;\n readonly table: string;\n readonly index: string;\n readonly columns: readonly string[];\n readonly extras?: CreateIndexExtras;\n }): Promise<SqlMigrationPlanOperation<PostgresPlanTargetDetails>> {\n return new CreateIndexCall(\n options.schema,\n options.table,\n options.index,\n options.columns,\n options.extras,\n ).toOp(this.controlAdapterFor('createIndex'));\n }\n\n protected dropIndex(options: {\n readonly schema: string;\n readonly table: string;\n readonly index: string;\n }): Promise<SqlMigrationPlanOperation<PostgresPlanTargetDetails>> {\n return new DropIndexCall(options.schema, options.table, options.index).toOp(\n this.controlAdapterFor('dropIndex'),\n );\n }\n\n protected installExtension(options: {\n readonly extensionName: string;\n readonly invariantId: string;\n readonly id: string;\n readonly label?: string;\n }): Promise<SqlMigrationPlanOperation<PostgresPlanTargetDetails>> {\n return installExtension(options, this.controlAdapterFor('installExtension'));\n }\n\n protected enableRowLevelSecurity(options: {\n readonly schema: string;\n readonly table: string;\n }): Promise<SqlMigrationPlanOperation<PostgresPlanTargetDetails>> {\n return new EnableRowLevelSecurityCall(options.schema, options.table).toOp(\n this.controlAdapterFor('enableRowLevelSecurity'),\n );\n }\n\n protected disableRowLevelSecurity(options: {\n readonly schema: string;\n readonly table: string;\n }): Promise<SqlMigrationPlanOperation<PostgresPlanTargetDetails>> {\n return new DisableRowLevelSecurityCall(options.schema, options.table).toOp(\n this.controlAdapterFor('disableRowLevelSecurity'),\n );\n }\n\n protected createRlsPolicy(options: {\n readonly schema: string;\n readonly table: string;\n readonly policy: PostgresRlsPolicyInput;\n }): Promise<SqlMigrationPlanOperation<PostgresPlanTargetDetails>> {\n return new CreatePostgresRlsPolicyCall(\n options.schema,\n options.table,\n new PostgresRlsPolicy(options.policy),\n ).toOp(this.controlAdapterFor('createRlsPolicy'));\n }\n\n protected dropRlsPolicy(options: {\n readonly schema: string;\n readonly table: string;\n readonly policy: string;\n }): Promise<SqlMigrationPlanOperation<PostgresPlanTargetDetails>> {\n return new DropPostgresRlsPolicyCall(options.schema, options.table, options.policy).toOp(\n this.controlAdapterFor('dropRlsPolicy'),\n );\n }\n\n protected renameRlsPolicy(options: {\n readonly schema: string;\n readonly table: string;\n readonly from: string;\n readonly to: string;\n }): Promise<SqlMigrationPlanOperation<PostgresPlanTargetDetails>> {\n return new RenamePostgresRlsPolicyCall(\n options.schema,\n options.table,\n options.from,\n options.to,\n ).toOp(this.controlAdapterFor('renameRlsPolicy'));\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"postgres-migration-1_ZoswMV.mjs","names":["SqlMigration","#endView","#startView"],"sources":["../src/core/migrations/postgres-migration.ts"],"sourcesContent":["import type { Contract } from '@prisma-next/contract/types';\nimport type { SqlMigrationPlanOperation } from '@prisma-next/family-sql/control';\nimport type { SqlControlAdapter } from '@prisma-next/family-sql/control-adapter';\nimport { Migration as SqlMigration } from '@prisma-next/family-sql/migration';\nimport type { ControlStack } from '@prisma-next/framework-components/control';\nimport { MigrationContractViews } from '@prisma-next/migration-tools/migration';\nimport type { SqlStorage } from '@prisma-next/sql-contract/types';\nimport type { DdlColumn, DdlTableConstraint } from '@prisma-next/sql-relational-core/ast';\nimport { errorPostgresMigrationStackMissing } from '../errors';\nimport { PostgresContractView } from '../postgres-contract-view';\nimport { PostgresRlsPolicy, type PostgresRlsPolicyInput } from '../postgres-rls-policy';\nimport {\n AddCheckConstraintCall,\n AddColumnCall,\n AddForeignKeyCall,\n AddNativeEnumValueCall,\n AddPrimaryKeyCall,\n AddUniqueCall,\n AlterColumnTypeCall,\n type AlterColumnTypeOptions,\n CreateIndexCall,\n CreateNativeEnumTypeCall,\n CreatePostgresRlsPolicyCall,\n CreateSchemaCall,\n CreateTableCall,\n DisableRowLevelSecurityCall,\n DropCheckConstraintCall,\n DropColumnCall,\n DropConstraintCall,\n DropDefaultCall,\n DropIndexCall,\n DropNativeEnumTypeCall,\n DropNotNullCall,\n DropPostgresRlsPolicyCall,\n DropTableCall,\n EnableRowLevelSecurityCall,\n RenamePostgresRlsPolicyCall,\n SetDefaultCall,\n SetNotNullCall,\n} from './op-factory-call';\nimport { type DataTransformOptions, dataTransform } from './operations/data-transform';\nimport { installExtension } from './operations/dependencies';\nimport type { CreateIndexExtras } from './operations/indexes';\nimport type { ForeignKeySpec } from './operations/shared';\nimport type { PostgresPlanTargetDetails } from './planner-target-details';\n\n/**\n * Target-owned base class for Postgres migrations.\n *\n * Fixes the `SqlMigration` generic to `PostgresPlanTargetDetails` and the\n * abstract `targetId` to the Postgres target-id string literal, so both\n * user-authored migrations and renderer-generated scaffolds (the output of\n * `renderCallsToTypeScript`) can extend `PostgresMigration` directly without\n * redeclaring target-local identity.\n *\n * Mirrors `MongoMigration` in `@prisma-next/family-mongo`: the renderer\n * emits `extends Migration` against a facade re-export of this class\n * from `@prisma-next/postgres/migration`, keeping the authoring surface\n * target-scoped rather than family-scoped.\n *\n * The constructor materializes a single Postgres `SqlControlAdapter` from\n * `stack.adapter.create(stack)` and stores it; the protected `dataTransform`\n * instance method forwards to the free `dataTransform` factory with that\n * stored adapter, so user migrations can write `this.dataTransform(...)`\n * without threading the adapter through every call.\n *\n * Every method requires an explicit `schema`. Postgres migrations name their\n * schema deliberately — there is no default and no `search_path`-relative\n * option. A migration that left the schema unspecified would resolve against\n * whatever `search_path` the connection happened to carry, and that ambiguity\n * is an antipattern in a migration. (The unbound/unspecified namespace concept\n * remains for SQLite, which has no schemas, and for Mongo's connection `db`.)\n */\nexport abstract class PostgresMigration<\n Start extends Contract<SqlStorage> = Contract<SqlStorage>,\n End extends Contract<SqlStorage> = Contract<SqlStorage>,\n> extends SqlMigration<PostgresPlanTargetDetails, 'postgres', Start, End> {\n readonly targetId = 'postgres' as const;\n\n /**\n * Materialized Postgres control adapter, created once per migration\n * instance from the injected stack. `undefined` only when the migration\n * was instantiated without a stack (test fixtures); `controlAdapterFor`\n * throws a PN-MIG-2007 in that case to surface the misuse.\n */\n protected readonly controlAdapter: SqlControlAdapter<'postgres'> | undefined;\n\n #endView = new MigrationContractViews<PostgresContractView<End>>(\n this,\n 'PostgresMigration',\n (json) => PostgresContractView.fromJson<End>(json),\n );\n #startView = new MigrationContractViews<PostgresContractView<Start>>(\n this,\n 'PostgresMigration',\n (json) => PostgresContractView.fromJson<Start>(json),\n );\n\n constructor(stack?: ControlStack<'sql', 'postgres'>) {\n super(stack);\n // The descriptor `create()` is typed as the wider `ControlAdapterInstance`;\n // the Postgres descriptor concretely returns a `SqlControlAdapter<'postgres'>`,\n // so the cast holds for any Postgres-target stack assembled at runtime.\n this.controlAdapter = stack?.adapter\n ? (stack.adapter.create(stack) as SqlControlAdapter<'postgres'>)\n : undefined;\n }\n\n /**\n * Returns the materialized control adapter, or throws a PN-MIG-2007 naming\n * `operation` when the migration was constructed without a `ControlStack`.\n * Single home for the null-check that every DDL/DML method shares.\n */\n private controlAdapterFor(operation: string): SqlControlAdapter<'postgres'> {\n if (!this.controlAdapter) {\n throw errorPostgresMigrationStackMissing(operation);\n }\n return this.controlAdapter;\n }\n\n /**\n * The typed, schema-qualified Postgres view over this migration's end-state\n * contract — `this.endContract.namespace.<schema>.table.<name>`, etc. Throws\n * if no `endContractJson` was provided.\n */\n get endContract(): PostgresContractView<End> {\n return this.#endView.endContract;\n }\n\n /**\n * The typed Postgres view over this migration's start-state contract, or\n * `null` for a baseline migration (no `startContractJson`).\n */\n get startContract(): PostgresContractView<Start> | null {\n return this.#startView.startContract;\n }\n\n /**\n * Instance-method wrapper around the free `dataTransform` factory that\n * supplies the stored control adapter. Authors call this from inside\n * `get operations()`; the adapter argument is hidden from the call site.\n */\n protected dataTransform<TContract extends Contract<SqlStorage>>(\n contract: TContract,\n name: string,\n options: DataTransformOptions,\n ): Promise<SqlMigrationPlanOperation<PostgresPlanTargetDetails>> {\n return dataTransform(contract, name, options, this.controlAdapterFor('dataTransform'));\n }\n\n /**\n * Emit a `CREATE TABLE` migration operation. Builds a typed DDL node from\n * the supplied options and lowers it through the stored control adapter.\n * Throws if no adapter is present (i.e. migration instantiated without a stack).\n */\n protected createTable(options: {\n readonly schema: string;\n readonly table: string;\n readonly ifNotExists?: boolean;\n readonly columns: readonly DdlColumn[];\n readonly constraints?: readonly DdlTableConstraint[];\n }): Promise<SqlMigrationPlanOperation<PostgresPlanTargetDetails>> {\n return new CreateTableCall(\n options.schema,\n options.table,\n options.columns,\n options.constraints,\n ).toOp(this.controlAdapterFor('createTable'));\n }\n\n /**\n * Emit a `CREATE SCHEMA` migration operation. Builds a typed DDL node from\n * the supplied options and lowers it through the stored control adapter.\n * Throws if no adapter is present (i.e. migration instantiated without a stack).\n */\n protected createSchema(options: {\n readonly schema: string;\n readonly ifNotExists?: boolean;\n }): Promise<SqlMigrationPlanOperation<PostgresPlanTargetDetails>> {\n return new CreateSchemaCall(options.schema).toOp(this.controlAdapterFor('createSchema'));\n }\n\n /**\n * Emit a `CREATE TYPE ... AS ENUM (...)` migration operation for a managed\n * native enum. Builds a typed DDL node and lowers it through the stored\n * control adapter (members render in declaration order). Throws if no adapter\n * is present.\n */\n protected createNativeEnumType(options: {\n readonly schema: string;\n readonly typeName: string;\n readonly members: readonly string[];\n }): Promise<SqlMigrationPlanOperation<PostgresPlanTargetDetails>> {\n return new CreateNativeEnumTypeCall(options.schema, options.typeName, options.members).toOp(\n this.controlAdapterFor('createNativeEnumType'),\n );\n }\n\n /**\n * Emit a `DROP TYPE` migration operation for a managed native enum, lowered\n * through the stored control adapter. Throws if no adapter is present.\n */\n protected dropNativeEnumType(options: {\n readonly schema: string;\n readonly typeName: string;\n }): Promise<SqlMigrationPlanOperation<PostgresPlanTargetDetails>> {\n return new DropNativeEnumTypeCall(options.schema, options.typeName).toOp(\n this.controlAdapterFor('dropNativeEnumType'),\n );\n }\n\n /**\n * Emit an `ALTER TYPE ... ADD VALUE` migration operation appending one\n * member to a managed native enum, lowered through the stored control\n * adapter. Throws if no adapter is present. Every appended value is its\n * own operation — call this once per value to append more than one.\n */\n protected addNativeEnumValue(options: {\n readonly schema: string;\n readonly typeName: string;\n readonly value: string;\n }): Promise<SqlMigrationPlanOperation<PostgresPlanTargetDetails>> {\n return new AddNativeEnumValueCall(options.schema, options.typeName, options.value).toOp(\n this.controlAdapterFor('addNativeEnumValue'),\n );\n }\n\n protected addColumn(options: {\n readonly schema: string;\n readonly table: string;\n readonly column: DdlColumn;\n }): Promise<SqlMigrationPlanOperation<PostgresPlanTargetDetails>> {\n return new AddColumnCall(options.schema, options.table, options.column).toOp(\n this.controlAdapterFor('addColumn'),\n );\n }\n\n protected addPrimaryKey(options: {\n readonly schema: string;\n readonly table: string;\n readonly constraint: string;\n readonly columns: readonly string[];\n }): Promise<SqlMigrationPlanOperation<PostgresPlanTargetDetails>> {\n return new AddPrimaryKeyCall(\n options.schema,\n options.table,\n options.constraint,\n options.columns,\n ).toOp(this.controlAdapterFor('addPrimaryKey'));\n }\n\n protected addUnique(options: {\n readonly schema: string;\n readonly table: string;\n readonly constraint: string;\n readonly columns: readonly string[];\n }): Promise<SqlMigrationPlanOperation<PostgresPlanTargetDetails>> {\n return new AddUniqueCall(\n options.schema,\n options.table,\n options.constraint,\n options.columns,\n ).toOp(this.controlAdapterFor('addUnique'));\n }\n\n protected addForeignKey(options: {\n readonly schema: string;\n readonly table: string;\n readonly foreignKey: ForeignKeySpec;\n }): Promise<SqlMigrationPlanOperation<PostgresPlanTargetDetails>> {\n return new AddForeignKeyCall(options.schema, options.table, options.foreignKey).toOp(\n this.controlAdapterFor('addForeignKey'),\n );\n }\n\n protected addCheckConstraint(options: {\n readonly schema: string;\n readonly table: string;\n readonly constraint: string;\n readonly column: string;\n readonly values: readonly string[];\n }): Promise<SqlMigrationPlanOperation<PostgresPlanTargetDetails>> {\n return new AddCheckConstraintCall(\n options.schema,\n options.table,\n options.constraint,\n options.column,\n options.values,\n ).toOp(this.controlAdapterFor('addCheckConstraint'));\n }\n\n protected dropCheckConstraint(options: {\n readonly schema: string;\n readonly table: string;\n readonly constraint: string;\n }): Promise<SqlMigrationPlanOperation<PostgresPlanTargetDetails>> {\n return new DropCheckConstraintCall(options.schema, options.table, options.constraint).toOp(\n this.controlAdapterFor('dropCheckConstraint'),\n );\n }\n\n protected dropConstraint(options: {\n readonly schema: string;\n readonly table: string;\n readonly constraint: string;\n readonly kind?: 'foreignKey' | 'unique' | 'primaryKey';\n }): Promise<SqlMigrationPlanOperation<PostgresPlanTargetDetails>> {\n return new DropConstraintCall(\n options.schema,\n options.table,\n options.constraint,\n options.kind ?? 'unique',\n ).toOp(this.controlAdapterFor('dropConstraint'));\n }\n\n protected dropTable(options: {\n readonly schema: string;\n readonly table: string;\n }): Promise<SqlMigrationPlanOperation<PostgresPlanTargetDetails>> {\n return new DropTableCall(options.schema, options.table).toOp(\n this.controlAdapterFor('dropTable'),\n );\n }\n\n protected dropColumn(options: {\n readonly schema: string;\n readonly table: string;\n readonly column: string;\n }): Promise<SqlMigrationPlanOperation<PostgresPlanTargetDetails>> {\n return new DropColumnCall(options.schema, options.table, options.column).toOp(\n this.controlAdapterFor('dropColumn'),\n );\n }\n\n protected alterColumnType(options: {\n readonly schema: string;\n readonly table: string;\n readonly column: string;\n readonly options: AlterColumnTypeOptions;\n }): Promise<SqlMigrationPlanOperation<PostgresPlanTargetDetails>> {\n return new AlterColumnTypeCall(\n options.schema,\n options.table,\n options.column,\n options.options,\n ).toOp(this.controlAdapterFor('alterColumnType'));\n }\n\n protected setNotNull(options: {\n readonly schema: string;\n readonly table: string;\n readonly column: string;\n }): Promise<SqlMigrationPlanOperation<PostgresPlanTargetDetails>> {\n return new SetNotNullCall(options.schema, options.table, options.column).toOp(\n this.controlAdapterFor('setNotNull'),\n );\n }\n\n protected dropNotNull(options: {\n readonly schema: string;\n readonly table: string;\n readonly column: string;\n }): Promise<SqlMigrationPlanOperation<PostgresPlanTargetDetails>> {\n return new DropNotNullCall(options.schema, options.table, options.column).toOp(\n this.controlAdapterFor('dropNotNull'),\n );\n }\n\n protected setDefault(options: {\n readonly schema: string;\n readonly table: string;\n readonly column: string;\n readonly defaultSql: string;\n readonly operationClass?: 'additive' | 'widening';\n }): Promise<SqlMigrationPlanOperation<PostgresPlanTargetDetails>> {\n return new SetDefaultCall(\n options.schema,\n options.table,\n options.column,\n options.defaultSql,\n options.operationClass,\n ).toOp(this.controlAdapterFor('setDefault'));\n }\n\n protected dropDefault(options: {\n readonly schema: string;\n readonly table: string;\n readonly column: string;\n }): Promise<SqlMigrationPlanOperation<PostgresPlanTargetDetails>> {\n return new DropDefaultCall(options.schema, options.table, options.column).toOp(\n this.controlAdapterFor('dropDefault'),\n );\n }\n\n protected createIndex(options: {\n readonly schema: string;\n readonly table: string;\n readonly index: string;\n readonly columns: readonly string[];\n readonly extras?: CreateIndexExtras;\n }): Promise<SqlMigrationPlanOperation<PostgresPlanTargetDetails>> {\n return new CreateIndexCall(\n options.schema,\n options.table,\n options.index,\n options.columns,\n options.extras,\n ).toOp(this.controlAdapterFor('createIndex'));\n }\n\n protected dropIndex(options: {\n readonly schema: string;\n readonly table: string;\n readonly index: string;\n }): Promise<SqlMigrationPlanOperation<PostgresPlanTargetDetails>> {\n return new DropIndexCall(options.schema, options.table, options.index).toOp(\n this.controlAdapterFor('dropIndex'),\n );\n }\n\n protected installExtension(options: {\n readonly extensionName: string;\n readonly invariantId: string;\n readonly id: string;\n readonly label?: string;\n }): Promise<SqlMigrationPlanOperation<PostgresPlanTargetDetails>> {\n return installExtension(options, this.controlAdapterFor('installExtension'));\n }\n\n protected enableRowLevelSecurity(options: {\n readonly schema: string;\n readonly table: string;\n }): Promise<SqlMigrationPlanOperation<PostgresPlanTargetDetails>> {\n return new EnableRowLevelSecurityCall(options.schema, options.table).toOp(\n this.controlAdapterFor('enableRowLevelSecurity'),\n );\n }\n\n protected disableRowLevelSecurity(options: {\n readonly schema: string;\n readonly table: string;\n }): Promise<SqlMigrationPlanOperation<PostgresPlanTargetDetails>> {\n return new DisableRowLevelSecurityCall(options.schema, options.table).toOp(\n this.controlAdapterFor('disableRowLevelSecurity'),\n );\n }\n\n protected createRlsPolicy(options: {\n readonly schema: string;\n readonly table: string;\n readonly policy: PostgresRlsPolicyInput;\n }): Promise<SqlMigrationPlanOperation<PostgresPlanTargetDetails>> {\n return new CreatePostgresRlsPolicyCall(\n options.schema,\n options.table,\n new PostgresRlsPolicy(options.policy),\n ).toOp(this.controlAdapterFor('createRlsPolicy'));\n }\n\n protected dropRlsPolicy(options: {\n readonly schema: string;\n readonly table: string;\n readonly policy: string;\n }): Promise<SqlMigrationPlanOperation<PostgresPlanTargetDetails>> {\n return new DropPostgresRlsPolicyCall(options.schema, options.table, options.policy).toOp(\n this.controlAdapterFor('dropRlsPolicy'),\n );\n }\n\n protected renameRlsPolicy(options: {\n readonly schema: string;\n readonly table: string;\n readonly from: string;\n readonly to: string;\n }): Promise<SqlMigrationPlanOperation<PostgresPlanTargetDetails>> {\n return new RenamePostgresRlsPolicyCall(\n options.schema,\n options.table,\n options.from,\n options.to,\n ).toOp(this.controlAdapterFor('renameRlsPolicy'));\n }\n}\n"],"mappings":"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"}
|
package/dist/runtime.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { t as postgresTargetDescriptorMetaRuntime } from "./descriptor-meta-runtime-UwYdV8fD.mjs";
|
|
2
|
-
import { n as PostgresContractSerializer, t as PostgresContractView } from "./postgres-contract-view-
|
|
2
|
+
import { n as PostgresContractSerializer, t as PostgresContractView } from "./postgres-contract-view-CWsxTdoA.mjs";
|
|
3
3
|
//#region src/exports/runtime.ts
|
|
4
4
|
/**
|
|
5
5
|
* Target-postgres deliberately does NOT import `SqlRuntimeTargetDescriptor` from `@prisma-next/sql-runtime`. The target package is a control-plane residence and must not pull the SQL execution-plane package into its dependency closure. The runtime descriptor here is shaped to satisfy the framework's `RuntimeTargetDescriptor` plus the structural `SqlStaticContributions` (`codecs:` returning a descriptor list) that
|
package/package.json
CHANGED
|
@@ -1,35 +1,35 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@prisma-next/target-postgres",
|
|
3
|
-
"version": "0.15.0-dev.
|
|
3
|
+
"version": "0.15.0-dev.14",
|
|
4
4
|
"license": "Apache-2.0",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"sideEffects": false,
|
|
7
7
|
"description": "Postgres target pack for Prisma Next",
|
|
8
8
|
"dependencies": {
|
|
9
|
-
"@prisma-next/cli": "0.15.0-dev.
|
|
10
|
-
"@prisma-next/contract": "0.15.0-dev.
|
|
11
|
-
"@prisma-next/errors": "0.15.0-dev.
|
|
12
|
-
"@prisma-next/family-sql": "0.15.0-dev.
|
|
13
|
-
"@prisma-next/framework-components": "0.15.0-dev.
|
|
14
|
-
"@prisma-next/migration-tools": "0.15.0-dev.
|
|
15
|
-
"@prisma-next/psl-parser": "0.15.0-dev.
|
|
16
|
-
"@prisma-next/sql-contract": "0.15.0-dev.
|
|
17
|
-
"@prisma-next/sql-errors": "0.15.0-dev.
|
|
18
|
-
"@prisma-next/sql-operations": "0.15.0-dev.
|
|
19
|
-
"@prisma-next/sql-relational-core": "0.15.0-dev.
|
|
20
|
-
"@prisma-next/sql-schema-ir": "0.15.0-dev.
|
|
21
|
-
"@prisma-next/ts-render": "0.15.0-dev.
|
|
22
|
-
"@prisma-next/utils": "0.15.0-dev.
|
|
9
|
+
"@prisma-next/cli": "0.15.0-dev.14",
|
|
10
|
+
"@prisma-next/contract": "0.15.0-dev.14",
|
|
11
|
+
"@prisma-next/errors": "0.15.0-dev.14",
|
|
12
|
+
"@prisma-next/family-sql": "0.15.0-dev.14",
|
|
13
|
+
"@prisma-next/framework-components": "0.15.0-dev.14",
|
|
14
|
+
"@prisma-next/migration-tools": "0.15.0-dev.14",
|
|
15
|
+
"@prisma-next/psl-parser": "0.15.0-dev.14",
|
|
16
|
+
"@prisma-next/sql-contract": "0.15.0-dev.14",
|
|
17
|
+
"@prisma-next/sql-errors": "0.15.0-dev.14",
|
|
18
|
+
"@prisma-next/sql-operations": "0.15.0-dev.14",
|
|
19
|
+
"@prisma-next/sql-relational-core": "0.15.0-dev.14",
|
|
20
|
+
"@prisma-next/sql-schema-ir": "0.15.0-dev.14",
|
|
21
|
+
"@prisma-next/ts-render": "0.15.0-dev.14",
|
|
22
|
+
"@prisma-next/utils": "0.15.0-dev.14",
|
|
23
23
|
"@standard-schema/spec": "^1.1.0",
|
|
24
24
|
"arktype": "^2.2.2",
|
|
25
25
|
"pathe": "^2.0.3"
|
|
26
26
|
},
|
|
27
27
|
"devDependencies": {
|
|
28
|
-
"@prisma-next/psl-printer": "0.15.0-dev.
|
|
29
|
-
"@prisma-next/sql-contract-psl": "0.15.0-dev.
|
|
30
|
-
"@prisma-next/test-utils": "0.15.0-dev.
|
|
31
|
-
"@prisma-next/tsconfig": "0.15.0-dev.
|
|
32
|
-
"@prisma-next/tsdown": "0.15.0-dev.
|
|
28
|
+
"@prisma-next/psl-printer": "0.15.0-dev.14",
|
|
29
|
+
"@prisma-next/sql-contract-psl": "0.15.0-dev.14",
|
|
30
|
+
"@prisma-next/test-utils": "0.15.0-dev.14",
|
|
31
|
+
"@prisma-next/tsconfig": "0.15.0-dev.14",
|
|
32
|
+
"@prisma-next/tsdown": "0.15.0-dev.14",
|
|
33
33
|
"tsdown": "0.22.3",
|
|
34
34
|
"typescript": "5.9.3",
|
|
35
35
|
"vitest": "4.1.10"
|
package/src/core/authoring.ts
CHANGED
|
@@ -1,4 +1,7 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
temporalAuthoringPresets,
|
|
3
|
+
temporalCodecPresetWithPrecision,
|
|
4
|
+
} from '@prisma-next/family-sql/control';
|
|
2
5
|
import type {
|
|
3
6
|
AuthoringEntityContext,
|
|
4
7
|
AuthoringEntityTypeFactoryOutput,
|
|
@@ -627,10 +630,20 @@ export const postgresAuthoringFieldPresets = {
|
|
|
627
630
|
nativeType: 'timestamptz',
|
|
628
631
|
},
|
|
629
632
|
},
|
|
630
|
-
temporal:
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
633
|
+
temporal: {
|
|
634
|
+
.../* @__PURE__ */ temporalAuthoringPresets({
|
|
635
|
+
codecId: 'pg/timestamptz@1',
|
|
636
|
+
nativeType: 'timestamptz',
|
|
637
|
+
}),
|
|
638
|
+
timestamp: /* @__PURE__ */ temporalCodecPresetWithPrecision({
|
|
639
|
+
codecId: 'pg/timestamp@1',
|
|
640
|
+
nativeType: 'timestamp',
|
|
641
|
+
}),
|
|
642
|
+
timestamptz: /* @__PURE__ */ temporalCodecPresetWithPrecision({
|
|
643
|
+
codecId: 'pg/timestamptz@1',
|
|
644
|
+
nativeType: 'timestamptz',
|
|
645
|
+
}),
|
|
646
|
+
},
|
|
634
647
|
uuidNative: {
|
|
635
648
|
kind: 'fieldPreset',
|
|
636
649
|
output: {
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"authoring-BtsOWgI3.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 {\n EntityHandleLoweringInput,\n LoweredPackEntity,\n ResolvedEntityHandleRef,\n ResolvedPslModelRefs,\n} from '@prisma-next/sql-contract/entity-handle-lowering-hook';\nimport type { SqlValueSetDerivingEntityTypeOutput } from '@prisma-next/sql-contract/value-set-derivation-hook';\nimport { assertDefined } from '@prisma-next/utils/assertions';\nimport { blindCast } from '@prisma-next/utils/casts';\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 {\n computeContentHash,\n normalizePredicate,\n POLICY_OPERATION_PREDICATES,\n} 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 * Model refs the family interpreter resolved from the block's descriptor-\n * declared `refKind: 'model'` parameters before invoking this factory\n * (keyed by parameter name). An unresolved required ref is the\n * interpreter's diagnostic; the factory is never called with one missing.\n */\n readonly resolvedModelRefs?: ResolvedPslModelRefs;\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\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\n/**\n * Assembles a {@link PostgresRlsPolicy} from lowered inputs: normalizes the\n * predicates, computes the content-hash wire name, and constructs the frozen\n * entity. The single hash-assembly body shared by the PSL block lowering\n * ({@link lowerRlsPolicyFromBlock}) and the TS entity-handle lowering\n * ({@link postgresLowerEntityHandles}) so the two surfaces cannot drift.\n */\nfunction buildRlsPolicyEntity(input: {\n readonly prefix: string;\n readonly tableName: string;\n readonly namespaceId: string;\n readonly operation: RlsPolicyOperation;\n readonly roles: readonly string[];\n readonly using?: string;\n readonly withCheck?: string;\n}): PostgresRlsPolicy {\n const wireHash = computeContentHash({\n ...ifDefined('using', input.using !== undefined ? normalizePredicate(input.using) : undefined),\n ...ifDefined(\n 'withCheck',\n input.withCheck !== undefined ? normalizePredicate(input.withCheck) : undefined,\n ),\n roles: input.roles,\n operation: input.operation,\n permissive: true,\n });\n\n return new PostgresRlsPolicy({\n name: formatRlsPolicyWireName(input.prefix, wireHash),\n prefix: input.prefix,\n tableName: input.tableName,\n namespaceId: input.namespaceId,\n operation: input.operation,\n roles: input.roles,\n ...ifDefined('using', input.using),\n ...ifDefined('withCheck', input.withCheck),\n permissive: true,\n });\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 // The interpreter resolves the descriptor-declared `target` model ref to\n // its storage table name before invoking this factory (an unresolved or\n // missing required ref is the interpreter's diagnostic), so a lookup miss\n // here is structurally impossible.\n const tableName = block.resolvedModelRefs?.['target']?.tableName;\n assertDefined(\n tableName,\n `lowerRlsPolicyFromBlock: policy \"${block.name}\" reached the factory without a resolved \\`target\\` ref; the interpreter resolves same-namespace model refs before invoking entity factories.`,\n );\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 return buildRlsPolicyEntity({\n prefix,\n tableName,\n namespaceId: block.namespaceId,\n operation,\n roles,\n ...ifDefined('using', using),\n ...ifDefined('withCheck', withCheck),\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\n/**\n * Postgres identifiers cap at 63 characters and the wire name appends a\n * 9-character `_<8hex>` suffix, so the authored prefix is bounded at 54.\n */\nconst RLS_POLICY_PREFIX_MAX_LENGTH = 54;\n\ninterface RlsRoleHandleShape {\n readonly entityKind: 'role';\n readonly name: string;\n}\n\ninterface RlsPolicyHandleShape {\n readonly entityKind: 'policy';\n readonly operation: RlsPolicyOperation;\n readonly name: string;\n readonly roles: readonly { readonly name: string }[];\n readonly using?: string;\n readonly withCheck?: string;\n}\n\ninterface RlsTargetCoordinate {\n readonly namespaceId: string;\n readonly tableName: string;\n}\n\n/**\n * Resolves an entity handle's `target` ref to a table coordinate of this\n * contract, or throws the load-time diagnostic naming the handle: a\n * cross-space target is rejected (you cannot CREATE POLICY on a table\n * another space owns) and an unresolved target names the model.\n */\nfunction requireLocalTarget(\n refs: Readonly<Record<string, ResolvedEntityHandleRef>>,\n subject: string,\n): RlsTargetCoordinate {\n const target = refs['target'];\n if (target !== undefined && target.kind === 'resolved') {\n return { namespaceId: target.namespaceId, tableName: target.tableName };\n }\n if (target !== undefined && target.kind === 'cross-space') {\n throw new Error(\n `defineContract: ${subject} targets model \"${target.modelName ?? target.tableName}\", which lives in another contract space. Policies and rlsEnabled entries must target a model declared in this contract.`,\n );\n }\n throw new Error(\n `defineContract: ${subject} targets model \"${target?.modelName ?? '<anonymous>'}\", which is not in the contract's models. Add the model to \\`models\\`.`,\n );\n}\n\n/**\n * The SQL-family entity-handle batch lowering hook for the Postgres pack\n * (`SqlEntityHandleLoweringContribution`). Receives every `entities` handle\n * whose kind this pack registered — batch, so the cross-entity diagnostics\n * (duplicate prefix, policy without rlsEnabled, duplicate role) can see\n * sibling handles — and lowers them with the same keying and hash assembly\n * as the PSL path: `policy` keyed by prefix (wire name via\n * {@link buildRlsPolicyEntity}), `rls` keyed by table name, `role` keyed by\n * name and filed under the default namespace (roles are declared\n * contract-wide; PSL has no role block to set a precedent).\n */\nexport function postgresLowerEntityHandles(\n input: EntityHandleLoweringInput,\n): readonly LoweredPackEntity[] {\n const enablements = new Map<\n string,\n { coordinate: RlsTargetCoordinate; entity: PostgresRlsEnablement }\n >();\n const roles = new Map<string, PostgresRole>();\n const policies: {\n readonly handle: RlsPolicyHandleShape;\n readonly refs: Readonly<Record<string, ResolvedEntityHandleRef>>;\n }[] = [];\n const coordinateKey = (coordinate: RlsTargetCoordinate): string =>\n `${coordinate.namespaceId} ${coordinate.tableName}`;\n\n for (const { handle, refs } of input.handles) {\n switch (handle.entityKind) {\n case 'rls': {\n const coordinate = requireLocalTarget(refs, 'an rlsEnabled entry');\n const key = coordinateKey(coordinate);\n if (!enablements.has(key)) {\n enablements.set(key, {\n coordinate,\n entity: new PostgresRlsEnablement({\n tableName: coordinate.tableName,\n namespaceId: coordinate.namespaceId,\n }),\n });\n }\n break;\n }\n case 'role': {\n const roleHandle = blindCast<\n RlsRoleHandleShape,\n 'role handles are constructed only by the postgres contract-builder role() constructor, which enforces this shape'\n >(handle);\n if (roles.has(roleHandle.name)) {\n throw new Error(\n `defineContract: role \"${roleHandle.name}\" is declared more than once in the entities list.`,\n );\n }\n // Roles are cluster-scoped in Postgres, so they always land in the\n // `__unbound__` namespace — identical to a PSL `role` block\n // (`lowerRoleFromBlock`) and matching the `PostgresRole` class's own\n // contract. The declaring surface (TS entities vs PSL) does not move\n // the slot.\n roles.set(\n roleHandle.name,\n new PostgresRole({ name: roleHandle.name, namespaceId: UNBOUND_NAMESPACE_ID }),\n );\n break;\n }\n case 'policy': {\n const policyHandle = blindCast<\n RlsPolicyHandleShape,\n 'policy handles are constructed only by the postgres contract-builder policy*() constructors, which enforce this shape'\n >(handle);\n policies.push({ handle: policyHandle, refs });\n break;\n }\n default:\n throw new Error(\n `defineContract: the postgres pack does not lower \"${handle.entityKind}\" handles from the entities list.`,\n );\n }\n }\n\n const rows: LoweredPackEntity[] = [];\n const seenPrefixes = new Set<string>();\n\n for (const { handle: policy, refs } of policies) {\n const prefix = policy.name;\n if (prefix.length > RLS_POLICY_PREFIX_MAX_LENGTH) {\n throw new Error(\n `defineContract: policy prefix \"${prefix}\" exceeds the ${RLS_POLICY_PREFIX_MAX_LENGTH}-character maximum (Postgres identifiers cap at 63 characters and the wire name appends a 9-character hash suffix).`,\n );\n }\n const coordinate = requireLocalTarget(refs, `policy \"${prefix}\"`);\n if (!enablements.has(coordinateKey(coordinate))) {\n const target = refs['target'];\n throw new Error(\n `defineContract: policy \"${prefix}\" targets model \"${target?.modelName ?? coordinate.tableName}\", whose table is not RLS-enabled. Add rlsEnabled(<model>) to the entities list.`,\n );\n }\n const prefixKey = `${coordinate.namespaceId} ${prefix}`;\n if (seenPrefixes.has(prefixKey)) {\n throw new Error(\n `defineContract: policy prefix \"${prefix}\" is declared more than once in namespace \"${coordinate.namespaceId}\". Policy prefixes must be unique per namespace.`,\n );\n }\n seenPrefixes.add(prefixKey);\n\n const roleNames = [...new Set(policy.roles.map((roleHandle) => roleHandle.name))].sort();\n rows.push({\n namespaceId: coordinate.namespaceId,\n entityKind: 'policy',\n key: prefix,\n entity: buildRlsPolicyEntity({\n prefix,\n tableName: coordinate.tableName,\n namespaceId: coordinate.namespaceId,\n operation: policy.operation,\n roles: roleNames,\n ...ifDefined('using', policy.using),\n ...ifDefined('withCheck', policy.withCheck),\n }),\n });\n }\n\n for (const { coordinate, entity } of enablements.values()) {\n rows.push({\n namespaceId: coordinate.namespaceId,\n entityKind: 'rls',\n key: coordinate.tableName,\n entity,\n });\n }\n for (const [name, entity] of roles) {\n rows.push({ namespaceId: UNBOUND_NAMESPACE_ID, entityKind: 'role', key: name, entity });\n }\n return rows;\n}\n"],"mappings":"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"}
|