@prisma-next/target-postgres 0.7.0 → 0.8.0-dev.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{codec-ids-CplrEfmx.d.mts → codec-ids-RvYfmUmi.d.mts} +1 -1
- package/dist/{codec-ids-CplrEfmx.d.mts.map → codec-ids-RvYfmUmi.d.mts.map} +1 -1
- package/dist/codec-ids.d.mts +1 -1
- package/dist/{codec-types-lrsb3N07.d.mts → codec-types-667FxIW8.d.mts} +2 -2
- package/dist/{codec-types-lrsb3N07.d.mts.map → codec-types-667FxIW8.d.mts.map} +1 -1
- package/dist/codec-types.d.mts +1 -1
- package/dist/{codecs-Cue97Xqf.d.mts → codecs-DXeDABSO.d.mts} +2 -2
- package/dist/{codecs-Cue97Xqf.d.mts.map → codecs-DXeDABSO.d.mts.map} +1 -1
- package/dist/codecs.d.mts +1 -1
- package/dist/control.d.mts +2 -2
- package/dist/control.d.mts.map +1 -1
- package/dist/control.mjs +38 -7
- package/dist/control.mjs.map +1 -1
- package/dist/{data-transform-bIeAcZIJ.d.mts → data-transform-B6p02mFJ.d.mts} +3 -3
- package/dist/{data-transform-bIeAcZIJ.d.mts.map → data-transform-B6p02mFJ.d.mts.map} +1 -1
- package/dist/{data-transform-DKWXdHuZ.mjs → data-transform-aF9az88u.mjs} +1 -1
- package/dist/{data-transform-DKWXdHuZ.mjs.map → data-transform-aF9az88u.mjs.map} +1 -1
- package/dist/data-transform.d.mts +1 -1
- package/dist/data-transform.mjs +1 -1
- package/dist/{default-normalizer-C8XyZj85.mjs → default-normalizer-DHCsbfjc.mjs} +1 -1
- package/dist/{default-normalizer-C8XyZj85.mjs.map → default-normalizer-DHCsbfjc.mjs.map} +1 -1
- package/dist/default-normalizer.mjs +1 -1
- package/dist/descriptor-meta-DFUCClk_.mjs +124 -0
- package/dist/descriptor-meta-DFUCClk_.mjs.map +1 -0
- package/dist/enum-planning-Bqp96iIw.mjs +63 -0
- package/dist/enum-planning-Bqp96iIw.mjs.map +1 -0
- package/dist/enum-planning.d.mts +48 -0
- package/dist/enum-planning.d.mts.map +1 -0
- package/dist/enum-planning.mjs +2 -0
- package/dist/{errors-Chm2bKcS.mjs → errors-BiOloWUh.mjs} +1 -1
- package/dist/{errors-Chm2bKcS.mjs.map → errors-BiOloWUh.mjs.map} +1 -1
- package/dist/errors.mjs +1 -1
- package/dist/{issue-planner-DQ6WJkad.mjs → issue-planner-BhWVYyE1.mjs} +114 -49
- package/dist/issue-planner-BhWVYyE1.mjs.map +1 -0
- package/dist/issue-planner.d.mts +11 -9
- package/dist/issue-planner.d.mts.map +1 -1
- package/dist/issue-planner.mjs +1 -1
- package/dist/migration.d.mts +4 -4
- package/dist/migration.d.mts.map +1 -1
- package/dist/migration.mjs +3 -3
- package/dist/{native-type-normalizer-Cry4QoLf.mjs → native-type-normalizer-DMikJJ1V.mjs} +1 -1
- package/dist/{native-type-normalizer-Cry4QoLf.mjs.map → native-type-normalizer-DMikJJ1V.mjs.map} +1 -1
- package/dist/native-type-normalizer.mjs +1 -1
- package/dist/{op-factory-call-DeaFxa8_.mjs → op-factory-call-DerP9BoT.mjs} +8 -5
- package/dist/{op-factory-call-DeaFxa8_.mjs.map → op-factory-call-DerP9BoT.mjs.map} +1 -1
- package/dist/{op-factory-call-UFpUPJL6.d.mts → op-factory-call-c1zELk3U.d.mts} +5 -4
- package/dist/{op-factory-call-UFpUPJL6.d.mts.map → op-factory-call-c1zELk3U.d.mts.map} +1 -1
- package/dist/op-factory-call.d.mts +1 -1
- package/dist/op-factory-call.mjs +1 -1
- package/dist/pack.d.mts +13 -24
- package/dist/pack.d.mts.map +1 -1
- package/dist/pack.mjs +1 -1
- package/dist/{planner-CYtKhLYa.mjs → planner-DSDXUbQ4.mjs} +8 -6
- package/dist/planner-DSDXUbQ4.mjs.map +1 -0
- package/dist/{planner-ddl-builders-CLB7Umhh.mjs → planner-ddl-builders-5QIyhBUF.mjs} +3 -3
- package/dist/planner-ddl-builders-5QIyhBUF.mjs.map +1 -0
- package/dist/planner-ddl-builders.d.mts +5 -5
- package/dist/planner-ddl-builders.d.mts.map +1 -1
- package/dist/planner-ddl-builders.mjs +1 -1
- package/dist/{planner-identity-values-DTx0gePL.mjs → planner-identity-values-BUYNOCwb.mjs} +9 -3
- package/dist/planner-identity-values-BUYNOCwb.mjs.map +1 -0
- package/dist/planner-identity-values.d.mts +1 -1
- package/dist/planner-identity-values.d.mts.map +1 -1
- package/dist/planner-identity-values.mjs +1 -1
- package/dist/{planner-produced-postgres-migration-CjxWIVgh.d.mts → planner-produced-postgres-migration-D34ftfEK.d.mts} +3 -3
- package/dist/{planner-produced-postgres-migration-CjxWIVgh.d.mts.map → planner-produced-postgres-migration-D34ftfEK.d.mts.map} +1 -1
- package/dist/{planner-produced-postgres-migration-DphktB2N.mjs → planner-produced-postgres-migration-D8OCSSLM.mjs} +4 -4
- package/dist/{planner-produced-postgres-migration-DphktB2N.mjs.map → planner-produced-postgres-migration-D8OCSSLM.mjs.map} +1 -1
- package/dist/planner-produced-postgres-migration.d.mts +1 -1
- package/dist/planner-produced-postgres-migration.mjs +1 -1
- package/dist/{planner-schema-lookup-B1ags8ys.mjs → planner-schema-lookup--u9whY_Y.mjs} +1 -1
- package/dist/{planner-schema-lookup-B1ags8ys.mjs.map → planner-schema-lookup--u9whY_Y.mjs.map} +1 -1
- package/dist/planner-schema-lookup.mjs +1 -1
- package/dist/{planner-sql-checks-DwZvGlV4.mjs → planner-sql-checks-Cd016Ycs.mjs} +7 -2
- package/dist/planner-sql-checks-Cd016Ycs.mjs.map +1 -0
- package/dist/planner-sql-checks.d.mts +2 -2
- package/dist/planner-sql-checks.d.mts.map +1 -1
- package/dist/planner-sql-checks.mjs +1 -1
- package/dist/{planner-target-details-bVVcanWh.d.mts → planner-target-details-iYJwzFHP.d.mts} +1 -1
- package/dist/{planner-target-details-bVVcanWh.d.mts.map → planner-target-details-iYJwzFHP.d.mts.map} +1 -1
- package/dist/planner-target-details.d.mts +1 -1
- package/dist/planner.d.mts +1 -1
- package/dist/planner.d.mts.map +1 -1
- package/dist/planner.mjs +1 -1
- package/dist/postgres-contract-serializer-D5VJk6lo.mjs +61 -0
- package/dist/postgres-contract-serializer-D5VJk6lo.mjs.map +1 -0
- package/dist/postgres-enum-type-CrKq8au9.d.mts +69 -0
- package/dist/postgres-enum-type-CrKq8au9.d.mts.map +1 -0
- package/dist/postgres-enum-type-DS-KLVRH.mjs +61 -0
- package/dist/postgres-enum-type-DS-KLVRH.mjs.map +1 -0
- package/dist/{postgres-migration-UkcHfZAA.d.mts → postgres-migration-CiQzhcMe.d.mts} +4 -4
- package/dist/{postgres-migration-UkcHfZAA.d.mts.map → postgres-migration-CiQzhcMe.d.mts.map} +1 -1
- package/dist/{postgres-migration-Bkv140RW.mjs → postgres-migration-Fdxzo6l2.mjs} +3 -3
- package/dist/{postgres-migration-Bkv140RW.mjs.map → postgres-migration-Fdxzo6l2.mjs.map} +1 -1
- package/dist/{render-ops--1nnfNus.mjs → render-ops-CkiuHSNj.mjs} +1 -1
- package/dist/{render-ops--1nnfNus.mjs.map → render-ops-CkiuHSNj.mjs.map} +1 -1
- package/dist/render-ops.d.mts +1 -1
- package/dist/render-ops.mjs +1 -1
- package/dist/{render-typescript-D3doH-vX.mjs → render-typescript-C9XWI8Ld.mjs} +1 -1
- package/dist/{render-typescript-D3doH-vX.mjs.map → render-typescript-C9XWI8Ld.mjs.map} +1 -1
- package/dist/render-typescript.mjs +1 -1
- package/dist/runtime.d.mts +25 -1
- package/dist/runtime.d.mts.map +1 -1
- package/dist/runtime.mjs +3 -2
- package/dist/runtime.mjs.map +1 -1
- package/dist/{shared-MpwjwAjM.d.mts → shared-DLYdmYo-.d.mts} +2 -2
- package/dist/{shared-MpwjwAjM.d.mts.map → shared-DLYdmYo-.d.mts.map} +1 -1
- package/dist/{sql-utils-CggjWNij.mjs → sql-utils-BewXAnsG.mjs} +1 -1
- package/dist/{sql-utils-CggjWNij.mjs.map → sql-utils-BewXAnsG.mjs.map} +1 -1
- package/dist/sql-utils.mjs +1 -1
- package/dist/{statement-builders-BT889jV0.mjs → statement-builders-BSIQMClE.mjs} +1 -1
- package/dist/{statement-builders-BT889jV0.mjs.map → statement-builders-BSIQMClE.mjs.map} +1 -1
- package/dist/statement-builders.mjs +1 -1
- package/dist/{tables-DgYIXjUt.mjs → tables-Ce_Q0I8B.mjs} +7 -7
- package/dist/{tables-DgYIXjUt.mjs.map → tables-Ce_Q0I8B.mjs.map} +1 -1
- package/dist/{types-CTqpysRY.d.mts → types-Dq74Z3eu.d.mts} +1 -1
- package/dist/types-Dq74Z3eu.d.mts.map +1 -0
- package/dist/types.d.mts +3 -2
- package/dist/types.mjs +2 -1
- package/package.json +20 -19
- package/src/core/authoring.ts +41 -9
- package/src/core/descriptor-meta.ts +6 -1
- package/src/core/migrations/enum-planning.ts +93 -0
- package/src/core/migrations/issue-planner.ts +25 -13
- package/src/core/migrations/op-factory-call.ts +12 -3
- package/src/core/migrations/operations/enums.ts +5 -4
- package/src/core/migrations/planner-ddl-builders.ts +4 -3
- package/src/core/migrations/planner-identity-values.ts +28 -4
- package/src/core/migrations/planner-recipes.ts +6 -2
- package/src/core/migrations/planner-sql-checks.ts +6 -2
- package/src/core/migrations/planner-strategies.ts +187 -74
- package/src/core/migrations/planner-type-resolution.ts +20 -2
- package/src/core/migrations/planner.ts +3 -0
- package/src/core/migrations/runner.ts +3 -0
- package/src/core/postgres-contract-serializer.ts +70 -0
- package/src/core/postgres-enum-type.ts +85 -0
- package/src/core/postgres-schema-verifier.ts +37 -0
- package/src/exports/control.ts +4 -0
- package/src/exports/enum-planning.ts +6 -0
- package/src/exports/runtime.ts +2 -0
- package/src/exports/types.ts +1 -0
- package/dist/descriptor-meta-Dde_BS3K.mjs +0 -99
- package/dist/descriptor-meta-Dde_BS3K.mjs.map +0 -1
- package/dist/issue-planner-DQ6WJkad.mjs.map +0 -1
- package/dist/planner-CYtKhLYa.mjs.map +0 -1
- package/dist/planner-ddl-builders-CLB7Umhh.mjs.map +0 -1
- package/dist/planner-identity-values-DTx0gePL.mjs.map +0 -1
- package/dist/planner-sql-checks-DwZvGlV4.mjs.map +0 -1
- package/dist/types-CTqpysRY.d.mts.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tables-DgYIXjUt.mjs","names":[],"sources":["../src/core/migrations/operations/shared.ts","../src/core/migrations/operations/columns.ts","../src/core/migrations/operations/constraints.ts","../src/core/migrations/operations/dependencies.ts","../src/core/migrations/operations/enums.ts","../src/core/migrations/operations/indexes.ts","../src/core/migrations/operations/tables.ts"],"sourcesContent":["import type { SqlMigrationPlanOperation } from '@prisma-next/family-sql/control';\nimport type { ReferentialAction } from '@prisma-next/sql-contract/types';\nimport { ifDefined } from '@prisma-next/utils/defined';\nimport { quoteIdentifier } from '../../sql-utils';\nimport type { OperationClass, PostgresPlanTargetDetails } from '../planner-target-details';\n\nexport type Op = SqlMigrationPlanOperation<PostgresPlanTargetDetails>;\n\n/**\n * Literal-args shape for a column definition consumed by `createTable` and\n * `addColumn`. Fully materialized: codec expansion and default rendering have\n * already happened in the wrapper.\n *\n * - `typeSql` is the column's DDL type string (e.g. `\"integer\"`, `\"SERIAL\"`,\n * `\"varchar(100)\"`), already produced by `buildColumnTypeSql` in the\n * call-factory wrapper.\n * - `defaultSql` is the full `DEFAULT …` clause (e.g. `\"DEFAULT 42\"`) or an\n * empty string when the column has no default, matching\n * `buildColumnDefaultSql`'s output.\n */\nexport interface ColumnSpec {\n readonly name: string;\n readonly typeSql: string;\n readonly defaultSql: string;\n readonly nullable: boolean;\n}\n\n/**\n * Literal-args shape for a foreign key definition. The referenced table is\n * assumed to live in the same schema as the constrained table.\n */\nexport interface ForeignKeySpec {\n readonly name: string;\n readonly columns: readonly string[];\n readonly references: {\n readonly table: string;\n readonly columns: readonly string[];\n };\n readonly onDelete?: ReferentialAction;\n readonly onUpdate?: ReferentialAction;\n}\n\nexport function step(description: string, sql: string) {\n return { description, sql };\n}\n\nexport function targetDetails(\n objectType: OperationClass,\n name: string,\n schema: string,\n table?: string,\n): { readonly id: 'postgres'; readonly details: PostgresPlanTargetDetails } {\n return {\n id: 'postgres',\n details: { schema, objectType, name, ...ifDefined('table', table) },\n };\n}\n\nexport function renderColumnDefinition(column: ColumnSpec): string {\n const parts = [\n quoteIdentifier(column.name),\n column.typeSql,\n column.defaultSql,\n column.nullable ? '' : 'NOT NULL',\n ].filter(Boolean);\n return parts.join(' ');\n}\n","import { quoteIdentifier } from '../../sql-utils';\nimport {\n columnDefaultExistsCheck,\n columnExistsCheck,\n columnNullabilityCheck,\n columnTypeCheck,\n qualifyTableName,\n} from '../planner-sql-checks';\nimport { type ColumnSpec, type Op, step, targetDetails } from './shared';\n\nexport function addColumn(schemaName: string, tableName: string, column: ColumnSpec): Op {\n const qualified = qualifyTableName(schemaName, tableName);\n const parts = [\n `ALTER TABLE ${qualified}`,\n `ADD COLUMN ${quoteIdentifier(column.name)} ${column.typeSql}`,\n column.defaultSql,\n column.nullable ? '' : 'NOT NULL',\n ].filter(Boolean);\n const addSql = parts.join(' ');\n\n return {\n id: `column.${tableName}.${column.name}`,\n label: `Add column \"${column.name}\" to \"${tableName}\"`,\n operationClass: 'additive',\n target: targetDetails('column', column.name, schemaName, tableName),\n precheck: [\n step(\n `ensure column \"${column.name}\" is missing`,\n columnExistsCheck({\n schema: schemaName,\n table: tableName,\n column: column.name,\n exists: false,\n }),\n ),\n ],\n execute: [step(`add column \"${column.name}\"`, addSql)],\n postcheck: [\n step(\n `verify column \"${column.name}\" exists`,\n columnExistsCheck({ schema: schemaName, table: tableName, column: column.name }),\n ),\n ],\n };\n}\n\nexport function dropColumn(schemaName: string, tableName: string, columnName: string): Op {\n const qualified = qualifyTableName(schemaName, tableName);\n return {\n id: `dropColumn.${tableName}.${columnName}`,\n label: `Drop column \"${columnName}\" from \"${tableName}\"`,\n operationClass: 'destructive',\n target: targetDetails('column', columnName, schemaName, tableName),\n precheck: [\n step(\n `ensure column \"${columnName}\" exists`,\n columnExistsCheck({ schema: schemaName, table: tableName, column: columnName }),\n ),\n ],\n execute: [\n step(\n `drop column \"${columnName}\"`,\n `ALTER TABLE ${qualified} DROP COLUMN ${quoteIdentifier(columnName)}`,\n ),\n ],\n postcheck: [\n step(\n `verify column \"${columnName}\" does not exist`,\n columnExistsCheck({\n schema: schemaName,\n table: tableName,\n column: columnName,\n exists: false,\n }),\n ),\n ],\n };\n}\n\n/**\n * `qualifiedTargetType` is the new column type as it appears in the\n * `ALTER COLUMN TYPE` clause (schema-qualified for user-defined types, raw\n * native name for built-ins). `formatTypeExpected` is the unqualified\n * `format_type` form used in the postcheck. `rawTargetTypeForLabel` is the\n * string appearing in the human-readable label (typically `toType` when\n * explicit, else the column's native type).\n */\nexport function alterColumnType(\n schemaName: string,\n tableName: string,\n columnName: string,\n options: {\n readonly qualifiedTargetType: string;\n readonly formatTypeExpected: string;\n readonly rawTargetTypeForLabel: string;\n readonly using?: string;\n },\n): Op {\n const qualified = qualifyTableName(schemaName, tableName);\n const usingClause = options.using\n ? ` USING ${options.using}`\n : ` USING ${quoteIdentifier(columnName)}::${options.qualifiedTargetType}`;\n return {\n id: `alterType.${tableName}.${columnName}`,\n label: `Alter type of \"${tableName}\".\"${columnName}\" to ${options.rawTargetTypeForLabel}`,\n operationClass: 'destructive',\n target: targetDetails('column', columnName, schemaName, tableName),\n precheck: [\n step(\n `ensure column \"${columnName}\" exists`,\n columnExistsCheck({ schema: schemaName, table: tableName, column: columnName }),\n ),\n ],\n execute: [\n step(\n `alter type of \"${columnName}\"`,\n `ALTER TABLE ${qualified} ALTER COLUMN ${quoteIdentifier(columnName)} TYPE ${options.qualifiedTargetType}${usingClause}`,\n ),\n ],\n postcheck: [\n step(\n `verify column \"${columnName}\" has type \"${options.formatTypeExpected}\"`,\n columnTypeCheck({\n schema: schemaName,\n table: tableName,\n column: columnName,\n expectedType: options.formatTypeExpected,\n }),\n ),\n ],\n meta: { warning: 'TABLE_REWRITE' },\n };\n}\n\nexport function setNotNull(schemaName: string, tableName: string, columnName: string): Op {\n const qualified = qualifyTableName(schemaName, tableName);\n return {\n id: `alterNullability.setNotNull.${tableName}.${columnName}`,\n label: `Set NOT NULL on \"${tableName}\".\"${columnName}\"`,\n operationClass: 'destructive',\n target: targetDetails('column', columnName, schemaName, tableName),\n precheck: [\n step(\n `ensure column \"${columnName}\" exists`,\n columnExistsCheck({ schema: schemaName, table: tableName, column: columnName }),\n ),\n step(\n `ensure no NULL values in \"${columnName}\"`,\n `SELECT NOT EXISTS (SELECT 1 FROM ${qualified} WHERE ${quoteIdentifier(columnName)} IS NULL)`,\n ),\n ],\n execute: [\n step(\n `set NOT NULL on \"${columnName}\"`,\n `ALTER TABLE ${qualified} ALTER COLUMN ${quoteIdentifier(columnName)} SET NOT NULL`,\n ),\n ],\n postcheck: [\n step(\n `verify column \"${columnName}\" is NOT NULL`,\n columnNullabilityCheck({\n schema: schemaName,\n table: tableName,\n column: columnName,\n nullable: false,\n }),\n ),\n ],\n };\n}\n\nexport function dropNotNull(schemaName: string, tableName: string, columnName: string): Op {\n const qualified = qualifyTableName(schemaName, tableName);\n return {\n id: `alterNullability.dropNotNull.${tableName}.${columnName}`,\n label: `Drop NOT NULL on \"${tableName}\".\"${columnName}\"`,\n operationClass: 'widening',\n target: targetDetails('column', columnName, schemaName, tableName),\n precheck: [\n step(\n `ensure column \"${columnName}\" exists`,\n columnExistsCheck({ schema: schemaName, table: tableName, column: columnName }),\n ),\n ],\n execute: [\n step(\n `drop NOT NULL on \"${columnName}\"`,\n `ALTER TABLE ${qualified} ALTER COLUMN ${quoteIdentifier(columnName)} DROP NOT NULL`,\n ),\n ],\n postcheck: [\n step(\n `verify column \"${columnName}\" is nullable`,\n columnNullabilityCheck({\n schema: schemaName,\n table: tableName,\n column: columnName,\n nullable: true,\n }),\n ),\n ],\n };\n}\n\n/**\n * `defaultSql` is the full `DEFAULT …` clause as produced by\n * `buildColumnDefaultSql` — e.g. `\"DEFAULT 42\"`,\n * `\"DEFAULT (CURRENT_TIMESTAMP)\"`, or `\"DEFAULT nextval('seq'::regclass)\"`.\n *\n * `operationClass` defaults to `'additive'` (setting a default on a column\n * that currently has none). The reconciliation planner passes `'widening'`\n * when the column already has a different default — policy enforcement\n * treats that as a widening change rather than an additive one.\n */\nexport function setDefault(\n schemaName: string,\n tableName: string,\n columnName: string,\n defaultSql: string,\n operationClass: 'additive' | 'widening' = 'additive',\n): Op {\n const qualified = qualifyTableName(schemaName, tableName);\n return {\n id: `setDefault.${tableName}.${columnName}`,\n label: `Set default on \"${tableName}\".\"${columnName}\"`,\n operationClass,\n target: targetDetails('column', columnName, schemaName, tableName),\n precheck: [\n step(\n `ensure column \"${columnName}\" exists`,\n columnExistsCheck({ schema: schemaName, table: tableName, column: columnName }),\n ),\n ],\n execute: [\n step(\n `set default on \"${columnName}\"`,\n `ALTER TABLE ${qualified} ALTER COLUMN ${quoteIdentifier(columnName)} SET ${defaultSql}`,\n ),\n ],\n postcheck: [\n step(\n `verify column \"${columnName}\" has a default`,\n columnDefaultExistsCheck({\n schema: schemaName,\n table: tableName,\n column: columnName,\n exists: true,\n }),\n ),\n ],\n };\n}\n\nexport function dropDefault(schemaName: string, tableName: string, columnName: string): Op {\n const qualified = qualifyTableName(schemaName, tableName);\n return {\n id: `dropDefault.${tableName}.${columnName}`,\n label: `Drop default on \"${tableName}\".\"${columnName}\"`,\n operationClass: 'destructive',\n target: targetDetails('column', columnName, schemaName, tableName),\n precheck: [\n step(\n `ensure column \"${columnName}\" exists`,\n columnExistsCheck({ schema: schemaName, table: tableName, column: columnName }),\n ),\n ],\n execute: [\n step(\n `drop default on \"${columnName}\"`,\n `ALTER TABLE ${qualified} ALTER COLUMN ${quoteIdentifier(columnName)} DROP DEFAULT`,\n ),\n ],\n postcheck: [\n step(\n `verify column \"${columnName}\" has no default`,\n columnDefaultExistsCheck({\n schema: schemaName,\n table: tableName,\n column: columnName,\n exists: false,\n }),\n ),\n ],\n };\n}\n","import type { ReferentialAction } from '@prisma-next/sql-contract/types';\nimport { quoteIdentifier } from '../../sql-utils';\nimport { constraintExistsCheck, qualifyTableName } from '../planner-sql-checks';\nimport { type ForeignKeySpec, type Op, step, targetDetails } from './shared';\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\nfunction renderForeignKeySql(schemaName: string, tableName: string, fk: ForeignKeySpec): string {\n let sql = `ALTER TABLE ${qualifyTableName(schemaName, tableName)}\nADD CONSTRAINT ${quoteIdentifier(fk.name)}\nFOREIGN KEY (${fk.columns.map(quoteIdentifier).join(', ')})\nREFERENCES ${qualifyTableName(schemaName, fk.references.table)} (${fk.references.columns\n .map(quoteIdentifier)\n .join(', ')})`;\n\n if (fk.onDelete !== undefined) {\n const action = REFERENTIAL_ACTION_SQL[fk.onDelete];\n if (!action) {\n throw new Error(`Unknown referential action for onDelete: ${String(fk.onDelete)}`);\n }\n sql += `\\nON DELETE ${action}`;\n }\n if (fk.onUpdate !== undefined) {\n const action = REFERENTIAL_ACTION_SQL[fk.onUpdate];\n if (!action) {\n throw new Error(`Unknown referential action for onUpdate: ${String(fk.onUpdate)}`);\n }\n sql += `\\nON UPDATE ${action}`;\n }\n return sql;\n}\n\nexport function addPrimaryKey(\n schemaName: string,\n tableName: string,\n constraintName: string,\n columns: readonly string[],\n): Op {\n const qualified = qualifyTableName(schemaName, tableName);\n const columnList = columns.map(quoteIdentifier).join(', ');\n return {\n id: `primaryKey.${tableName}.${constraintName}`,\n label: `Add primary key on \"${tableName}\"`,\n operationClass: 'additive',\n target: targetDetails('primaryKey', constraintName, schemaName, tableName),\n precheck: [\n step(\n `ensure primary key \"${constraintName}\" does not exist`,\n constraintExistsCheck({\n constraintName,\n schema: schemaName,\n table: tableName,\n exists: false,\n }),\n ),\n ],\n execute: [\n step(\n `add primary key \"${constraintName}\"`,\n `ALTER TABLE ${qualified} ADD CONSTRAINT ${quoteIdentifier(constraintName)} PRIMARY KEY (${columnList})`,\n ),\n ],\n postcheck: [\n step(\n `verify primary key \"${constraintName}\" exists`,\n constraintExistsCheck({ constraintName, schema: schemaName, table: tableName }),\n ),\n ],\n };\n}\n\nexport function addUnique(\n schemaName: string,\n tableName: string,\n constraintName: string,\n columns: readonly string[],\n): Op {\n const qualified = qualifyTableName(schemaName, tableName);\n const columnList = columns.map(quoteIdentifier).join(', ');\n return {\n id: `unique.${tableName}.${constraintName}`,\n label: `Add unique constraint on \"${tableName}\" (${columns.join(', ')})`,\n operationClass: 'additive',\n target: targetDetails('unique', constraintName, schemaName, tableName),\n precheck: [\n step(\n `ensure constraint \"${constraintName}\" does not exist`,\n constraintExistsCheck({\n constraintName,\n schema: schemaName,\n table: tableName,\n exists: false,\n }),\n ),\n ],\n execute: [\n step(\n `add unique constraint \"${constraintName}\"`,\n `ALTER TABLE ${qualified} ADD CONSTRAINT ${quoteIdentifier(constraintName)} UNIQUE (${columnList})`,\n ),\n ],\n postcheck: [\n step(\n `verify constraint \"${constraintName}\" exists`,\n constraintExistsCheck({ constraintName, schema: schemaName, table: tableName }),\n ),\n ],\n };\n}\n\nexport function addForeignKey(schemaName: string, tableName: string, fk: ForeignKeySpec): Op {\n return {\n id: `foreignKey.${tableName}.${fk.name}`,\n label: `Add foreign key \"${fk.name}\" on \"${tableName}\"`,\n operationClass: 'additive',\n target: targetDetails('foreignKey', fk.name, schemaName, tableName),\n precheck: [\n step(\n `ensure FK \"${fk.name}\" does not exist`,\n constraintExistsCheck({\n constraintName: fk.name,\n schema: schemaName,\n table: tableName,\n exists: false,\n }),\n ),\n ],\n execute: [step(`add FK \"${fk.name}\"`, renderForeignKeySql(schemaName, tableName, fk))],\n postcheck: [\n step(\n `verify FK \"${fk.name}\" exists`,\n constraintExistsCheck({\n constraintName: fk.name,\n schema: schemaName,\n table: tableName,\n }),\n ),\n ],\n };\n}\n\n/**\n * `kind` feeds the operation's `target.details.objectType`. Descriptor-flow\n * does not carry kind information in its drop-constraint descriptor, so the\n * default is `'unique'`. The reconciliation planner passes the correct kind\n * (`'foreignKey'`, `'primaryKey'`, or `'unique'`) based on the `SchemaIssue`\n * that produced the drop.\n */\nexport function dropConstraint(\n schemaName: string,\n tableName: string,\n constraintName: string,\n kind: 'foreignKey' | 'unique' | 'primaryKey' = 'unique',\n): Op {\n const qualified = qualifyTableName(schemaName, tableName);\n return {\n id: `dropConstraint.${tableName}.${constraintName}`,\n label: `Drop constraint \"${constraintName}\" on \"${tableName}\"`,\n operationClass: 'destructive',\n target: targetDetails(kind, constraintName, schemaName, tableName),\n precheck: [\n step(\n `ensure constraint \"${constraintName}\" exists`,\n constraintExistsCheck({ constraintName, schema: schemaName, table: tableName }),\n ),\n ],\n execute: [\n step(\n `drop constraint \"${constraintName}\"`,\n `ALTER TABLE ${qualified} DROP CONSTRAINT ${quoteIdentifier(constraintName)}`,\n ),\n ],\n postcheck: [\n step(\n `verify constraint \"${constraintName}\" does not exist`,\n constraintExistsCheck({\n constraintName,\n schema: schemaName,\n table: tableName,\n exists: false,\n }),\n ),\n ],\n };\n}\n","import { quoteIdentifier } from '../../sql-utils';\nimport { type Op, step } from './shared';\n\nexport function createExtension(extensionName: string): Op {\n return {\n id: `extension.${extensionName}`,\n label: `Create extension \"${extensionName}\"`,\n operationClass: 'additive',\n target: { id: 'postgres' },\n precheck: [],\n execute: [\n step(\n `Create extension \"${extensionName}\"`,\n `CREATE EXTENSION IF NOT EXISTS ${quoteIdentifier(extensionName)}`,\n ),\n ],\n postcheck: [],\n };\n}\n\n/**\n * Install a Postgres extension as the baseline op for an extension-pack\n * contract space. Layered on top of {@link createExtension}: stamps an\n * `invariantId` (required so the per-space marker records the install),\n * scopes the op `id` under a caller-chosen namespace (e.g. `pgvector.`),\n * and emits pre- and postcheck SQL probing `pg_extension`. The richer\n * shape lets the runner's idempotency probe skip the install on re-run\n * (postcheck-pre-satisfied) without firing the precheck.\n *\n * Use this for hand-rolled baseline migrations in contract-space\n * extension packages (e.g. `extension-pgvector`, `extension-paradedb`);\n * use the bare {@link createExtension} for planner-emitted ops where the\n * caller already controls idempotency through the surrounding plan.\n */\nexport function installExtension(options: {\n readonly extensionName: string;\n readonly invariantId: string;\n readonly id: string;\n readonly label?: string;\n}): Op {\n const { extensionName, invariantId, id } = options;\n const label = options.label ?? `Enable extension \"${extensionName}\"`;\n return {\n id,\n label,\n operationClass: 'additive',\n invariantId,\n target: {\n id: 'postgres',\n details: { schema: 'public', objectType: 'dependency', name: extensionName },\n },\n precheck: [\n step(\n `verify extension \"${extensionName}\" is not already enabled`,\n `SELECT NOT EXISTS (SELECT 1 FROM pg_extension WHERE extname = '${extensionName}')`,\n ),\n ],\n execute: [\n step(\n `create extension \"${extensionName}\"`,\n `CREATE EXTENSION IF NOT EXISTS ${extensionName}`,\n ),\n ],\n postcheck: [\n step(\n `confirm extension \"${extensionName}\" is enabled`,\n `SELECT EXISTS (SELECT 1 FROM pg_extension WHERE extname = '${extensionName}')`,\n ),\n ],\n };\n}\n\nexport function createSchema(schemaName: string): Op {\n return {\n id: `schema.${schemaName}`,\n label: `Create schema \"${schemaName}\"`,\n operationClass: 'additive',\n target: { id: 'postgres' },\n precheck: [],\n execute: [\n step(\n `Create schema \"${schemaName}\"`,\n `CREATE SCHEMA IF NOT EXISTS ${quoteIdentifier(schemaName)}`,\n ),\n ],\n postcheck: [],\n };\n}\n","import { escapeLiteral, qualifyName, quoteIdentifier } from '../../sql-utils';\nimport { type Op, step, targetDetails } from './shared';\n\nfunction enumTypeExistsCheck(schemaName: string, nativeType: string, exists = true): string {\n const clause = exists ? 'EXISTS' : 'NOT EXISTS';\n return `SELECT ${clause} (\n SELECT 1\n FROM pg_type t\n JOIN pg_namespace n ON t.typnamespace = n.oid\n WHERE n.nspname = '${escapeLiteral(schemaName)}'\n AND t.typname = '${escapeLiteral(nativeType)}'\n)`;\n}\n\nexport function createEnumType(\n schemaName: string,\n typeName: string,\n values: readonly string[],\n): Op {\n const qualifiedType = qualifyName(schemaName, typeName);\n const literalValues = values.map((v) => `'${escapeLiteral(v)}'`).join(', ');\n return {\n id: `type.${typeName}`,\n label: `Create enum type \"${typeName}\"`,\n operationClass: 'additive',\n target: targetDetails('type', typeName, schemaName),\n precheck: [\n step(\n `ensure type \"${typeName}\" does not exist`,\n enumTypeExistsCheck(schemaName, typeName, false),\n ),\n ],\n execute: [\n step(\n `create enum type \"${typeName}\"`,\n `CREATE TYPE ${qualifiedType} AS ENUM (${literalValues})`,\n ),\n ],\n postcheck: [\n step(`verify type \"${typeName}\" exists`, enumTypeExistsCheck(schemaName, typeName)),\n ],\n };\n}\n\n/**\n * `typeName` is the contract-facing type name (used for id/label).\n * `nativeType` is the Postgres type name to mutate (may differ for external types).\n */\nexport function addEnumValues(\n schemaName: string,\n typeName: string,\n nativeType: string,\n values: readonly string[],\n): Op {\n const qualifiedType = qualifyName(schemaName, nativeType);\n return {\n id: `type.${typeName}.addValues`,\n label: `Add values to enum type \"${typeName}\": ${values.join(', ')}`,\n operationClass: 'additive',\n target: targetDetails('type', typeName, schemaName),\n precheck: [\n step(`ensure type \"${nativeType}\" exists`, enumTypeExistsCheck(schemaName, nativeType)),\n ],\n execute: values.map((value) =>\n step(\n `add value '${value}' to enum \"${nativeType}\"`,\n `ALTER TYPE ${qualifiedType} ADD VALUE '${escapeLiteral(value)}'`,\n ),\n ),\n postcheck: [\n step(`verify type \"${nativeType}\" exists`, enumTypeExistsCheck(schemaName, nativeType)),\n ],\n };\n}\n\nexport function dropEnumType(schemaName: string, typeName: string): Op {\n const qualified = qualifyName(schemaName, typeName);\n return {\n id: `type.${typeName}.drop`,\n label: `Drop enum type \"${typeName}\"`,\n operationClass: 'destructive',\n target: targetDetails('type', typeName, schemaName),\n precheck: [step(`ensure type \"${typeName}\" exists`, enumTypeExistsCheck(schemaName, typeName))],\n execute: [step(`drop enum type \"${typeName}\"`, `DROP TYPE ${qualified}`)],\n postcheck: [\n step(`verify type \"${typeName}\" removed`, enumTypeExistsCheck(schemaName, typeName, false)),\n ],\n };\n}\n\nexport function renameType(schemaName: string, fromName: string, toName: string): Op {\n const qualifiedFrom = qualifyName(schemaName, fromName);\n return {\n id: `type.${fromName}.rename`,\n label: `Rename type \"${fromName}\" to \"${toName}\"`,\n operationClass: 'destructive',\n target: targetDetails('type', fromName, schemaName),\n precheck: [\n step(`ensure type \"${fromName}\" exists`, enumTypeExistsCheck(schemaName, fromName)),\n step(\n `ensure type \"${toName}\" does not already exist`,\n enumTypeExistsCheck(schemaName, toName, false),\n ),\n ],\n execute: [\n step(\n `rename type \"${fromName}\" to \"${toName}\"`,\n `ALTER TYPE ${qualifiedFrom} RENAME TO ${quoteIdentifier(toName)}`,\n ),\n ],\n postcheck: [step(`verify type \"${toName}\" exists`, enumTypeExistsCheck(schemaName, toName))],\n };\n}\n","import { escapeLiteral, quoteIdentifier } from '../../sql-utils';\nimport { qualifyTableName, toRegclassLiteral } from '../planner-sql-checks';\nimport { type Op, step, targetDetails } from './shared';\n\nexport interface CreateIndexExtras {\n readonly type?: string;\n readonly options?: Record<string, unknown>;\n}\n\nfunction renderIndexOptionValue(key: string, value: unknown): string {\n if (typeof value === 'string') return `'${escapeLiteral(value)}'`;\n if (typeof value === 'number' && Number.isFinite(value)) return String(value);\n if (typeof value === 'boolean') return value ? 'true' : 'false';\n throw new Error(\n `Index option \"${key}\" must be a string, finite number, or boolean; got ${typeof value}`,\n );\n}\n\nfunction renderIndexOptions(options: Record<string, unknown>): string {\n return Object.entries(options)\n .map(([key, value]) => `${quoteIdentifier(key)} = ${renderIndexOptionValue(key, value)}`)\n .join(', ');\n}\n\nexport function createIndex(\n schemaName: string,\n tableName: string,\n indexName: string,\n columns: readonly string[],\n extras?: CreateIndexExtras,\n): Op {\n const qualified = qualifyTableName(schemaName, tableName);\n const columnList = columns.map(quoteIdentifier).join(', ');\n const using = extras?.type ? ` USING ${quoteIdentifier(extras.type)}` : '';\n const options = extras?.options;\n const withClause =\n options && Object.keys(options).length > 0 ? ` WITH (${renderIndexOptions(options)})` : '';\n return {\n id: `index.${tableName}.${indexName}`,\n label: `Create index \"${indexName}\" on \"${tableName}\"`,\n operationClass: 'additive',\n target: targetDetails('index', indexName, schemaName, tableName),\n precheck: [\n step(\n `ensure index \"${indexName}\" does not exist`,\n `SELECT to_regclass(${toRegclassLiteral(schemaName, indexName)}) IS NULL`,\n ),\n ],\n execute: [\n step(\n `create index \"${indexName}\"`,\n `CREATE INDEX ${quoteIdentifier(indexName)} ON ${qualified}${using} (${columnList})${withClause}`,\n ),\n ],\n postcheck: [\n step(\n `verify index \"${indexName}\" exists`,\n `SELECT to_regclass(${toRegclassLiteral(schemaName, indexName)}) IS NOT NULL`,\n ),\n ],\n };\n}\n\nexport function dropIndex(schemaName: string, tableName: string, indexName: string): Op {\n return {\n id: `dropIndex.${tableName}.${indexName}`,\n label: `Drop index \"${indexName}\"`,\n operationClass: 'destructive',\n target: targetDetails('index', indexName, schemaName, tableName),\n precheck: [\n step(\n `ensure index \"${indexName}\" exists`,\n `SELECT to_regclass(${toRegclassLiteral(schemaName, indexName)}) IS NOT NULL`,\n ),\n ],\n execute: [\n step(`drop index \"${indexName}\"`, `DROP INDEX ${qualifyTableName(schemaName, indexName)}`),\n ],\n postcheck: [\n step(\n `verify index \"${indexName}\" does not exist`,\n `SELECT to_regclass(${toRegclassLiteral(schemaName, indexName)}) IS NULL`,\n ),\n ],\n };\n}\n","import { quoteIdentifier } from '../../sql-utils';\nimport { qualifyTableName, toRegclassLiteral } from '../planner-sql-checks';\nimport { type ColumnSpec, type Op, renderColumnDefinition, step, targetDetails } from './shared';\n\nexport function createTable(\n schemaName: string,\n tableName: string,\n columns: ReadonlyArray<ColumnSpec>,\n primaryKey?: { readonly columns: readonly string[] },\n): Op {\n const qualified = qualifyTableName(schemaName, tableName);\n const columnDefs = columns.map(renderColumnDefinition);\n const constraintDefs: string[] = [];\n if (primaryKey) {\n constraintDefs.push(`PRIMARY KEY (${primaryKey.columns.map(quoteIdentifier).join(', ')})`);\n }\n const allDefs = [...columnDefs, ...constraintDefs];\n const createSql = `CREATE TABLE ${qualified} (\\n ${allDefs.join(',\\n ')}\\n)`;\n\n return {\n id: `table.${tableName}`,\n label: `Create table \"${tableName}\"`,\n summary: `Creates table \"${tableName}\"`,\n operationClass: 'additive',\n target: targetDetails('table', tableName, schemaName),\n precheck: [\n step(\n `ensure table \"${tableName}\" does not exist`,\n `SELECT to_regclass(${toRegclassLiteral(schemaName, tableName)}) IS NULL`,\n ),\n ],\n execute: [step(`create table \"${tableName}\"`, createSql)],\n postcheck: [\n step(\n `verify table \"${tableName}\" exists`,\n `SELECT to_regclass(${toRegclassLiteral(schemaName, tableName)}) IS NOT NULL`,\n ),\n ],\n };\n}\n\nexport function dropTable(schemaName: string, tableName: string): Op {\n const qualified = qualifyTableName(schemaName, tableName);\n return {\n id: `dropTable.${tableName}`,\n label: `Drop table \"${tableName}\"`,\n operationClass: 'destructive',\n target: targetDetails('table', tableName, schemaName),\n precheck: [\n step(\n `ensure table \"${tableName}\" exists`,\n `SELECT to_regclass(${toRegclassLiteral(schemaName, tableName)}) IS NOT NULL`,\n ),\n ],\n execute: [step(`drop table \"${tableName}\"`, `DROP TABLE ${qualified}`)],\n postcheck: [\n step(\n `verify table \"${tableName}\" does not exist`,\n `SELECT to_regclass(${toRegclassLiteral(schemaName, tableName)}) IS NULL`,\n ),\n ],\n };\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"tables-Ce_Q0I8B.mjs","names":[],"sources":["../src/core/migrations/operations/shared.ts","../src/core/migrations/operations/columns.ts","../src/core/migrations/operations/constraints.ts","../src/core/migrations/operations/dependencies.ts","../src/core/migrations/operations/enums.ts","../src/core/migrations/operations/indexes.ts","../src/core/migrations/operations/tables.ts"],"sourcesContent":["import type { SqlMigrationPlanOperation } from '@prisma-next/family-sql/control';\nimport type { ReferentialAction } from '@prisma-next/sql-contract/types';\nimport { ifDefined } from '@prisma-next/utils/defined';\nimport { quoteIdentifier } from '../../sql-utils';\nimport type { OperationClass, PostgresPlanTargetDetails } from '../planner-target-details';\n\nexport type Op = SqlMigrationPlanOperation<PostgresPlanTargetDetails>;\n\n/**\n * Literal-args shape for a column definition consumed by `createTable` and\n * `addColumn`. Fully materialized: codec expansion and default rendering have\n * already happened in the wrapper.\n *\n * - `typeSql` is the column's DDL type string (e.g. `\"integer\"`, `\"SERIAL\"`,\n * `\"varchar(100)\"`), already produced by `buildColumnTypeSql` in the\n * call-factory wrapper.\n * - `defaultSql` is the full `DEFAULT …` clause (e.g. `\"DEFAULT 42\"`) or an\n * empty string when the column has no default, matching\n * `buildColumnDefaultSql`'s output.\n */\nexport interface ColumnSpec {\n readonly name: string;\n readonly typeSql: string;\n readonly defaultSql: string;\n readonly nullable: boolean;\n}\n\n/**\n * Literal-args shape for a foreign key definition. The referenced table is\n * assumed to live in the same schema as the constrained table.\n */\nexport interface ForeignKeySpec {\n readonly name: string;\n readonly columns: readonly string[];\n readonly references: {\n readonly table: string;\n readonly columns: readonly string[];\n };\n readonly onDelete?: ReferentialAction;\n readonly onUpdate?: ReferentialAction;\n}\n\nexport function step(description: string, sql: string) {\n return { description, sql };\n}\n\nexport function targetDetails(\n objectType: OperationClass,\n name: string,\n schema: string,\n table?: string,\n): { readonly id: 'postgres'; readonly details: PostgresPlanTargetDetails } {\n return {\n id: 'postgres',\n details: { schema, objectType, name, ...ifDefined('table', table) },\n };\n}\n\nexport function renderColumnDefinition(column: ColumnSpec): string {\n const parts = [\n quoteIdentifier(column.name),\n column.typeSql,\n column.defaultSql,\n column.nullable ? '' : 'NOT NULL',\n ].filter(Boolean);\n return parts.join(' ');\n}\n","import { quoteIdentifier } from '../../sql-utils';\nimport {\n columnDefaultExistsCheck,\n columnExistsCheck,\n columnNullabilityCheck,\n columnTypeCheck,\n qualifyTableName,\n} from '../planner-sql-checks';\nimport { type ColumnSpec, type Op, step, targetDetails } from './shared';\n\nexport function addColumn(schemaName: string, tableName: string, column: ColumnSpec): Op {\n const qualified = qualifyTableName(schemaName, tableName);\n const parts = [\n `ALTER TABLE ${qualified}`,\n `ADD COLUMN ${quoteIdentifier(column.name)} ${column.typeSql}`,\n column.defaultSql,\n column.nullable ? '' : 'NOT NULL',\n ].filter(Boolean);\n const addSql = parts.join(' ');\n\n return {\n id: `column.${tableName}.${column.name}`,\n label: `Add column \"${column.name}\" to \"${tableName}\"`,\n operationClass: 'additive',\n target: targetDetails('column', column.name, schemaName, tableName),\n precheck: [\n step(\n `ensure column \"${column.name}\" is missing`,\n columnExistsCheck({\n schema: schemaName,\n table: tableName,\n column: column.name,\n exists: false,\n }),\n ),\n ],\n execute: [step(`add column \"${column.name}\"`, addSql)],\n postcheck: [\n step(\n `verify column \"${column.name}\" exists`,\n columnExistsCheck({ schema: schemaName, table: tableName, column: column.name }),\n ),\n ],\n };\n}\n\nexport function dropColumn(schemaName: string, tableName: string, columnName: string): Op {\n const qualified = qualifyTableName(schemaName, tableName);\n return {\n id: `dropColumn.${tableName}.${columnName}`,\n label: `Drop column \"${columnName}\" from \"${tableName}\"`,\n operationClass: 'destructive',\n target: targetDetails('column', columnName, schemaName, tableName),\n precheck: [\n step(\n `ensure column \"${columnName}\" exists`,\n columnExistsCheck({ schema: schemaName, table: tableName, column: columnName }),\n ),\n ],\n execute: [\n step(\n `drop column \"${columnName}\"`,\n `ALTER TABLE ${qualified} DROP COLUMN ${quoteIdentifier(columnName)}`,\n ),\n ],\n postcheck: [\n step(\n `verify column \"${columnName}\" does not exist`,\n columnExistsCheck({\n schema: schemaName,\n table: tableName,\n column: columnName,\n exists: false,\n }),\n ),\n ],\n };\n}\n\n/**\n * `qualifiedTargetType` is the new column type as it appears in the\n * `ALTER COLUMN TYPE` clause (schema-qualified for user-defined types, raw\n * native name for built-ins). `formatTypeExpected` is the unqualified\n * `format_type` form used in the postcheck. `rawTargetTypeForLabel` is the\n * string appearing in the human-readable label (typically `toType` when\n * explicit, else the column's native type).\n */\nexport function alterColumnType(\n schemaName: string,\n tableName: string,\n columnName: string,\n options: {\n readonly qualifiedTargetType: string;\n readonly formatTypeExpected: string;\n readonly rawTargetTypeForLabel: string;\n readonly using?: string;\n },\n): Op {\n const qualified = qualifyTableName(schemaName, tableName);\n const usingClause = options.using\n ? ` USING ${options.using}`\n : ` USING ${quoteIdentifier(columnName)}::${options.qualifiedTargetType}`;\n return {\n id: `alterType.${tableName}.${columnName}`,\n label: `Alter type of \"${tableName}\".\"${columnName}\" to ${options.rawTargetTypeForLabel}`,\n operationClass: 'destructive',\n target: targetDetails('column', columnName, schemaName, tableName),\n precheck: [\n step(\n `ensure column \"${columnName}\" exists`,\n columnExistsCheck({ schema: schemaName, table: tableName, column: columnName }),\n ),\n ],\n execute: [\n step(\n `alter type of \"${columnName}\"`,\n `ALTER TABLE ${qualified} ALTER COLUMN ${quoteIdentifier(columnName)} TYPE ${options.qualifiedTargetType}${usingClause}`,\n ),\n ],\n postcheck: [\n step(\n `verify column \"${columnName}\" has type \"${options.formatTypeExpected}\"`,\n columnTypeCheck({\n schema: schemaName,\n table: tableName,\n column: columnName,\n expectedType: options.formatTypeExpected,\n }),\n ),\n ],\n meta: { warning: 'TABLE_REWRITE' },\n };\n}\n\nexport function setNotNull(schemaName: string, tableName: string, columnName: string): Op {\n const qualified = qualifyTableName(schemaName, tableName);\n return {\n id: `alterNullability.setNotNull.${tableName}.${columnName}`,\n label: `Set NOT NULL on \"${tableName}\".\"${columnName}\"`,\n operationClass: 'destructive',\n target: targetDetails('column', columnName, schemaName, tableName),\n precheck: [\n step(\n `ensure column \"${columnName}\" exists`,\n columnExistsCheck({ schema: schemaName, table: tableName, column: columnName }),\n ),\n step(\n `ensure no NULL values in \"${columnName}\"`,\n `SELECT NOT EXISTS (SELECT 1 FROM ${qualified} WHERE ${quoteIdentifier(columnName)} IS NULL)`,\n ),\n ],\n execute: [\n step(\n `set NOT NULL on \"${columnName}\"`,\n `ALTER TABLE ${qualified} ALTER COLUMN ${quoteIdentifier(columnName)} SET NOT NULL`,\n ),\n ],\n postcheck: [\n step(\n `verify column \"${columnName}\" is NOT NULL`,\n columnNullabilityCheck({\n schema: schemaName,\n table: tableName,\n column: columnName,\n nullable: false,\n }),\n ),\n ],\n };\n}\n\nexport function dropNotNull(schemaName: string, tableName: string, columnName: string): Op {\n const qualified = qualifyTableName(schemaName, tableName);\n return {\n id: `alterNullability.dropNotNull.${tableName}.${columnName}`,\n label: `Drop NOT NULL on \"${tableName}\".\"${columnName}\"`,\n operationClass: 'widening',\n target: targetDetails('column', columnName, schemaName, tableName),\n precheck: [\n step(\n `ensure column \"${columnName}\" exists`,\n columnExistsCheck({ schema: schemaName, table: tableName, column: columnName }),\n ),\n ],\n execute: [\n step(\n `drop NOT NULL on \"${columnName}\"`,\n `ALTER TABLE ${qualified} ALTER COLUMN ${quoteIdentifier(columnName)} DROP NOT NULL`,\n ),\n ],\n postcheck: [\n step(\n `verify column \"${columnName}\" is nullable`,\n columnNullabilityCheck({\n schema: schemaName,\n table: tableName,\n column: columnName,\n nullable: true,\n }),\n ),\n ],\n };\n}\n\n/**\n * `defaultSql` is the full `DEFAULT …` clause as produced by\n * `buildColumnDefaultSql` — e.g. `\"DEFAULT 42\"`,\n * `\"DEFAULT (CURRENT_TIMESTAMP)\"`, or `\"DEFAULT nextval('seq'::regclass)\"`.\n *\n * `operationClass` defaults to `'additive'` (setting a default on a column\n * that currently has none). The reconciliation planner passes `'widening'`\n * when the column already has a different default — policy enforcement\n * treats that as a widening change rather than an additive one.\n */\nexport function setDefault(\n schemaName: string,\n tableName: string,\n columnName: string,\n defaultSql: string,\n operationClass: 'additive' | 'widening' = 'additive',\n): Op {\n const qualified = qualifyTableName(schemaName, tableName);\n return {\n id: `setDefault.${tableName}.${columnName}`,\n label: `Set default on \"${tableName}\".\"${columnName}\"`,\n operationClass,\n target: targetDetails('column', columnName, schemaName, tableName),\n precheck: [\n step(\n `ensure column \"${columnName}\" exists`,\n columnExistsCheck({ schema: schemaName, table: tableName, column: columnName }),\n ),\n ],\n execute: [\n step(\n `set default on \"${columnName}\"`,\n `ALTER TABLE ${qualified} ALTER COLUMN ${quoteIdentifier(columnName)} SET ${defaultSql}`,\n ),\n ],\n postcheck: [\n step(\n `verify column \"${columnName}\" has a default`,\n columnDefaultExistsCheck({\n schema: schemaName,\n table: tableName,\n column: columnName,\n exists: true,\n }),\n ),\n ],\n };\n}\n\nexport function dropDefault(schemaName: string, tableName: string, columnName: string): Op {\n const qualified = qualifyTableName(schemaName, tableName);\n return {\n id: `dropDefault.${tableName}.${columnName}`,\n label: `Drop default on \"${tableName}\".\"${columnName}\"`,\n operationClass: 'destructive',\n target: targetDetails('column', columnName, schemaName, tableName),\n precheck: [\n step(\n `ensure column \"${columnName}\" exists`,\n columnExistsCheck({ schema: schemaName, table: tableName, column: columnName }),\n ),\n ],\n execute: [\n step(\n `drop default on \"${columnName}\"`,\n `ALTER TABLE ${qualified} ALTER COLUMN ${quoteIdentifier(columnName)} DROP DEFAULT`,\n ),\n ],\n postcheck: [\n step(\n `verify column \"${columnName}\" has no default`,\n columnDefaultExistsCheck({\n schema: schemaName,\n table: tableName,\n column: columnName,\n exists: false,\n }),\n ),\n ],\n };\n}\n","import type { ReferentialAction } from '@prisma-next/sql-contract/types';\nimport { quoteIdentifier } from '../../sql-utils';\nimport { constraintExistsCheck, qualifyTableName } from '../planner-sql-checks';\nimport { type ForeignKeySpec, type Op, step, targetDetails } from './shared';\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\nfunction renderForeignKeySql(schemaName: string, tableName: string, fk: ForeignKeySpec): string {\n let sql = `ALTER TABLE ${qualifyTableName(schemaName, tableName)}\nADD CONSTRAINT ${quoteIdentifier(fk.name)}\nFOREIGN KEY (${fk.columns.map(quoteIdentifier).join(', ')})\nREFERENCES ${qualifyTableName(schemaName, fk.references.table)} (${fk.references.columns\n .map(quoteIdentifier)\n .join(', ')})`;\n\n if (fk.onDelete !== undefined) {\n const action = REFERENTIAL_ACTION_SQL[fk.onDelete];\n if (!action) {\n throw new Error(`Unknown referential action for onDelete: ${String(fk.onDelete)}`);\n }\n sql += `\\nON DELETE ${action}`;\n }\n if (fk.onUpdate !== undefined) {\n const action = REFERENTIAL_ACTION_SQL[fk.onUpdate];\n if (!action) {\n throw new Error(`Unknown referential action for onUpdate: ${String(fk.onUpdate)}`);\n }\n sql += `\\nON UPDATE ${action}`;\n }\n return sql;\n}\n\nexport function addPrimaryKey(\n schemaName: string,\n tableName: string,\n constraintName: string,\n columns: readonly string[],\n): Op {\n const qualified = qualifyTableName(schemaName, tableName);\n const columnList = columns.map(quoteIdentifier).join(', ');\n return {\n id: `primaryKey.${tableName}.${constraintName}`,\n label: `Add primary key on \"${tableName}\"`,\n operationClass: 'additive',\n target: targetDetails('primaryKey', constraintName, schemaName, tableName),\n precheck: [\n step(\n `ensure primary key \"${constraintName}\" does not exist`,\n constraintExistsCheck({\n constraintName,\n schema: schemaName,\n table: tableName,\n exists: false,\n }),\n ),\n ],\n execute: [\n step(\n `add primary key \"${constraintName}\"`,\n `ALTER TABLE ${qualified} ADD CONSTRAINT ${quoteIdentifier(constraintName)} PRIMARY KEY (${columnList})`,\n ),\n ],\n postcheck: [\n step(\n `verify primary key \"${constraintName}\" exists`,\n constraintExistsCheck({ constraintName, schema: schemaName, table: tableName }),\n ),\n ],\n };\n}\n\nexport function addUnique(\n schemaName: string,\n tableName: string,\n constraintName: string,\n columns: readonly string[],\n): Op {\n const qualified = qualifyTableName(schemaName, tableName);\n const columnList = columns.map(quoteIdentifier).join(', ');\n return {\n id: `unique.${tableName}.${constraintName}`,\n label: `Add unique constraint on \"${tableName}\" (${columns.join(', ')})`,\n operationClass: 'additive',\n target: targetDetails('unique', constraintName, schemaName, tableName),\n precheck: [\n step(\n `ensure constraint \"${constraintName}\" does not exist`,\n constraintExistsCheck({\n constraintName,\n schema: schemaName,\n table: tableName,\n exists: false,\n }),\n ),\n ],\n execute: [\n step(\n `add unique constraint \"${constraintName}\"`,\n `ALTER TABLE ${qualified} ADD CONSTRAINT ${quoteIdentifier(constraintName)} UNIQUE (${columnList})`,\n ),\n ],\n postcheck: [\n step(\n `verify constraint \"${constraintName}\" exists`,\n constraintExistsCheck({ constraintName, schema: schemaName, table: tableName }),\n ),\n ],\n };\n}\n\nexport function addForeignKey(schemaName: string, tableName: string, fk: ForeignKeySpec): Op {\n return {\n id: `foreignKey.${tableName}.${fk.name}`,\n label: `Add foreign key \"${fk.name}\" on \"${tableName}\"`,\n operationClass: 'additive',\n target: targetDetails('foreignKey', fk.name, schemaName, tableName),\n precheck: [\n step(\n `ensure FK \"${fk.name}\" does not exist`,\n constraintExistsCheck({\n constraintName: fk.name,\n schema: schemaName,\n table: tableName,\n exists: false,\n }),\n ),\n ],\n execute: [step(`add FK \"${fk.name}\"`, renderForeignKeySql(schemaName, tableName, fk))],\n postcheck: [\n step(\n `verify FK \"${fk.name}\" exists`,\n constraintExistsCheck({\n constraintName: fk.name,\n schema: schemaName,\n table: tableName,\n }),\n ),\n ],\n };\n}\n\n/**\n * `kind` feeds the operation's `target.details.objectType`. Descriptor-flow\n * does not carry kind information in its drop-constraint descriptor, so the\n * default is `'unique'`. The reconciliation planner passes the correct kind\n * (`'foreignKey'`, `'primaryKey'`, or `'unique'`) based on the `SchemaIssue`\n * that produced the drop.\n */\nexport function dropConstraint(\n schemaName: string,\n tableName: string,\n constraintName: string,\n kind: 'foreignKey' | 'unique' | 'primaryKey' = 'unique',\n): Op {\n const qualified = qualifyTableName(schemaName, tableName);\n return {\n id: `dropConstraint.${tableName}.${constraintName}`,\n label: `Drop constraint \"${constraintName}\" on \"${tableName}\"`,\n operationClass: 'destructive',\n target: targetDetails(kind, constraintName, schemaName, tableName),\n precheck: [\n step(\n `ensure constraint \"${constraintName}\" exists`,\n constraintExistsCheck({ constraintName, schema: schemaName, table: tableName }),\n ),\n ],\n execute: [\n step(\n `drop constraint \"${constraintName}\"`,\n `ALTER TABLE ${qualified} DROP CONSTRAINT ${quoteIdentifier(constraintName)}`,\n ),\n ],\n postcheck: [\n step(\n `verify constraint \"${constraintName}\" does not exist`,\n constraintExistsCheck({\n constraintName,\n schema: schemaName,\n table: tableName,\n exists: false,\n }),\n ),\n ],\n };\n}\n","import { quoteIdentifier } from '../../sql-utils';\nimport { type Op, step } from './shared';\n\nexport function createExtension(extensionName: string): Op {\n return {\n id: `extension.${extensionName}`,\n label: `Create extension \"${extensionName}\"`,\n operationClass: 'additive',\n target: { id: 'postgres' },\n precheck: [],\n execute: [\n step(\n `Create extension \"${extensionName}\"`,\n `CREATE EXTENSION IF NOT EXISTS ${quoteIdentifier(extensionName)}`,\n ),\n ],\n postcheck: [],\n };\n}\n\n/**\n * Install a Postgres extension as the baseline op for an extension-pack\n * contract space. Layered on top of {@link createExtension}: stamps an\n * `invariantId` (required so the per-space marker records the install),\n * scopes the op `id` under a caller-chosen namespace (e.g. `pgvector.`),\n * and emits pre- and postcheck SQL probing `pg_extension`. The richer\n * shape lets the runner's idempotency probe skip the install on re-run\n * (postcheck-pre-satisfied) without firing the precheck.\n *\n * Use this for hand-rolled baseline migrations in contract-space\n * extension packages (e.g. `extension-pgvector`, `extension-paradedb`);\n * use the bare {@link createExtension} for planner-emitted ops where the\n * caller already controls idempotency through the surrounding plan.\n */\nexport function installExtension(options: {\n readonly extensionName: string;\n readonly invariantId: string;\n readonly id: string;\n readonly label?: string;\n}): Op {\n const { extensionName, invariantId, id } = options;\n const label = options.label ?? `Enable extension \"${extensionName}\"`;\n return {\n id,\n label,\n operationClass: 'additive',\n invariantId,\n target: {\n id: 'postgres',\n details: { schema: 'public', objectType: 'dependency', name: extensionName },\n },\n precheck: [\n step(\n `verify extension \"${extensionName}\" is not already enabled`,\n `SELECT NOT EXISTS (SELECT 1 FROM pg_extension WHERE extname = '${extensionName}')`,\n ),\n ],\n execute: [\n step(\n `create extension \"${extensionName}\"`,\n `CREATE EXTENSION IF NOT EXISTS ${extensionName}`,\n ),\n ],\n postcheck: [\n step(\n `confirm extension \"${extensionName}\" is enabled`,\n `SELECT EXISTS (SELECT 1 FROM pg_extension WHERE extname = '${extensionName}')`,\n ),\n ],\n };\n}\n\nexport function createSchema(schemaName: string): Op {\n return {\n id: `schema.${schemaName}`,\n label: `Create schema \"${schemaName}\"`,\n operationClass: 'additive',\n target: { id: 'postgres' },\n precheck: [],\n execute: [\n step(\n `Create schema \"${schemaName}\"`,\n `CREATE SCHEMA IF NOT EXISTS ${quoteIdentifier(schemaName)}`,\n ),\n ],\n postcheck: [],\n };\n}\n","import { escapeLiteral, qualifyName, quoteIdentifier } from '../../sql-utils';\nimport { type Op, step, targetDetails } from './shared';\n\nfunction enumTypeExistsCheck(schemaName: string, nativeType: string, exists = true): string {\n const clause = exists ? 'EXISTS' : 'NOT EXISTS';\n return `SELECT ${clause} (\n SELECT 1\n FROM pg_type t\n JOIN pg_namespace n ON t.typnamespace = n.oid\n WHERE n.nspname = '${escapeLiteral(schemaName)}'\n AND t.typname = '${escapeLiteral(nativeType)}'\n)`;\n}\n\nexport function createEnumType(\n schemaName: string,\n typeName: string,\n values: readonly string[],\n nativeType: string = typeName,\n): Op {\n const qualifiedType = qualifyName(schemaName, nativeType);\n const literalValues = values.map((v) => `'${escapeLiteral(v)}'`).join(', ');\n return {\n id: `type.${typeName}`,\n label: `Create enum type \"${typeName}\"`,\n operationClass: 'additive',\n target: targetDetails('type', typeName, schemaName),\n precheck: [\n step(\n `ensure type \"${nativeType}\" does not exist`,\n enumTypeExistsCheck(schemaName, nativeType, false),\n ),\n ],\n execute: [\n step(\n `create enum type \"${typeName}\"`,\n `CREATE TYPE ${qualifiedType} AS ENUM (${literalValues})`,\n ),\n ],\n postcheck: [\n step(`verify type \"${nativeType}\" exists`, enumTypeExistsCheck(schemaName, nativeType)),\n ],\n };\n}\n\n/**\n * `typeName` is the contract-facing type name (used for id/label).\n * `nativeType` is the Postgres type name to mutate (may differ for external types).\n */\nexport function addEnumValues(\n schemaName: string,\n typeName: string,\n nativeType: string,\n values: readonly string[],\n): Op {\n const qualifiedType = qualifyName(schemaName, nativeType);\n return {\n id: `type.${typeName}.addValues`,\n label: `Add values to enum type \"${typeName}\": ${values.join(', ')}`,\n operationClass: 'additive',\n target: targetDetails('type', typeName, schemaName),\n precheck: [\n step(`ensure type \"${nativeType}\" exists`, enumTypeExistsCheck(schemaName, nativeType)),\n ],\n execute: values.map((value) =>\n step(\n `add value '${value}' to enum \"${nativeType}\"`,\n `ALTER TYPE ${qualifiedType} ADD VALUE '${escapeLiteral(value)}'`,\n ),\n ),\n postcheck: [\n step(`verify type \"${nativeType}\" exists`, enumTypeExistsCheck(schemaName, nativeType)),\n ],\n };\n}\n\nexport function dropEnumType(schemaName: string, typeName: string): Op {\n const qualified = qualifyName(schemaName, typeName);\n return {\n id: `type.${typeName}.drop`,\n label: `Drop enum type \"${typeName}\"`,\n operationClass: 'destructive',\n target: targetDetails('type', typeName, schemaName),\n precheck: [step(`ensure type \"${typeName}\" exists`, enumTypeExistsCheck(schemaName, typeName))],\n execute: [step(`drop enum type \"${typeName}\"`, `DROP TYPE ${qualified}`)],\n postcheck: [\n step(`verify type \"${typeName}\" removed`, enumTypeExistsCheck(schemaName, typeName, false)),\n ],\n };\n}\n\nexport function renameType(schemaName: string, fromName: string, toName: string): Op {\n const qualifiedFrom = qualifyName(schemaName, fromName);\n return {\n id: `type.${fromName}.rename`,\n label: `Rename type \"${fromName}\" to \"${toName}\"`,\n operationClass: 'destructive',\n target: targetDetails('type', fromName, schemaName),\n precheck: [\n step(`ensure type \"${fromName}\" exists`, enumTypeExistsCheck(schemaName, fromName)),\n step(\n `ensure type \"${toName}\" does not already exist`,\n enumTypeExistsCheck(schemaName, toName, false),\n ),\n ],\n execute: [\n step(\n `rename type \"${fromName}\" to \"${toName}\"`,\n `ALTER TYPE ${qualifiedFrom} RENAME TO ${quoteIdentifier(toName)}`,\n ),\n ],\n postcheck: [step(`verify type \"${toName}\" exists`, enumTypeExistsCheck(schemaName, toName))],\n };\n}\n","import { escapeLiteral, quoteIdentifier } from '../../sql-utils';\nimport { qualifyTableName, toRegclassLiteral } from '../planner-sql-checks';\nimport { type Op, step, targetDetails } from './shared';\n\nexport interface CreateIndexExtras {\n readonly type?: string;\n readonly options?: Record<string, unknown>;\n}\n\nfunction renderIndexOptionValue(key: string, value: unknown): string {\n if (typeof value === 'string') return `'${escapeLiteral(value)}'`;\n if (typeof value === 'number' && Number.isFinite(value)) return String(value);\n if (typeof value === 'boolean') return value ? 'true' : 'false';\n throw new Error(\n `Index option \"${key}\" must be a string, finite number, or boolean; got ${typeof value}`,\n );\n}\n\nfunction renderIndexOptions(options: Record<string, unknown>): string {\n return Object.entries(options)\n .map(([key, value]) => `${quoteIdentifier(key)} = ${renderIndexOptionValue(key, value)}`)\n .join(', ');\n}\n\nexport function createIndex(\n schemaName: string,\n tableName: string,\n indexName: string,\n columns: readonly string[],\n extras?: CreateIndexExtras,\n): Op {\n const qualified = qualifyTableName(schemaName, tableName);\n const columnList = columns.map(quoteIdentifier).join(', ');\n const using = extras?.type ? ` USING ${quoteIdentifier(extras.type)}` : '';\n const options = extras?.options;\n const withClause =\n options && Object.keys(options).length > 0 ? ` WITH (${renderIndexOptions(options)})` : '';\n return {\n id: `index.${tableName}.${indexName}`,\n label: `Create index \"${indexName}\" on \"${tableName}\"`,\n operationClass: 'additive',\n target: targetDetails('index', indexName, schemaName, tableName),\n precheck: [\n step(\n `ensure index \"${indexName}\" does not exist`,\n `SELECT to_regclass(${toRegclassLiteral(schemaName, indexName)}) IS NULL`,\n ),\n ],\n execute: [\n step(\n `create index \"${indexName}\"`,\n `CREATE INDEX ${quoteIdentifier(indexName)} ON ${qualified}${using} (${columnList})${withClause}`,\n ),\n ],\n postcheck: [\n step(\n `verify index \"${indexName}\" exists`,\n `SELECT to_regclass(${toRegclassLiteral(schemaName, indexName)}) IS NOT NULL`,\n ),\n ],\n };\n}\n\nexport function dropIndex(schemaName: string, tableName: string, indexName: string): Op {\n return {\n id: `dropIndex.${tableName}.${indexName}`,\n label: `Drop index \"${indexName}\"`,\n operationClass: 'destructive',\n target: targetDetails('index', indexName, schemaName, tableName),\n precheck: [\n step(\n `ensure index \"${indexName}\" exists`,\n `SELECT to_regclass(${toRegclassLiteral(schemaName, indexName)}) IS NOT NULL`,\n ),\n ],\n execute: [\n step(`drop index \"${indexName}\"`, `DROP INDEX ${qualifyTableName(schemaName, indexName)}`),\n ],\n postcheck: [\n step(\n `verify index \"${indexName}\" does not exist`,\n `SELECT to_regclass(${toRegclassLiteral(schemaName, indexName)}) IS NULL`,\n ),\n ],\n };\n}\n","import { quoteIdentifier } from '../../sql-utils';\nimport { qualifyTableName, toRegclassLiteral } from '../planner-sql-checks';\nimport { type ColumnSpec, type Op, renderColumnDefinition, step, targetDetails } from './shared';\n\nexport function createTable(\n schemaName: string,\n tableName: string,\n columns: ReadonlyArray<ColumnSpec>,\n primaryKey?: { readonly columns: readonly string[] },\n): Op {\n const qualified = qualifyTableName(schemaName, tableName);\n const columnDefs = columns.map(renderColumnDefinition);\n const constraintDefs: string[] = [];\n if (primaryKey) {\n constraintDefs.push(`PRIMARY KEY (${primaryKey.columns.map(quoteIdentifier).join(', ')})`);\n }\n const allDefs = [...columnDefs, ...constraintDefs];\n const createSql = `CREATE TABLE ${qualified} (\\n ${allDefs.join(',\\n ')}\\n)`;\n\n return {\n id: `table.${tableName}`,\n label: `Create table \"${tableName}\"`,\n summary: `Creates table \"${tableName}\"`,\n operationClass: 'additive',\n target: targetDetails('table', tableName, schemaName),\n precheck: [\n step(\n `ensure table \"${tableName}\" does not exist`,\n `SELECT to_regclass(${toRegclassLiteral(schemaName, tableName)}) IS NULL`,\n ),\n ],\n execute: [step(`create table \"${tableName}\"`, createSql)],\n postcheck: [\n step(\n `verify table \"${tableName}\" exists`,\n `SELECT to_regclass(${toRegclassLiteral(schemaName, tableName)}) IS NOT NULL`,\n ),\n ],\n };\n}\n\nexport function dropTable(schemaName: string, tableName: string): Op {\n const qualified = qualifyTableName(schemaName, tableName);\n return {\n id: `dropTable.${tableName}`,\n label: `Drop table \"${tableName}\"`,\n operationClass: 'destructive',\n target: targetDetails('table', tableName, schemaName),\n precheck: [\n step(\n `ensure table \"${tableName}\" exists`,\n `SELECT to_regclass(${toRegclassLiteral(schemaName, tableName)}) IS NOT NULL`,\n ),\n ],\n execute: [step(`drop table \"${tableName}\"`, `DROP TABLE ${qualified}`)],\n postcheck: [\n step(\n `verify table \"${tableName}\" does not exist`,\n `SELECT to_regclass(${toRegclassLiteral(schemaName, tableName)}) IS NULL`,\n ),\n ],\n };\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types-Dq74Z3eu.d.mts","names":[],"sources":["../src/core/types.ts"],"mappings":";;;KAEY,qBAAA,GACR,aAAA;EAAA,SACW,IAAA;EAAA,SAA2B,IAAA;AAAA"}
|
package/dist/types.d.mts
CHANGED
|
@@ -1,2 +1,3 @@
|
|
|
1
|
-
import { t as
|
|
2
|
-
|
|
1
|
+
import { n as PostgresEnumTypeInput, t as PostgresEnumType } from "./postgres-enum-type-CrKq8au9.mjs";
|
|
2
|
+
import { t as PostgresColumnDefault } from "./types-Dq74Z3eu.mjs";
|
|
3
|
+
export { type PostgresColumnDefault, PostgresEnumType, type PostgresEnumTypeInput };
|
package/dist/types.mjs
CHANGED
|
@@ -1 +1,2 @@
|
|
|
1
|
-
|
|
1
|
+
import { t as PostgresEnumType } from "./postgres-enum-type-DS-KLVRH.mjs";
|
|
2
|
+
export { PostgresEnumType };
|
package/package.json
CHANGED
|
@@ -1,35 +1,35 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@prisma-next/target-postgres",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.8.0-dev.1",
|
|
4
4
|
"license": "Apache-2.0",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"sideEffects": false,
|
|
7
7
|
"description": "Postgres target pack for Prisma Next",
|
|
8
8
|
"dependencies": {
|
|
9
|
+
"@prisma-next/cli": "0.8.0-dev.1",
|
|
10
|
+
"@prisma-next/contract": "0.8.0-dev.1",
|
|
11
|
+
"@prisma-next/errors": "0.8.0-dev.1",
|
|
12
|
+
"@prisma-next/family-sql": "0.8.0-dev.1",
|
|
13
|
+
"@prisma-next/framework-components": "0.8.0-dev.1",
|
|
14
|
+
"@prisma-next/migration-tools": "0.8.0-dev.1",
|
|
15
|
+
"@prisma-next/ts-render": "0.8.0-dev.1",
|
|
16
|
+
"@prisma-next/sql-contract": "0.8.0-dev.1",
|
|
17
|
+
"@prisma-next/sql-errors": "0.8.0-dev.1",
|
|
18
|
+
"@prisma-next/sql-operations": "0.8.0-dev.1",
|
|
19
|
+
"@prisma-next/sql-relational-core": "0.8.0-dev.1",
|
|
20
|
+
"@prisma-next/sql-schema-ir": "0.8.0-dev.1",
|
|
21
|
+
"@prisma-next/utils": "0.8.0-dev.1",
|
|
9
22
|
"@standard-schema/spec": "^1.1.0",
|
|
10
23
|
"arktype": "^2.1.29",
|
|
11
|
-
"pathe": "^2.0.3"
|
|
12
|
-
"@prisma-next/cli": "0.7.0",
|
|
13
|
-
"@prisma-next/contract": "0.7.0",
|
|
14
|
-
"@prisma-next/errors": "0.7.0",
|
|
15
|
-
"@prisma-next/family-sql": "0.7.0",
|
|
16
|
-
"@prisma-next/framework-components": "0.7.0",
|
|
17
|
-
"@prisma-next/migration-tools": "0.7.0",
|
|
18
|
-
"@prisma-next/ts-render": "0.7.0",
|
|
19
|
-
"@prisma-next/sql-errors": "0.7.0",
|
|
20
|
-
"@prisma-next/sql-contract": "0.7.0",
|
|
21
|
-
"@prisma-next/sql-operations": "0.7.0",
|
|
22
|
-
"@prisma-next/sql-relational-core": "0.7.0",
|
|
23
|
-
"@prisma-next/sql-schema-ir": "0.7.0",
|
|
24
|
-
"@prisma-next/utils": "0.7.0"
|
|
24
|
+
"pathe": "^2.0.3"
|
|
25
25
|
},
|
|
26
26
|
"devDependencies": {
|
|
27
|
+
"@prisma-next/test-utils": "0.8.0-dev.1",
|
|
28
|
+
"@prisma-next/tsconfig": "0.8.0-dev.1",
|
|
29
|
+
"@prisma-next/tsdown": "0.8.0-dev.1",
|
|
27
30
|
"tsdown": "0.22.0",
|
|
28
31
|
"typescript": "5.9.3",
|
|
29
|
-
"vitest": "4.1.5"
|
|
30
|
-
"@prisma-next/test-utils": "0.7.0",
|
|
31
|
-
"@prisma-next/tsconfig": "0.7.0",
|
|
32
|
-
"@prisma-next/tsdown": "0.7.0"
|
|
32
|
+
"vitest": "4.1.5"
|
|
33
33
|
},
|
|
34
34
|
"files": [
|
|
35
35
|
"dist",
|
|
@@ -43,6 +43,7 @@
|
|
|
43
43
|
"./control": "./dist/control.mjs",
|
|
44
44
|
"./data-transform": "./dist/data-transform.mjs",
|
|
45
45
|
"./default-normalizer": "./dist/default-normalizer.mjs",
|
|
46
|
+
"./enum-planning": "./dist/enum-planning.mjs",
|
|
46
47
|
"./errors": "./dist/errors.mjs",
|
|
47
48
|
"./issue-planner": "./dist/issue-planner.mjs",
|
|
48
49
|
"./migration": "./dist/migration.mjs",
|
package/src/core/authoring.ts
CHANGED
|
@@ -1,22 +1,54 @@
|
|
|
1
1
|
import { temporalAuthoringPresets } from '@prisma-next/family-sql/control';
|
|
2
2
|
import type {
|
|
3
|
+
AuthoringEntityTypeNamespace,
|
|
3
4
|
AuthoringFieldNamespace,
|
|
4
5
|
AuthoringTypeNamespace,
|
|
5
6
|
} from '@prisma-next/framework-components/authoring';
|
|
7
|
+
import type { PostgresEnumStorageEntry } from '@prisma-next/sql-contract/types';
|
|
8
|
+
import { PostgresEnumType, type PostgresEnumTypeInput } from './postgres-enum-type';
|
|
6
9
|
|
|
7
|
-
export const postgresAuthoringTypes = {
|
|
10
|
+
export const postgresAuthoringTypes = {} as const satisfies AuthoringTypeNamespace;
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Entity type contributions surface as top-level helpers on the
|
|
14
|
+
* composed-helpers shape (e.g. `helpers.enum({...})`), flattened
|
|
15
|
+
* alongside the built-in `model` / `rel` helpers. Pack contributions
|
|
16
|
+
* still ship via the contribution data structure
|
|
17
|
+
* `authoring.entityTypes.<name>`; the composed-helpers template
|
|
18
|
+
* performs the rename in the type system.
|
|
19
|
+
*
|
|
20
|
+
* `enum` is the first real consumer of the entities-namespace mechanism:
|
|
21
|
+
* the factory constructs a `PostgresEnumType` IR-class instance from
|
|
22
|
+
* the user-supplied input. Both authoring runtimes (TS DSL and PSL)
|
|
23
|
+
* dispatch through this single contribution — PSL `enum Status { … }`
|
|
24
|
+
* declarations are lowered by the interpreter into a factory call
|
|
25
|
+
* with the parsed name + value list; TS DSL `helpers.enum({...})`
|
|
26
|
+
* resolves through the same path. Removing this contribution makes
|
|
27
|
+
* both surfaces fail with a "no entity helper named `enum`" type
|
|
28
|
+
* error at the contract-definition site.
|
|
29
|
+
*/
|
|
30
|
+
/**
|
|
31
|
+
* The factory constructs a `PostgresEnumType` instance natively — the
|
|
32
|
+
* `SqlStorage.types` slot accepts polymorphic IR (the framework
|
|
33
|
+
* `StorageType` alphabet), so no cast is needed at the contribution
|
|
34
|
+
* surface. The declared return type is the structural
|
|
35
|
+
* `PostgresEnumStorageEntry` so the inferred contract type stays
|
|
36
|
+
* portable (it names a type exported from
|
|
37
|
+
* `@prisma-next/sql-contract/types`, a public surface every consumer
|
|
38
|
+
* already imports). Sharpening the inferred contract type to surface
|
|
39
|
+
* enum-specific narrowing through `EntityHelperFunction` is a
|
|
40
|
+
* separable refinement and lives outside this PR.
|
|
41
|
+
*/
|
|
42
|
+
export const postgresAuthoringEntityTypes = {
|
|
8
43
|
enum: {
|
|
9
|
-
kind: '
|
|
10
|
-
|
|
44
|
+
kind: 'entity',
|
|
45
|
+
discriminator: 'postgres-enum',
|
|
11
46
|
output: {
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
typeParams: {
|
|
15
|
-
values: { kind: 'arg', index: 1 },
|
|
16
|
-
},
|
|
47
|
+
factory: (input: PostgresEnumTypeInput): PostgresEnumStorageEntry =>
|
|
48
|
+
new PostgresEnumType(input),
|
|
17
49
|
},
|
|
18
50
|
},
|
|
19
|
-
} as const satisfies
|
|
51
|
+
} as const satisfies AuthoringEntityTypeNamespace;
|
|
20
52
|
|
|
21
53
|
/**
|
|
22
54
|
* Field presets contributed by the Postgres target pack.
|
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
import type { CodecTypes } from '../exports/codec-types';
|
|
2
|
-
import {
|
|
2
|
+
import {
|
|
3
|
+
postgresAuthoringEntityTypes,
|
|
4
|
+
postgresAuthoringFieldPresets,
|
|
5
|
+
postgresAuthoringTypes,
|
|
6
|
+
} from './authoring';
|
|
3
7
|
|
|
4
8
|
const postgresTargetDescriptorMetaBase = {
|
|
5
9
|
kind: 'target',
|
|
@@ -11,6 +15,7 @@ const postgresTargetDescriptorMetaBase = {
|
|
|
11
15
|
authoring: {
|
|
12
16
|
type: postgresAuthoringTypes,
|
|
13
17
|
field: postgresAuthoringFieldPresets,
|
|
18
|
+
entityTypes: postgresAuthoringEntityTypes,
|
|
14
19
|
},
|
|
15
20
|
} as const;
|
|
16
21
|
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pure planning helpers for Postgres enum types: the diff/rebuild logic
|
|
3
|
+
* that the verifier and planner use to walk `PostgresEnumType` instances
|
|
4
|
+
* natively. Op builders live in `./operations/enums.ts`.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { arraysEqual } from '@prisma-next/family-sql/schema-verify';
|
|
8
|
+
import type { SqlSchemaIR } from '@prisma-next/sql-schema-ir/types';
|
|
9
|
+
import { PG_ENUM_CODEC_ID } from '../codec-ids';
|
|
10
|
+
import type { PostgresEnumType } from '../postgres-enum-type';
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Categorisation of how an existing enum type's values relate to the
|
|
14
|
+
* desired set in the contract.
|
|
15
|
+
*/
|
|
16
|
+
export type EnumDiff =
|
|
17
|
+
| { readonly kind: 'unchanged' }
|
|
18
|
+
| { readonly kind: 'add_values'; readonly values: readonly string[] }
|
|
19
|
+
| { readonly kind: 'rebuild'; readonly removedValues: readonly string[] };
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Reads existing enum values for `nativeType` from the
|
|
23
|
+
* Postgres-introspected `schema.annotations.pg.storageTypes` map.
|
|
24
|
+
*
|
|
25
|
+
* Schema IR's `storageTypes` slots are always codec-typed
|
|
26
|
+
* (`{codecId: PG_ENUM_CODEC_ID, typeParams.values}`): the introspector
|
|
27
|
+
* writes that shape, and the Contract→Schema IR projector resolves
|
|
28
|
+
* `PostgresEnumType` instances down to the same codec-typed triple before
|
|
29
|
+
* they ever land in Schema IR. There is no second on-disk shape to
|
|
30
|
+
* accept here.
|
|
31
|
+
*
|
|
32
|
+
* Returns `null` when no enum entry exists for the given native type.
|
|
33
|
+
*/
|
|
34
|
+
export function readExistingEnumValues(
|
|
35
|
+
schema: SqlSchemaIR,
|
|
36
|
+
nativeType: string,
|
|
37
|
+
): readonly string[] | null {
|
|
38
|
+
const storageTypes = (schema.annotations?.['pg'] as Record<string, unknown> | undefined)?.[
|
|
39
|
+
'storageTypes'
|
|
40
|
+
] as
|
|
41
|
+
| Record<
|
|
42
|
+
string,
|
|
43
|
+
{
|
|
44
|
+
codecId?: string;
|
|
45
|
+
typeParams?: { values?: unknown };
|
|
46
|
+
}
|
|
47
|
+
>
|
|
48
|
+
| undefined;
|
|
49
|
+
const existing = storageTypes?.[nativeType];
|
|
50
|
+
if (!existing || existing.codecId !== PG_ENUM_CODEC_ID) {
|
|
51
|
+
return null;
|
|
52
|
+
}
|
|
53
|
+
const enumValues = existing.typeParams?.values;
|
|
54
|
+
if (!Array.isArray(enumValues) || !enumValues.every((v) => typeof v === 'string')) {
|
|
55
|
+
return null;
|
|
56
|
+
}
|
|
57
|
+
return enumValues as readonly string[];
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Determines what changes are needed to transform existing enum values to
|
|
62
|
+
* desired values.
|
|
63
|
+
*
|
|
64
|
+
* Postgres enums can only have values added (not removed or reordered)
|
|
65
|
+
* without a full type rebuild involving temp type creation and column
|
|
66
|
+
* migration; `'rebuild'` covers the value-removal and reorder cases.
|
|
67
|
+
*/
|
|
68
|
+
export function determineEnumDiff(
|
|
69
|
+
existing: readonly string[],
|
|
70
|
+
desired: readonly string[],
|
|
71
|
+
): EnumDiff {
|
|
72
|
+
if (arraysEqual(existing, desired)) {
|
|
73
|
+
return { kind: 'unchanged' };
|
|
74
|
+
}
|
|
75
|
+
const existingSet = new Set(existing);
|
|
76
|
+
const desiredSet = new Set(desired);
|
|
77
|
+
const missingValues = desired.filter((value) => !existingSet.has(value));
|
|
78
|
+
const removedValues = existing.filter((value) => !desiredSet.has(value));
|
|
79
|
+
const orderMismatch =
|
|
80
|
+
missingValues.length === 0 && removedValues.length === 0 && !arraysEqual(existing, desired);
|
|
81
|
+
if (removedValues.length > 0 || orderMismatch) {
|
|
82
|
+
return { kind: 'rebuild', removedValues };
|
|
83
|
+
}
|
|
84
|
+
return { kind: 'add_values', values: missingValues };
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* Convenience accessor — returns the enum's desired values from a
|
|
89
|
+
* `PostgresEnumType` IR instance.
|
|
90
|
+
*/
|
|
91
|
+
export function getDesiredEnumValues(typeInstance: PostgresEnumType): readonly string[] {
|
|
92
|
+
return typeInstance.values;
|
|
93
|
+
}
|
|
@@ -19,6 +19,7 @@ import { arraysEqual } from '@prisma-next/family-sql/schema-verify';
|
|
|
19
19
|
import type { TargetBoundComponentDescriptor } from '@prisma-next/framework-components/components';
|
|
20
20
|
import type { SchemaIssue } from '@prisma-next/framework-components/control';
|
|
21
21
|
import type {
|
|
22
|
+
PostgresEnumStorageEntry,
|
|
22
23
|
SqlStorage,
|
|
23
24
|
StorageColumn,
|
|
24
25
|
StorageTypeInstance,
|
|
@@ -26,6 +27,7 @@ import type {
|
|
|
26
27
|
import type { SqlSchemaIR } from '@prisma-next/sql-schema-ir/types';
|
|
27
28
|
import type { Result } from '@prisma-next/utils/result';
|
|
28
29
|
import { notOk, ok } from '@prisma-next/utils/result';
|
|
30
|
+
import { PostgresEnumType } from '../postgres-enum-type';
|
|
29
31
|
import {
|
|
30
32
|
AddColumnCall,
|
|
31
33
|
AddForeignKeyCall,
|
|
@@ -131,7 +133,7 @@ export interface IssuePlannerOptions {
|
|
|
131
133
|
readonly fromContract: Contract<SqlStorage> | null;
|
|
132
134
|
readonly schemaName: string;
|
|
133
135
|
readonly codecHooks: ReadonlyMap<string, CodecControlHooks>;
|
|
134
|
-
readonly storageTypes: Readonly<Record<string, StorageTypeInstance>>;
|
|
136
|
+
readonly storageTypes: Readonly<Record<string, StorageTypeInstance | PostgresEnumStorageEntry>>;
|
|
135
137
|
/**
|
|
136
138
|
* Current database schema IR. Strategies read this to detect whether a
|
|
137
139
|
* structure already exists (e.g. `buildSchemaLookupMap` for shared-temp-
|
|
@@ -162,14 +164,14 @@ function toColumnSpec(
|
|
|
162
164
|
name: string,
|
|
163
165
|
column: StorageColumn,
|
|
164
166
|
codecHooks: ReadonlyMap<string, CodecControlHooks>,
|
|
165
|
-
storageTypes: Readonly<Record<string, StorageTypeInstance>>,
|
|
167
|
+
storageTypes: Readonly<Record<string, StorageTypeInstance | PostgresEnumStorageEntry>>,
|
|
166
168
|
): ColumnSpec {
|
|
167
169
|
return {
|
|
168
170
|
name,
|
|
169
171
|
typeSql: buildColumnTypeSql(
|
|
170
172
|
column,
|
|
171
173
|
codecHooks as Map<string, CodecControlHooks>,
|
|
172
|
-
storageTypes as Record<string, StorageTypeInstance>,
|
|
174
|
+
storageTypes as Record<string, StorageTypeInstance | PostgresEnumStorageEntry>,
|
|
173
175
|
),
|
|
174
176
|
defaultSql: buildColumnDefaultSql(column.default, column),
|
|
175
177
|
nullable: column.nullable,
|
|
@@ -378,7 +380,10 @@ function mapIssueToCall(
|
|
|
378
380
|
),
|
|
379
381
|
);
|
|
380
382
|
const hooksMap = codecHooks as Map<string, CodecControlHooks>;
|
|
381
|
-
const typesMap = storageTypes as Record<
|
|
383
|
+
const typesMap = storageTypes as Record<
|
|
384
|
+
string,
|
|
385
|
+
StorageTypeInstance | PostgresEnumStorageEntry
|
|
386
|
+
>;
|
|
382
387
|
const qualifiedTargetType = buildColumnTypeSql(column, hooksMap, typesMap, false);
|
|
383
388
|
const formatTypeExpected = buildExpectedFormatType(column, hooksMap, typesMap);
|
|
384
389
|
return ok([
|
|
@@ -515,9 +520,15 @@ function mapIssueToCall(
|
|
|
515
520
|
),
|
|
516
521
|
);
|
|
517
522
|
}
|
|
518
|
-
if (typeInstance
|
|
519
|
-
|
|
520
|
-
|
|
523
|
+
if (typeInstance instanceof PostgresEnumType) {
|
|
524
|
+
return ok([
|
|
525
|
+
new CreateEnumTypeCall(
|
|
526
|
+
schemaName,
|
|
527
|
+
issue.typeName,
|
|
528
|
+
typeInstance.values,
|
|
529
|
+
typeInstance.nativeType,
|
|
530
|
+
),
|
|
531
|
+
]);
|
|
521
532
|
}
|
|
522
533
|
return notOk(
|
|
523
534
|
issueConflict(
|
|
@@ -793,12 +804,13 @@ export function planIssues(
|
|
|
793
804
|
return notOk(conflicts);
|
|
794
805
|
}
|
|
795
806
|
|
|
796
|
-
// Recipe strategies (`
|
|
797
|
-
// etc.) emit a cohesive sequence that must
|
|
798
|
-
// inserted at a single pattern slot. Non-recipe
|
|
799
|
-
// (`dependencyInstallCallStrategy`,
|
|
800
|
-
// `notNullAddColumnCallStrategy`) produce
|
|
801
|
-
// that slot into DDL buckets alongside
|
|
807
|
+
// Recipe strategies (`nativeEnumPlanCallStrategy`,
|
|
808
|
+
// `notNullBackfillCallStrategy`, etc.) emit a cohesive sequence that must
|
|
809
|
+
// stay contiguous. They are inserted at a single pattern slot. Non-recipe
|
|
810
|
+
// pattern strategies (`dependencyInstallCallStrategy`,
|
|
811
|
+
// `storageTypePlanCallStrategy`, `notNullAddColumnCallStrategy`) produce
|
|
812
|
+
// individually classifiable calls that slot into DDL buckets alongside
|
|
813
|
+
// default-mapped calls.
|
|
802
814
|
const combinedBucketable = [...gatedDefault, ...gatedBucketable];
|
|
803
815
|
const byCategory = (cat: CallCategory) =>
|
|
804
816
|
combinedBucketable.filter((c) => classifyCall(c) === cat);
|
|
@@ -589,24 +589,33 @@ export class CreateEnumTypeCall extends PostgresOpFactoryCallNode {
|
|
|
589
589
|
readonly operationClass = 'additive' as const;
|
|
590
590
|
readonly schemaName: string;
|
|
591
591
|
readonly typeName: string;
|
|
592
|
+
readonly nativeType: string;
|
|
592
593
|
readonly values: readonly string[];
|
|
593
594
|
readonly label: string;
|
|
594
595
|
|
|
595
|
-
constructor(
|
|
596
|
+
constructor(
|
|
597
|
+
schemaName: string,
|
|
598
|
+
typeName: string,
|
|
599
|
+
values: readonly string[],
|
|
600
|
+
nativeType: string = typeName,
|
|
601
|
+
) {
|
|
596
602
|
super();
|
|
597
603
|
this.schemaName = schemaName;
|
|
598
604
|
this.typeName = typeName;
|
|
605
|
+
this.nativeType = nativeType;
|
|
599
606
|
this.values = values;
|
|
600
607
|
this.label = `Create enum type "${typeName}"`;
|
|
601
608
|
this.freeze();
|
|
602
609
|
}
|
|
603
610
|
|
|
604
611
|
toOp(): Op {
|
|
605
|
-
return createEnumType(this.schemaName, this.typeName, this.values);
|
|
612
|
+
return createEnumType(this.schemaName, this.typeName, this.values, this.nativeType);
|
|
606
613
|
}
|
|
607
614
|
|
|
608
615
|
renderTypeScript(): string {
|
|
609
|
-
|
|
616
|
+
const nativeArg =
|
|
617
|
+
this.nativeType === this.typeName ? '' : `, ${jsonToTsSource(this.nativeType)}`;
|
|
618
|
+
return `createEnumType(${jsonToTsSource(this.schemaName)}, ${jsonToTsSource(this.typeName)}, ${jsonToTsSource(this.values)}${nativeArg})`;
|
|
610
619
|
}
|
|
611
620
|
}
|
|
612
621
|
|
|
@@ -16,8 +16,9 @@ export function createEnumType(
|
|
|
16
16
|
schemaName: string,
|
|
17
17
|
typeName: string,
|
|
18
18
|
values: readonly string[],
|
|
19
|
+
nativeType: string = typeName,
|
|
19
20
|
): Op {
|
|
20
|
-
const qualifiedType = qualifyName(schemaName,
|
|
21
|
+
const qualifiedType = qualifyName(schemaName, nativeType);
|
|
21
22
|
const literalValues = values.map((v) => `'${escapeLiteral(v)}'`).join(', ');
|
|
22
23
|
return {
|
|
23
24
|
id: `type.${typeName}`,
|
|
@@ -26,8 +27,8 @@ export function createEnumType(
|
|
|
26
27
|
target: targetDetails('type', typeName, schemaName),
|
|
27
28
|
precheck: [
|
|
28
29
|
step(
|
|
29
|
-
`ensure type "${
|
|
30
|
-
enumTypeExistsCheck(schemaName,
|
|
30
|
+
`ensure type "${nativeType}" does not exist`,
|
|
31
|
+
enumTypeExistsCheck(schemaName, nativeType, false),
|
|
31
32
|
),
|
|
32
33
|
],
|
|
33
34
|
execute: [
|
|
@@ -37,7 +38,7 @@ export function createEnumType(
|
|
|
37
38
|
),
|
|
38
39
|
],
|
|
39
40
|
postcheck: [
|
|
40
|
-
step(`verify type "${
|
|
41
|
+
step(`verify type "${nativeType}" exists`, enumTypeExistsCheck(schemaName, nativeType)),
|
|
41
42
|
],
|
|
42
43
|
};
|
|
43
44
|
}
|