@prisma-next/target-postgres 0.10.0 → 0.11.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (63) hide show
  1. package/dist/control.mjs +4 -4
  2. package/dist/descriptor-meta-DLA2xV6B.mjs +126 -0
  3. package/dist/descriptor-meta-DLA2xV6B.mjs.map +1 -0
  4. package/dist/{issue-planner-qalHRCI2.mjs → issue-planner-OthDciOe.mjs} +5 -5
  5. package/dist/{issue-planner-qalHRCI2.mjs.map → issue-planner-OthDciOe.mjs.map} +1 -1
  6. package/dist/issue-planner.mjs +1 -1
  7. package/dist/migration.d.mts +1 -1
  8. package/dist/migration.mjs +2 -2
  9. package/dist/{op-factory-call-Zsrdty3k.mjs → op-factory-call-Bgb_ghPb.mjs} +3 -3
  10. package/dist/op-factory-call-Bgb_ghPb.mjs.map +1 -0
  11. package/dist/op-factory-call.mjs +1 -1
  12. package/dist/pack.d.mts +7 -0
  13. package/dist/pack.d.mts.map +1 -1
  14. package/dist/pack.mjs +1 -1
  15. package/dist/{planner-C8yhbXOq.mjs → planner-DZG1dsSW.mjs} +4 -4
  16. package/dist/{planner-C8yhbXOq.mjs.map → planner-DZG1dsSW.mjs.map} +1 -1
  17. package/dist/{planner-ddl-builders-DINYrbJ3.mjs → planner-ddl-builders-DYMuN0w1.mjs} +2 -2
  18. package/dist/{planner-ddl-builders-DINYrbJ3.mjs.map → planner-ddl-builders-DYMuN0w1.mjs.map} +1 -1
  19. package/dist/planner-ddl-builders.mjs +1 -1
  20. package/dist/{planner-produced-postgres-migration-BqGLw7VT.mjs → planner-produced-postgres-migration-TJWH2m_x.mjs} +3 -3
  21. package/dist/{planner-produced-postgres-migration-BqGLw7VT.mjs.map → planner-produced-postgres-migration-TJWH2m_x.mjs.map} +1 -1
  22. package/dist/{planner-produced-postgres-migration-c9lpjPv1.d.mts → planner-produced-postgres-migration-p-VKkCia.d.mts} +2 -2
  23. package/dist/{planner-produced-postgres-migration-c9lpjPv1.d.mts.map → planner-produced-postgres-migration-p-VKkCia.d.mts.map} +1 -1
  24. package/dist/planner-produced-postgres-migration.d.mts +1 -1
  25. package/dist/planner-produced-postgres-migration.mjs +1 -1
  26. package/dist/{planner-sql-checks-BM4sD6Xc.mjs → planner-sql-checks-K-mTBJDi.mjs} +2 -2
  27. package/dist/{planner-sql-checks-BM4sD6Xc.mjs.map → planner-sql-checks-K-mTBJDi.mjs.map} +1 -1
  28. package/dist/planner-sql-checks.mjs +1 -1
  29. package/dist/planner.d.mts +1 -1
  30. package/dist/planner.mjs +1 -1
  31. package/dist/{postgres-contract-serializer-CcZO9ukP.mjs → postgres-contract-serializer-CrET5Ov0.mjs} +41 -19
  32. package/dist/postgres-contract-serializer-CrET5Ov0.mjs.map +1 -0
  33. package/dist/{postgres-migration-jvsKgUDM.d.mts → postgres-migration-Fd4fQkBw.d.mts} +4 -4
  34. package/dist/{postgres-migration-jvsKgUDM.d.mts.map → postgres-migration-Fd4fQkBw.d.mts.map} +1 -1
  35. package/dist/{postgres-migration-C5os-tkl.mjs → postgres-migration-uADmx0dW.mjs} +4 -4
  36. package/dist/postgres-migration-uADmx0dW.mjs.map +1 -0
  37. package/dist/{postgres-schema-BosNxhWq.mjs → postgres-schema-CK82EuWq.mjs} +7 -2
  38. package/dist/postgres-schema-CK82EuWq.mjs.map +1 -0
  39. package/dist/{render-typescript-nRHbqLbI.mjs → render-typescript-CI1wbgUc.mjs} +5 -5
  40. package/dist/render-typescript-CI1wbgUc.mjs.map +1 -0
  41. package/dist/render-typescript.mjs +1 -1
  42. package/dist/runtime.d.mts.map +1 -1
  43. package/dist/runtime.mjs +2 -2
  44. package/dist/{tables-DZ-5Yxi0.mjs → tables-CWxZgD0H.mjs} +2 -2
  45. package/dist/{tables-DZ-5Yxi0.mjs.map → tables-CWxZgD0H.mjs.map} +1 -1
  46. package/dist/types.d.mts +1 -1
  47. package/dist/types.d.mts.map +1 -1
  48. package/dist/types.mjs +1 -1
  49. package/package.json +17 -17
  50. package/src/core/authoring.ts +2 -0
  51. package/src/core/migrations/op-factory-call.ts +1 -1
  52. package/src/core/migrations/postgres-migration.ts +3 -3
  53. package/src/core/migrations/render-typescript.ts +4 -4
  54. package/src/core/postgres-contract-serializer.ts +76 -41
  55. package/src/core/postgres-schema.ts +7 -1
  56. package/src/exports/migration.ts +4 -4
  57. package/dist/descriptor-meta-zrZzWmJF.mjs +0 -91
  58. package/dist/descriptor-meta-zrZzWmJF.mjs.map +0 -1
  59. package/dist/op-factory-call-Zsrdty3k.mjs.map +0 -1
  60. package/dist/postgres-contract-serializer-CcZO9ukP.mjs.map +0 -1
  61. package/dist/postgres-migration-C5os-tkl.mjs.map +0 -1
  62. package/dist/postgres-schema-BosNxhWq.mjs.map +0 -1
  63. package/dist/render-typescript-nRHbqLbI.mjs.map +0 -1
@@ -0,0 +1 @@
1
+ {"version":3,"file":"op-factory-call-Bgb_ghPb.mjs","names":[],"sources":["../src/core/migrations/op-factory-call.ts"],"sourcesContent":["/**\n * Postgres migration IR: one concrete `*Call` class per pure factory under\n * `operations/`, plus a shared `PostgresOpFactoryCallNode` abstract base.\n *\n * Every call class carries the literal arguments its backing factory would\n * receive, computes a human-readable `label` in its constructor, and\n * implements two polymorphic hooks:\n *\n * - `toOp()` — converts the IR node to a runtime\n * `SqlMigrationPlanOperation` by delegating to the matching pure factory\n * under `operations/`. `DataTransformCall.toOp()` always throws\n * `PN-MIG-2001` because a planner-generated data transform is an\n * unfilled authoring stub by construction.\n * - `renderTypeScript()` / `importRequirements()` — inherited from\n * `TsExpression`. Used by `renderCallsToTypeScript` to emit the call as\n * a TypeScript expression inside the scaffolded `migration.ts`.\n *\n * The abstract base and all concrete classes are package-private. External\n * consumers see only the framework-level `OpFactoryCall` interface and the\n * `PostgresOpFactoryCall` union.\n */\n\nimport { errorUnfilledPlaceholder } from '@prisma-next/errors/migration';\nimport type { SqlMigrationPlanOperation } from '@prisma-next/family-sql/control';\nimport type {\n OpFactoryCall as FrameworkOpFactoryCall,\n MigrationOperationClass,\n} from '@prisma-next/framework-components/control';\nimport { type ImportRequirement, jsonToTsSource, TsExpression } from '@prisma-next/ts-render';\nimport {\n addColumn,\n alterColumnType,\n dropColumn,\n dropDefault,\n dropNotNull,\n setDefault,\n setNotNull,\n} from './operations/columns';\nimport { addForeignKey, addPrimaryKey, addUnique, dropConstraint } from './operations/constraints';\nimport { createExtension, createSchema } from './operations/dependencies';\nimport { addEnumValues, createEnumType, dropEnumType, renameType } from './operations/enums';\nimport { createIndex, dropIndex } from './operations/indexes';\nimport type { ColumnSpec, ForeignKeySpec } from './operations/shared';\nimport { createTable, dropTable } from './operations/tables';\nimport type { PostgresPlanTargetDetails } from './planner-target-details';\n\ntype Op = SqlMigrationPlanOperation<PostgresPlanTargetDetails>;\n\nconst TARGET_MIGRATION_MODULE = '@prisma-next/postgres/migration';\n\nabstract class PostgresOpFactoryCallNode extends TsExpression implements FrameworkOpFactoryCall {\n abstract readonly factoryName: string;\n abstract readonly operationClass: MigrationOperationClass;\n abstract readonly label: string;\n abstract toOp(): Op;\n\n importRequirements(): readonly ImportRequirement[] {\n return [{ moduleSpecifier: TARGET_MIGRATION_MODULE, symbol: this.factoryName }];\n }\n\n protected freeze(): void {\n Object.freeze(this);\n }\n}\n\n// ============================================================================\n// Table\n// ============================================================================\n\nexport interface CreateTablePrimaryKey {\n readonly columns: readonly string[];\n}\n\nexport class CreateTableCall extends PostgresOpFactoryCallNode {\n readonly factoryName = 'createTable' as const;\n readonly operationClass = 'additive' as const;\n readonly schemaName: string;\n readonly tableName: string;\n readonly columns: readonly ColumnSpec[];\n readonly primaryKey: CreateTablePrimaryKey | undefined;\n readonly label: string;\n\n constructor(\n schemaName: string,\n tableName: string,\n columns: readonly ColumnSpec[],\n primaryKey?: CreateTablePrimaryKey,\n ) {\n super();\n this.schemaName = schemaName;\n this.tableName = tableName;\n this.columns = columns;\n this.primaryKey = primaryKey;\n this.label = `Create table \"${tableName}\"`;\n this.freeze();\n }\n\n toOp(): Op {\n return createTable(this.schemaName, this.tableName, this.columns, this.primaryKey);\n }\n\n renderTypeScript(): string {\n const args = [\n jsonToTsSource(this.schemaName),\n jsonToTsSource(this.tableName),\n jsonToTsSource(this.columns),\n ];\n if (this.primaryKey) args.push(jsonToTsSource(this.primaryKey));\n return `createTable(${args.join(', ')})`;\n }\n}\n\nexport class DropTableCall extends PostgresOpFactoryCallNode {\n readonly factoryName = 'dropTable' as const;\n readonly operationClass = 'destructive' as const;\n readonly schemaName: string;\n readonly tableName: string;\n readonly label: string;\n\n constructor(schemaName: string, tableName: string) {\n super();\n this.schemaName = schemaName;\n this.tableName = tableName;\n this.label = `Drop table \"${tableName}\"`;\n this.freeze();\n }\n\n toOp(): Op {\n return dropTable(this.schemaName, this.tableName);\n }\n\n renderTypeScript(): string {\n return `dropTable(${jsonToTsSource(this.schemaName)}, ${jsonToTsSource(this.tableName)})`;\n }\n}\n\n// ============================================================================\n// Column\n// ============================================================================\n\nexport class AddColumnCall extends PostgresOpFactoryCallNode {\n readonly factoryName = 'addColumn' as const;\n readonly operationClass = 'additive' as const;\n readonly schemaName: string;\n readonly tableName: string;\n readonly column: ColumnSpec;\n readonly label: string;\n\n constructor(schemaName: string, tableName: string, column: ColumnSpec) {\n super();\n this.schemaName = schemaName;\n this.tableName = tableName;\n this.column = column;\n this.label = `Add column \"${column.name}\" to \"${tableName}\"`;\n this.freeze();\n }\n\n toOp(): Op {\n return addColumn(this.schemaName, this.tableName, this.column);\n }\n\n renderTypeScript(): string {\n return `addColumn(${jsonToTsSource(this.schemaName)}, ${jsonToTsSource(this.tableName)}, ${jsonToTsSource(this.column)})`;\n }\n}\n\nexport class DropColumnCall extends PostgresOpFactoryCallNode {\n readonly factoryName = 'dropColumn' as const;\n readonly operationClass = 'destructive' as const;\n readonly schemaName: string;\n readonly tableName: string;\n readonly columnName: string;\n readonly label: string;\n\n constructor(schemaName: string, tableName: string, columnName: string) {\n super();\n this.schemaName = schemaName;\n this.tableName = tableName;\n this.columnName = columnName;\n this.label = `Drop column \"${columnName}\" from \"${tableName}\"`;\n this.freeze();\n }\n\n toOp(): Op {\n return dropColumn(this.schemaName, this.tableName, this.columnName);\n }\n\n renderTypeScript(): string {\n return `dropColumn(${jsonToTsSource(this.schemaName)}, ${jsonToTsSource(this.tableName)}, ${jsonToTsSource(this.columnName)})`;\n }\n}\n\nexport interface AlterColumnTypeOptions {\n readonly qualifiedTargetType: string;\n readonly formatTypeExpected: string;\n readonly rawTargetTypeForLabel: string;\n readonly using?: string;\n}\n\nexport class AlterColumnTypeCall extends PostgresOpFactoryCallNode {\n readonly factoryName = 'alterColumnType' as const;\n readonly operationClass = 'destructive' as const;\n readonly schemaName: string;\n readonly tableName: string;\n readonly columnName: string;\n readonly options: AlterColumnTypeOptions;\n readonly label: string;\n\n constructor(\n schemaName: string,\n tableName: string,\n columnName: string,\n options: AlterColumnTypeOptions,\n ) {\n super();\n this.schemaName = schemaName;\n this.tableName = tableName;\n this.columnName = columnName;\n this.options = options;\n this.label = `Alter type of \"${tableName}\".\"${columnName}\" to ${options.rawTargetTypeForLabel}`;\n this.freeze();\n }\n\n toOp(): Op {\n return alterColumnType(this.schemaName, this.tableName, this.columnName, this.options);\n }\n\n renderTypeScript(): string {\n return `alterColumnType(${jsonToTsSource(this.schemaName)}, ${jsonToTsSource(this.tableName)}, ${jsonToTsSource(this.columnName)}, ${jsonToTsSource(this.options)})`;\n }\n}\n\nexport class SetNotNullCall extends PostgresOpFactoryCallNode {\n readonly factoryName = 'setNotNull' as const;\n readonly operationClass = 'destructive' as const;\n readonly schemaName: string;\n readonly tableName: string;\n readonly columnName: string;\n readonly label: string;\n\n constructor(schemaName: string, tableName: string, columnName: string) {\n super();\n this.schemaName = schemaName;\n this.tableName = tableName;\n this.columnName = columnName;\n this.label = `Set NOT NULL on \"${tableName}\".\"${columnName}\"`;\n this.freeze();\n }\n\n toOp(): Op {\n return setNotNull(this.schemaName, this.tableName, this.columnName);\n }\n\n renderTypeScript(): string {\n return `setNotNull(${jsonToTsSource(this.schemaName)}, ${jsonToTsSource(this.tableName)}, ${jsonToTsSource(this.columnName)})`;\n }\n}\n\nexport class DropNotNullCall extends PostgresOpFactoryCallNode {\n readonly factoryName = 'dropNotNull' as const;\n readonly operationClass = 'widening' as const;\n readonly schemaName: string;\n readonly tableName: string;\n readonly columnName: string;\n readonly label: string;\n\n constructor(schemaName: string, tableName: string, columnName: string) {\n super();\n this.schemaName = schemaName;\n this.tableName = tableName;\n this.columnName = columnName;\n this.label = `Drop NOT NULL on \"${tableName}\".\"${columnName}\"`;\n this.freeze();\n }\n\n toOp(): Op {\n return dropNotNull(this.schemaName, this.tableName, this.columnName);\n }\n\n renderTypeScript(): string {\n return `dropNotNull(${jsonToTsSource(this.schemaName)}, ${jsonToTsSource(this.tableName)}, ${jsonToTsSource(this.columnName)})`;\n }\n}\n\nexport class SetDefaultCall extends PostgresOpFactoryCallNode {\n readonly factoryName = 'setDefault' as const;\n readonly operationClass: 'additive' | 'widening';\n readonly schemaName: string;\n readonly tableName: string;\n readonly columnName: string;\n readonly defaultSql: string;\n readonly label: string;\n\n constructor(\n schemaName: string,\n tableName: string,\n columnName: string,\n defaultSql: string,\n operationClass: 'additive' | 'widening' = 'additive',\n ) {\n super();\n this.schemaName = schemaName;\n this.tableName = tableName;\n this.columnName = columnName;\n this.defaultSql = defaultSql;\n this.operationClass = operationClass;\n this.label = `Set default on \"${tableName}\".\"${columnName}\"`;\n this.freeze();\n }\n\n toOp(): Op {\n return setDefault(\n this.schemaName,\n this.tableName,\n this.columnName,\n this.defaultSql,\n this.operationClass,\n );\n }\n\n renderTypeScript(): string {\n const args = [\n jsonToTsSource(this.schemaName),\n jsonToTsSource(this.tableName),\n jsonToTsSource(this.columnName),\n jsonToTsSource(this.defaultSql),\n ];\n if (this.operationClass !== 'additive') {\n args.push(jsonToTsSource(this.operationClass));\n }\n return `setDefault(${args.join(', ')})`;\n }\n}\n\nexport class DropDefaultCall extends PostgresOpFactoryCallNode {\n readonly factoryName = 'dropDefault' as const;\n readonly operationClass = 'destructive' as const;\n readonly schemaName: string;\n readonly tableName: string;\n readonly columnName: string;\n readonly label: string;\n\n constructor(schemaName: string, tableName: string, columnName: string) {\n super();\n this.schemaName = schemaName;\n this.tableName = tableName;\n this.columnName = columnName;\n this.label = `Drop default on \"${tableName}\".\"${columnName}\"`;\n this.freeze();\n }\n\n toOp(): Op {\n return dropDefault(this.schemaName, this.tableName, this.columnName);\n }\n\n renderTypeScript(): string {\n return `dropDefault(${jsonToTsSource(this.schemaName)}, ${jsonToTsSource(this.tableName)}, ${jsonToTsSource(this.columnName)})`;\n }\n}\n\n// ============================================================================\n// Constraints\n// ============================================================================\n\nexport class AddPrimaryKeyCall extends PostgresOpFactoryCallNode {\n readonly factoryName = 'addPrimaryKey' as const;\n readonly operationClass = 'additive' as const;\n readonly schemaName: string;\n readonly tableName: string;\n readonly constraintName: string;\n readonly columns: readonly string[];\n readonly label: string;\n\n constructor(\n schemaName: string,\n tableName: string,\n constraintName: string,\n columns: readonly string[],\n ) {\n super();\n this.schemaName = schemaName;\n this.tableName = tableName;\n this.constraintName = constraintName;\n this.columns = columns;\n this.label = `Add primary key on \"${tableName}\"`;\n this.freeze();\n }\n\n toOp(): Op {\n return addPrimaryKey(this.schemaName, this.tableName, this.constraintName, this.columns);\n }\n\n renderTypeScript(): string {\n return `addPrimaryKey(${jsonToTsSource(this.schemaName)}, ${jsonToTsSource(this.tableName)}, ${jsonToTsSource(this.constraintName)}, ${jsonToTsSource(this.columns)})`;\n }\n}\n\nexport class AddUniqueCall extends PostgresOpFactoryCallNode {\n readonly factoryName = 'addUnique' as const;\n readonly operationClass = 'additive' as const;\n readonly schemaName: string;\n readonly tableName: string;\n readonly constraintName: string;\n readonly columns: readonly string[];\n readonly label: string;\n\n constructor(\n schemaName: string,\n tableName: string,\n constraintName: string,\n columns: readonly string[],\n ) {\n super();\n this.schemaName = schemaName;\n this.tableName = tableName;\n this.constraintName = constraintName;\n this.columns = columns;\n this.label = `Add unique constraint on \"${tableName}\" (${columns.join(', ')})`;\n this.freeze();\n }\n\n toOp(): Op {\n return addUnique(this.schemaName, this.tableName, this.constraintName, this.columns);\n }\n\n renderTypeScript(): string {\n return `addUnique(${jsonToTsSource(this.schemaName)}, ${jsonToTsSource(this.tableName)}, ${jsonToTsSource(this.constraintName)}, ${jsonToTsSource(this.columns)})`;\n }\n}\n\nexport class AddForeignKeyCall extends PostgresOpFactoryCallNode {\n readonly factoryName = 'addForeignKey' as const;\n readonly operationClass = 'additive' as const;\n readonly schemaName: string;\n readonly tableName: string;\n readonly fk: ForeignKeySpec;\n readonly label: string;\n\n constructor(schemaName: string, tableName: string, fk: ForeignKeySpec) {\n super();\n this.schemaName = schemaName;\n this.tableName = tableName;\n this.fk = fk;\n this.label = `Add foreign key \"${fk.name}\" on \"${tableName}\"`;\n this.freeze();\n }\n\n toOp(): Op {\n return addForeignKey(this.schemaName, this.tableName, this.fk);\n }\n\n renderTypeScript(): string {\n return `addForeignKey(${jsonToTsSource(this.schemaName)}, ${jsonToTsSource(this.tableName)}, ${jsonToTsSource(this.fk)})`;\n }\n}\n\nexport class DropConstraintCall extends PostgresOpFactoryCallNode {\n readonly factoryName = 'dropConstraint' as const;\n readonly operationClass = 'destructive' as const;\n readonly schemaName: string;\n readonly tableName: string;\n readonly constraintName: string;\n readonly kind: 'foreignKey' | 'unique' | 'primaryKey';\n readonly label: string;\n\n constructor(\n schemaName: string,\n tableName: string,\n constraintName: string,\n kind: 'foreignKey' | 'unique' | 'primaryKey' = 'unique',\n ) {\n super();\n this.schemaName = schemaName;\n this.tableName = tableName;\n this.constraintName = constraintName;\n this.kind = kind;\n this.label = `Drop constraint \"${constraintName}\" on \"${tableName}\"`;\n this.freeze();\n }\n\n toOp(): Op {\n return dropConstraint(this.schemaName, this.tableName, this.constraintName, this.kind);\n }\n\n renderTypeScript(): string {\n const args = [\n jsonToTsSource(this.schemaName),\n jsonToTsSource(this.tableName),\n jsonToTsSource(this.constraintName),\n ];\n if (this.kind !== 'unique') {\n args.push(jsonToTsSource(this.kind));\n }\n return `dropConstraint(${args.join(', ')})`;\n }\n}\n\n// ============================================================================\n// Indexes\n// ============================================================================\n\nexport class CreateIndexCall extends PostgresOpFactoryCallNode {\n readonly factoryName = 'createIndex' as const;\n readonly operationClass = 'additive' as const;\n readonly schemaName: string;\n readonly tableName: string;\n readonly indexName: string;\n readonly columns: readonly string[];\n // Named indexType (not typeName) to avoid collision with CreateEnumTypeCall.typeName,\n // which identifies a CREATE TYPE target and is read by `locationForCall` in issue-planner.ts.\n readonly indexType: string | undefined;\n readonly options: Record<string, unknown> | undefined;\n readonly label: string;\n\n constructor(\n schemaName: string,\n tableName: string,\n indexName: string,\n columns: readonly string[],\n extras?: { readonly type?: string; readonly options?: Record<string, unknown> },\n ) {\n super();\n this.schemaName = schemaName;\n this.tableName = tableName;\n this.indexName = indexName;\n this.columns = columns;\n this.indexType = extras?.type;\n this.options = extras?.options;\n this.label = `Create index \"${indexName}\" on \"${tableName}\"`;\n this.freeze();\n }\n\n toOp(): Op {\n const extras: { type?: string; options?: Record<string, unknown> } = {};\n if (this.indexType !== undefined) extras.type = this.indexType;\n if (this.options !== undefined) extras.options = this.options;\n return createIndex(this.schemaName, this.tableName, this.indexName, this.columns, extras);\n }\n\n renderTypeScript(): string {\n const args = [\n jsonToTsSource(this.schemaName),\n jsonToTsSource(this.tableName),\n jsonToTsSource(this.indexName),\n jsonToTsSource(this.columns),\n ];\n if (this.indexType !== undefined || this.options !== undefined) {\n const extrasParts: string[] = [];\n if (this.indexType !== undefined) extrasParts.push(`type: ${jsonToTsSource(this.indexType)}`);\n if (this.options !== undefined) extrasParts.push(`options: ${jsonToTsSource(this.options)}`);\n args.push(`{ ${extrasParts.join(', ')} }`);\n }\n return `createIndex(${args.join(', ')})`;\n }\n}\n\nexport class DropIndexCall extends PostgresOpFactoryCallNode {\n readonly factoryName = 'dropIndex' as const;\n readonly operationClass = 'destructive' as const;\n readonly schemaName: string;\n readonly tableName: string;\n readonly indexName: string;\n readonly label: string;\n\n constructor(schemaName: string, tableName: string, indexName: string) {\n super();\n this.schemaName = schemaName;\n this.tableName = tableName;\n this.indexName = indexName;\n this.label = `Drop index \"${indexName}\"`;\n this.freeze();\n }\n\n toOp(): Op {\n return dropIndex(this.schemaName, this.tableName, this.indexName);\n }\n\n renderTypeScript(): string {\n return `dropIndex(${jsonToTsSource(this.schemaName)}, ${jsonToTsSource(this.tableName)}, ${jsonToTsSource(this.indexName)})`;\n }\n}\n\n// ============================================================================\n// Enum types\n// ============================================================================\n\nexport class CreateEnumTypeCall extends PostgresOpFactoryCallNode {\n readonly factoryName = 'createEnumType' as const;\n readonly operationClass = 'additive' as const;\n readonly schemaName: string;\n readonly typeName: string;\n readonly nativeType: string;\n readonly values: readonly string[];\n readonly label: string;\n\n constructor(\n schemaName: string,\n typeName: string,\n values: readonly string[],\n nativeType: string = typeName,\n ) {\n super();\n this.schemaName = schemaName;\n this.typeName = typeName;\n this.nativeType = nativeType;\n this.values = values;\n this.label = `Create enum type \"${typeName}\"`;\n this.freeze();\n }\n\n toOp(): Op {\n return createEnumType(this.schemaName, this.typeName, this.values, this.nativeType);\n }\n\n renderTypeScript(): string {\n const nativeArg =\n this.nativeType === this.typeName ? '' : `, ${jsonToTsSource(this.nativeType)}`;\n return `createEnumType(${jsonToTsSource(this.schemaName)}, ${jsonToTsSource(this.typeName)}, ${jsonToTsSource(this.values)}${nativeArg})`;\n }\n}\n\nexport class AddEnumValuesCall extends PostgresOpFactoryCallNode {\n readonly factoryName = 'addEnumValues' as const;\n readonly operationClass = 'additive' as const;\n readonly schemaName: string;\n readonly typeName: string;\n readonly nativeType: string;\n readonly values: readonly string[];\n readonly label: string;\n\n constructor(schemaName: string, typeName: string, nativeType: string, values: readonly string[]) {\n super();\n this.schemaName = schemaName;\n this.typeName = typeName;\n this.nativeType = nativeType;\n this.values = values;\n this.label = `Add values to enum type \"${typeName}\": ${values.join(', ')}`;\n this.freeze();\n }\n\n toOp(): Op {\n return addEnumValues(this.schemaName, this.typeName, this.nativeType, this.values);\n }\n\n renderTypeScript(): string {\n return `addEnumValues(${jsonToTsSource(this.schemaName)}, ${jsonToTsSource(this.typeName)}, ${jsonToTsSource(this.nativeType)}, ${jsonToTsSource(this.values)})`;\n }\n}\n\nexport class DropEnumTypeCall extends PostgresOpFactoryCallNode {\n readonly factoryName = 'dropEnumType' as const;\n readonly operationClass = 'destructive' as const;\n readonly schemaName: string;\n readonly typeName: string;\n readonly label: string;\n\n constructor(schemaName: string, typeName: string) {\n super();\n this.schemaName = schemaName;\n this.typeName = typeName;\n this.label = `Drop enum type \"${typeName}\"`;\n this.freeze();\n }\n\n toOp(): Op {\n return dropEnumType(this.schemaName, this.typeName);\n }\n\n renderTypeScript(): string {\n return `dropEnumType(${jsonToTsSource(this.schemaName)}, ${jsonToTsSource(this.typeName)})`;\n }\n}\n\nexport class RenameTypeCall extends PostgresOpFactoryCallNode {\n readonly factoryName = 'renameType' as const;\n readonly operationClass = 'destructive' as const;\n readonly schemaName: string;\n readonly fromName: string;\n readonly toName: string;\n readonly label: string;\n\n constructor(schemaName: string, fromName: string, toName: string) {\n super();\n this.schemaName = schemaName;\n this.fromName = fromName;\n this.toName = toName;\n this.label = `Rename type \"${fromName}\" to \"${toName}\"`;\n this.freeze();\n }\n\n toOp(): Op {\n return renameType(this.schemaName, this.fromName, this.toName);\n }\n\n renderTypeScript(): string {\n return `renameType(${jsonToTsSource(this.schemaName)}, ${jsonToTsSource(this.fromName)}, ${jsonToTsSource(this.toName)})`;\n }\n}\n\n// ============================================================================\n// Raw SQL\n// ============================================================================\n\n/**\n * Laundered pre-built operation.\n *\n * Wraps an already-materialized `SqlMigrationPlanOperation` — typically one\n * produced by a SQL-family method or a codec control hook — so the planner\n * can carry it alongside IR nodes without reverse-engineering it into a\n * structured call class. Doubles as the user-facing escape hatch for raw\n * migrations: authors can pass a full op shape to `rawSql({...})`.\n *\n * `toOp()` returns the stored op unchanged. `renderTypeScript()` emits\n * `rawSql({...})` with the op serialized as a JSON literal — round-tripping\n * requires every field on the op to be JSON-serializable (no closures).\n */\nexport class RawSqlCall extends PostgresOpFactoryCallNode {\n readonly factoryName = 'rawSql' as const;\n readonly operationClass: MigrationOperationClass;\n readonly label: string;\n readonly op: Op;\n\n constructor(op: Op) {\n super();\n this.op = op;\n this.label = op.label;\n this.operationClass = op.operationClass;\n this.freeze();\n }\n\n toOp(): Op {\n return this.op;\n }\n\n renderTypeScript(): string {\n return `rawSql(${jsonToTsSource(this.op)})`;\n }\n}\n\n// ============================================================================\n// Database dependencies (structured DDL)\n// ============================================================================\n\nexport class CreateExtensionCall extends PostgresOpFactoryCallNode {\n readonly factoryName = 'createExtension' as const;\n readonly operationClass = 'additive' as const;\n readonly extensionName: string;\n readonly label: string;\n\n constructor(extensionName: string) {\n super();\n this.extensionName = extensionName;\n this.label = `Create extension \"${extensionName}\"`;\n this.freeze();\n }\n\n toOp(): Op {\n return createExtension(this.extensionName);\n }\n\n renderTypeScript(): string {\n return `createExtension(${jsonToTsSource(this.extensionName)})`;\n }\n}\n\nexport class CreateSchemaCall extends PostgresOpFactoryCallNode {\n readonly factoryName = 'createSchema' as const;\n readonly operationClass = 'additive' as const;\n readonly schemaName: string;\n readonly label: string;\n\n constructor(schemaName: string) {\n super();\n this.schemaName = schemaName;\n this.label = `Create schema \"${schemaName}\"`;\n this.freeze();\n }\n\n toOp(): Op {\n return createSchema(this.schemaName);\n }\n\n renderTypeScript(): string {\n return `createSchema(${jsonToTsSource(this.schemaName)})`;\n }\n}\n\n// ============================================================================\n// Data transform\n// ============================================================================\n\n/**\n * A planner-generated data-transform stub. `checkSlot` and `runSlot` name\n * the unfilled authoring slots that the rendered `migration.ts` will expose\n * to the user via `placeholder(\"…\")` calls. `toOp()` always throws\n * `PN-MIG-2001`: the planner cannot lower a stubbed transform to a runtime\n * op — the user must fill the rendered `migration.ts` and re-emit.\n */\nexport class DataTransformCall extends PostgresOpFactoryCallNode {\n readonly factoryName = 'dataTransform' as const;\n readonly operationClass: MigrationOperationClass;\n readonly label: string;\n readonly checkSlot: string;\n readonly runSlot: string;\n\n constructor(\n label: string,\n checkSlot: string,\n runSlot: string,\n operationClass: MigrationOperationClass = 'data',\n ) {\n super();\n this.label = label;\n this.checkSlot = checkSlot;\n this.runSlot = runSlot;\n this.operationClass = operationClass;\n this.freeze();\n }\n\n toOp(): Op {\n throw errorUnfilledPlaceholder(this.label);\n }\n\n renderTypeScript(): string {\n return [\n `this.dataTransform(endContract, ${jsonToTsSource(this.label)}, {`,\n ` check: () => placeholder(${jsonToTsSource(this.checkSlot)}),`,\n ` run: () => placeholder(${jsonToTsSource(this.runSlot)}),`,\n '})',\n ].join('\\n');\n }\n\n override importRequirements(): readonly ImportRequirement[] {\n return [\n { moduleSpecifier: TARGET_MIGRATION_MODULE, symbol: 'placeholder' },\n {\n moduleSpecifier: './end-contract.json',\n symbol: 'endContract',\n kind: 'default',\n attributes: { type: 'json' },\n },\n ];\n }\n}\n\nexport type PostgresOpFactoryCall =\n | CreateTableCall\n | DropTableCall\n | AddColumnCall\n | DropColumnCall\n | AlterColumnTypeCall\n | SetNotNullCall\n | DropNotNullCall\n | SetDefaultCall\n | DropDefaultCall\n | AddPrimaryKeyCall\n | AddForeignKeyCall\n | AddUniqueCall\n | CreateIndexCall\n | DropIndexCall\n | DropConstraintCall\n | CreateEnumTypeCall\n | AddEnumValuesCall\n | DropEnumTypeCall\n | RenameTypeCall\n | RawSqlCall\n | CreateExtensionCall\n | CreateSchemaCall\n | DataTransformCall;\n\n/**\n * Stable identity key for reconciliation-level dedup.\n *\n * Two calls whose runtime ops would share the same `id` return the same\n * key, so a `Set<string>` can collapse them before they're emitted. The\n * current implementation delegates to `toOp().id`, which is the\n * authoritative identity; isolating dedup behind this helper lets a future\n * pass replace it with an allocation-free computation directly from the\n * call's fields without touching call sites.\n *\n * `DataTransformCall` intentionally has no sensible identity today — it\n * throws `PN-MIG-2001` on `toOp()`. Reconciliation never produces one; the\n * helper is unspecified for that variant and only meant for\n * reconciliation-emitted calls.\n */\nexport function identityKeyFor(call: PostgresOpFactoryCall): string {\n return call.toOp().id;\n}\n"],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- import { C as SetNotNullCall, S as SetDefaultCall, _ as DropIndexCall, a as AddUniqueCall, b as RawSqlCall, c as CreateExtensionCall, d as CreateTableCall, f as DataTransformCall, g as DropEnumTypeCall, h as DropDefaultCall, i as AddPrimaryKeyCall, l as CreateIndexCall, m as DropConstraintCall, n as AddEnumValuesCall, o as AlterColumnTypeCall, p as DropColumnCall, r as AddForeignKeyCall, s as CreateEnumTypeCall, t as AddColumnCall, u as CreateSchemaCall, v as DropNotNullCall, x as RenameTypeCall, y as DropTableCall } from "./op-factory-call-Zsrdty3k.mjs";
1
+ import { C as SetNotNullCall, S as SetDefaultCall, _ as DropIndexCall, a as AddUniqueCall, b as RawSqlCall, c as CreateExtensionCall, d as CreateTableCall, f as DataTransformCall, g as DropEnumTypeCall, h as DropDefaultCall, i as AddPrimaryKeyCall, l as CreateIndexCall, m as DropConstraintCall, n as AddEnumValuesCall, o as AlterColumnTypeCall, p as DropColumnCall, r as AddForeignKeyCall, s as CreateEnumTypeCall, t as AddColumnCall, u as CreateSchemaCall, v as DropNotNullCall, x as RenameTypeCall, y as DropTableCall } from "./op-factory-call-Bgb_ghPb.mjs";
2
2
  export { AddColumnCall, AddEnumValuesCall, AddForeignKeyCall, AddPrimaryKeyCall, AddUniqueCall, AlterColumnTypeCall, CreateEnumTypeCall, CreateExtensionCall, CreateIndexCall, CreateSchemaCall, CreateTableCall, DataTransformCall, DropColumnCall, DropConstraintCall, DropDefaultCall, DropEnumTypeCall, DropIndexCall, DropNotNullCall, DropTableCall, RawSqlCall, RenameTypeCall, SetDefaultCall, SetNotNullCall };
package/dist/pack.d.mts CHANGED
@@ -1,6 +1,7 @@
1
1
  import { r as CodecTypes } from "./codec-types-CRlHq7Cz.mjs";
2
2
  import { n as PostgresEnumTypeInput } from "./postgres-enum-type-CNhPTDhy.mjs";
3
3
  import * as _$_prisma_next_sql_contract_types0 from "@prisma-next/sql-contract/types";
4
+ import * as _$arktype_internal_variants_object_ts0 from "arktype/internal/variants/object.ts";
4
5
 
5
6
  //#region src/core/descriptor-meta.d.ts
6
7
  declare const postgresTargetDescriptorMetaBase: {
@@ -111,6 +112,12 @@ declare const postgresTargetDescriptorMetaBase: {
111
112
  readonly enum: {
112
113
  readonly kind: "entity";
113
114
  readonly discriminator: "postgres-enum";
115
+ readonly validatorSchema: _$arktype_internal_variants_object_ts0.ObjectType<{
116
+ kind: "postgres-enum";
117
+ values: readonly string[];
118
+ name?: string;
119
+ nativeType?: string;
120
+ }, {}>;
114
121
  readonly output: {
115
122
  readonly factory: (input: PostgresEnumTypeInput) => _$_prisma_next_sql_contract_types0.PostgresEnumStorageEntry;
116
123
  };
@@ -1 +1 @@
1
- {"version":3,"file":"pack.d.mts","names":[],"sources":["../src/core/descriptor-meta.ts"],"mappings":";;;;;cAOM,gCAAA;EAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;oCAYI,qBAAA,KAAA,kCAAA,CAAA,wBAAA;QAAA;MAAA;IAAA;EAAA;AAAA;AAAA,cAEG,4BAAA,SAAqC,gCAAA;EAAA,SACvC,YAAA,GAAe,UAAA;AAAA"}
1
+ {"version":3,"file":"pack.d.mts","names":[],"sources":["../src/core/descriptor-meta.ts"],"mappings":";;;;;;cAOM,gCAAA;EAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;kCAYI,sCAAA,CAAA,UAAA;;;;;;;;;;;;;cAEG,4BAAA,SAAqC,gCAAA;EAAA,SACvC,YAAA,GAAe,UAAA;AAAA"}
package/dist/pack.mjs CHANGED
@@ -1,2 +1,2 @@
1
- import { t as postgresTargetDescriptorMeta } from "./descriptor-meta-zrZzWmJF.mjs";
1
+ import { t as postgresTargetDescriptorMeta } from "./descriptor-meta-DLA2xV6B.mjs";
2
2
  export { postgresTargetDescriptorMeta as default };
@@ -1,9 +1,9 @@
1
1
  import { t as parsePostgresDefault } from "./default-normalizer-DHCsbfjc.mjs";
2
2
  import { t as normalizeSchemaNativeType } from "./native-type-normalizer-DMikJJ1V.mjs";
3
3
  import { r as readExistingEnumValues } from "./enum-planning-Bqp96iIw.mjs";
4
- import { r as isPostgresSchema } from "./postgres-schema-BosNxhWq.mjs";
5
- import { n as postgresPlannerStrategies, t as planIssues } from "./issue-planner-qalHRCI2.mjs";
6
- import { t as TypeScriptRenderablePostgresMigration } from "./planner-produced-postgres-migration-BqGLw7VT.mjs";
4
+ import { r as isPostgresSchema } from "./postgres-schema-CK82EuWq.mjs";
5
+ import { n as postgresPlannerStrategies, t as planIssues } from "./issue-planner-OthDciOe.mjs";
6
+ import { t as TypeScriptRenderablePostgresMigration } from "./planner-produced-postgres-migration-TJWH2m_x.mjs";
7
7
  import { extractCodecControlHooks, planFieldEventOperations, plannerFailure } from "@prisma-next/family-sql/control";
8
8
  import { UNBOUND_NAMESPACE_ID } from "@prisma-next/framework-components/ir";
9
9
  import { verifySqlSchema } from "@prisma-next/family-sql/schema-verify";
@@ -182,4 +182,4 @@ var PostgresMigrationPlanner = class {
182
182
  //#endregion
183
183
  export { createPostgresMigrationPlanner as t };
184
184
 
185
- //# sourceMappingURL=planner-C8yhbXOq.mjs.map
185
+ //# sourceMappingURL=planner-DZG1dsSW.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"planner-C8yhbXOq.mjs","names":[],"sources":["../src/core/migrations/verify-postgres-namespaces.ts","../src/core/migrations/planner.ts"],"sourcesContent":["import type { Contract } from '@prisma-next/contract/types';\nimport type { SchemaIssue } 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 { isPostgresSchema } from '../postgres-schema';\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 Postgres-flavoured\n * annotations slot on the schema IR. Defaults to the always-present\n * `public` schema when introspection did not populate the slot — a fresh\n * Postgres database always carries `public` (unless an operator dropped\n * it manually), so any verifier path that runs without an enriched\n * introspection still suppresses the redundant `CREATE SCHEMA \"public\"`.\n *\n * Production introspection (`PostgresControlAdapter.introspect`) is the\n * authoritative source: it queries `pg_namespace` and writes every\n * non-system schema into `annotations.pg.existingSchemas`. Tests that\n * want to assert against a richer initial state pass the slot\n * explicitly via the schema IR.\n */\nfunction existingSchemasFromSchema(schema: SqlSchemaIR): readonly string[] {\n const annotations = (schema as { annotations?: { pg?: { existingSchemas?: unknown } } })\n .annotations;\n const slot = annotations?.pg?.existingSchemas;\n if (Array.isArray(slot)) {\n return slot.filter((s): s is string => typeof s === 'string');\n }\n return ['public'];\n}\n\n/**\n * Emits a `missing_schema` issue for every contract-declared Postgres\n * namespace whose live container does not yet exist.\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 projects to `public` (sibling\n * present) or the framework sentinel (sibling absent). Issues are\n * emitted only when the resolved name is a real, creatable schema\n * (not the unbound sentinel) and is missing from the introspected\n * list. `public` is suppressed implicitly because the introspection\n * (or its sensible default) always carries it.\n *\n * Each emitted issue stamps `namespaceId` with the contract namespace\n * coordinate so the downstream `mapIssueToCall` re-resolves the DDL\n * schema name through the same polymorphic path — keeping the\n * coordinate, not the resolved name, as the issue's stable identity.\n */\nexport function verifyPostgresNamespacePresence(input: {\n readonly contract: Contract<SqlStorage>;\n readonly schema: SqlSchemaIR;\n}): readonly SchemaIssue[] {\n const { contract, schema } = input;\n const existing = new Set(existingSchemasFromSchema(schema));\n const issues: SchemaIssue[] = [];\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 issues.push({\n kind: 'missing_schema',\n namespaceId,\n message: `Schema \"${ddlName}\" is missing from database`,\n });\n }\n return issues;\n}\n","import type { Contract } from '@prisma-next/contract/types';\nimport type {\n MigrationOperationPolicy,\n SqlMigrationPlannerPlanOptions,\n SqlPlannerFailureResult,\n} from '@prisma-next/family-sql/control';\nimport {\n extractCodecControlHooks,\n planFieldEventOperations,\n plannerFailure,\n} from '@prisma-next/family-sql/control';\nimport { verifySqlSchema } from '@prisma-next/family-sql/schema-verify';\nimport type { TargetBoundComponentDescriptor } from '@prisma-next/framework-components/components';\nimport type {\n MigrationPlanner,\n MigrationPlanWithAuthoringSurface,\n MigrationScaffoldContext,\n SchemaIssue,\n} from '@prisma-next/framework-components/control';\nimport { parsePostgresDefault } from '../default-normalizer';\nimport { normalizeSchemaNativeType } from '../native-type-normalizer';\nimport { readExistingEnumValues } from './enum-planning';\nimport { planIssues } from './issue-planner';\nimport { TypeScriptRenderablePostgresMigration } from './planner-produced-postgres-migration';\nimport { postgresPlannerStrategies } from './planner-strategies';\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\ntype VerifySqlSchemaOptionsWithComponents = Parameters<typeof verifySqlSchema>[0] & {\n readonly frameworkComponents: PlannerFrameworkComponents;\n};\n\ninterface PlannerConfig {\n readonly defaultSchema: string;\n}\n\nconst DEFAULT_PLANNER_CONFIG: PlannerConfig = {\n defaultSchema: 'public',\n};\n\nexport function createPostgresMigrationPlanner(\n config: Partial<PlannerConfig> = {},\n): PostgresMigrationPlanner {\n return new PostgresMigrationPlanner({\n ...DEFAULT_PLANNER_CONFIG,\n ...config,\n });\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 | { readonly kind: 'success'; readonly plan: TypeScriptRenderablePostgresMigration }\n | SqlPlannerFailureResult;\n\n/**\n * Postgres migration planner — a thin wrapper over `planIssues`.\n *\n * `plan()` verifies the live schema against the target contract (producing\n * `SchemaIssue[]`) and delegates to `planIssues` with the unified\n * `postgresPlannerStrategies` list: enum-change, NOT-NULL backfill,\n * type-change, nullable-tightening, codec-hook storage types,\n * component-declared dependency installs, and shared-temp-default /\n * empty-table-guarded NOT-NULL add-column. The same strategy list runs for\n * `migration plan`, `db update`, and `db init`; behavior diverges purely on\n * `policy.allowedOperationClasses` (the data-safe strategies short-circuit\n * when `'data'` is excluded). The issue planner applies operation-class\n * policy gates and emits a single `PostgresOpFactoryCall[]` that drives both\n * the runtime-ops view (via `renderOps`) and the `renderTypeScript()`\n * authoring surface.\n */\nexport class PostgresMigrationPlanner implements MigrationPlanner<'sql', 'postgres'> {\n constructor(private readonly config: PlannerConfig) {}\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 }): 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 );\n }\n\n private planSql(options: SqlMigrationPlannerPlanOptions): PostgresPlanResult {\n const schemaName = options.schemaName ?? this.config.defaultSchema;\n const policyResult = this.ensureAdditivePolicy(options.policy);\n if (policyResult) {\n return policyResult;\n }\n\n const schemaIssues = this.collectSchemaIssues(options);\n const codecHooks = extractCodecControlHooks(options.frameworkComponents);\n const storageTypes = options.contract.storage.types ?? {};\n\n const result = planIssues({\n issues: schemaIssues,\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 // `mapIssueToCall`'s direct destructive handlers.\n fromContract: options.fromContract,\n schemaName,\n codecHooks,\n storageTypes,\n schema: options.schema,\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 // 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-emitted calls already conform to `OpFactoryCall` — render +\n // toOp + importRequirements ride directly through the same emit path\n // as structural ops, no `RawSqlCall` wrap.\n const calls = [...result.value.calls, ...fieldEventOps];\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 ),\n });\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 private collectSchemaIssues(options: PlannerOptionsWithComponents): readonly SchemaIssue[] {\n // `db init` uses additive-only policy and intentionally ignores extra\n // schema objects. Any reconciliation-capable policy (widening or\n // destructive) must inspect extras to reconcile strict equality.\n const allowed = options.policy.allowedOperationClasses;\n const strict = allowed.includes('widening') || allowed.includes('destructive');\n const verifyOptions: VerifySqlSchemaOptionsWithComponents = {\n contract: options.contract,\n schema: options.schema,\n strict,\n typeMetadataRegistry: new Map(),\n frameworkComponents: options.frameworkComponents,\n normalizeDefault: parsePostgresDefault,\n normalizeNativeType: normalizeSchemaNativeType,\n resolveExistingEnumValues: (schema, enumType) =>\n readExistingEnumValues(schema, enumType.nativeType),\n };\n const verifyResult = verifySqlSchema(verifyOptions);\n // Schema presence is a Postgres-specific concern (no equivalent in\n // SQLite / Mongo), so the issue emission lives in the target layer\n // rather than in the family verifier. Stitch it in here so a single\n // `SchemaIssue[]` flows through `planIssues` and the planner emits\n // CREATE SCHEMA in the dep bucket before any CreateTableCall.\n const namespaceIssues = verifyPostgresNamespacePresence({\n contract: options.contract,\n schema: options.schema,\n });\n if (namespaceIssues.length === 0) {\n return verifyResult.schema.issues;\n }\n return [...namespaceIssues, ...verifyResult.schema.issues];\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"planner-DZG1dsSW.mjs","names":[],"sources":["../src/core/migrations/verify-postgres-namespaces.ts","../src/core/migrations/planner.ts"],"sourcesContent":["import type { Contract } from '@prisma-next/contract/types';\nimport type { SchemaIssue } 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 { isPostgresSchema } from '../postgres-schema';\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 Postgres-flavoured\n * annotations slot on the schema IR. Defaults to the always-present\n * `public` schema when introspection did not populate the slot — a fresh\n * Postgres database always carries `public` (unless an operator dropped\n * it manually), so any verifier path that runs without an enriched\n * introspection still suppresses the redundant `CREATE SCHEMA \"public\"`.\n *\n * Production introspection (`PostgresControlAdapter.introspect`) is the\n * authoritative source: it queries `pg_namespace` and writes every\n * non-system schema into `annotations.pg.existingSchemas`. Tests that\n * want to assert against a richer initial state pass the slot\n * explicitly via the schema IR.\n */\nfunction existingSchemasFromSchema(schema: SqlSchemaIR): readonly string[] {\n const annotations = (schema as { annotations?: { pg?: { existingSchemas?: unknown } } })\n .annotations;\n const slot = annotations?.pg?.existingSchemas;\n if (Array.isArray(slot)) {\n return slot.filter((s): s is string => typeof s === 'string');\n }\n return ['public'];\n}\n\n/**\n * Emits a `missing_schema` issue for every contract-declared Postgres\n * namespace whose live container does not yet exist.\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 projects to `public` (sibling\n * present) or the framework sentinel (sibling absent). Issues are\n * emitted only when the resolved name is a real, creatable schema\n * (not the unbound sentinel) and is missing from the introspected\n * list. `public` is suppressed implicitly because the introspection\n * (or its sensible default) always carries it.\n *\n * Each emitted issue stamps `namespaceId` with the contract namespace\n * coordinate so the downstream `mapIssueToCall` re-resolves the DDL\n * schema name through the same polymorphic path — keeping the\n * coordinate, not the resolved name, as the issue's stable identity.\n */\nexport function verifyPostgresNamespacePresence(input: {\n readonly contract: Contract<SqlStorage>;\n readonly schema: SqlSchemaIR;\n}): readonly SchemaIssue[] {\n const { contract, schema } = input;\n const existing = new Set(existingSchemasFromSchema(schema));\n const issues: SchemaIssue[] = [];\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 issues.push({\n kind: 'missing_schema',\n namespaceId,\n message: `Schema \"${ddlName}\" is missing from database`,\n });\n }\n return issues;\n}\n","import type { Contract } from '@prisma-next/contract/types';\nimport type {\n MigrationOperationPolicy,\n SqlMigrationPlannerPlanOptions,\n SqlPlannerFailureResult,\n} from '@prisma-next/family-sql/control';\nimport {\n extractCodecControlHooks,\n planFieldEventOperations,\n plannerFailure,\n} from '@prisma-next/family-sql/control';\nimport { verifySqlSchema } from '@prisma-next/family-sql/schema-verify';\nimport type { TargetBoundComponentDescriptor } from '@prisma-next/framework-components/components';\nimport type {\n MigrationPlanner,\n MigrationPlanWithAuthoringSurface,\n MigrationScaffoldContext,\n SchemaIssue,\n} from '@prisma-next/framework-components/control';\nimport { parsePostgresDefault } from '../default-normalizer';\nimport { normalizeSchemaNativeType } from '../native-type-normalizer';\nimport { readExistingEnumValues } from './enum-planning';\nimport { planIssues } from './issue-planner';\nimport { TypeScriptRenderablePostgresMigration } from './planner-produced-postgres-migration';\nimport { postgresPlannerStrategies } from './planner-strategies';\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\ntype VerifySqlSchemaOptionsWithComponents = Parameters<typeof verifySqlSchema>[0] & {\n readonly frameworkComponents: PlannerFrameworkComponents;\n};\n\ninterface PlannerConfig {\n readonly defaultSchema: string;\n}\n\nconst DEFAULT_PLANNER_CONFIG: PlannerConfig = {\n defaultSchema: 'public',\n};\n\nexport function createPostgresMigrationPlanner(\n config: Partial<PlannerConfig> = {},\n): PostgresMigrationPlanner {\n return new PostgresMigrationPlanner({\n ...DEFAULT_PLANNER_CONFIG,\n ...config,\n });\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 | { readonly kind: 'success'; readonly plan: TypeScriptRenderablePostgresMigration }\n | SqlPlannerFailureResult;\n\n/**\n * Postgres migration planner — a thin wrapper over `planIssues`.\n *\n * `plan()` verifies the live schema against the target contract (producing\n * `SchemaIssue[]`) and delegates to `planIssues` with the unified\n * `postgresPlannerStrategies` list: enum-change, NOT-NULL backfill,\n * type-change, nullable-tightening, codec-hook storage types,\n * component-declared dependency installs, and shared-temp-default /\n * empty-table-guarded NOT-NULL add-column. The same strategy list runs for\n * `migration plan`, `db update`, and `db init`; behavior diverges purely on\n * `policy.allowedOperationClasses` (the data-safe strategies short-circuit\n * when `'data'` is excluded). The issue planner applies operation-class\n * policy gates and emits a single `PostgresOpFactoryCall[]` that drives both\n * the runtime-ops view (via `renderOps`) and the `renderTypeScript()`\n * authoring surface.\n */\nexport class PostgresMigrationPlanner implements MigrationPlanner<'sql', 'postgres'> {\n constructor(private readonly config: PlannerConfig) {}\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 }): 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 );\n }\n\n private planSql(options: SqlMigrationPlannerPlanOptions): PostgresPlanResult {\n const schemaName = options.schemaName ?? this.config.defaultSchema;\n const policyResult = this.ensureAdditivePolicy(options.policy);\n if (policyResult) {\n return policyResult;\n }\n\n const schemaIssues = this.collectSchemaIssues(options);\n const codecHooks = extractCodecControlHooks(options.frameworkComponents);\n const storageTypes = options.contract.storage.types ?? {};\n\n const result = planIssues({\n issues: schemaIssues,\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 // `mapIssueToCall`'s direct destructive handlers.\n fromContract: options.fromContract,\n schemaName,\n codecHooks,\n storageTypes,\n schema: options.schema,\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 // 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-emitted calls already conform to `OpFactoryCall` — render +\n // toOp + importRequirements ride directly through the same emit path\n // as structural ops, no `RawSqlCall` wrap.\n const calls = [...result.value.calls, ...fieldEventOps];\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 ),\n });\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 private collectSchemaIssues(options: PlannerOptionsWithComponents): readonly SchemaIssue[] {\n // `db init` uses additive-only policy and intentionally ignores extra\n // schema objects. Any reconciliation-capable policy (widening or\n // destructive) must inspect extras to reconcile strict equality.\n const allowed = options.policy.allowedOperationClasses;\n const strict = allowed.includes('widening') || allowed.includes('destructive');\n const verifyOptions: VerifySqlSchemaOptionsWithComponents = {\n contract: options.contract,\n schema: options.schema,\n strict,\n typeMetadataRegistry: new Map(),\n frameworkComponents: options.frameworkComponents,\n normalizeDefault: parsePostgresDefault,\n normalizeNativeType: normalizeSchemaNativeType,\n resolveExistingEnumValues: (schema, enumType) =>\n readExistingEnumValues(schema, enumType.nativeType),\n };\n const verifyResult = verifySqlSchema(verifyOptions);\n // Schema presence is a Postgres-specific concern (no equivalent in\n // SQLite / Mongo), so the issue emission lives in the target layer\n // rather than in the family verifier. Stitch it in here so a single\n // `SchemaIssue[]` flows through `planIssues` and the planner emits\n // CREATE SCHEMA in the dep bucket before any CreateTableCall.\n const namespaceIssues = verifyPostgresNamespacePresence({\n contract: options.contract,\n schema: options.schema,\n });\n if (namespaceIssues.length === 0) {\n return verifyResult.schema.issues;\n }\n return [...namespaceIssues, ...verifyResult.schema.issues];\n }\n}\n"],"mappings":"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"}
@@ -1,5 +1,5 @@
1
1
  import { i as quoteIdentifier, n as escapeLiteral } from "./sql-utils-BewXAnsG.mjs";
2
- import { c as qualifyTableName, f as resolveColumnTypeMetadata } from "./planner-sql-checks-BM4sD6Xc.mjs";
2
+ import { c as qualifyTableName, f as resolveColumnTypeMetadata } from "./planner-sql-checks-K-mTBJDi.mjs";
3
3
  //#region src/core/migrations/planner-ddl-builders.ts
4
4
  function buildCreateTableSql(qualifiedTableName, table, codecHooks, storageTypes = {}) {
5
5
  const columnDefinitions = Object.entries(table.columns).map(([columnName, column]) => {
@@ -128,4 +128,4 @@ REFERENCES ${qualifyTableName(schemaName, foreignKey.target.tableName)} (${forei
128
128
  //#endregion
129
129
  export { buildForeignKeySql as a, buildCreateTableSql as i, buildColumnDefaultSql as n, renderDefaultLiteral as o, buildColumnTypeSql as r, buildAddColumnSql as t };
130
130
 
131
- //# sourceMappingURL=planner-ddl-builders-DINYrbJ3.mjs.map
131
+ //# sourceMappingURL=planner-ddl-builders-DYMuN0w1.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"planner-ddl-builders-DINYrbJ3.mjs","names":[],"sources":["../src/core/migrations/planner-ddl-builders.ts"],"sourcesContent":["import type { CodecControlHooks } from '@prisma-next/family-sql/control';\nimport type {\n ForeignKey,\n PostgresEnumStorageEntry,\n ReferentialAction,\n StorageColumn,\n StorageTable,\n StorageTypeInstance,\n} from '@prisma-next/sql-contract/types';\nimport { escapeLiteral, quoteIdentifier } from '../sql-utils';\nimport type { PostgresColumnDefault } from '../types';\nimport { qualifyTableName } from './planner-sql-checks';\nimport { resolveColumnTypeMetadata } from './planner-type-resolution';\n\nexport function buildCreateTableSql(\n qualifiedTableName: string,\n table: StorageTable,\n codecHooks: Map<string, CodecControlHooks>,\n storageTypes: Record<string, StorageTypeInstance | PostgresEnumStorageEntry> = {},\n): string {\n const columnDefinitions = Object.entries(table.columns).map(\n ([columnName, column]: [string, StorageColumn]) => {\n const parts = [\n quoteIdentifier(columnName),\n buildColumnTypeSql(column, codecHooks, storageTypes),\n buildColumnDefaultSql(column.default, column),\n column.nullable ? '' : 'NOT NULL',\n ].filter(Boolean);\n return parts.join(' ');\n },\n );\n\n const constraintDefinitions: string[] = [];\n if (table.primaryKey) {\n constraintDefinitions.push(\n `PRIMARY KEY (${table.primaryKey.columns.map(quoteIdentifier).join(', ')})`,\n );\n }\n\n const allDefinitions = [...columnDefinitions, ...constraintDefinitions];\n return `CREATE TABLE ${qualifiedTableName} (\\n ${allDefinitions.join(',\\n ')}\\n)`;\n}\n\n/**\n * Pattern for safe PostgreSQL type names.\n * Allows letters, digits, underscores, spaces (for \"double precision\", \"character varying\"),\n * and trailing [] for array types.\n */\nconst SAFE_NATIVE_TYPE_PATTERN = /^[a-zA-Z][a-zA-Z0-9_ ]*(\\[\\])?$/;\n\nfunction assertSafeNativeType(nativeType: string): void {\n if (!SAFE_NATIVE_TYPE_PATTERN.test(nativeType)) {\n throw new Error(\n `Unsafe native type name in contract: \"${nativeType}\". ` +\n 'Native type names must match /^[a-zA-Z][a-zA-Z0-9_ ]*(\\\\[\\\\])?$/',\n );\n }\n}\n\n/**\n * Sanity check against accidental SQL injection from malformed contract files.\n * Rejects semicolons, SQL comment tokens, and dollar-quoting.\n * Not a comprehensive security boundary — the contract is developer-authored.\n */\nfunction assertSafeDefaultExpression(expression: string): void {\n if (expression.includes(';') || /--|\\/\\*|\\$\\$|\\bSELECT\\b/i.test(expression)) {\n throw new Error(\n `Unsafe default expression in contract: \"${expression}\". ` +\n 'Default expressions must not contain semicolons, SQL comment tokens, dollar-quoting, or subqueries.',\n );\n }\n}\n\n/**\n * Renders the SQL type for a column in DDL context.\n *\n * @param allowPseudoTypes - When true (default), autoincrement integer columns\n * produce SERIAL/BIGSERIAL/SMALLSERIAL pseudo-types. Set to false for contexts\n * like ALTER COLUMN TYPE where pseudo-types are invalid.\n */\nexport function buildColumnTypeSql(\n column: StorageColumn,\n codecHooks: Map<string, CodecControlHooks>,\n storageTypes: Record<string, StorageTypeInstance | PostgresEnumStorageEntry> = {},\n allowPseudoTypes = true,\n): string {\n const resolved = resolveColumnTypeMetadata(column, storageTypes);\n\n if (allowPseudoTypes) {\n const columnDefault = column.default;\n if (columnDefault?.kind === 'function' && columnDefault.expression === 'autoincrement()') {\n if (resolved.nativeType === 'int4' || resolved.nativeType === 'integer') {\n return 'SERIAL';\n }\n if (resolved.nativeType === 'int8' || resolved.nativeType === 'bigint') {\n return 'BIGSERIAL';\n }\n if (resolved.nativeType === 'int2' || resolved.nativeType === 'smallint') {\n return 'SMALLSERIAL';\n }\n }\n }\n\n const expanded = expandParameterizedTypeSql(resolved, codecHooks);\n if (expanded !== null) {\n return expanded;\n }\n\n if (column.typeRef) {\n return quoteIdentifier(resolved.nativeType);\n }\n\n assertSafeNativeType(resolved.nativeType);\n return resolved.nativeType;\n}\n\nfunction expandParameterizedTypeSql(\n column: Pick<StorageColumn, 'nativeType' | 'codecId' | 'typeParams'>,\n codecHooks: Map<string, CodecControlHooks>,\n): string | null {\n if (!column.typeParams) {\n return null;\n }\n\n if (!column.codecId) {\n throw new Error(\n `Column declares typeParams for nativeType \"${column.nativeType}\" but has no codecId. ` +\n 'Ensure the column is associated with a codec.',\n );\n }\n\n const hooks = codecHooks.get(column.codecId);\n if (!hooks?.expandNativeType) {\n if (hooks?.planTypeOperations) {\n return null;\n }\n throw new Error(\n `Column declares typeParams for nativeType \"${column.nativeType}\" ` +\n `but no expandNativeType hook is registered for codecId \"${column.codecId}\". ` +\n 'Ensure the extension providing this codec is included in extensionPacks.',\n );\n }\n\n const expanded = hooks.expandNativeType({\n nativeType: column.nativeType,\n codecId: column.codecId,\n typeParams: column.typeParams,\n });\n\n return expanded !== column.nativeType ? expanded : null;\n}\n\n/** Autoincrement columns use SERIAL types, so this returns empty for them. */\nexport function buildColumnDefaultSql(\n columnDefault: PostgresColumnDefault | undefined,\n column?: StorageColumn,\n): string {\n if (!columnDefault) {\n return '';\n }\n\n switch (columnDefault.kind) {\n case 'literal':\n return `DEFAULT ${renderDefaultLiteral(columnDefault.value, column)}`;\n case 'function': {\n if (columnDefault.expression === 'autoincrement()') {\n return '';\n }\n assertSafeDefaultExpression(columnDefault.expression);\n return `DEFAULT (${columnDefault.expression})`;\n }\n case 'sequence':\n return `DEFAULT nextval('${escapeLiteral(quoteIdentifier(columnDefault.name))}'::regclass)`;\n }\n}\n\nexport function renderDefaultLiteral(value: unknown, column?: StorageColumn): string {\n const isJsonColumn = column?.nativeType === 'json' || column?.nativeType === 'jsonb';\n\n if (value instanceof Date) {\n return `'${escapeLiteral(value.toISOString())}'`;\n }\n if (typeof value === 'string') {\n return `'${escapeLiteral(value)}'`;\n }\n if (typeof value === 'number' || typeof value === 'boolean') {\n return String(value);\n }\n if (value === null) {\n return 'NULL';\n }\n const json = JSON.stringify(value);\n if (isJsonColumn) {\n return `'${escapeLiteral(json)}'::${column.nativeType}`;\n }\n return `'${escapeLiteral(json)}'`;\n}\n\nexport function buildAddColumnSql(\n qualifiedTableName: string,\n columnName: string,\n column: StorageColumn,\n codecHooks: Map<string, CodecControlHooks>,\n temporaryDefault?: string | null,\n storageTypes: Record<string, StorageTypeInstance | PostgresEnumStorageEntry> = {},\n): string {\n const typeSql = buildColumnTypeSql(column, codecHooks, storageTypes);\n const defaultSql =\n buildColumnDefaultSql(column.default, column) ||\n (temporaryDefault ? `DEFAULT ${temporaryDefault}` : '');\n const parts = [\n `ALTER TABLE ${qualifiedTableName}`,\n `ADD COLUMN ${quoteIdentifier(columnName)} ${typeSql}`,\n defaultSql,\n column.nullable ? '' : 'NOT NULL',\n ].filter(Boolean);\n return parts.join(' ');\n}\n\nconst REFERENTIAL_ACTION_SQL: Record<ReferentialAction, string> = {\n noAction: 'NO ACTION',\n restrict: 'RESTRICT',\n cascade: 'CASCADE',\n setNull: 'SET NULL',\n setDefault: 'SET DEFAULT',\n};\n\nexport function buildForeignKeySql(\n schemaName: string,\n tableName: string,\n fkName: string,\n foreignKey: ForeignKey,\n): string {\n let sql = `ALTER TABLE ${qualifyTableName(schemaName, tableName)}\nADD CONSTRAINT ${quoteIdentifier(fkName)}\nFOREIGN KEY (${foreignKey.source.columns.map(quoteIdentifier).join(', ')})\nREFERENCES ${qualifyTableName(schemaName, foreignKey.target.tableName)} (${foreignKey.target.columns\n .map(quoteIdentifier)\n .join(', ')})`;\n\n if (foreignKey.onDelete !== undefined) {\n const action = REFERENTIAL_ACTION_SQL[foreignKey.onDelete];\n if (!action) {\n throw new Error(`Unknown referential action for onDelete: ${String(foreignKey.onDelete)}`);\n }\n sql += `\\nON DELETE ${action}`;\n }\n if (foreignKey.onUpdate !== undefined) {\n const action = REFERENTIAL_ACTION_SQL[foreignKey.onUpdate];\n if (!action) {\n throw new Error(`Unknown referential action for onUpdate: ${String(foreignKey.onUpdate)}`);\n }\n sql += `\\nON UPDATE ${action}`;\n }\n\n return sql;\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"planner-ddl-builders-DYMuN0w1.mjs","names":[],"sources":["../src/core/migrations/planner-ddl-builders.ts"],"sourcesContent":["import type { CodecControlHooks } from '@prisma-next/family-sql/control';\nimport type {\n ForeignKey,\n PostgresEnumStorageEntry,\n ReferentialAction,\n StorageColumn,\n StorageTable,\n StorageTypeInstance,\n} from '@prisma-next/sql-contract/types';\nimport { escapeLiteral, quoteIdentifier } from '../sql-utils';\nimport type { PostgresColumnDefault } from '../types';\nimport { qualifyTableName } from './planner-sql-checks';\nimport { resolveColumnTypeMetadata } from './planner-type-resolution';\n\nexport function buildCreateTableSql(\n qualifiedTableName: string,\n table: StorageTable,\n codecHooks: Map<string, CodecControlHooks>,\n storageTypes: Record<string, StorageTypeInstance | PostgresEnumStorageEntry> = {},\n): string {\n const columnDefinitions = Object.entries(table.columns).map(\n ([columnName, column]: [string, StorageColumn]) => {\n const parts = [\n quoteIdentifier(columnName),\n buildColumnTypeSql(column, codecHooks, storageTypes),\n buildColumnDefaultSql(column.default, column),\n column.nullable ? '' : 'NOT NULL',\n ].filter(Boolean);\n return parts.join(' ');\n },\n );\n\n const constraintDefinitions: string[] = [];\n if (table.primaryKey) {\n constraintDefinitions.push(\n `PRIMARY KEY (${table.primaryKey.columns.map(quoteIdentifier).join(', ')})`,\n );\n }\n\n const allDefinitions = [...columnDefinitions, ...constraintDefinitions];\n return `CREATE TABLE ${qualifiedTableName} (\\n ${allDefinitions.join(',\\n ')}\\n)`;\n}\n\n/**\n * Pattern for safe PostgreSQL type names.\n * Allows letters, digits, underscores, spaces (for \"double precision\", \"character varying\"),\n * and trailing [] for array types.\n */\nconst SAFE_NATIVE_TYPE_PATTERN = /^[a-zA-Z][a-zA-Z0-9_ ]*(\\[\\])?$/;\n\nfunction assertSafeNativeType(nativeType: string): void {\n if (!SAFE_NATIVE_TYPE_PATTERN.test(nativeType)) {\n throw new Error(\n `Unsafe native type name in contract: \"${nativeType}\". ` +\n 'Native type names must match /^[a-zA-Z][a-zA-Z0-9_ ]*(\\\\[\\\\])?$/',\n );\n }\n}\n\n/**\n * Sanity check against accidental SQL injection from malformed contract files.\n * Rejects semicolons, SQL comment tokens, and dollar-quoting.\n * Not a comprehensive security boundary — the contract is developer-authored.\n */\nfunction assertSafeDefaultExpression(expression: string): void {\n if (expression.includes(';') || /--|\\/\\*|\\$\\$|\\bSELECT\\b/i.test(expression)) {\n throw new Error(\n `Unsafe default expression in contract: \"${expression}\". ` +\n 'Default expressions must not contain semicolons, SQL comment tokens, dollar-quoting, or subqueries.',\n );\n }\n}\n\n/**\n * Renders the SQL type for a column in DDL context.\n *\n * @param allowPseudoTypes - When true (default), autoincrement integer columns\n * produce SERIAL/BIGSERIAL/SMALLSERIAL pseudo-types. Set to false for contexts\n * like ALTER COLUMN TYPE where pseudo-types are invalid.\n */\nexport function buildColumnTypeSql(\n column: StorageColumn,\n codecHooks: Map<string, CodecControlHooks>,\n storageTypes: Record<string, StorageTypeInstance | PostgresEnumStorageEntry> = {},\n allowPseudoTypes = true,\n): string {\n const resolved = resolveColumnTypeMetadata(column, storageTypes);\n\n if (allowPseudoTypes) {\n const columnDefault = column.default;\n if (columnDefault?.kind === 'function' && columnDefault.expression === 'autoincrement()') {\n if (resolved.nativeType === 'int4' || resolved.nativeType === 'integer') {\n return 'SERIAL';\n }\n if (resolved.nativeType === 'int8' || resolved.nativeType === 'bigint') {\n return 'BIGSERIAL';\n }\n if (resolved.nativeType === 'int2' || resolved.nativeType === 'smallint') {\n return 'SMALLSERIAL';\n }\n }\n }\n\n const expanded = expandParameterizedTypeSql(resolved, codecHooks);\n if (expanded !== null) {\n return expanded;\n }\n\n if (column.typeRef) {\n return quoteIdentifier(resolved.nativeType);\n }\n\n assertSafeNativeType(resolved.nativeType);\n return resolved.nativeType;\n}\n\nfunction expandParameterizedTypeSql(\n column: Pick<StorageColumn, 'nativeType' | 'codecId' | 'typeParams'>,\n codecHooks: Map<string, CodecControlHooks>,\n): string | null {\n if (!column.typeParams) {\n return null;\n }\n\n if (!column.codecId) {\n throw new Error(\n `Column declares typeParams for nativeType \"${column.nativeType}\" but has no codecId. ` +\n 'Ensure the column is associated with a codec.',\n );\n }\n\n const hooks = codecHooks.get(column.codecId);\n if (!hooks?.expandNativeType) {\n if (hooks?.planTypeOperations) {\n return null;\n }\n throw new Error(\n `Column declares typeParams for nativeType \"${column.nativeType}\" ` +\n `but no expandNativeType hook is registered for codecId \"${column.codecId}\". ` +\n 'Ensure the extension providing this codec is included in extensionPacks.',\n );\n }\n\n const expanded = hooks.expandNativeType({\n nativeType: column.nativeType,\n codecId: column.codecId,\n typeParams: column.typeParams,\n });\n\n return expanded !== column.nativeType ? expanded : null;\n}\n\n/** Autoincrement columns use SERIAL types, so this returns empty for them. */\nexport function buildColumnDefaultSql(\n columnDefault: PostgresColumnDefault | undefined,\n column?: StorageColumn,\n): string {\n if (!columnDefault) {\n return '';\n }\n\n switch (columnDefault.kind) {\n case 'literal':\n return `DEFAULT ${renderDefaultLiteral(columnDefault.value, column)}`;\n case 'function': {\n if (columnDefault.expression === 'autoincrement()') {\n return '';\n }\n assertSafeDefaultExpression(columnDefault.expression);\n return `DEFAULT (${columnDefault.expression})`;\n }\n case 'sequence':\n return `DEFAULT nextval('${escapeLiteral(quoteIdentifier(columnDefault.name))}'::regclass)`;\n }\n}\n\nexport function renderDefaultLiteral(value: unknown, column?: StorageColumn): string {\n const isJsonColumn = column?.nativeType === 'json' || column?.nativeType === 'jsonb';\n\n if (value instanceof Date) {\n return `'${escapeLiteral(value.toISOString())}'`;\n }\n if (typeof value === 'string') {\n return `'${escapeLiteral(value)}'`;\n }\n if (typeof value === 'number' || typeof value === 'boolean') {\n return String(value);\n }\n if (value === null) {\n return 'NULL';\n }\n const json = JSON.stringify(value);\n if (isJsonColumn) {\n return `'${escapeLiteral(json)}'::${column.nativeType}`;\n }\n return `'${escapeLiteral(json)}'`;\n}\n\nexport function buildAddColumnSql(\n qualifiedTableName: string,\n columnName: string,\n column: StorageColumn,\n codecHooks: Map<string, CodecControlHooks>,\n temporaryDefault?: string | null,\n storageTypes: Record<string, StorageTypeInstance | PostgresEnumStorageEntry> = {},\n): string {\n const typeSql = buildColumnTypeSql(column, codecHooks, storageTypes);\n const defaultSql =\n buildColumnDefaultSql(column.default, column) ||\n (temporaryDefault ? `DEFAULT ${temporaryDefault}` : '');\n const parts = [\n `ALTER TABLE ${qualifiedTableName}`,\n `ADD COLUMN ${quoteIdentifier(columnName)} ${typeSql}`,\n defaultSql,\n column.nullable ? '' : 'NOT NULL',\n ].filter(Boolean);\n return parts.join(' ');\n}\n\nconst REFERENTIAL_ACTION_SQL: Record<ReferentialAction, string> = {\n noAction: 'NO ACTION',\n restrict: 'RESTRICT',\n cascade: 'CASCADE',\n setNull: 'SET NULL',\n setDefault: 'SET DEFAULT',\n};\n\nexport function buildForeignKeySql(\n schemaName: string,\n tableName: string,\n fkName: string,\n foreignKey: ForeignKey,\n): string {\n let sql = `ALTER TABLE ${qualifyTableName(schemaName, tableName)}\nADD CONSTRAINT ${quoteIdentifier(fkName)}\nFOREIGN KEY (${foreignKey.source.columns.map(quoteIdentifier).join(', ')})\nREFERENCES ${qualifyTableName(schemaName, foreignKey.target.tableName)} (${foreignKey.target.columns\n .map(quoteIdentifier)\n .join(', ')})`;\n\n if (foreignKey.onDelete !== undefined) {\n const action = REFERENTIAL_ACTION_SQL[foreignKey.onDelete];\n if (!action) {\n throw new Error(`Unknown referential action for onDelete: ${String(foreignKey.onDelete)}`);\n }\n sql += `\\nON DELETE ${action}`;\n }\n if (foreignKey.onUpdate !== undefined) {\n const action = REFERENTIAL_ACTION_SQL[foreignKey.onUpdate];\n if (!action) {\n throw new Error(`Unknown referential action for onUpdate: ${String(foreignKey.onUpdate)}`);\n }\n sql += `\\nON UPDATE ${action}`;\n }\n\n return sql;\n}\n"],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- import { a as buildForeignKeySql, i as buildCreateTableSql, n as buildColumnDefaultSql, o as renderDefaultLiteral, r as buildColumnTypeSql, t as buildAddColumnSql } from "./planner-ddl-builders-DINYrbJ3.mjs";
1
+ import { a as buildForeignKeySql, i as buildCreateTableSql, n as buildColumnDefaultSql, o as renderDefaultLiteral, r as buildColumnTypeSql, t as buildAddColumnSql } from "./planner-ddl-builders-DYMuN0w1.mjs";
2
2
  export { buildAddColumnSql, buildColumnDefaultSql, buildColumnTypeSql, buildCreateTableSql, buildForeignKeySql, renderDefaultLiteral };
@@ -1,6 +1,6 @@
1
- import { t as PostgresMigration } from "./postgres-migration-C5os-tkl.mjs";
1
+ import { t as PostgresMigration } from "./postgres-migration-uADmx0dW.mjs";
2
2
  import { t as renderOps } from "./render-ops-BC2PtCkj.mjs";
3
- import { t as renderCallsToTypeScript } from "./render-typescript-nRHbqLbI.mjs";
3
+ import { t as renderCallsToTypeScript } from "./render-typescript-CI1wbgUc.mjs";
4
4
  import { ifDefined } from "@prisma-next/utils/defined";
5
5
  //#region src/core/migrations/planner-produced-postgres-migration.ts
6
6
  var TypeScriptRenderablePostgresMigration = class extends PostgresMigration {
@@ -38,4 +38,4 @@ var TypeScriptRenderablePostgresMigration = class extends PostgresMigration {
38
38
  //#endregion
39
39
  export { TypeScriptRenderablePostgresMigration as t };
40
40
 
41
- //# sourceMappingURL=planner-produced-postgres-migration-BqGLw7VT.mjs.map
41
+ //# sourceMappingURL=planner-produced-postgres-migration-TJWH2m_x.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"planner-produced-postgres-migration-BqGLw7VT.mjs","names":["#calls","#meta","#spaceId"],"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 {\n MigrationPlanWithAuthoringSurface,\n OpFactoryCall,\n} from '@prisma-next/framework-components/control';\nimport type { MigrationMeta } from '@prisma-next/migration-tools/migration';\nimport { ifDefined } from '@prisma-next/utils/defined';\nimport type { PostgresPlanTargetDetails } from './planner-target-details';\nimport { PostgresMigration } from './postgres-migration';\nimport { renderOps } from './render-ops';\nimport { renderCallsToTypeScript } from './render-typescript';\n\ntype Op = SqlMigrationPlanOperation<PostgresPlanTargetDetails>;\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\n constructor(calls: readonly OpFactoryCall[], meta: MigrationMeta, spaceId: string) {\n super();\n this.#calls = calls;\n this.#meta = meta;\n this.#spaceId = spaceId;\n }\n\n override get operations(): readonly Op[] {\n return renderOps(this.#calls);\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, {\n from: this.#meta.from,\n to: this.#meta.to,\n ...ifDefined('labels', this.#meta.labels),\n });\n }\n}\n"],"mappings":";;;;;AAuCA,IAAa,wCAAb,cACU,kBAEV;CACE;CACA;CACA;CAEA,YAAY,OAAiC,MAAqB,SAAiB;EACjF,OAAO;EACP,KAAKA,SAAS;EACd,KAAKC,QAAQ;EACb,KAAKC,WAAW;;CAGlB,IAAa,aAA4B;EACvC,OAAO,UAAU,KAAKF,OAAO;;CAG/B,WAAmC;EACjC,OAAO,KAAKC;;;;;;;CAQd,IAAI,UAAkB;EACpB,OAAO,KAAKC;;CAGd,mBAA2B;EACzB,OAAO,wBAAwB,KAAKF,QAAQ;GAC1C,MAAM,KAAKC,MAAM;GACjB,IAAI,KAAKA,MAAM;GACf,GAAG,UAAU,UAAU,KAAKA,MAAM,OAAO;GAC1C,CAAC"}
1
+ {"version":3,"file":"planner-produced-postgres-migration-TJWH2m_x.mjs","names":["#calls","#meta","#spaceId"],"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 {\n MigrationPlanWithAuthoringSurface,\n OpFactoryCall,\n} from '@prisma-next/framework-components/control';\nimport type { MigrationMeta } from '@prisma-next/migration-tools/migration';\nimport { ifDefined } from '@prisma-next/utils/defined';\nimport type { PostgresPlanTargetDetails } from './planner-target-details';\nimport { PostgresMigration } from './postgres-migration';\nimport { renderOps } from './render-ops';\nimport { renderCallsToTypeScript } from './render-typescript';\n\ntype Op = SqlMigrationPlanOperation<PostgresPlanTargetDetails>;\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\n constructor(calls: readonly OpFactoryCall[], meta: MigrationMeta, spaceId: string) {\n super();\n this.#calls = calls;\n this.#meta = meta;\n this.#spaceId = spaceId;\n }\n\n override get operations(): readonly Op[] {\n return renderOps(this.#calls);\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, {\n from: this.#meta.from,\n to: this.#meta.to,\n ...ifDefined('labels', this.#meta.labels),\n });\n }\n}\n"],"mappings":";;;;;AAuCA,IAAa,wCAAb,cACU,kBAEV;CACE;CACA;CACA;CAEA,YAAY,OAAiC,MAAqB,SAAiB;EACjF,OAAO;EACP,KAAKA,SAAS;EACd,KAAKC,QAAQ;EACb,KAAKC,WAAW;;CAGlB,IAAa,aAA4B;EACvC,OAAO,UAAU,KAAKF,OAAO;;CAG/B,WAAmC;EACjC,OAAO,KAAKC;;;;;;;CAQd,IAAI,UAAkB;EACpB,OAAO,KAAKC;;CAGd,mBAA2B;EACzB,OAAO,wBAAwB,KAAKF,QAAQ;GAC1C,MAAM,KAAKC,MAAM;GACjB,IAAI,KAAKA,MAAM;GACf,GAAG,UAAU,UAAU,KAAKA,MAAM,OAAO;GAC1C,CAAC"}
@@ -1,5 +1,5 @@
1
1
  import { t as PostgresPlanTargetDetails } from "./planner-target-details-CIj61DUj.mjs";
2
- import { t as PostgresMigration } from "./postgres-migration-jvsKgUDM.mjs";
2
+ import { t as PostgresMigration } from "./postgres-migration-Fd4fQkBw.mjs";
3
3
  import { SqlMigrationPlanOperation } from "@prisma-next/family-sql/control";
4
4
  import { MigrationPlanWithAuthoringSurface, OpFactoryCall } from "@prisma-next/framework-components/control";
5
5
  import { MigrationMeta } from "@prisma-next/migration-tools/migration";
@@ -21,4 +21,4 @@ declare class TypeScriptRenderablePostgresMigration extends PostgresMigration im
21
21
  }
22
22
  //#endregion
23
23
  export { TypeScriptRenderablePostgresMigration as t };
24
- //# sourceMappingURL=planner-produced-postgres-migration-c9lpjPv1.d.mts.map
24
+ //# sourceMappingURL=planner-produced-postgres-migration-p-VKkCia.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"planner-produced-postgres-migration-c9lpjPv1.d.mts","names":[],"sources":["../src/core/migrations/planner-produced-postgres-migration.ts"],"mappings":";;;;;;;KAqCK,EAAA,GAAK,yBAAA,CAA0B,yBAAA;AAAA,cAEvB,qCAAA,SACH,iBAAA,YACG,iCAAA;EAAA;cAMC,KAAA,WAAgB,aAAA,IAAiB,IAAA,EAAM,aAAA,EAAe,OAAA;EAAA,IAOrD,UAAA,CAAA,YAAuB,EAAA;EAI3B,QAAA,CAAA,GAAY,aAAA;EAAA;;;;;EAAA,IASjB,OAAA,CAAA;EAIJ,gBAAA,CAAA;AAAA"}
1
+ {"version":3,"file":"planner-produced-postgres-migration-p-VKkCia.d.mts","names":[],"sources":["../src/core/migrations/planner-produced-postgres-migration.ts"],"mappings":";;;;;;;KAqCK,EAAA,GAAK,yBAAA,CAA0B,yBAAA;AAAA,cAEvB,qCAAA,SACH,iBAAA,YACG,iCAAA;EAAA;cAMC,KAAA,WAAgB,aAAA,IAAiB,IAAA,EAAM,aAAA,EAAe,OAAA;EAAA,IAOrD,UAAA,CAAA,YAAuB,EAAA;EAI3B,QAAA,CAAA,GAAY,aAAA;EAAA;;;;;EAAA,IASjB,OAAA,CAAA;EAIJ,gBAAA,CAAA;AAAA"}
@@ -1,2 +1,2 @@
1
- import { t as TypeScriptRenderablePostgresMigration } from "./planner-produced-postgres-migration-c9lpjPv1.mjs";
1
+ import { t as TypeScriptRenderablePostgresMigration } from "./planner-produced-postgres-migration-p-VKkCia.mjs";
2
2
  export { TypeScriptRenderablePostgresMigration };
@@ -1,2 +1,2 @@
1
- import { t as TypeScriptRenderablePostgresMigration } from "./planner-produced-postgres-migration-BqGLw7VT.mjs";
1
+ import { t as TypeScriptRenderablePostgresMigration } from "./planner-produced-postgres-migration-TJWH2m_x.mjs";
2
2
  export { TypeScriptRenderablePostgresMigration };
@@ -1,5 +1,5 @@
1
1
  import { i as quoteIdentifier, n as escapeLiteral } from "./sql-utils-BewXAnsG.mjs";
2
- import { i as postgresCreateNamespace } from "./postgres-schema-BosNxhWq.mjs";
2
+ import { i as postgresCreateNamespace } from "./postgres-schema-CK82EuWq.mjs";
3
3
  import { isPostgresEnumStorageEntry } from "@prisma-next/sql-contract/types";
4
4
  //#region src/core/migrations/planner-type-resolution.ts
5
5
  function resolveColumnTypeMetadata(column, storageTypes) {
@@ -258,4 +258,4 @@ function tableHasPrimaryKeyCheck(schema, table, exists, constraintName) {
258
258
  //#endregion
259
259
  export { columnNullabilityCheck as a, qualifyTableName as c, toRegclassLiteral as d, resolveColumnTypeMetadata as f, columnHasNoDefaultCheck as i, tableHasPrimaryKeyCheck as l, columnDefaultExistsCheck as n, columnTypeCheck as o, columnExistsCheck as r, constraintExistsCheck as s, buildExpectedFormatType as t, tableIsEmptyCheck as u };
260
260
 
261
- //# sourceMappingURL=planner-sql-checks-BM4sD6Xc.mjs.map
261
+ //# sourceMappingURL=planner-sql-checks-K-mTBJDi.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"planner-sql-checks-BM4sD6Xc.mjs","names":[],"sources":["../src/core/migrations/planner-type-resolution.ts","../src/core/migrations/planner-sql-checks.ts"],"sourcesContent":["import {\n isPostgresEnumStorageEntry,\n type PostgresEnumStorageEntry,\n type StorageColumn,\n type StorageTypeInstance,\n} from '@prisma-next/sql-contract/types';\n\nexport type ResolvedColumnTypeMetadata = Pick<\n StorageColumn,\n 'nativeType' | 'codecId' | 'typeParams'\n>;\n\nexport function resolveColumnTypeMetadata(\n column: StorageColumn,\n storageTypes: Readonly<Record<string, StorageTypeInstance | PostgresEnumStorageEntry>>,\n): ResolvedColumnTypeMetadata {\n if (!column.typeRef) {\n return column;\n }\n\n const referencedType = storageTypes[column.typeRef];\n if (!referencedType) {\n return column;\n }\n\n if (isPostgresEnumStorageEntry(referencedType)) {\n // Enum types are referenced by name (`quoteIdentifier(nativeType)`),\n // not via parameterised codec expansion. The structural shape\n // carries `codecId` as an enumerable property (mirroring the\n // codec-typed view); `typeParams` is intentionally omitted here so\n // `expandParameterizedTypeSql` does not try to look up a\n // (deliberately absent) `expandNativeType` hook for `pg/enum@*`.\n return {\n codecId: referencedType.codecId,\n nativeType: referencedType.nativeType,\n };\n }\n\n return {\n codecId: referencedType.codecId,\n nativeType: referencedType.nativeType,\n typeParams: referencedType.typeParams,\n };\n}\n","import type { CodecControlHooks } from '@prisma-next/family-sql/control';\nimport type {\n PostgresEnumStorageEntry,\n StorageColumn,\n StorageTypeInstance,\n} from '@prisma-next/sql-contract/types';\nimport { postgresCreateNamespace } from '../postgres-schema';\nimport { escapeLiteral, quoteIdentifier } from '../sql-utils';\nimport { resolveColumnTypeMetadata } from './planner-type-resolution';\n\n/**\n * String-keyed entry points the migration ops use to render\n * schema-qualified DDL and catalog checks. The `schema` argument is\n * interpreted as a namespace coordinate: the framework `__unbound__`\n * sentinel resolves to the late-bound `PostgresUnboundSchema` singleton\n * (which elides the qualifier so `search_path` decides at runtime); any\n * other id materialises a `PostgresSchema(id)` whose qualifier is the\n * named schema. Helpers route through these `Namespace` concretions so\n * the unbound branch lives in the polymorphic override, not the call\n * site.\n */\nexport function qualifyTableName(schema: string, table: string): string {\n return postgresCreateNamespace({ id: schema }).qualifyTable(table);\n}\n\nexport function toRegclassLiteral(schema: string, name: string): string {\n return postgresCreateNamespace({ id: schema }).regclassLiteral(name);\n}\n\n/**\n * When `table` is omitted the check matches by name + schema across all tables.\n * Pass `table` to scope the check to a single table (prevents false matches on\n * identically-named constraints in different tables).\n */\nexport function constraintExistsCheck({\n constraintName,\n schema,\n table,\n exists = true,\n}: {\n constraintName: string;\n schema: string;\n table?: string;\n exists?: boolean;\n}): string {\n const namespace = postgresCreateNamespace({ id: schema });\n const existsClause = exists ? 'EXISTS' : 'NOT EXISTS';\n const tableFilter = table\n ? `AND c.conrelid = to_regclass(${namespace.regclassLiteral(table)})`\n : '';\n return `SELECT ${existsClause} (\n SELECT 1 FROM pg_constraint c\n JOIN pg_namespace n ON c.connamespace = n.oid\n WHERE c.conname = '${escapeLiteral(constraintName)}'\n AND n.nspname = ${namespace.schemaSqlExpression()}\n ${tableFilter}\n)`;\n}\n\nexport function columnExistsCheck({\n schema,\n table,\n column,\n exists = true,\n}: {\n schema: string;\n table: string;\n column: string;\n exists?: boolean;\n}): string {\n const namespace = postgresCreateNamespace({ id: schema });\n const existsClause = exists ? '' : 'NOT ';\n return `SELECT ${existsClause}EXISTS (\n SELECT 1\n FROM information_schema.columns\n WHERE table_schema = ${namespace.schemaSqlExpression()}\n AND table_name = '${escapeLiteral(table)}'\n AND column_name = '${escapeLiteral(column)}'\n)`;\n}\n\nexport function columnNullabilityCheck({\n schema,\n table,\n column,\n nullable,\n}: {\n schema: string;\n table: string;\n column: string;\n nullable: boolean;\n}): string {\n const namespace = postgresCreateNamespace({ id: schema });\n const expected = nullable ? 'YES' : 'NO';\n return `SELECT EXISTS (\n SELECT 1\n FROM information_schema.columns\n WHERE table_schema = ${namespace.schemaSqlExpression()}\n AND table_name = '${escapeLiteral(table)}'\n AND column_name = '${escapeLiteral(column)}'\n AND is_nullable = '${expected}'\n)`;\n}\n\nexport function tableIsEmptyCheck(qualifiedTableName: string): string {\n return `SELECT NOT EXISTS (SELECT 1 FROM ${qualifiedTableName} LIMIT 1)`;\n}\n\nexport function columnHasNoDefaultCheck(opts: {\n schema: string;\n table: string;\n column: string;\n}): string {\n const namespace = postgresCreateNamespace({ id: opts.schema });\n return `SELECT NOT EXISTS (\n SELECT 1\n FROM information_schema.columns\n WHERE table_schema = ${namespace.schemaSqlExpression()}\n AND table_name = '${escapeLiteral(opts.table)}'\n AND column_name = '${escapeLiteral(opts.column)}'\n AND column_default IS NOT NULL\n)`;\n}\n\nconst FORMAT_TYPE_DISPLAY: ReadonlyMap<string, string> = new Map([\n ['int2', 'smallint'],\n ['int4', 'integer'],\n ['int8', 'bigint'],\n ['float4', 'real'],\n ['float8', 'double precision'],\n ['bool', 'boolean'],\n ['timestamp', 'timestamp without time zone'],\n ['timestamptz', 'timestamp with time zone'],\n ['time', 'time without time zone'],\n ['timetz', 'time with time zone'],\n]);\n\nconst UNQUOTED_POSTGRES_IDENTIFIER_PATTERN = /^[a-z_][a-z0-9_$]*$/;\n\nconst POSTGRES_RESERVED_IDENTIFIER_WORDS = new Set([\n 'all',\n 'analyse',\n 'analyze',\n 'and',\n 'any',\n 'array',\n 'as',\n 'asc',\n 'asymmetric',\n 'authorization',\n 'between',\n 'binary',\n 'both',\n 'case',\n 'cast',\n 'check',\n 'collate',\n 'column',\n 'constraint',\n 'create',\n 'current_catalog',\n 'current_date',\n 'current_role',\n 'current_time',\n 'current_timestamp',\n 'current_user',\n 'default',\n 'deferrable',\n 'desc',\n 'distinct',\n 'do',\n 'else',\n 'end',\n 'except',\n 'false',\n 'fetch',\n 'for',\n 'foreign',\n 'freeze',\n 'from',\n 'full',\n 'grant',\n 'group',\n 'having',\n 'ilike',\n 'in',\n 'initially',\n 'inner',\n 'intersect',\n 'into',\n 'is',\n 'isnull',\n 'join',\n 'lateral',\n 'leading',\n 'left',\n 'like',\n 'limit',\n 'localtime',\n 'localtimestamp',\n 'natural',\n 'not',\n 'notnull',\n 'null',\n 'offset',\n 'on',\n 'only',\n 'or',\n 'order',\n 'outer',\n 'overlaps',\n 'placing',\n 'primary',\n 'references',\n 'right',\n 'select',\n 'session_user',\n 'similar',\n 'some',\n 'symmetric',\n 'table',\n 'then',\n 'to',\n 'trailing',\n 'true',\n 'union',\n 'unique',\n 'user',\n 'using',\n 'variadic',\n 'verbose',\n 'when',\n 'where',\n 'window',\n 'with',\n]);\n\nfunction formatUserDefinedTypeName(identifier: string): string {\n if (\n UNQUOTED_POSTGRES_IDENTIFIER_PATTERN.test(identifier) &&\n !POSTGRES_RESERVED_IDENTIFIER_WORDS.has(identifier)\n ) {\n return identifier;\n }\n\n return quoteIdentifier(identifier);\n}\n\nexport function buildExpectedFormatType(\n column: StorageColumn,\n codecHooks: Map<string, CodecControlHooks>,\n storageTypes: Record<string, StorageTypeInstance | PostgresEnumStorageEntry> = {},\n): string {\n const resolved = resolveColumnTypeMetadata(column, storageTypes);\n\n if (resolved.typeParams && resolved.codecId) {\n const hooks = codecHooks.get(resolved.codecId);\n if (hooks?.expandNativeType) {\n return hooks.expandNativeType({\n nativeType: resolved.nativeType,\n codecId: resolved.codecId,\n typeParams: resolved.typeParams,\n });\n }\n }\n\n if (column.typeRef) {\n return formatUserDefinedTypeName(resolved.nativeType);\n }\n\n return FORMAT_TYPE_DISPLAY.get(resolved.nativeType) ?? resolved.nativeType;\n}\n\nexport function columnTypeCheck({\n schema,\n table,\n column,\n expectedType,\n}: {\n schema: string;\n table: string;\n column: string;\n expectedType: string;\n}): string {\n const namespace = postgresCreateNamespace({ id: schema });\n return `SELECT EXISTS (\n SELECT 1\n FROM pg_attribute a\n JOIN pg_class c ON c.oid = a.attrelid\n JOIN pg_namespace n ON n.oid = c.relnamespace\n WHERE n.nspname = ${namespace.schemaSqlExpression()}\n AND c.relname = '${escapeLiteral(table)}'\n AND a.attname = '${escapeLiteral(column)}'\n AND format_type(a.atttypid, a.atttypmod) = '${escapeLiteral(expectedType)}'\n AND NOT a.attisdropped\n)`;\n}\n\nexport function columnDefaultExistsCheck({\n schema,\n table,\n column,\n exists = true,\n}: {\n schema: string;\n table: string;\n column: string;\n exists?: boolean;\n}): string {\n const namespace = postgresCreateNamespace({ id: schema });\n const nullCheck = exists ? 'IS NOT NULL' : 'IS NULL';\n return `SELECT EXISTS (\n SELECT 1\n FROM information_schema.columns\n WHERE table_schema = ${namespace.schemaSqlExpression()}\n AND table_name = '${escapeLiteral(table)}'\n AND column_name = '${escapeLiteral(column)}'\n AND column_default ${nullCheck}\n)`;\n}\n\nexport function tableHasPrimaryKeyCheck(\n schema: string,\n table: string,\n exists: boolean,\n constraintName?: string,\n): string {\n const namespace = postgresCreateNamespace({ id: schema });\n const comparison = exists ? '' : 'NOT ';\n const constraintFilter = constraintName\n ? `AND c2.relname = '${escapeLiteral(constraintName)}'`\n : '';\n return `SELECT ${comparison}EXISTS (\n SELECT 1\n FROM pg_index i\n JOIN pg_class c ON c.oid = i.indrelid\n JOIN pg_namespace n ON n.oid = c.relnamespace\n LEFT JOIN pg_class c2 ON c2.oid = i.indexrelid\n WHERE n.nspname = ${namespace.schemaSqlExpression()}\n AND c.relname = '${escapeLiteral(table)}'\n AND i.indisprimary\n ${constraintFilter}\n)`;\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"planner-sql-checks-K-mTBJDi.mjs","names":[],"sources":["../src/core/migrations/planner-type-resolution.ts","../src/core/migrations/planner-sql-checks.ts"],"sourcesContent":["import {\n isPostgresEnumStorageEntry,\n type PostgresEnumStorageEntry,\n type StorageColumn,\n type StorageTypeInstance,\n} from '@prisma-next/sql-contract/types';\n\nexport type ResolvedColumnTypeMetadata = Pick<\n StorageColumn,\n 'nativeType' | 'codecId' | 'typeParams'\n>;\n\nexport function resolveColumnTypeMetadata(\n column: StorageColumn,\n storageTypes: Readonly<Record<string, StorageTypeInstance | PostgresEnumStorageEntry>>,\n): ResolvedColumnTypeMetadata {\n if (!column.typeRef) {\n return column;\n }\n\n const referencedType = storageTypes[column.typeRef];\n if (!referencedType) {\n return column;\n }\n\n if (isPostgresEnumStorageEntry(referencedType)) {\n // Enum types are referenced by name (`quoteIdentifier(nativeType)`),\n // not via parameterised codec expansion. The structural shape\n // carries `codecId` as an enumerable property (mirroring the\n // codec-typed view); `typeParams` is intentionally omitted here so\n // `expandParameterizedTypeSql` does not try to look up a\n // (deliberately absent) `expandNativeType` hook for `pg/enum@*`.\n return {\n codecId: referencedType.codecId,\n nativeType: referencedType.nativeType,\n };\n }\n\n return {\n codecId: referencedType.codecId,\n nativeType: referencedType.nativeType,\n typeParams: referencedType.typeParams,\n };\n}\n","import type { CodecControlHooks } from '@prisma-next/family-sql/control';\nimport type {\n PostgresEnumStorageEntry,\n StorageColumn,\n StorageTypeInstance,\n} from '@prisma-next/sql-contract/types';\nimport { postgresCreateNamespace } from '../postgres-schema';\nimport { escapeLiteral, quoteIdentifier } from '../sql-utils';\nimport { resolveColumnTypeMetadata } from './planner-type-resolution';\n\n/**\n * String-keyed entry points the migration ops use to render\n * schema-qualified DDL and catalog checks. The `schema` argument is\n * interpreted as a namespace coordinate: the framework `__unbound__`\n * sentinel resolves to the late-bound `PostgresUnboundSchema` singleton\n * (which elides the qualifier so `search_path` decides at runtime); any\n * other id materialises a `PostgresSchema(id)` whose qualifier is the\n * named schema. Helpers route through these `Namespace` concretions so\n * the unbound branch lives in the polymorphic override, not the call\n * site.\n */\nexport function qualifyTableName(schema: string, table: string): string {\n return postgresCreateNamespace({ id: schema }).qualifyTable(table);\n}\n\nexport function toRegclassLiteral(schema: string, name: string): string {\n return postgresCreateNamespace({ id: schema }).regclassLiteral(name);\n}\n\n/**\n * When `table` is omitted the check matches by name + schema across all tables.\n * Pass `table` to scope the check to a single table (prevents false matches on\n * identically-named constraints in different tables).\n */\nexport function constraintExistsCheck({\n constraintName,\n schema,\n table,\n exists = true,\n}: {\n constraintName: string;\n schema: string;\n table?: string;\n exists?: boolean;\n}): string {\n const namespace = postgresCreateNamespace({ id: schema });\n const existsClause = exists ? 'EXISTS' : 'NOT EXISTS';\n const tableFilter = table\n ? `AND c.conrelid = to_regclass(${namespace.regclassLiteral(table)})`\n : '';\n return `SELECT ${existsClause} (\n SELECT 1 FROM pg_constraint c\n JOIN pg_namespace n ON c.connamespace = n.oid\n WHERE c.conname = '${escapeLiteral(constraintName)}'\n AND n.nspname = ${namespace.schemaSqlExpression()}\n ${tableFilter}\n)`;\n}\n\nexport function columnExistsCheck({\n schema,\n table,\n column,\n exists = true,\n}: {\n schema: string;\n table: string;\n column: string;\n exists?: boolean;\n}): string {\n const namespace = postgresCreateNamespace({ id: schema });\n const existsClause = exists ? '' : 'NOT ';\n return `SELECT ${existsClause}EXISTS (\n SELECT 1\n FROM information_schema.columns\n WHERE table_schema = ${namespace.schemaSqlExpression()}\n AND table_name = '${escapeLiteral(table)}'\n AND column_name = '${escapeLiteral(column)}'\n)`;\n}\n\nexport function columnNullabilityCheck({\n schema,\n table,\n column,\n nullable,\n}: {\n schema: string;\n table: string;\n column: string;\n nullable: boolean;\n}): string {\n const namespace = postgresCreateNamespace({ id: schema });\n const expected = nullable ? 'YES' : 'NO';\n return `SELECT EXISTS (\n SELECT 1\n FROM information_schema.columns\n WHERE table_schema = ${namespace.schemaSqlExpression()}\n AND table_name = '${escapeLiteral(table)}'\n AND column_name = '${escapeLiteral(column)}'\n AND is_nullable = '${expected}'\n)`;\n}\n\nexport function tableIsEmptyCheck(qualifiedTableName: string): string {\n return `SELECT NOT EXISTS (SELECT 1 FROM ${qualifiedTableName} LIMIT 1)`;\n}\n\nexport function columnHasNoDefaultCheck(opts: {\n schema: string;\n table: string;\n column: string;\n}): string {\n const namespace = postgresCreateNamespace({ id: opts.schema });\n return `SELECT NOT EXISTS (\n SELECT 1\n FROM information_schema.columns\n WHERE table_schema = ${namespace.schemaSqlExpression()}\n AND table_name = '${escapeLiteral(opts.table)}'\n AND column_name = '${escapeLiteral(opts.column)}'\n AND column_default IS NOT NULL\n)`;\n}\n\nconst FORMAT_TYPE_DISPLAY: ReadonlyMap<string, string> = new Map([\n ['int2', 'smallint'],\n ['int4', 'integer'],\n ['int8', 'bigint'],\n ['float4', 'real'],\n ['float8', 'double precision'],\n ['bool', 'boolean'],\n ['timestamp', 'timestamp without time zone'],\n ['timestamptz', 'timestamp with time zone'],\n ['time', 'time without time zone'],\n ['timetz', 'time with time zone'],\n]);\n\nconst UNQUOTED_POSTGRES_IDENTIFIER_PATTERN = /^[a-z_][a-z0-9_$]*$/;\n\nconst POSTGRES_RESERVED_IDENTIFIER_WORDS = new Set([\n 'all',\n 'analyse',\n 'analyze',\n 'and',\n 'any',\n 'array',\n 'as',\n 'asc',\n 'asymmetric',\n 'authorization',\n 'between',\n 'binary',\n 'both',\n 'case',\n 'cast',\n 'check',\n 'collate',\n 'column',\n 'constraint',\n 'create',\n 'current_catalog',\n 'current_date',\n 'current_role',\n 'current_time',\n 'current_timestamp',\n 'current_user',\n 'default',\n 'deferrable',\n 'desc',\n 'distinct',\n 'do',\n 'else',\n 'end',\n 'except',\n 'false',\n 'fetch',\n 'for',\n 'foreign',\n 'freeze',\n 'from',\n 'full',\n 'grant',\n 'group',\n 'having',\n 'ilike',\n 'in',\n 'initially',\n 'inner',\n 'intersect',\n 'into',\n 'is',\n 'isnull',\n 'join',\n 'lateral',\n 'leading',\n 'left',\n 'like',\n 'limit',\n 'localtime',\n 'localtimestamp',\n 'natural',\n 'not',\n 'notnull',\n 'null',\n 'offset',\n 'on',\n 'only',\n 'or',\n 'order',\n 'outer',\n 'overlaps',\n 'placing',\n 'primary',\n 'references',\n 'right',\n 'select',\n 'session_user',\n 'similar',\n 'some',\n 'symmetric',\n 'table',\n 'then',\n 'to',\n 'trailing',\n 'true',\n 'union',\n 'unique',\n 'user',\n 'using',\n 'variadic',\n 'verbose',\n 'when',\n 'where',\n 'window',\n 'with',\n]);\n\nfunction formatUserDefinedTypeName(identifier: string): string {\n if (\n UNQUOTED_POSTGRES_IDENTIFIER_PATTERN.test(identifier) &&\n !POSTGRES_RESERVED_IDENTIFIER_WORDS.has(identifier)\n ) {\n return identifier;\n }\n\n return quoteIdentifier(identifier);\n}\n\nexport function buildExpectedFormatType(\n column: StorageColumn,\n codecHooks: Map<string, CodecControlHooks>,\n storageTypes: Record<string, StorageTypeInstance | PostgresEnumStorageEntry> = {},\n): string {\n const resolved = resolveColumnTypeMetadata(column, storageTypes);\n\n if (resolved.typeParams && resolved.codecId) {\n const hooks = codecHooks.get(resolved.codecId);\n if (hooks?.expandNativeType) {\n return hooks.expandNativeType({\n nativeType: resolved.nativeType,\n codecId: resolved.codecId,\n typeParams: resolved.typeParams,\n });\n }\n }\n\n if (column.typeRef) {\n return formatUserDefinedTypeName(resolved.nativeType);\n }\n\n return FORMAT_TYPE_DISPLAY.get(resolved.nativeType) ?? resolved.nativeType;\n}\n\nexport function columnTypeCheck({\n schema,\n table,\n column,\n expectedType,\n}: {\n schema: string;\n table: string;\n column: string;\n expectedType: string;\n}): string {\n const namespace = postgresCreateNamespace({ id: schema });\n return `SELECT EXISTS (\n SELECT 1\n FROM pg_attribute a\n JOIN pg_class c ON c.oid = a.attrelid\n JOIN pg_namespace n ON n.oid = c.relnamespace\n WHERE n.nspname = ${namespace.schemaSqlExpression()}\n AND c.relname = '${escapeLiteral(table)}'\n AND a.attname = '${escapeLiteral(column)}'\n AND format_type(a.atttypid, a.atttypmod) = '${escapeLiteral(expectedType)}'\n AND NOT a.attisdropped\n)`;\n}\n\nexport function columnDefaultExistsCheck({\n schema,\n table,\n column,\n exists = true,\n}: {\n schema: string;\n table: string;\n column: string;\n exists?: boolean;\n}): string {\n const namespace = postgresCreateNamespace({ id: schema });\n const nullCheck = exists ? 'IS NOT NULL' : 'IS NULL';\n return `SELECT EXISTS (\n SELECT 1\n FROM information_schema.columns\n WHERE table_schema = ${namespace.schemaSqlExpression()}\n AND table_name = '${escapeLiteral(table)}'\n AND column_name = '${escapeLiteral(column)}'\n AND column_default ${nullCheck}\n)`;\n}\n\nexport function tableHasPrimaryKeyCheck(\n schema: string,\n table: string,\n exists: boolean,\n constraintName?: string,\n): string {\n const namespace = postgresCreateNamespace({ id: schema });\n const comparison = exists ? '' : 'NOT ';\n const constraintFilter = constraintName\n ? `AND c2.relname = '${escapeLiteral(constraintName)}'`\n : '';\n return `SELECT ${comparison}EXISTS (\n SELECT 1\n FROM pg_index i\n JOIN pg_class c ON c.oid = i.indrelid\n JOIN pg_namespace n ON n.oid = c.relnamespace\n LEFT JOIN pg_class c2 ON c2.oid = i.indexrelid\n WHERE n.nspname = ${namespace.schemaSqlExpression()}\n AND c.relname = '${escapeLiteral(table)}'\n AND i.indisprimary\n ${constraintFilter}\n)`;\n}\n"],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- import { a as columnNullabilityCheck, c as qualifyTableName, d as toRegclassLiteral, i as columnHasNoDefaultCheck, l as tableHasPrimaryKeyCheck, r as columnExistsCheck, s as constraintExistsCheck, t as buildExpectedFormatType, u as tableIsEmptyCheck } from "./planner-sql-checks-BM4sD6Xc.mjs";
1
+ import { a as columnNullabilityCheck, c as qualifyTableName, d as toRegclassLiteral, i as columnHasNoDefaultCheck, l as tableHasPrimaryKeyCheck, r as columnExistsCheck, s as constraintExistsCheck, t as buildExpectedFormatType, u as tableIsEmptyCheck } from "./planner-sql-checks-K-mTBJDi.mjs";
2
2
  export { buildExpectedFormatType, columnExistsCheck, columnHasNoDefaultCheck, columnNullabilityCheck, constraintExistsCheck, qualifyTableName, tableHasPrimaryKeyCheck, tableIsEmptyCheck, toRegclassLiteral };
@@ -1,4 +1,4 @@
1
- import { t as TypeScriptRenderablePostgresMigration } from "./planner-produced-postgres-migration-c9lpjPv1.mjs";
1
+ import { t as TypeScriptRenderablePostgresMigration } from "./planner-produced-postgres-migration-p-VKkCia.mjs";
2
2
  import { MigrationOperationPolicy, SqlPlannerFailureResult } from "@prisma-next/family-sql/control";
3
3
  import { MigrationPlanWithAuthoringSurface, MigrationPlanner, MigrationScaffoldContext } from "@prisma-next/framework-components/control";
4
4
  import { Contract } from "@prisma-next/contract/types";
package/dist/planner.mjs CHANGED
@@ -1,2 +1,2 @@
1
- import { t as createPostgresMigrationPlanner } from "./planner-C8yhbXOq.mjs";
1
+ import { t as createPostgresMigrationPlanner } from "./planner-DZG1dsSW.mjs";
2
2
  export { createPostgresMigrationPlanner };
@@ -1,29 +1,51 @@
1
- import { t as PostgresEnumType } from "./postgres-enum-type-DS-KLVRH.mjs";
2
- import { r as isPostgresSchema, t as PostgresSchema } from "./postgres-schema-BosNxhWq.mjs";
1
+ import { n as postgresAuthoringEntityTypes } from "./descriptor-meta-DLA2xV6B.mjs";
2
+ import { r as isPostgresSchema, t as PostgresSchema } from "./postgres-schema-CK82EuWq.mjs";
3
3
  import { NamespaceBase, UNBOUND_NAMESPACE_ID } from "@prisma-next/framework-components/ir";
4
- import { StorageTable } from "@prisma-next/sql-contract/types";
5
4
  import { SqlContractSerializerBase } from "@prisma-next/family-sql/ir";
5
+ import { isAuthoringEntityTypeDescriptor } from "@prisma-next/framework-components/authoring";
6
6
  //#region src/core/postgres-contract-serializer.ts
7
+ const POSTGRES_AUTHORING_CTX = {
8
+ family: "sql",
9
+ target: "postgres"
10
+ };
11
+ function isAuthoringEntityTypeFactoryOutput(output) {
12
+ return typeof output === "object" && output !== null && typeof output.factory === "function";
13
+ }
14
+ /**
15
+ * Walks a pack's entity-type namespace tree and emits the maps the
16
+ * family base consumes — hydrators and validator-schema fragments, both
17
+ * keyed by the descriptor's `discriminator`.
18
+ */
19
+ function collectEntityRegistryContributions(namespace) {
20
+ const entityTypeRegistry = /* @__PURE__ */ new Map();
21
+ const validatorFragments = /* @__PURE__ */ new Map();
22
+ const walk = (node) => {
23
+ for (const value of Object.values(node)) {
24
+ if (isAuthoringEntityTypeDescriptor(value)) {
25
+ if (isAuthoringEntityTypeFactoryOutput(value.output)) {
26
+ const { factory } = value.output;
27
+ entityTypeRegistry.set(value.discriminator, (raw) => factory(raw, POSTGRES_AUTHORING_CTX));
28
+ }
29
+ if (value.validatorSchema !== void 0) validatorFragments.set(value.discriminator, value.validatorSchema);
30
+ continue;
31
+ }
32
+ if (typeof value === "object" && value !== null) walk(value);
33
+ }
34
+ };
35
+ walk(namespace);
36
+ return {
37
+ entityTypeRegistry,
38
+ validatorFragments
39
+ };
40
+ }
7
41
  var PostgresContractSerializer = class extends SqlContractSerializerBase {
8
42
  constructor() {
9
- super(/* @__PURE__ */ new Map());
43
+ const { entityTypeRegistry, validatorFragments } = collectEntityRegistryContributions(postgresAuthoringEntityTypes);
44
+ super(entityTypeRegistry, validatorFragments);
10
45
  }
11
46
  hydrateSqlNamespaceEntry(nsId, raw) {
12
47
  if (raw instanceof NamespaceBase) return raw;
13
- const obj = raw;
14
- const id = obj.id ?? nsId;
15
- const tables = Object.fromEntries(Object.entries(obj.tables ?? {}).map(([tableName, table]) => [tableName, table instanceof StorageTable ? table : new StorageTable(table)]));
16
- const typeEntries = obj.types;
17
- const hydratedNsTypes = typeEntries !== void 0 && Object.keys(typeEntries).length > 0 ? Object.fromEntries(Object.entries(typeEntries).map(([typeName, entry]) => {
18
- if (entry instanceof PostgresEnumType) return [typeName, entry];
19
- const plain = entry;
20
- const name = typeof plain["name"] === "string" ? plain["name"] : typeName;
21
- return [typeName, new PostgresEnumType({
22
- name,
23
- nativeType: typeof plain["nativeType"] === "string" ? plain["nativeType"] : name,
24
- values: Array.isArray(plain["values"]) ? plain["values"] : []
25
- })];
26
- })) : void 0;
48
+ const { id, tables, types: hydratedNsTypes } = super.hydrateSqlNamespaceEntry(nsId, raw);
27
49
  const emptyTables = Object.keys(tables).length === 0;
28
50
  const emptyTypes = !hydratedNsTypes || Object.keys(hydratedNsTypes).length === 0;
29
51
  if (id === UNBOUND_NAMESPACE_ID && emptyTables && emptyTypes) return PostgresSchema.unbound;
@@ -80,4 +102,4 @@ var PostgresContractSerializer = class extends SqlContractSerializerBase {
80
102
  //#endregion
81
103
  export { PostgresContractSerializer as t };
82
104
 
83
- //# sourceMappingURL=postgres-contract-serializer-CcZO9ukP.mjs.map
105
+ //# sourceMappingURL=postgres-contract-serializer-CrET5Ov0.mjs.map