@prisma-next/target-postgres 0.5.0-dev.6 → 0.5.0-dev.60

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 (81) hide show
  1. package/dist/{codec-ids-CojIXVf9.mjs → codec-ids-ckQX9Kcg.mjs} +3 -2
  2. package/dist/{codec-ids-CojIXVf9.mjs.map → codec-ids-ckQX9Kcg.mjs.map} +1 -1
  3. package/dist/codec-ids.d.mts +2 -1
  4. package/dist/codec-ids.d.mts.map +1 -1
  5. package/dist/codec-ids.mjs +2 -2
  6. package/dist/codec-types.d.mts +1 -1
  7. package/dist/codec-types.mjs +2 -1
  8. package/dist/{codecs-D-F2KJqt.d.mts → codecs-B03dFv94.d.mts} +64 -30
  9. package/dist/codecs-B03dFv94.d.mts.map +1 -0
  10. package/dist/{codecs-BoahtY_Q.mjs → codecs-D0oXyJIH.mjs} +24 -104
  11. package/dist/codecs-D0oXyJIH.mjs.map +1 -0
  12. package/dist/codecs.d.mts +1 -1
  13. package/dist/codecs.mjs +2 -1
  14. package/dist/control.mjs +21 -63
  15. package/dist/control.mjs.map +1 -1
  16. package/dist/{data-transform-VfEGzXWt.mjs → data-transform-Be_i_DBc.mjs} +24 -5
  17. package/dist/data-transform-Be_i_DBc.mjs.map +1 -0
  18. package/dist/data-transform-CrpmG4uJ.d.mts +39 -0
  19. package/dist/data-transform-CrpmG4uJ.d.mts.map +1 -0
  20. package/dist/data-transform.d.mts +1 -1
  21. package/dist/data-transform.mjs +1 -1
  22. package/dist/{descriptor-meta-BVoVtyp-.mjs → descriptor-meta-Ieg1XLOs.mjs} +7 -12
  23. package/dist/descriptor-meta-Ieg1XLOs.mjs.map +1 -0
  24. package/dist/issue-planner.d.mts +1 -1
  25. package/dist/migration.d.mts +2 -2
  26. package/dist/migration.mjs +2 -2
  27. package/dist/op-factory-call-C3bWXKSP.d.mts.map +1 -1
  28. package/dist/pack.d.mts +28 -9
  29. package/dist/pack.d.mts.map +1 -1
  30. package/dist/pack.mjs +1 -1
  31. package/dist/{planner-CLUvVhUN.mjs → planner-Cm-ZLutk.mjs} +6 -6
  32. package/dist/planner-Cm-ZLutk.mjs.map +1 -0
  33. package/dist/{planner-produced-postgres-migration-DSSPq8QS.mjs → planner-produced-postgres-migration-Bi-RWO4-.mjs} +3 -4
  34. package/dist/{planner-produced-postgres-migration-DSSPq8QS.mjs.map → planner-produced-postgres-migration-Bi-RWO4-.mjs.map} +1 -1
  35. package/dist/{planner-produced-postgres-migration-CRRTno6Z.d.mts → planner-produced-postgres-migration-M3EfhWSS.d.mts} +2 -2
  36. package/dist/planner-produced-postgres-migration-M3EfhWSS.d.mts.map +1 -0
  37. package/dist/planner-produced-postgres-migration.d.mts +3 -2
  38. package/dist/planner-produced-postgres-migration.mjs +1 -1
  39. package/dist/planner.d.mts +17 -10
  40. package/dist/planner.d.mts.map +1 -1
  41. package/dist/planner.mjs +1 -1
  42. package/dist/{postgres-migration-BjA3Zmts.d.mts → postgres-migration-BFjbb25b.d.mts} +4 -3
  43. package/dist/postgres-migration-BFjbb25b.d.mts.map +1 -0
  44. package/dist/{postgres-migration-qtmtbONe.mjs → postgres-migration-BS9vQW97.mjs} +2 -2
  45. package/dist/postgres-migration-BS9vQW97.mjs.map +1 -0
  46. package/dist/{render-typescript-1rF_SB4g.mjs → render-typescript-Co3Emwgz.mjs} +1 -2
  47. package/dist/render-typescript-Co3Emwgz.mjs.map +1 -0
  48. package/dist/render-typescript.d.mts +1 -2
  49. package/dist/render-typescript.d.mts.map +1 -1
  50. package/dist/render-typescript.mjs +1 -1
  51. package/dist/runtime.mjs +1 -1
  52. package/dist/{statement-builders-BPnmt6wx.mjs → statement-builders-CHqCtSfe.mjs} +13 -8
  53. package/dist/statement-builders-CHqCtSfe.mjs.map +1 -0
  54. package/dist/statement-builders.d.mts +10 -3
  55. package/dist/statement-builders.d.mts.map +1 -1
  56. package/dist/statement-builders.mjs +2 -2
  57. package/package.json +15 -14
  58. package/src/core/authoring.ts +5 -11
  59. package/src/core/codec-ids.ts +1 -0
  60. package/src/core/codecs.ts +53 -40
  61. package/src/core/migrations/operations/data-transform.ts +86 -21
  62. package/src/core/migrations/planner-produced-postgres-migration.ts +0 -1
  63. package/src/core/migrations/planner.ts +17 -11
  64. package/src/core/migrations/postgres-migration.ts +3 -6
  65. package/src/core/migrations/render-typescript.ts +1 -5
  66. package/src/core/migrations/runner.ts +43 -112
  67. package/src/core/migrations/statement-builders.ts +22 -6
  68. package/src/exports/statement-builders.ts +1 -1
  69. package/dist/codecs-BoahtY_Q.mjs.map +0 -1
  70. package/dist/codecs-D-F2KJqt.d.mts.map +0 -1
  71. package/dist/data-transform-CxFRBIUp.d.mts +0 -32
  72. package/dist/data-transform-CxFRBIUp.d.mts.map +0 -1
  73. package/dist/data-transform-VfEGzXWt.mjs.map +0 -1
  74. package/dist/descriptor-meta-BVoVtyp-.mjs.map +0 -1
  75. package/dist/planner-CLUvVhUN.mjs.map +0 -1
  76. package/dist/planner-produced-postgres-migration-CRRTno6Z.d.mts.map +0 -1
  77. package/dist/postgres-migration-BjA3Zmts.d.mts.map +0 -1
  78. package/dist/postgres-migration-qtmtbONe.mjs.map +0 -1
  79. package/dist/render-typescript-1rF_SB4g.mjs.map +0 -1
  80. package/dist/statement-builders-BPnmt6wx.mjs.map +0 -1
  81. package/src/core/json-schema-type-expression.ts +0 -131
package/dist/control.mjs CHANGED
@@ -1,23 +1,19 @@
1
- import { t as postgresTargetDescriptorMeta } from "./descriptor-meta-BVoVtyp-.mjs";
1
+ import { t as postgresTargetDescriptorMeta } from "./descriptor-meta-Ieg1XLOs.mjs";
2
2
  import { t as parsePostgresDefault } from "./default-normalizer-DNOpRoOF.mjs";
3
3
  import { t as normalizeSchemaNativeType } from "./native-type-normalizer-CInai_oY.mjs";
4
4
  import { o as renderDefaultLiteral } from "./planner-ddl-builders-Dxvw1LHw.mjs";
5
5
  import "./issue-planner-CFjB0_oO.mjs";
6
- import { t as createPostgresMigrationPlanner } from "./planner-CLUvVhUN.mjs";
7
- import { a as ensurePrismaContractSchemaStatement, i as ensureMarkerTableStatement, n as buildWriteMarkerStatements, r as ensureLedgerTableStatement, t as buildLedgerInsertStatement } from "./statement-builders-BPnmt6wx.mjs";
6
+ import { t as createPostgresMigrationPlanner } from "./planner-Cm-ZLutk.mjs";
7
+ import { a as ensurePrismaContractSchemaStatement, i as ensureMarkerTableStatement, n as buildMergeMarkerStatements, r as ensureLedgerTableStatement, t as buildLedgerInsertStatement } from "./statement-builders-CHqCtSfe.mjs";
8
8
  import { ifDefined } from "@prisma-next/utils/defined";
9
9
  import { contractToSchemaIR, extractCodecControlHooks, runnerFailure, runnerSuccess } from "@prisma-next/family-sql/control";
10
10
  import { verifySqlSchema } from "@prisma-next/family-sql/schema-verify";
11
11
  import { ok, okVoid } from "@prisma-next/utils/result";
12
- import { readMarker } from "@prisma-next/family-sql/verify";
13
12
  import { SqlQueryError } from "@prisma-next/sql-errors";
14
13
 
15
14
  //#region src/core/migrations/runner.ts
16
15
  const DEFAULT_CONFIG = { defaultSchema: "public" };
17
16
  const LOCK_DOMAIN = "prisma_next.contract.marker";
18
- function isDataTransformOperation(op) {
19
- return typeof op === "object" && op !== null && "operationClass" in op && op.operationClass === "data" && "name" in op && "check" in op && "run" in op;
20
- }
21
17
  /**
22
18
  * Deep clones and freezes a record object to prevent mutation.
23
19
  * Recursively clones nested objects and arrays to ensure complete isolation.
@@ -54,10 +50,12 @@ var PostgresMigrationRunner = class {
54
50
  try {
55
51
  await this.acquireLock(driver, lockKey);
56
52
  await this.ensureControlTables(driver);
57
- const existingMarker = await readMarker(driver);
53
+ const existingMarker = await this.family.readMarker({ driver });
58
54
  const markerCheck = this.ensureMarkerCompatibility(existingMarker, options.plan);
59
55
  if (!markerCheck.ok) return markerCheck;
60
- const skipOperations = this.markerMatchesDestination(existingMarker, options.plan) && options.plan.origin != null;
56
+ const markerAtDestination = this.markerMatchesDestination(existingMarker, options.plan);
57
+ const isSelfEdge = options.plan.origin?.storageHash === options.plan.destination.storageHash;
58
+ const skipOperations = markerAtDestination && options.plan.origin != null && !isSelfEdge;
61
59
  let applyValue;
62
60
  if (skipOperations) applyValue = {
63
61
  operationsExecuted: 0,
@@ -86,8 +84,13 @@ var PostgresMigrationRunner = class {
86
84
  why: "The resulting database schema does not satisfy the destination contract.",
87
85
  meta: { issues: schemaVerifyResult.schema.issues }
88
86
  });
89
- await this.upsertMarker(driver, options, existingMarker);
90
- await this.recordLedgerEntry(driver, options, existingMarker, applyValue.executedOperations);
87
+ const incomingInvariants = options.plan.providedInvariants ?? [];
88
+ const existingInvariants = new Set(existingMarker?.invariants ?? []);
89
+ const incomingIsSubsetOfExisting = incomingInvariants.every((id) => existingInvariants.has(id));
90
+ if (!(isSelfEdge && applyValue.operationsExecuted === 0 && incomingIsSubsetOfExisting)) {
91
+ await this.upsertMarker(driver, options, existingMarker);
92
+ await this.recordLedgerEntry(driver, options, existingMarker, applyValue.executedOperations);
93
+ }
91
94
  await this.commitTransaction(driver);
92
95
  committed = true;
93
96
  return runnerSuccess({
@@ -108,13 +111,6 @@ var PostgresMigrationRunner = class {
108
111
  for (const operation of options.plan.operations) {
109
112
  options.callbacks?.onOperationStart?.(operation);
110
113
  try {
111
- if (operation.operationClass === "data" && isDataTransformOperation(operation)) {
112
- const dtResult = await this.executeDataTransform(driver, operation, { runIdempotency });
113
- if (!dtResult.ok) return dtResult;
114
- executedOperations.push(operation);
115
- operationsExecuted += 1;
116
- continue;
117
- }
118
114
  if (runPostchecks && runIdempotency) {
119
115
  if (await this.expectationsAreSatisfied(driver, operation.postcheck)) {
120
116
  executedOperations.push(this.createPostcheckPreSatisfiedSkipRecord(operation));
@@ -142,46 +138,6 @@ var PostgresMigrationRunner = class {
142
138
  executedOperations
143
139
  });
144
140
  }
145
- /**
146
- * Executes a data transform operation with the check → (skip or run) → check lifecycle.
147
- *
148
- * 1. If check is a query AST: render to SQL, execute. Empty result = already applied (skip).
149
- * 2. If check is `true`: always skip. If `false`: always run.
150
- * 3. Execute run ASTs (rendered to SQL) sequentially.
151
- * 4. Re-execute check as post-run validation. If violations remain, fail.
152
- */
153
- async executeDataTransform(driver, op, options) {
154
- if (op.check === true) return okVoid();
155
- if (options.runIdempotency && op.check !== null && op.check !== false) {
156
- if ((await driver.query(op.check.sql, op.check.params)).rows.length === 0) return okVoid();
157
- }
158
- if (op.run) for (const plan of op.run) try {
159
- await driver.query(plan.sql, plan.params);
160
- } catch (error) {
161
- if (SqlQueryError.is(error)) return runnerFailure("EXECUTION_FAILED", `Data transform "${op.name}" failed: ${error.message}`, {
162
- why: error.message,
163
- meta: {
164
- operationId: op.id,
165
- dataTransformName: op.name,
166
- sql: plan.sql,
167
- sqlState: error.sqlState
168
- }
169
- });
170
- throw error;
171
- }
172
- if (op.check !== null && op.check !== false) {
173
- const checkResult = await driver.query(op.check.sql, op.check.params);
174
- if (checkResult.rows.length > 0) return runnerFailure("POSTCHECK_FAILED", `Data transform "${op.name}" did not resolve all violations (${checkResult.rows.length} remaining)`, {
175
- why: `After executing the data transform, the check query still returns ${checkResult.rows.length} violation(s).`,
176
- meta: {
177
- operationId: op.id,
178
- dataTransformName: op.name,
179
- remainingViolations: checkResult.rows.length
180
- }
181
- });
182
- }
183
- return okVoid();
184
- }
185
141
  async ensureControlTables(driver) {
186
142
  await this.executeStatement(driver, ensurePrismaContractSchemaStatement);
187
143
  await this.executeStatement(driver, ensureMarkerTableStatement);
@@ -189,7 +145,7 @@ var PostgresMigrationRunner = class {
189
145
  }
190
146
  async runExpectationSteps(driver, steps, operation, phase) {
191
147
  for (const step of steps) {
192
- const result = await driver.query(step.sql);
148
+ const result = await driver.query(step.sql, step.params ?? []);
193
149
  if (!this.stepResultIsTrue(result.rows)) return runnerFailure(phase === "precheck" ? "PRECHECK_FAILED" : "POSTCHECK_FAILED", `Operation ${operation.id} failed during ${phase}: ${step.description}`, { meta: {
194
150
  operationId: operation.id,
195
151
  phase,
@@ -200,7 +156,7 @@ var PostgresMigrationRunner = class {
200
156
  }
201
157
  async runExecuteSteps(driver, steps, operation) {
202
158
  for (const step of steps) try {
203
- await driver.query(step.sql);
159
+ await driver.query(step.sql, step.params ?? []);
204
160
  } catch (error) {
205
161
  if (SqlQueryError.is(error)) return runnerFailure("EXECUTION_FAILED", `Operation ${operation.id} failed during execution: ${step.description}`, {
206
162
  why: error.message,
@@ -236,7 +192,7 @@ var PostgresMigrationRunner = class {
236
192
  async expectationsAreSatisfied(driver, steps) {
237
193
  if (steps.length === 0) return false;
238
194
  for (const step of steps) {
239
- const result = await driver.query(step.sql);
195
+ const result = await driver.query(step.sql, step.params ?? []);
240
196
  if (!this.stepResultIsTrue(result.rows)) return false;
241
197
  }
242
198
  return true;
@@ -308,12 +264,14 @@ var PostgresMigrationRunner = class {
308
264
  return okVoid();
309
265
  }
310
266
  async upsertMarker(driver, options, existingMarker) {
311
- const writeStatements = buildWriteMarkerStatements({
267
+ const incomingInvariants = options.plan.providedInvariants ?? [];
268
+ const writeStatements = buildMergeMarkerStatements({
312
269
  storageHash: options.plan.destination.storageHash,
313
270
  profileHash: options.plan.destination.profileHash ?? options.destinationContract.profileHash ?? options.plan.destination.storageHash,
314
271
  contractJson: options.destinationContract,
315
272
  canonicalVersion: null,
316
- meta: {}
273
+ meta: {},
274
+ invariants: incomingInvariants
317
275
  });
318
276
  const statement = existingMarker ? writeStatements.update : writeStatements.insert;
319
277
  await this.executeStatement(driver, statement);
@@ -1 +1 @@
1
- {"version":3,"file":"control.mjs","names":["DEFAULT_CONFIG: RunnerConfig","cloned: Record<string, unknown>","family: SqlControlFamilyInstance","config: RunnerConfig","applyValue: ApplyPlanSuccessValue","executedOperations: Array<SqlMigrationPlanOperation<PostgresPlanTargetDetails>>","error: unknown","postgresTargetDescriptor: SqlControlTargetDescriptor<'postgres', PostgresPlanTargetDetails>"],"sources":["../src/core/migrations/runner.ts","../src/exports/control.ts"],"sourcesContent":["import type { ContractMarkerRecord } from '@prisma-next/contract/types';\nimport type {\n MigrationOperationPolicy,\n SqlControlFamilyInstance,\n SqlMigrationPlanContractInfo,\n SqlMigrationPlanOperation,\n SqlMigrationPlanOperationStep,\n SqlMigrationRunner,\n SqlMigrationRunnerExecuteOptions,\n SqlMigrationRunnerFailure,\n SqlMigrationRunnerResult,\n} from '@prisma-next/family-sql/control';\nimport { runnerFailure, runnerSuccess } from '@prisma-next/family-sql/control';\nimport { verifySqlSchema } from '@prisma-next/family-sql/schema-verify';\nimport { readMarker } from '@prisma-next/family-sql/verify';\nimport type { DataTransformOperation } from '@prisma-next/framework-components/control';\nimport { SqlQueryError } from '@prisma-next/sql-errors';\nimport { ifDefined } from '@prisma-next/utils/defined';\nimport type { Result } from '@prisma-next/utils/result';\nimport { ok, okVoid } from '@prisma-next/utils/result';\nimport { parsePostgresDefault } from '../default-normalizer';\nimport { normalizeSchemaNativeType } from '../native-type-normalizer';\nimport type { PostgresPlanTargetDetails } from './planner-target-details';\nimport {\n buildLedgerInsertStatement,\n buildWriteMarkerStatements,\n ensureLedgerTableStatement,\n ensureMarkerTableStatement,\n ensurePrismaContractSchemaStatement,\n type SqlStatement,\n} from './statement-builders';\n\ninterface RunnerConfig {\n readonly defaultSchema: string;\n}\n\ninterface ApplyPlanSuccessValue {\n readonly operationsExecuted: number;\n readonly executedOperations: readonly SqlMigrationPlanOperation<PostgresPlanTargetDetails>[];\n}\n\nconst DEFAULT_CONFIG: RunnerConfig = {\n defaultSchema: 'public',\n};\n\nconst LOCK_DOMAIN = 'prisma_next.contract.marker';\n\nfunction isDataTransformOperation(op: unknown): op is DataTransformOperation {\n return (\n typeof op === 'object' &&\n op !== null &&\n 'operationClass' in op &&\n (op as { operationClass: string }).operationClass === 'data' &&\n 'name' in op &&\n 'check' in op &&\n 'run' in op\n );\n}\n\n/**\n * Deep clones and freezes a record object to prevent mutation.\n * Recursively clones nested objects and arrays to ensure complete isolation.\n */\nfunction cloneAndFreezeRecord<T extends Record<string, unknown>>(value: T): T {\n const cloned: Record<string, unknown> = {};\n for (const [key, val] of Object.entries(value)) {\n if (val === null || val === undefined) {\n cloned[key] = val;\n } else if (Array.isArray(val)) {\n // Clone array (shallow clone of array elements)\n cloned[key] = Object.freeze([...val]);\n } else if (typeof val === 'object') {\n // Recursively clone nested objects\n cloned[key] = cloneAndFreezeRecord(val as Record<string, unknown>);\n } else {\n // Primitives are copied as-is\n cloned[key] = val;\n }\n }\n return Object.freeze(cloned) as T;\n}\n\nexport function createPostgresMigrationRunner(\n family: SqlControlFamilyInstance,\n config: Partial<RunnerConfig> = {},\n): SqlMigrationRunner<PostgresPlanTargetDetails> {\n return new PostgresMigrationRunner(family, { ...DEFAULT_CONFIG, ...config });\n}\n\nclass PostgresMigrationRunner implements SqlMigrationRunner<PostgresPlanTargetDetails> {\n constructor(\n private readonly family: SqlControlFamilyInstance,\n private readonly config: RunnerConfig,\n ) {}\n\n async execute(\n options: SqlMigrationRunnerExecuteOptions<PostgresPlanTargetDetails>,\n ): Promise<SqlMigrationRunnerResult> {\n const schema = options.schemaName ?? this.config.defaultSchema;\n const driver = options.driver;\n const lockKey = `${LOCK_DOMAIN}:${schema}`;\n\n // Static checks - fail fast before transaction\n const destinationCheck = this.ensurePlanMatchesDestinationContract(\n options.plan.destination,\n options.destinationContract,\n );\n if (!destinationCheck.ok) {\n return destinationCheck;\n }\n\n const policyCheck = this.enforcePolicyCompatibility(options.policy, options.plan.operations);\n if (!policyCheck.ok) {\n return policyCheck;\n }\n\n // Begin transaction for DB operations\n await this.beginTransaction(driver);\n let committed = false;\n try {\n await this.acquireLock(driver, lockKey);\n await this.ensureControlTables(driver);\n const existingMarker = await readMarker(driver);\n\n // Validate plan origin matches existing marker (needs marker from DB)\n const markerCheck = this.ensureMarkerCompatibility(existingMarker, options.plan);\n if (!markerCheck.ok) {\n return markerCheck;\n }\n\n // db update (origin: null) always applies; migration-apply (origin set) skips if marker matches.\n const markerAtDestination = this.markerMatchesDestination(existingMarker, options.plan);\n const skipOperations = markerAtDestination && options.plan.origin != null;\n let applyValue: ApplyPlanSuccessValue;\n\n if (skipOperations) {\n applyValue = { operationsExecuted: 0, executedOperations: [] };\n } else {\n const applyResult = await this.applyPlan(driver, options);\n if (!applyResult.ok) {\n return applyResult;\n }\n applyValue = applyResult.value;\n }\n\n // Verify resulting schema matches contract\n // Step 1: Introspect live schema (DB I/O, family-owned)\n const schemaIR = await this.family.introspect({\n driver,\n contract: options.destinationContract,\n });\n\n // Step 2: Pure verification (no DB I/O)\n const schemaVerifyResult = verifySqlSchema({\n contract: options.destinationContract,\n schema: schemaIR,\n strict: options.strictVerification ?? true,\n context: options.context ?? {},\n typeMetadataRegistry: this.family.typeMetadataRegistry,\n frameworkComponents: options.frameworkComponents,\n normalizeDefault: parsePostgresDefault,\n normalizeNativeType: normalizeSchemaNativeType,\n });\n if (!schemaVerifyResult.ok) {\n return runnerFailure('SCHEMA_VERIFY_FAILED', schemaVerifyResult.summary, {\n why: 'The resulting database schema does not satisfy the destination contract.',\n meta: {\n issues: schemaVerifyResult.schema.issues,\n },\n });\n }\n\n // Record marker and ledger entries\n await this.upsertMarker(driver, options, existingMarker);\n await this.recordLedgerEntry(driver, options, existingMarker, applyValue.executedOperations);\n\n await this.commitTransaction(driver);\n committed = true;\n return runnerSuccess({\n operationsPlanned: options.plan.operations.length,\n operationsExecuted: applyValue.operationsExecuted,\n });\n } finally {\n if (!committed) {\n await this.rollbackTransaction(driver);\n }\n }\n }\n\n private async applyPlan(\n driver: SqlMigrationRunnerExecuteOptions<PostgresPlanTargetDetails>['driver'],\n options: SqlMigrationRunnerExecuteOptions<PostgresPlanTargetDetails>,\n ): Promise<Result<ApplyPlanSuccessValue, SqlMigrationRunnerFailure>> {\n const checks = options.executionChecks;\n const runPrechecks = checks?.prechecks !== false; // Default true\n const runPostchecks = checks?.postchecks !== false; // Default true\n const runIdempotency = checks?.idempotencyChecks !== false; // Default true\n\n let operationsExecuted = 0;\n const executedOperations: Array<SqlMigrationPlanOperation<PostgresPlanTargetDetails>> = [];\n for (const operation of options.plan.operations) {\n options.callbacks?.onOperationStart?.(operation);\n try {\n // Data transform operations have a different execution lifecycle\n if (operation.operationClass === 'data' && isDataTransformOperation(operation)) {\n const dtResult = await this.executeDataTransform(driver, operation, {\n runIdempotency,\n });\n if (!dtResult.ok) {\n return dtResult;\n }\n executedOperations.push(operation);\n operationsExecuted += 1;\n continue;\n }\n\n // Idempotency probe: only run if both postchecks and idempotency checks are enabled\n if (runPostchecks && runIdempotency) {\n const postcheckAlreadySatisfied = await this.expectationsAreSatisfied(\n driver,\n operation.postcheck,\n );\n if (postcheckAlreadySatisfied) {\n executedOperations.push(this.createPostcheckPreSatisfiedSkipRecord(operation));\n continue;\n }\n }\n\n // Prechecks: only run if enabled\n if (runPrechecks) {\n const precheckResult = await this.runExpectationSteps(\n driver,\n operation.precheck,\n operation,\n 'precheck',\n );\n if (!precheckResult.ok) {\n return precheckResult;\n }\n }\n\n const executeResult = await this.runExecuteSteps(driver, operation.execute, operation);\n if (!executeResult.ok) {\n return executeResult;\n }\n\n // Postchecks: only run if enabled\n if (runPostchecks) {\n const postcheckResult = await this.runExpectationSteps(\n driver,\n operation.postcheck,\n operation,\n 'postcheck',\n );\n if (!postcheckResult.ok) {\n return postcheckResult;\n }\n }\n\n executedOperations.push(operation);\n operationsExecuted += 1;\n } finally {\n options.callbacks?.onOperationComplete?.(operation);\n }\n }\n return ok({ operationsExecuted, executedOperations });\n }\n\n /**\n * Executes a data transform operation with the check → (skip or run) → check lifecycle.\n *\n * 1. If check is a query AST: render to SQL, execute. Empty result = already applied (skip).\n * 2. If check is `true`: always skip. If `false`: always run.\n * 3. Execute run ASTs (rendered to SQL) sequentially.\n * 4. Re-execute check as post-run validation. If violations remain, fail.\n */\n private async executeDataTransform(\n driver: SqlMigrationRunnerExecuteOptions<PostgresPlanTargetDetails>['driver'],\n op: DataTransformOperation,\n options: { runIdempotency: boolean },\n ): Promise<Result<void, SqlMigrationRunnerFailure>> {\n // Step 1: Check (skip guard)\n if (op.check === true) {\n // Always skip, regardless of idempotency setting\n return okVoid();\n }\n if (options.runIdempotency && op.check !== null && op.check !== false) {\n const checkResult = await driver.query(op.check.sql, op.check.params);\n if (checkResult.rows.length === 0) {\n // No violations — already applied, skip\n return okVoid();\n }\n }\n\n // Step 2: Execute run steps\n if (op.run) {\n for (const plan of op.run) {\n try {\n await driver.query(plan.sql, plan.params);\n } catch (error: unknown) {\n if (SqlQueryError.is(error)) {\n return runnerFailure(\n 'EXECUTION_FAILED',\n `Data transform \"${op.name}\" failed: ${error.message}`,\n {\n why: error.message,\n meta: {\n operationId: op.id,\n dataTransformName: op.name,\n sql: plan.sql,\n sqlState: error.sqlState,\n },\n },\n );\n }\n throw error;\n }\n }\n }\n\n // Step 3: Post-run validation (check again)\n if (op.check !== null && op.check !== false) {\n const checkResult = await driver.query(op.check.sql, op.check.params);\n if (checkResult.rows.length > 0) {\n return runnerFailure(\n 'POSTCHECK_FAILED',\n `Data transform \"${op.name}\" did not resolve all violations (${checkResult.rows.length} remaining)`,\n {\n why: `After executing the data transform, the check query still returns ${checkResult.rows.length} violation(s).`,\n meta: {\n operationId: op.id,\n dataTransformName: op.name,\n remainingViolations: checkResult.rows.length,\n },\n },\n );\n }\n }\n\n return okVoid();\n }\n\n private async ensureControlTables(\n driver: SqlMigrationRunnerExecuteOptions<PostgresPlanTargetDetails>['driver'],\n ): Promise<void> {\n await this.executeStatement(driver, ensurePrismaContractSchemaStatement);\n await this.executeStatement(driver, ensureMarkerTableStatement);\n await this.executeStatement(driver, ensureLedgerTableStatement);\n }\n\n private async runExpectationSteps(\n driver: SqlMigrationRunnerExecuteOptions<PostgresPlanTargetDetails>['driver'],\n steps: readonly SqlMigrationPlanOperationStep[],\n operation: SqlMigrationPlanOperation<PostgresPlanTargetDetails>,\n phase: 'precheck' | 'postcheck',\n ): Promise<Result<void, SqlMigrationRunnerFailure>> {\n for (const step of steps) {\n const result = await driver.query(step.sql);\n if (!this.stepResultIsTrue(result.rows)) {\n const code = phase === 'precheck' ? 'PRECHECK_FAILED' : 'POSTCHECK_FAILED';\n return runnerFailure(\n code,\n `Operation ${operation.id} failed during ${phase}: ${step.description}`,\n {\n meta: {\n operationId: operation.id,\n phase,\n stepDescription: step.description,\n },\n },\n );\n }\n }\n return okVoid();\n }\n\n private async runExecuteSteps(\n driver: SqlMigrationRunnerExecuteOptions<PostgresPlanTargetDetails>['driver'],\n steps: readonly SqlMigrationPlanOperationStep[],\n operation: SqlMigrationPlanOperation<PostgresPlanTargetDetails>,\n ): Promise<Result<void, SqlMigrationRunnerFailure>> {\n for (const step of steps) {\n try {\n await driver.query(step.sql);\n } catch (error: unknown) {\n // Catch SqlQueryError and include normalized metadata\n if (SqlQueryError.is(error)) {\n return runnerFailure(\n 'EXECUTION_FAILED',\n `Operation ${operation.id} failed during execution: ${step.description}`,\n {\n why: error.message,\n meta: {\n operationId: operation.id,\n stepDescription: step.description,\n sql: step.sql,\n sqlState: error.sqlState,\n constraint: error.constraint,\n table: error.table,\n column: error.column,\n detail: error.detail,\n },\n },\n );\n }\n // Let SqlConnectionError and other errors propagate (fail-fast)\n throw error;\n }\n }\n return okVoid();\n }\n\n private stepResultIsTrue(rows: readonly Record<string, unknown>[]): boolean {\n if (!rows || rows.length === 0) {\n return false;\n }\n const firstRow = rows[0];\n const firstValue = firstRow ? Object.values(firstRow)[0] : undefined;\n if (typeof firstValue === 'boolean') {\n return firstValue;\n }\n if (typeof firstValue === 'number') {\n return firstValue !== 0;\n }\n if (typeof firstValue === 'string') {\n const lower = firstValue.toLowerCase();\n // PostgreSQL boolean representations: 't'/'f', 'true'/'false', '1'/'0'\n if (lower === 't' || lower === 'true' || lower === '1') {\n return true;\n }\n if (lower === 'f' || lower === 'false' || lower === '0') {\n return false;\n }\n // For other strings, non-empty is truthy (though this case shouldn't occur for boolean checks)\n return firstValue.length > 0;\n }\n return Boolean(firstValue);\n }\n\n private async expectationsAreSatisfied(\n driver: SqlMigrationRunnerExecuteOptions<PostgresPlanTargetDetails>['driver'],\n steps: readonly SqlMigrationPlanOperationStep[],\n ): Promise<boolean> {\n if (steps.length === 0) {\n return false;\n }\n for (const step of steps) {\n const result = await driver.query(step.sql);\n if (!this.stepResultIsTrue(result.rows)) {\n return false;\n }\n }\n return true;\n }\n\n private createPostcheckPreSatisfiedSkipRecord(\n operation: SqlMigrationPlanOperation<PostgresPlanTargetDetails>,\n ): SqlMigrationPlanOperation<PostgresPlanTargetDetails> {\n // Clone and freeze existing meta if present\n const clonedMeta = operation.meta ? cloneAndFreezeRecord(operation.meta) : undefined;\n\n // Create frozen runner metadata\n const runnerMeta = Object.freeze({\n skipped: true,\n reason: 'postcheck_pre_satisfied',\n });\n\n // Merge and freeze the combined meta\n const mergedMeta = Object.freeze({\n ...(clonedMeta ?? {}),\n runner: runnerMeta,\n });\n\n // Clone and freeze arrays to prevent mutation\n const frozenPostcheck = Object.freeze([...operation.postcheck]);\n\n return Object.freeze({\n id: operation.id,\n label: operation.label,\n ...ifDefined('summary', operation.summary),\n operationClass: operation.operationClass,\n target: operation.target, // Already frozen from plan creation\n precheck: Object.freeze([]),\n execute: Object.freeze([]),\n postcheck: frozenPostcheck,\n ...ifDefined('meta', operation.meta || mergedMeta ? mergedMeta : undefined),\n });\n }\n\n private markerMatchesDestination(\n marker: ContractMarkerRecord | null,\n plan: SqlMigrationRunnerExecuteOptions<PostgresPlanTargetDetails>['plan'],\n ): boolean {\n if (!marker) {\n return false;\n }\n if (marker.storageHash !== plan.destination.storageHash) {\n return false;\n }\n if (plan.destination.profileHash && marker.profileHash !== plan.destination.profileHash) {\n return false;\n }\n return true;\n }\n\n private enforcePolicyCompatibility(\n policy: MigrationOperationPolicy,\n operations: readonly SqlMigrationPlanOperation<PostgresPlanTargetDetails>[],\n ): Result<void, SqlMigrationRunnerFailure> {\n const allowedClasses = new Set(policy.allowedOperationClasses);\n for (const operation of operations) {\n if (!allowedClasses.has(operation.operationClass)) {\n return runnerFailure(\n 'POLICY_VIOLATION',\n `Operation ${operation.id} has class \"${operation.operationClass}\" which is not allowed by policy.`,\n {\n why: `Policy only allows: ${policy.allowedOperationClasses.join(', ')}.`,\n meta: {\n operationId: operation.id,\n operationClass: operation.operationClass,\n allowedClasses: policy.allowedOperationClasses,\n },\n },\n );\n }\n }\n return okVoid();\n }\n\n private ensureMarkerCompatibility(\n marker: ContractMarkerRecord | null,\n plan: SqlMigrationRunnerExecuteOptions<PostgresPlanTargetDetails>['plan'],\n ): Result<void, SqlMigrationRunnerFailure> {\n const origin = plan.origin ?? null;\n if (!origin) {\n // No origin assertion on the plan — the caller does not want origin validation.\n // This is the case for `db update`, which introspects the live schema and does not\n // rely on marker continuity. `db init` handles its own marker checks before the runner.\n return okVoid();\n }\n\n if (!marker) {\n return runnerFailure(\n 'MARKER_ORIGIN_MISMATCH',\n `Missing contract marker: expected origin storage hash ${origin.storageHash}.`,\n {\n meta: {\n expectedOriginStorageHash: origin.storageHash,\n },\n },\n );\n }\n if (marker.storageHash !== origin.storageHash) {\n return runnerFailure(\n 'MARKER_ORIGIN_MISMATCH',\n `Existing contract marker (${marker.storageHash}) does not match plan origin (${origin.storageHash}).`,\n {\n meta: {\n markerStorageHash: marker.storageHash,\n expectedOriginStorageHash: origin.storageHash,\n },\n },\n );\n }\n if (origin.profileHash && marker.profileHash !== origin.profileHash) {\n return runnerFailure(\n 'MARKER_ORIGIN_MISMATCH',\n `Existing contract marker profile hash (${marker.profileHash}) does not match plan origin profile hash (${origin.profileHash}).`,\n {\n meta: {\n markerProfileHash: marker.profileHash,\n expectedOriginProfileHash: origin.profileHash,\n },\n },\n );\n }\n return okVoid();\n }\n\n private ensurePlanMatchesDestinationContract(\n destination: SqlMigrationPlanContractInfo,\n contract: SqlMigrationRunnerExecuteOptions<PostgresPlanTargetDetails>['destinationContract'],\n ): Result<void, SqlMigrationRunnerFailure> {\n if (destination.storageHash !== contract.storage.storageHash) {\n return runnerFailure(\n 'DESTINATION_CONTRACT_MISMATCH',\n `Plan destination storage hash (${destination.storageHash}) does not match provided contract storage hash (${contract.storage.storageHash}).`,\n {\n meta: {\n planStorageHash: destination.storageHash,\n contractStorageHash: contract.storage.storageHash,\n },\n },\n );\n }\n if (\n destination.profileHash &&\n contract.profileHash &&\n destination.profileHash !== contract.profileHash\n ) {\n return runnerFailure(\n 'DESTINATION_CONTRACT_MISMATCH',\n `Plan destination profile hash (${destination.profileHash}) does not match provided contract profile hash (${contract.profileHash}).`,\n {\n meta: {\n planProfileHash: destination.profileHash,\n contractProfileHash: contract.profileHash,\n },\n },\n );\n }\n return okVoid();\n }\n\n private async upsertMarker(\n driver: SqlMigrationRunnerExecuteOptions<PostgresPlanTargetDetails>['driver'],\n options: SqlMigrationRunnerExecuteOptions<PostgresPlanTargetDetails>,\n existingMarker: ContractMarkerRecord | null,\n ): Promise<void> {\n const writeStatements = buildWriteMarkerStatements({\n storageHash: options.plan.destination.storageHash,\n profileHash:\n options.plan.destination.profileHash ??\n options.destinationContract.profileHash ??\n options.plan.destination.storageHash,\n contractJson: options.destinationContract,\n canonicalVersion: null,\n meta: {},\n });\n const statement = existingMarker ? writeStatements.update : writeStatements.insert;\n await this.executeStatement(driver, statement);\n }\n\n private async recordLedgerEntry(\n driver: SqlMigrationRunnerExecuteOptions<PostgresPlanTargetDetails>['driver'],\n options: SqlMigrationRunnerExecuteOptions<PostgresPlanTargetDetails>,\n existingMarker: ContractMarkerRecord | null,\n executedOperations: readonly SqlMigrationPlanOperation<PostgresPlanTargetDetails>[],\n ): Promise<void> {\n const ledgerStatement = buildLedgerInsertStatement({\n originStorageHash: existingMarker?.storageHash ?? null,\n originProfileHash: existingMarker?.profileHash ?? null,\n destinationStorageHash: options.plan.destination.storageHash,\n destinationProfileHash:\n options.plan.destination.profileHash ??\n options.destinationContract.profileHash ??\n options.plan.destination.storageHash,\n contractJsonBefore: existingMarker?.contractJson ?? null,\n contractJsonAfter: options.destinationContract,\n operations: executedOperations,\n });\n await this.executeStatement(driver, ledgerStatement);\n }\n\n private async acquireLock(\n driver: SqlMigrationRunnerExecuteOptions<PostgresPlanTargetDetails>['driver'],\n key: string,\n ): Promise<void> {\n await driver.query('select pg_advisory_xact_lock(hashtext($1))', [key]);\n }\n\n private async beginTransaction(\n driver: SqlMigrationRunnerExecuteOptions<PostgresPlanTargetDetails>['driver'],\n ): Promise<void> {\n await driver.query('BEGIN');\n }\n\n private async commitTransaction(\n driver: SqlMigrationRunnerExecuteOptions<PostgresPlanTargetDetails>['driver'],\n ): Promise<void> {\n await driver.query('COMMIT');\n }\n\n private async rollbackTransaction(\n driver: SqlMigrationRunnerExecuteOptions<PostgresPlanTargetDetails>['driver'],\n ): Promise<void> {\n await driver.query('ROLLBACK');\n }\n\n private async executeStatement(\n driver: SqlMigrationRunnerExecuteOptions<PostgresPlanTargetDetails>['driver'],\n statement: SqlStatement,\n ): Promise<void> {\n if (statement.params.length > 0) {\n await driver.query(statement.sql, statement.params);\n return;\n }\n await driver.query(statement.sql);\n }\n}\n","import type { ColumnDefault, Contract } from '@prisma-next/contract/types';\nimport type {\n SqlControlFamilyInstance,\n SqlControlTargetDescriptor,\n} from '@prisma-next/family-sql/control';\nimport { contractToSchemaIR, extractCodecControlHooks } from '@prisma-next/family-sql/control';\nimport type { TargetBoundComponentDescriptor } from '@prisma-next/framework-components/components';\nimport type {\n ControlTargetInstance,\n MigrationRunner,\n} from '@prisma-next/framework-components/control';\nimport type { SqlStorage, StorageColumn } from '@prisma-next/sql-contract/types';\nimport { ifDefined } from '@prisma-next/utils/defined';\nimport { postgresTargetDescriptorMeta } from '../core/descriptor-meta';\nimport { createPostgresMigrationPlanner } from '../core/migrations/planner';\nimport { renderDefaultLiteral } from '../core/migrations/planner-ddl-builders';\nimport type { PostgresPlanTargetDetails } from '../core/migrations/planner-target-details';\nimport { createPostgresMigrationRunner } from '../core/migrations/runner';\n\nfunction buildNativeTypeExpander(\n frameworkComponents?: ReadonlyArray<TargetBoundComponentDescriptor<'sql', 'postgres'>>,\n) {\n if (!frameworkComponents) {\n return undefined;\n }\n const codecHooks = extractCodecControlHooks(frameworkComponents);\n return (input: {\n readonly nativeType: string;\n readonly codecId?: string;\n readonly typeParams?: Record<string, unknown>;\n }) => {\n if (!input.typeParams) return input.nativeType;\n // Mirror `renderExpectedNativeType` in verify-sql-schema: when a codec\n // has no `expandNativeType` hook (e.g. `pg/enum@1`, whose typeParams\n // describe the value set rather than a DDL suffix), fall back to the\n // bare native type rather than throwing. Throwing here would reject\n // every plan involving an enum-/values-typed column as soon as its\n // `typeRef` resolved to a `StorageTypeInstance` carrying typeParams.\n if (!input.codecId) return input.nativeType;\n const hooks = codecHooks.get(input.codecId);\n if (!hooks?.expandNativeType) return input.nativeType;\n return hooks.expandNativeType(input);\n };\n}\n\nexport function postgresRenderDefault(def: ColumnDefault, column: StorageColumn): string {\n if (def.kind === 'function') {\n return def.expression;\n }\n return renderDefaultLiteral(def.value, column);\n}\n\nconst postgresTargetDescriptor: SqlControlTargetDescriptor<'postgres', PostgresPlanTargetDetails> =\n {\n ...postgresTargetDescriptorMeta,\n migrations: {\n createPlanner(_family: SqlControlFamilyInstance) {\n return createPostgresMigrationPlanner();\n },\n createRunner(family) {\n return createPostgresMigrationRunner(family) as MigrationRunner<'sql', 'postgres'>;\n },\n contractToSchema(contract, frameworkComponents) {\n const expander = buildNativeTypeExpander(frameworkComponents);\n return contractToSchemaIR(contract as Contract<SqlStorage> | null, {\n annotationNamespace: 'pg',\n ...ifDefined('expandNativeType', expander),\n renderDefault: postgresRenderDefault,\n frameworkComponents: frameworkComponents ?? [],\n });\n },\n },\n create(): ControlTargetInstance<'sql', 'postgres'> {\n return {\n familyId: 'sql',\n targetId: 'postgres',\n };\n },\n /**\n * Direct method for SQL-specific usage.\n * @deprecated Use migrations.createPlanner() for CLI compatibility.\n */\n createPlanner(_family: SqlControlFamilyInstance) {\n return createPostgresMigrationPlanner();\n },\n /**\n * Direct method for SQL-specific usage.\n * @deprecated Use migrations.createRunner() for CLI compatibility.\n */\n createRunner(family) {\n return createPostgresMigrationRunner(family);\n },\n };\n\nexport default postgresTargetDescriptor;\n"],"mappings":"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"}
1
+ {"version":3,"file":"control.mjs","names":["DEFAULT_CONFIG: RunnerConfig","cloned: Record<string, unknown>","family: SqlControlFamilyInstance","config: RunnerConfig","applyValue: ApplyPlanSuccessValue","executedOperations: Array<SqlMigrationPlanOperation<PostgresPlanTargetDetails>>","error: unknown","postgresTargetDescriptor: SqlControlTargetDescriptor<'postgres', PostgresPlanTargetDetails>"],"sources":["../src/core/migrations/runner.ts","../src/exports/control.ts"],"sourcesContent":["import type { ContractMarkerRecord } from '@prisma-next/contract/types';\nimport type {\n MigrationOperationPolicy,\n SqlControlFamilyInstance,\n SqlMigrationPlanContractInfo,\n SqlMigrationPlanOperation,\n SqlMigrationPlanOperationStep,\n SqlMigrationRunner,\n SqlMigrationRunnerExecuteOptions,\n SqlMigrationRunnerFailure,\n SqlMigrationRunnerResult,\n} from '@prisma-next/family-sql/control';\nimport { runnerFailure, runnerSuccess } from '@prisma-next/family-sql/control';\nimport { verifySqlSchema } from '@prisma-next/family-sql/schema-verify';\nimport { SqlQueryError } from '@prisma-next/sql-errors';\nimport { ifDefined } from '@prisma-next/utils/defined';\nimport type { Result } from '@prisma-next/utils/result';\nimport { ok, okVoid } from '@prisma-next/utils/result';\nimport { parsePostgresDefault } from '../default-normalizer';\nimport { normalizeSchemaNativeType } from '../native-type-normalizer';\nimport type { PostgresPlanTargetDetails } from './planner-target-details';\nimport {\n buildLedgerInsertStatement,\n buildMergeMarkerStatements,\n ensureLedgerTableStatement,\n ensureMarkerTableStatement,\n ensurePrismaContractSchemaStatement,\n type SqlStatement,\n} from './statement-builders';\n\ninterface RunnerConfig {\n readonly defaultSchema: string;\n}\n\ninterface ApplyPlanSuccessValue {\n readonly operationsExecuted: number;\n readonly executedOperations: readonly SqlMigrationPlanOperation<PostgresPlanTargetDetails>[];\n}\n\nconst DEFAULT_CONFIG: RunnerConfig = {\n defaultSchema: 'public',\n};\n\nconst LOCK_DOMAIN = 'prisma_next.contract.marker';\n\n/**\n * Deep clones and freezes a record object to prevent mutation.\n * Recursively clones nested objects and arrays to ensure complete isolation.\n */\nfunction cloneAndFreezeRecord<T extends Record<string, unknown>>(value: T): T {\n const cloned: Record<string, unknown> = {};\n for (const [key, val] of Object.entries(value)) {\n if (val === null || val === undefined) {\n cloned[key] = val;\n } else if (Array.isArray(val)) {\n // Clone array (shallow clone of array elements)\n cloned[key] = Object.freeze([...val]);\n } else if (typeof val === 'object') {\n // Recursively clone nested objects\n cloned[key] = cloneAndFreezeRecord(val as Record<string, unknown>);\n } else {\n // Primitives are copied as-is\n cloned[key] = val;\n }\n }\n return Object.freeze(cloned) as T;\n}\n\nexport function createPostgresMigrationRunner(\n family: SqlControlFamilyInstance,\n config: Partial<RunnerConfig> = {},\n): SqlMigrationRunner<PostgresPlanTargetDetails> {\n return new PostgresMigrationRunner(family, { ...DEFAULT_CONFIG, ...config });\n}\n\nclass PostgresMigrationRunner implements SqlMigrationRunner<PostgresPlanTargetDetails> {\n constructor(\n private readonly family: SqlControlFamilyInstance,\n private readonly config: RunnerConfig,\n ) {}\n\n async execute(\n options: SqlMigrationRunnerExecuteOptions<PostgresPlanTargetDetails>,\n ): Promise<SqlMigrationRunnerResult> {\n const schema = options.schemaName ?? this.config.defaultSchema;\n const driver = options.driver;\n const lockKey = `${LOCK_DOMAIN}:${schema}`;\n\n // Static checks - fail fast before transaction\n const destinationCheck = this.ensurePlanMatchesDestinationContract(\n options.plan.destination,\n options.destinationContract,\n );\n if (!destinationCheck.ok) {\n return destinationCheck;\n }\n\n const policyCheck = this.enforcePolicyCompatibility(options.policy, options.plan.operations);\n if (!policyCheck.ok) {\n return policyCheck;\n }\n\n // Begin transaction for DB operations\n await this.beginTransaction(driver);\n let committed = false;\n try {\n await this.acquireLock(driver, lockKey);\n await this.ensureControlTables(driver);\n const existingMarker = await this.family.readMarker({ driver });\n\n // Validate plan origin matches existing marker (needs marker from DB)\n const markerCheck = this.ensureMarkerCompatibility(existingMarker, options.plan);\n if (!markerCheck.ok) {\n return markerCheck;\n }\n\n // db update (origin: null) always applies; migration-apply (origin set,\n // origin !== destination) skips if marker already matches destination.\n // Self-edges (origin === destination) intentionally bypass the skip:\n // the migration is data-only, and the data transform's own check\n // decides whether `run` fires.\n const markerAtDestination = this.markerMatchesDestination(existingMarker, options.plan);\n const isSelfEdge = options.plan.origin?.storageHash === options.plan.destination.storageHash;\n const skipOperations = markerAtDestination && options.plan.origin != null && !isSelfEdge;\n let applyValue: ApplyPlanSuccessValue;\n\n if (skipOperations) {\n applyValue = { operationsExecuted: 0, executedOperations: [] };\n } else {\n const applyResult = await this.applyPlan(driver, options);\n if (!applyResult.ok) {\n return applyResult;\n }\n applyValue = applyResult.value;\n }\n\n // Verify resulting schema matches contract\n // Step 1: Introspect live schema (DB I/O, family-owned)\n const schemaIR = await this.family.introspect({\n driver,\n contract: options.destinationContract,\n });\n\n // Step 2: Pure verification (no DB I/O)\n const schemaVerifyResult = verifySqlSchema({\n contract: options.destinationContract,\n schema: schemaIR,\n strict: options.strictVerification ?? true,\n context: options.context ?? {},\n typeMetadataRegistry: this.family.typeMetadataRegistry,\n frameworkComponents: options.frameworkComponents,\n normalizeDefault: parsePostgresDefault,\n normalizeNativeType: normalizeSchemaNativeType,\n });\n if (!schemaVerifyResult.ok) {\n return runnerFailure('SCHEMA_VERIFY_FAILED', schemaVerifyResult.summary, {\n why: 'The resulting database schema does not satisfy the destination contract.',\n meta: {\n issues: schemaVerifyResult.schema.issues,\n },\n });\n }\n\n // Self-edge no-op detection: a self-edge migration whose ops all\n // self-skipped (every op pre-satisfied) and that brings no new\n // invariants produced no observable change. Skip the marker +\n // ledger writes so an idempotent re-apply of a self-edge data\n // transform doesn't churn updatedAt or pile up empty ledger\n // entries. With data transforms now flowing through the unified\n // op loop, a pre-satisfied DT lands in the\n // `postcheckAlreadySatisfied` skip path which does not increment\n // `operationsExecuted`, so the check below correctly distinguishes\n // \"every op self-skipped\" from \"the plan had ops that ran\". `db\n // update` no-ops still write a ledger entry as audit trail.\n const incomingInvariants = options.plan.providedInvariants ?? [];\n const existingInvariants = new Set(existingMarker?.invariants ?? []);\n const incomingIsSubsetOfExisting = incomingInvariants.every((id) =>\n existingInvariants.has(id),\n );\n const isSelfEdgeNoOp =\n isSelfEdge && applyValue.operationsExecuted === 0 && incomingIsSubsetOfExisting;\n\n if (!isSelfEdgeNoOp) {\n await this.upsertMarker(driver, options, existingMarker);\n await this.recordLedgerEntry(\n driver,\n options,\n existingMarker,\n applyValue.executedOperations,\n );\n }\n\n await this.commitTransaction(driver);\n committed = true;\n return runnerSuccess({\n operationsPlanned: options.plan.operations.length,\n operationsExecuted: applyValue.operationsExecuted,\n });\n } finally {\n if (!committed) {\n await this.rollbackTransaction(driver);\n }\n }\n }\n\n private async applyPlan(\n driver: SqlMigrationRunnerExecuteOptions<PostgresPlanTargetDetails>['driver'],\n options: SqlMigrationRunnerExecuteOptions<PostgresPlanTargetDetails>,\n ): Promise<Result<ApplyPlanSuccessValue, SqlMigrationRunnerFailure>> {\n const checks = options.executionChecks;\n const runPrechecks = checks?.prechecks !== false; // Default true\n const runPostchecks = checks?.postchecks !== false; // Default true\n const runIdempotency = checks?.idempotencyChecks !== false; // Default true\n\n let operationsExecuted = 0;\n const executedOperations: Array<SqlMigrationPlanOperation<PostgresPlanTargetDetails>> = [];\n for (const operation of options.plan.operations) {\n options.callbacks?.onOperationStart?.(operation);\n try {\n // Idempotency probe: only run if both postchecks and idempotency checks are enabled\n if (runPostchecks && runIdempotency) {\n const postcheckAlreadySatisfied = await this.expectationsAreSatisfied(\n driver,\n operation.postcheck,\n );\n if (postcheckAlreadySatisfied) {\n executedOperations.push(this.createPostcheckPreSatisfiedSkipRecord(operation));\n continue;\n }\n }\n\n // Prechecks: only run if enabled\n if (runPrechecks) {\n const precheckResult = await this.runExpectationSteps(\n driver,\n operation.precheck,\n operation,\n 'precheck',\n );\n if (!precheckResult.ok) {\n return precheckResult;\n }\n }\n\n const executeResult = await this.runExecuteSteps(driver, operation.execute, operation);\n if (!executeResult.ok) {\n return executeResult;\n }\n\n // Postchecks: only run if enabled\n if (runPostchecks) {\n const postcheckResult = await this.runExpectationSteps(\n driver,\n operation.postcheck,\n operation,\n 'postcheck',\n );\n if (!postcheckResult.ok) {\n return postcheckResult;\n }\n }\n\n executedOperations.push(operation);\n operationsExecuted += 1;\n } finally {\n options.callbacks?.onOperationComplete?.(operation);\n }\n }\n return ok({ operationsExecuted, executedOperations });\n }\n\n private async ensureControlTables(\n driver: SqlMigrationRunnerExecuteOptions<PostgresPlanTargetDetails>['driver'],\n ): Promise<void> {\n await this.executeStatement(driver, ensurePrismaContractSchemaStatement);\n await this.executeStatement(driver, ensureMarkerTableStatement);\n await this.executeStatement(driver, ensureLedgerTableStatement);\n }\n\n private async runExpectationSteps(\n driver: SqlMigrationRunnerExecuteOptions<PostgresPlanTargetDetails>['driver'],\n steps: readonly SqlMigrationPlanOperationStep[],\n operation: SqlMigrationPlanOperation<PostgresPlanTargetDetails>,\n phase: 'precheck' | 'postcheck',\n ): Promise<Result<void, SqlMigrationRunnerFailure>> {\n for (const step of steps) {\n const result = await driver.query(step.sql, step.params ?? []);\n if (!this.stepResultIsTrue(result.rows)) {\n const code = phase === 'precheck' ? 'PRECHECK_FAILED' : 'POSTCHECK_FAILED';\n return runnerFailure(\n code,\n `Operation ${operation.id} failed during ${phase}: ${step.description}`,\n {\n meta: {\n operationId: operation.id,\n phase,\n stepDescription: step.description,\n },\n },\n );\n }\n }\n return okVoid();\n }\n\n private async runExecuteSteps(\n driver: SqlMigrationRunnerExecuteOptions<PostgresPlanTargetDetails>['driver'],\n steps: readonly SqlMigrationPlanOperationStep[],\n operation: SqlMigrationPlanOperation<PostgresPlanTargetDetails>,\n ): Promise<Result<void, SqlMigrationRunnerFailure>> {\n for (const step of steps) {\n try {\n await driver.query(step.sql, step.params ?? []);\n } catch (error: unknown) {\n // Catch SqlQueryError and include normalized metadata\n if (SqlQueryError.is(error)) {\n return runnerFailure(\n 'EXECUTION_FAILED',\n `Operation ${operation.id} failed during execution: ${step.description}`,\n {\n why: error.message,\n meta: {\n operationId: operation.id,\n stepDescription: step.description,\n sql: step.sql,\n sqlState: error.sqlState,\n constraint: error.constraint,\n table: error.table,\n column: error.column,\n detail: error.detail,\n },\n },\n );\n }\n // Let SqlConnectionError and other errors propagate (fail-fast)\n throw error;\n }\n }\n return okVoid();\n }\n\n private stepResultIsTrue(rows: readonly Record<string, unknown>[]): boolean {\n if (!rows || rows.length === 0) {\n return false;\n }\n const firstRow = rows[0];\n const firstValue = firstRow ? Object.values(firstRow)[0] : undefined;\n if (typeof firstValue === 'boolean') {\n return firstValue;\n }\n if (typeof firstValue === 'number') {\n return firstValue !== 0;\n }\n if (typeof firstValue === 'string') {\n const lower = firstValue.toLowerCase();\n // PostgreSQL boolean representations: 't'/'f', 'true'/'false', '1'/'0'\n if (lower === 't' || lower === 'true' || lower === '1') {\n return true;\n }\n if (lower === 'f' || lower === 'false' || lower === '0') {\n return false;\n }\n // For other strings, non-empty is truthy (though this case shouldn't occur for boolean checks)\n return firstValue.length > 0;\n }\n return Boolean(firstValue);\n }\n\n private async expectationsAreSatisfied(\n driver: SqlMigrationRunnerExecuteOptions<PostgresPlanTargetDetails>['driver'],\n steps: readonly SqlMigrationPlanOperationStep[],\n ): Promise<boolean> {\n if (steps.length === 0) {\n return false;\n }\n for (const step of steps) {\n const result = await driver.query(step.sql, step.params ?? []);\n if (!this.stepResultIsTrue(result.rows)) {\n return false;\n }\n }\n return true;\n }\n\n private createPostcheckPreSatisfiedSkipRecord(\n operation: SqlMigrationPlanOperation<PostgresPlanTargetDetails>,\n ): SqlMigrationPlanOperation<PostgresPlanTargetDetails> {\n // Clone and freeze existing meta if present\n const clonedMeta = operation.meta ? cloneAndFreezeRecord(operation.meta) : undefined;\n\n // Create frozen runner metadata\n const runnerMeta = Object.freeze({\n skipped: true,\n reason: 'postcheck_pre_satisfied',\n });\n\n // Merge and freeze the combined meta\n const mergedMeta = Object.freeze({\n ...(clonedMeta ?? {}),\n runner: runnerMeta,\n });\n\n // Clone and freeze arrays to prevent mutation\n const frozenPostcheck = Object.freeze([...operation.postcheck]);\n\n return Object.freeze({\n id: operation.id,\n label: operation.label,\n ...ifDefined('summary', operation.summary),\n operationClass: operation.operationClass,\n target: operation.target, // Already frozen from plan creation\n precheck: Object.freeze([]),\n execute: Object.freeze([]),\n postcheck: frozenPostcheck,\n ...ifDefined('meta', operation.meta || mergedMeta ? mergedMeta : undefined),\n });\n }\n\n private markerMatchesDestination(\n marker: ContractMarkerRecord | null,\n plan: SqlMigrationRunnerExecuteOptions<PostgresPlanTargetDetails>['plan'],\n ): boolean {\n if (!marker) {\n return false;\n }\n if (marker.storageHash !== plan.destination.storageHash) {\n return false;\n }\n if (plan.destination.profileHash && marker.profileHash !== plan.destination.profileHash) {\n return false;\n }\n return true;\n }\n\n private enforcePolicyCompatibility(\n policy: MigrationOperationPolicy,\n operations: readonly SqlMigrationPlanOperation<PostgresPlanTargetDetails>[],\n ): Result<void, SqlMigrationRunnerFailure> {\n const allowedClasses = new Set(policy.allowedOperationClasses);\n for (const operation of operations) {\n if (!allowedClasses.has(operation.operationClass)) {\n return runnerFailure(\n 'POLICY_VIOLATION',\n `Operation ${operation.id} has class \"${operation.operationClass}\" which is not allowed by policy.`,\n {\n why: `Policy only allows: ${policy.allowedOperationClasses.join(', ')}.`,\n meta: {\n operationId: operation.id,\n operationClass: operation.operationClass,\n allowedClasses: policy.allowedOperationClasses,\n },\n },\n );\n }\n }\n return okVoid();\n }\n\n private ensureMarkerCompatibility(\n marker: ContractMarkerRecord | null,\n plan: SqlMigrationRunnerExecuteOptions<PostgresPlanTargetDetails>['plan'],\n ): Result<void, SqlMigrationRunnerFailure> {\n const origin = plan.origin ?? null;\n if (!origin) {\n // No origin assertion on the plan — the caller does not want origin validation.\n // This is the case for `db update`, which introspects the live schema and does not\n // rely on marker continuity. `db init` handles its own marker checks before the runner.\n return okVoid();\n }\n\n if (!marker) {\n return runnerFailure(\n 'MARKER_ORIGIN_MISMATCH',\n `Missing contract marker: expected origin storage hash ${origin.storageHash}.`,\n {\n meta: {\n expectedOriginStorageHash: origin.storageHash,\n },\n },\n );\n }\n if (marker.storageHash !== origin.storageHash) {\n return runnerFailure(\n 'MARKER_ORIGIN_MISMATCH',\n `Existing contract marker (${marker.storageHash}) does not match plan origin (${origin.storageHash}).`,\n {\n meta: {\n markerStorageHash: marker.storageHash,\n expectedOriginStorageHash: origin.storageHash,\n },\n },\n );\n }\n if (origin.profileHash && marker.profileHash !== origin.profileHash) {\n return runnerFailure(\n 'MARKER_ORIGIN_MISMATCH',\n `Existing contract marker profile hash (${marker.profileHash}) does not match plan origin profile hash (${origin.profileHash}).`,\n {\n meta: {\n markerProfileHash: marker.profileHash,\n expectedOriginProfileHash: origin.profileHash,\n },\n },\n );\n }\n return okVoid();\n }\n\n private ensurePlanMatchesDestinationContract(\n destination: SqlMigrationPlanContractInfo,\n contract: SqlMigrationRunnerExecuteOptions<PostgresPlanTargetDetails>['destinationContract'],\n ): Result<void, SqlMigrationRunnerFailure> {\n if (destination.storageHash !== contract.storage.storageHash) {\n return runnerFailure(\n 'DESTINATION_CONTRACT_MISMATCH',\n `Plan destination storage hash (${destination.storageHash}) does not match provided contract storage hash (${contract.storage.storageHash}).`,\n {\n meta: {\n planStorageHash: destination.storageHash,\n contractStorageHash: contract.storage.storageHash,\n },\n },\n );\n }\n if (\n destination.profileHash &&\n contract.profileHash &&\n destination.profileHash !== contract.profileHash\n ) {\n return runnerFailure(\n 'DESTINATION_CONTRACT_MISMATCH',\n `Plan destination profile hash (${destination.profileHash}) does not match provided contract profile hash (${contract.profileHash}).`,\n {\n meta: {\n planProfileHash: destination.profileHash,\n contractProfileHash: contract.profileHash,\n },\n },\n );\n }\n return okVoid();\n }\n\n private async upsertMarker(\n driver: SqlMigrationRunnerExecuteOptions<PostgresPlanTargetDetails>['driver'],\n options: SqlMigrationRunnerExecuteOptions<PostgresPlanTargetDetails>,\n existingMarker: ContractMarkerRecord | null,\n ): Promise<void> {\n const incomingInvariants = options.plan.providedInvariants ?? [];\n const writeStatements = buildMergeMarkerStatements({\n storageHash: options.plan.destination.storageHash,\n profileHash:\n options.plan.destination.profileHash ??\n options.destinationContract.profileHash ??\n options.plan.destination.storageHash,\n contractJson: options.destinationContract,\n canonicalVersion: null,\n meta: {},\n invariants: incomingInvariants,\n });\n const statement = existingMarker ? writeStatements.update : writeStatements.insert;\n await this.executeStatement(driver, statement);\n }\n\n private async recordLedgerEntry(\n driver: SqlMigrationRunnerExecuteOptions<PostgresPlanTargetDetails>['driver'],\n options: SqlMigrationRunnerExecuteOptions<PostgresPlanTargetDetails>,\n existingMarker: ContractMarkerRecord | null,\n executedOperations: readonly SqlMigrationPlanOperation<PostgresPlanTargetDetails>[],\n ): Promise<void> {\n const ledgerStatement = buildLedgerInsertStatement({\n originStorageHash: existingMarker?.storageHash ?? null,\n originProfileHash: existingMarker?.profileHash ?? null,\n destinationStorageHash: options.plan.destination.storageHash,\n destinationProfileHash:\n options.plan.destination.profileHash ??\n options.destinationContract.profileHash ??\n options.plan.destination.storageHash,\n contractJsonBefore: existingMarker?.contractJson ?? null,\n contractJsonAfter: options.destinationContract,\n operations: executedOperations,\n });\n await this.executeStatement(driver, ledgerStatement);\n }\n\n private async acquireLock(\n driver: SqlMigrationRunnerExecuteOptions<PostgresPlanTargetDetails>['driver'],\n key: string,\n ): Promise<void> {\n await driver.query('select pg_advisory_xact_lock(hashtext($1))', [key]);\n }\n\n private async beginTransaction(\n driver: SqlMigrationRunnerExecuteOptions<PostgresPlanTargetDetails>['driver'],\n ): Promise<void> {\n await driver.query('BEGIN');\n }\n\n private async commitTransaction(\n driver: SqlMigrationRunnerExecuteOptions<PostgresPlanTargetDetails>['driver'],\n ): Promise<void> {\n await driver.query('COMMIT');\n }\n\n private async rollbackTransaction(\n driver: SqlMigrationRunnerExecuteOptions<PostgresPlanTargetDetails>['driver'],\n ): Promise<void> {\n await driver.query('ROLLBACK');\n }\n\n private async executeStatement(\n driver: SqlMigrationRunnerExecuteOptions<PostgresPlanTargetDetails>['driver'],\n statement: SqlStatement,\n ): Promise<void> {\n if (statement.params.length > 0) {\n await driver.query(statement.sql, statement.params);\n return;\n }\n await driver.query(statement.sql);\n }\n}\n","import type { ColumnDefault, Contract } from '@prisma-next/contract/types';\nimport type {\n SqlControlFamilyInstance,\n SqlControlTargetDescriptor,\n} from '@prisma-next/family-sql/control';\nimport { contractToSchemaIR, extractCodecControlHooks } from '@prisma-next/family-sql/control';\nimport type { TargetBoundComponentDescriptor } from '@prisma-next/framework-components/components';\nimport type {\n ControlTargetInstance,\n MigrationRunner,\n} from '@prisma-next/framework-components/control';\nimport type { SqlStorage, StorageColumn } from '@prisma-next/sql-contract/types';\nimport { ifDefined } from '@prisma-next/utils/defined';\nimport { postgresTargetDescriptorMeta } from '../core/descriptor-meta';\nimport { createPostgresMigrationPlanner } from '../core/migrations/planner';\nimport { renderDefaultLiteral } from '../core/migrations/planner-ddl-builders';\nimport type { PostgresPlanTargetDetails } from '../core/migrations/planner-target-details';\nimport { createPostgresMigrationRunner } from '../core/migrations/runner';\n\nfunction buildNativeTypeExpander(\n frameworkComponents?: ReadonlyArray<TargetBoundComponentDescriptor<'sql', 'postgres'>>,\n) {\n if (!frameworkComponents) {\n return undefined;\n }\n const codecHooks = extractCodecControlHooks(frameworkComponents);\n return (input: {\n readonly nativeType: string;\n readonly codecId?: string;\n readonly typeParams?: Record<string, unknown>;\n }) => {\n if (!input.typeParams) return input.nativeType;\n // Mirror `renderExpectedNativeType` in verify-sql-schema: when a codec\n // has no `expandNativeType` hook (e.g. `pg/enum@1`, whose typeParams\n // describe the value set rather than a DDL suffix), fall back to the\n // bare native type rather than throwing. Throwing here would reject\n // every plan involving an enum-/values-typed column as soon as its\n // `typeRef` resolved to a `StorageTypeInstance` carrying typeParams.\n if (!input.codecId) return input.nativeType;\n const hooks = codecHooks.get(input.codecId);\n if (!hooks?.expandNativeType) return input.nativeType;\n return hooks.expandNativeType(input);\n };\n}\n\nexport function postgresRenderDefault(def: ColumnDefault, column: StorageColumn): string {\n if (def.kind === 'function') {\n return def.expression;\n }\n return renderDefaultLiteral(def.value, column);\n}\n\nconst postgresTargetDescriptor: SqlControlTargetDescriptor<'postgres', PostgresPlanTargetDetails> =\n {\n ...postgresTargetDescriptorMeta,\n migrations: {\n createPlanner(_family: SqlControlFamilyInstance) {\n return createPostgresMigrationPlanner();\n },\n createRunner(family) {\n return createPostgresMigrationRunner(family) as MigrationRunner<'sql', 'postgres'>;\n },\n contractToSchema(contract, frameworkComponents) {\n const expander = buildNativeTypeExpander(frameworkComponents);\n return contractToSchemaIR(contract as Contract<SqlStorage> | null, {\n annotationNamespace: 'pg',\n ...ifDefined('expandNativeType', expander),\n renderDefault: postgresRenderDefault,\n frameworkComponents: frameworkComponents ?? [],\n });\n },\n },\n create(): ControlTargetInstance<'sql', 'postgres'> {\n return {\n familyId: 'sql',\n targetId: 'postgres',\n };\n },\n /**\n * Direct method for SQL-specific usage.\n * @deprecated Use migrations.createPlanner() for CLI compatibility.\n */\n createPlanner(_family: SqlControlFamilyInstance) {\n return createPostgresMigrationPlanner();\n },\n /**\n * Direct method for SQL-specific usage.\n * @deprecated Use migrations.createRunner() for CLI compatibility.\n */\n createRunner(family) {\n return createPostgresMigrationRunner(family);\n },\n };\n\nexport default postgresTargetDescriptor;\n"],"mappings":"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"}
@@ -1,16 +1,35 @@
1
+ import { ifDefined } from "@prisma-next/utils/defined";
1
2
  import { errorDataTransformContractMismatch } from "@prisma-next/errors/migration";
2
3
 
3
4
  //#region src/core/migrations/operations/data-transform.ts
4
5
  function dataTransform(contract, name, options, adapter) {
5
6
  const runClosures = Array.isArray(options.run) ? options.run : [options.run];
7
+ const checkPlan = options.check ? invokeAndLower(options.check, contract, adapter, name) : null;
8
+ const runPlans = runClosures.map((closure) => invokeAndLower(closure, contract, adapter, name));
9
+ const precheck = checkPlan ? [{
10
+ description: `Check ${name} has work to do`,
11
+ sql: `SELECT EXISTS (${checkPlan.sql}) AS ok`,
12
+ params: checkPlan.params
13
+ }] : [];
14
+ const execute = runPlans.map((plan) => ({
15
+ description: `Run ${name}`,
16
+ sql: plan.sql,
17
+ params: plan.params
18
+ }));
19
+ const postcheck = checkPlan ? [{
20
+ description: `Verify ${name} resolved all violations`,
21
+ sql: `SELECT NOT EXISTS (${checkPlan.sql}) AS ok`,
22
+ params: checkPlan.params
23
+ }] : [];
6
24
  return {
7
25
  id: `data_migration.${name}`,
8
26
  label: `Data transform: ${name}`,
9
27
  operationClass: "data",
10
- name,
11
- source: "migration.ts",
12
- check: options.check ? invokeAndLower(options.check, contract, adapter, name) : null,
13
- run: runClosures.map((closure) => invokeAndLower(closure, contract, adapter, name))
28
+ ...ifDefined("invariantId", options.invariantId),
29
+ target: { id: "postgres" },
30
+ precheck,
31
+ execute,
32
+ postcheck
14
33
  };
15
34
  }
16
35
  function invokeAndLower(closure, contract, adapter, name) {
@@ -36,4 +55,4 @@ function assertContractMatches(plan, contract, name) {
36
55
 
37
56
  //#endregion
38
57
  export { dataTransform as t };
39
- //# sourceMappingURL=data-transform-VfEGzXWt.mjs.map
58
+ //# sourceMappingURL=data-transform-Be_i_DBc.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"data-transform-Be_i_DBc.mjs","names":["runClosures: readonly DataTransformClosure[]","precheck: readonly SqlMigrationPlanOperationStep[]","execute: readonly SqlMigrationPlanOperationStep[]","postcheck: readonly SqlMigrationPlanOperationStep[]"],"sources":["../src/core/migrations/operations/data-transform.ts"],"sourcesContent":["/**\n * User-facing `dataTransform` factory for the Postgres migration authoring\n * surface. Invoked directly inside a `migration.ts` file via the\n * `PostgresMigration` instance method (`this.dataTransform(...)`), which\n * supplies the control adapter from the migration's injected stack:\n *\n * ```ts\n * import endContract from './end-contract.json' with { type: 'json' };\n *\n * class M extends Migration {\n * override get operations() {\n * return [\n * this.dataTransform(endContract, 'backfill emails', {\n * check: () => db.users.select('id').where(({ email }) => email.isNull()).limit(1),\n * run: () => db.users.update({ email: '' }).where(({ email }) => email.isNull()),\n * }),\n * ];\n * }\n * }\n * ```\n *\n * The factory accepts lazy closures (`() => SqlQueryPlan | Buildable`),\n * invokes each one, asserts that its `meta.storageHash` matches the\n * `contract` it was handed (→ `PN-MIG-2005` on mismatch), and lowers the\n * plan via the supplied control adapter to a serialized `{sql, params}`\n * payload.\n *\n * The factory then lowers the data transform to the unified migration-op\n * shape `{ precheck, execute, postcheck }`. The user's `check` plan is\n * wrapped twice with opposite truth values:\n *\n * - precheck `SELECT EXISTS (<check>) AS ok` asserts there is work to do\n * (precheck is short-circuited by the runner's pre-satisfied-skip path\n * when nothing remains to backfill).\n * - postcheck `SELECT NOT EXISTS (<check>) AS ok` asserts the work is\n * complete after the run steps execute.\n *\n * The `check` plan is therefore expected to be a **rowset query whose\n * presence of any row signals \"work remains\"** — typically `select('id')\n * .where(<violation predicate>).limit(1)`. Scalar/aggregate shapes\n * (`count(*)`, `bool_and(...)`) do not work under this contract: they\n * always return exactly one row, so `EXISTS` is always true and\n * `NOT EXISTS` is always false. (This is the same row-presence contract\n * the pre-unification runner relied on; the wrapping is just lifting it\n * into SQL.)\n *\n * Each `run` plan becomes an execute step. Because the `Step.params`\n * field threads through `driver.query(sql, params)`, the user's bound\n * values flow through the driver's parameter binder rather than being\n * inlined into the SQL text.\n *\n * The free factory remains usable standalone (tests, ad-hoc tooling,\n * non-class contexts) by passing the adapter explicitly as the fourth\n * argument.\n */\n\nimport type { Contract } from '@prisma-next/contract/types';\nimport { errorDataTransformContractMismatch } from '@prisma-next/errors/migration';\nimport type {\n SqlMigrationPlanOperation,\n SqlMigrationPlanOperationStep,\n} from '@prisma-next/family-sql/control';\nimport type { SqlControlAdapter } from '@prisma-next/family-sql/control-adapter';\nimport type { SerializedQueryPlan } from '@prisma-next/framework-components/control';\nimport type { SqlStorage } from '@prisma-next/sql-contract/types';\nimport type { SqlQueryPlan } from '@prisma-next/sql-relational-core/plan';\nimport { ifDefined } from '@prisma-next/utils/defined';\nimport type { PostgresPlanTargetDetails } from '../planner-target-details';\n\ninterface Buildable<R = unknown> {\n build(): SqlQueryPlan<R>;\n}\n\n/**\n * A single-closure producer of a SQL query plan. Shared between\n * `check` and each `run` entry.\n */\nexport type DataTransformClosure = () => SqlQueryPlan | Buildable;\n\nexport interface DataTransformOptions {\n /**\n * Optional opt-in routing identity. Presence opts the transform into\n * invariant-aware routing; absence means it is path-dependent and\n * not referenceable from refs.\n */\n readonly invariantId?: string;\n /**\n * Optional pre-flight query. `undefined` means \"no check\". When\n * supplied, the closure must return a **rowset query** whose\n * presence of any row signals \"violations remain\". Conventional\n * shape: `db.<table>.select('id').where(<violation>).limit(1)`.\n * Scalar/aggregate shapes do not satisfy this contract.\n */\n readonly check?: DataTransformClosure;\n /** One or more mutation queries to execute. */\n readonly run: DataTransformClosure | readonly DataTransformClosure[];\n}\n\nexport function dataTransform<TContract extends Contract<SqlStorage>>(\n contract: TContract,\n name: string,\n options: DataTransformOptions,\n adapter: SqlControlAdapter<'postgres'>,\n): SqlMigrationPlanOperation<PostgresPlanTargetDetails> {\n const runClosures: readonly DataTransformClosure[] = Array.isArray(options.run)\n ? options.run\n : [options.run as DataTransformClosure];\n\n const checkPlan = options.check ? invokeAndLower(options.check, contract, adapter, name) : null;\n const runPlans = runClosures.map((closure) => invokeAndLower(closure, contract, adapter, name));\n\n const precheck: readonly SqlMigrationPlanOperationStep[] = checkPlan\n ? [\n {\n description: `Check ${name} has work to do`,\n sql: `SELECT EXISTS (${checkPlan.sql}) AS ok`,\n params: checkPlan.params,\n },\n ]\n : [];\n\n const execute: readonly SqlMigrationPlanOperationStep[] = runPlans.map((plan) => ({\n description: `Run ${name}`,\n sql: plan.sql,\n params: plan.params,\n }));\n\n const postcheck: readonly SqlMigrationPlanOperationStep[] = checkPlan\n ? [\n {\n description: `Verify ${name} resolved all violations`,\n sql: `SELECT NOT EXISTS (${checkPlan.sql}) AS ok`,\n params: checkPlan.params,\n },\n ]\n : [];\n\n return {\n id: `data_migration.${name}`,\n label: `Data transform: ${name}`,\n operationClass: 'data',\n ...ifDefined('invariantId', options.invariantId),\n target: { id: 'postgres' },\n precheck,\n execute,\n postcheck,\n };\n}\n\nfunction invokeAndLower(\n closure: DataTransformClosure,\n contract: Contract<SqlStorage>,\n adapter: SqlControlAdapter<'postgres'>,\n name: string,\n): SerializedQueryPlan {\n const result = closure();\n const plan = isBuildable(result) ? result.build() : result;\n assertContractMatches(plan, contract, name);\n const lowered = adapter.lower(plan.ast, { contract });\n return { sql: lowered.sql, params: lowered.params };\n}\n\nfunction isBuildable(value: unknown): value is Buildable {\n return (\n typeof value === 'object' &&\n value !== null &&\n 'build' in value &&\n typeof (value as { build: unknown }).build === 'function'\n );\n}\n\nfunction assertContractMatches(\n plan: SqlQueryPlan,\n contract: Contract<SqlStorage>,\n name: string,\n): void {\n if (plan.meta.storageHash !== contract.storage.storageHash) {\n throw errorDataTransformContractMismatch({\n dataTransformName: name,\n expected: contract.storage.storageHash,\n actual: plan.meta.storageHash,\n });\n }\n}\n"],"mappings":";;;;AAkGA,SAAgB,cACd,UACA,MACA,SACA,SACsD;CACtD,MAAMA,cAA+C,MAAM,QAAQ,QAAQ,IAAI,GAC3E,QAAQ,MACR,CAAC,QAAQ,IAA4B;CAEzC,MAAM,YAAY,QAAQ,QAAQ,eAAe,QAAQ,OAAO,UAAU,SAAS,KAAK,GAAG;CAC3F,MAAM,WAAW,YAAY,KAAK,YAAY,eAAe,SAAS,UAAU,SAAS,KAAK,CAAC;CAE/F,MAAMC,WAAqD,YACvD,CACE;EACE,aAAa,SAAS,KAAK;EAC3B,KAAK,kBAAkB,UAAU,IAAI;EACrC,QAAQ,UAAU;EACnB,CACF,GACD,EAAE;CAEN,MAAMC,UAAoD,SAAS,KAAK,UAAU;EAChF,aAAa,OAAO;EACpB,KAAK,KAAK;EACV,QAAQ,KAAK;EACd,EAAE;CAEH,MAAMC,YAAsD,YACxD,CACE;EACE,aAAa,UAAU,KAAK;EAC5B,KAAK,sBAAsB,UAAU,IAAI;EACzC,QAAQ,UAAU;EACnB,CACF,GACD,EAAE;AAEN,QAAO;EACL,IAAI,kBAAkB;EACtB,OAAO,mBAAmB;EAC1B,gBAAgB;EAChB,GAAG,UAAU,eAAe,QAAQ,YAAY;EAChD,QAAQ,EAAE,IAAI,YAAY;EAC1B;EACA;EACA;EACD;;AAGH,SAAS,eACP,SACA,UACA,SACA,MACqB;CACrB,MAAM,SAAS,SAAS;CACxB,MAAM,OAAO,YAAY,OAAO,GAAG,OAAO,OAAO,GAAG;AACpD,uBAAsB,MAAM,UAAU,KAAK;CAC3C,MAAM,UAAU,QAAQ,MAAM,KAAK,KAAK,EAAE,UAAU,CAAC;AACrD,QAAO;EAAE,KAAK,QAAQ;EAAK,QAAQ,QAAQ;EAAQ;;AAGrD,SAAS,YAAY,OAAoC;AACvD,QACE,OAAO,UAAU,YACjB,UAAU,QACV,WAAW,SACX,OAAQ,MAA6B,UAAU;;AAInD,SAAS,sBACP,MACA,UACA,MACM;AACN,KAAI,KAAK,KAAK,gBAAgB,SAAS,QAAQ,YAC7C,OAAM,mCAAmC;EACvC,mBAAmB;EACnB,UAAU,SAAS,QAAQ;EAC3B,QAAQ,KAAK,KAAK;EACnB,CAAC"}
@@ -0,0 +1,39 @@
1
+ import { t as PostgresPlanTargetDetails } from "./planner-target-details-DH-azLu-.mjs";
2
+ import { SqlMigrationPlanOperation } from "@prisma-next/family-sql/control";
3
+ import { Contract } from "@prisma-next/contract/types";
4
+ import { SqlStorage } from "@prisma-next/sql-contract/types";
5
+ import { SqlControlAdapter } from "@prisma-next/family-sql/control-adapter";
6
+ import { SqlQueryPlan } from "@prisma-next/sql-relational-core/plan";
7
+
8
+ //#region src/core/migrations/operations/data-transform.d.ts
9
+
10
+ interface Buildable<R = unknown> {
11
+ build(): SqlQueryPlan<R>;
12
+ }
13
+ /**
14
+ * A single-closure producer of a SQL query plan. Shared between
15
+ * `check` and each `run` entry.
16
+ */
17
+ type DataTransformClosure = () => SqlQueryPlan | Buildable;
18
+ interface DataTransformOptions {
19
+ /**
20
+ * Optional opt-in routing identity. Presence opts the transform into
21
+ * invariant-aware routing; absence means it is path-dependent and
22
+ * not referenceable from refs.
23
+ */
24
+ readonly invariantId?: string;
25
+ /**
26
+ * Optional pre-flight query. `undefined` means "no check". When
27
+ * supplied, the closure must return a **rowset query** whose
28
+ * presence of any row signals "violations remain". Conventional
29
+ * shape: `db.<table>.select('id').where(<violation>).limit(1)`.
30
+ * Scalar/aggregate shapes do not satisfy this contract.
31
+ */
32
+ readonly check?: DataTransformClosure;
33
+ /** One or more mutation queries to execute. */
34
+ readonly run: DataTransformClosure | readonly DataTransformClosure[];
35
+ }
36
+ declare function dataTransform<TContract extends Contract<SqlStorage>>(contract: TContract, name: string, options: DataTransformOptions, adapter: SqlControlAdapter<'postgres'>): SqlMigrationPlanOperation<PostgresPlanTargetDetails>;
37
+ //#endregion
38
+ export { DataTransformOptions as n, dataTransform as r, DataTransformClosure as t };
39
+ //# sourceMappingURL=data-transform-CrpmG4uJ.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"data-transform-CrpmG4uJ.d.mts","names":[],"sources":["../src/core/migrations/operations/data-transform.ts"],"sourcesContent":[],"mappings":";;;;;;;;;UAqEU;WACC,aAAa;;;;;;KAOZ,oBAAA,SAA6B,eAAe;UAEvC,oBAAA;;;;;;;;;;;;;;mBAcE;;gBAEH,gCAAgC;;iBAGhC,gCAAgC,SAAS,uBAC7C,kCAED,+BACA,gCACR,0BAA0B"}
@@ -1,2 +1,2 @@
1
- import { i as dataTransform } from "./data-transform-CxFRBIUp.mjs";
1
+ import { r as dataTransform } from "./data-transform-CrpmG4uJ.mjs";
2
2
  export { dataTransform };
@@ -1,3 +1,3 @@
1
- import { t as dataTransform } from "./data-transform-VfEGzXWt.mjs";
1
+ import { t as dataTransform } from "./data-transform-Be_i_DBc.mjs";
2
2
 
3
3
  export { dataTransform };
@@ -1,3 +1,5 @@
1
+ import { temporalAuthoringPresets } from "@prisma-next/family-sql/control";
2
+
1
3
  //#region src/core/authoring.ts
2
4
  const postgresAuthoringTypes = { enum: {
3
5
  kind: "typeConstructor",
@@ -86,17 +88,10 @@ const postgresAuthoringFieldPresets = {
86
88
  nativeType: "timestamptz"
87
89
  }
88
90
  },
89
- createdAt: {
90
- kind: "fieldPreset",
91
- output: {
92
- codecId: "pg/timestamptz@1",
93
- nativeType: "timestamptz",
94
- default: {
95
- kind: "function",
96
- expression: "now()"
97
- }
98
- }
99
- }
91
+ temporal: temporalAuthoringPresets({
92
+ codecId: "pg/timestamptz@1",
93
+ nativeType: "timestamptz"
94
+ })
100
95
  };
101
96
 
102
97
  //#endregion
@@ -117,4 +112,4 @@ const postgresTargetDescriptorMeta = postgresTargetDescriptorMetaBase;
117
112
 
118
113
  //#endregion
119
114
  export { postgresTargetDescriptorMeta as t };
120
- //# sourceMappingURL=descriptor-meta-BVoVtyp-.mjs.map
115
+ //# sourceMappingURL=descriptor-meta-Ieg1XLOs.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"descriptor-meta-Ieg1XLOs.mjs","names":["postgresTargetDescriptorMeta: typeof postgresTargetDescriptorMetaBase & {\n readonly __codecTypes?: CodecTypes;\n}"],"sources":["../src/core/authoring.ts","../src/core/descriptor-meta.ts"],"sourcesContent":["import { temporalAuthoringPresets } from '@prisma-next/family-sql/control';\nimport type {\n AuthoringFieldNamespace,\n AuthoringTypeNamespace,\n} from '@prisma-next/framework-components/authoring';\n\nexport const postgresAuthoringTypes = {\n enum: {\n kind: 'typeConstructor',\n args: [{ kind: 'string' }, { kind: 'stringArray' }],\n output: {\n codecId: 'pg/enum@1',\n nativeType: { kind: 'arg', index: 0 },\n typeParams: {\n values: { kind: 'arg', index: 1 },\n },\n },\n },\n} as const satisfies AuthoringTypeNamespace;\n\n/**\n * Field presets contributed by the Postgres target pack.\n *\n * These mirror the PSL scalar-to-codec mapping used by the Postgres adapter\n * (see `createPostgresPslScalarTypeDescriptors`), so that authoring a field\n * via the TS callback surface (e.g. `field.int()`) and via the PSL scalar\n * surface (e.g. `Int`) lowers to byte-identical contracts.\n */\nexport const postgresAuthoringFieldPresets = {\n text: {\n kind: 'fieldPreset',\n output: {\n codecId: 'pg/text@1',\n nativeType: 'text',\n },\n },\n int: {\n kind: 'fieldPreset',\n output: {\n codecId: 'pg/int4@1',\n nativeType: 'int4',\n },\n },\n bigint: {\n kind: 'fieldPreset',\n output: {\n codecId: 'pg/int8@1',\n nativeType: 'int8',\n },\n },\n float: {\n kind: 'fieldPreset',\n output: {\n codecId: 'pg/float8@1',\n nativeType: 'float8',\n },\n },\n decimal: {\n kind: 'fieldPreset',\n output: {\n codecId: 'pg/numeric@1',\n nativeType: 'numeric',\n },\n },\n boolean: {\n kind: 'fieldPreset',\n output: {\n codecId: 'pg/bool@1',\n nativeType: 'bool',\n },\n },\n json: {\n kind: 'fieldPreset',\n output: {\n codecId: 'pg/jsonb@1',\n nativeType: 'jsonb',\n },\n },\n bytes: {\n kind: 'fieldPreset',\n output: {\n codecId: 'pg/bytea@1',\n nativeType: 'bytea',\n },\n },\n dateTime: {\n kind: 'fieldPreset',\n output: {\n codecId: 'pg/timestamptz@1',\n nativeType: 'timestamptz',\n },\n },\n temporal: temporalAuthoringPresets({\n codecId: 'pg/timestamptz@1',\n nativeType: 'timestamptz',\n }),\n} as const satisfies AuthoringFieldNamespace;\n","import { postgresAuthoringFieldPresets, postgresAuthoringTypes } from './authoring';\nimport type { CodecTypes } from './codecs';\n\nconst postgresTargetDescriptorMetaBase = {\n kind: 'target',\n familyId: 'sql',\n targetId: 'postgres',\n id: 'postgres',\n version: '0.0.1',\n capabilities: {},\n authoring: {\n type: postgresAuthoringTypes,\n field: postgresAuthoringFieldPresets,\n },\n} as const;\n\nexport const postgresTargetDescriptorMeta: typeof postgresTargetDescriptorMetaBase & {\n readonly __codecTypes?: CodecTypes;\n} = postgresTargetDescriptorMetaBase;\n"],"mappings":";;;AAMA,MAAa,yBAAyB,EACpC,MAAM;CACJ,MAAM;CACN,MAAM,CAAC,EAAE,MAAM,UAAU,EAAE,EAAE,MAAM,eAAe,CAAC;CACnD,QAAQ;EACN,SAAS;EACT,YAAY;GAAE,MAAM;GAAO,OAAO;GAAG;EACrC,YAAY,EACV,QAAQ;GAAE,MAAM;GAAO,OAAO;GAAG,EAClC;EACF;CACF,EACF;;;;;;;;;AAUD,MAAa,gCAAgC;CAC3C,MAAM;EACJ,MAAM;EACN,QAAQ;GACN,SAAS;GACT,YAAY;GACb;EACF;CACD,KAAK;EACH,MAAM;EACN,QAAQ;GACN,SAAS;GACT,YAAY;GACb;EACF;CACD,QAAQ;EACN,MAAM;EACN,QAAQ;GACN,SAAS;GACT,YAAY;GACb;EACF;CACD,OAAO;EACL,MAAM;EACN,QAAQ;GACN,SAAS;GACT,YAAY;GACb;EACF;CACD,SAAS;EACP,MAAM;EACN,QAAQ;GACN,SAAS;GACT,YAAY;GACb;EACF;CACD,SAAS;EACP,MAAM;EACN,QAAQ;GACN,SAAS;GACT,YAAY;GACb;EACF;CACD,MAAM;EACJ,MAAM;EACN,QAAQ;GACN,SAAS;GACT,YAAY;GACb;EACF;CACD,OAAO;EACL,MAAM;EACN,QAAQ;GACN,SAAS;GACT,YAAY;GACb;EACF;CACD,UAAU;EACR,MAAM;EACN,QAAQ;GACN,SAAS;GACT,YAAY;GACb;EACF;CACD,UAAU,yBAAyB;EACjC,SAAS;EACT,YAAY;EACb,CAAC;CACH;;;;AC7FD,MAAM,mCAAmC;CACvC,MAAM;CACN,UAAU;CACV,UAAU;CACV,IAAI;CACJ,SAAS;CACT,cAAc,EAAE;CAChB,WAAW;EACT,MAAM;EACN,OAAO;EACR;CACF;AAED,MAAaA,+BAET"}
@@ -4,8 +4,8 @@ import { CodecControlHooks, MigrationOperationPolicy, SqlPlannerConflict } from
4
4
  import { Result } from "@prisma-next/utils/result";
5
5
  import { Contract } from "@prisma-next/contract/types";
6
6
  import { SqlStorage, StorageTypeInstance } from "@prisma-next/sql-contract/types";
7
- import { SchemaIssue } from "@prisma-next/framework-components/control";
8
7
  import { TargetBoundComponentDescriptor } from "@prisma-next/framework-components/components";
8
+ import { SchemaIssue } from "@prisma-next/framework-components/control";
9
9
  import { SqlSchemaIR } from "@prisma-next/sql-schema-ir/types";
10
10
 
11
11
  //#region src/core/migrations/planner-strategies.d.ts
@@ -1,6 +1,6 @@
1
- import { i as dataTransform, n as DataTransformOptions, t as DataTransformClosure } from "./data-transform-CxFRBIUp.mjs";
1
+ import { n as DataTransformOptions, r as dataTransform, t as DataTransformClosure } from "./data-transform-CrpmG4uJ.mjs";
2
2
  import { n as ForeignKeySpec, r as Op, t as ColumnSpec } from "./shared-Bxkt8pNO.mjs";
3
- import { t as PostgresMigration } from "./postgres-migration-BjA3Zmts.mjs";
3
+ import { t as PostgresMigration } from "./postgres-migration-BFjbb25b.mjs";
4
4
  import { placeholder } from "@prisma-next/errors/migration";
5
5
  import { MigrationCLI } from "@prisma-next/cli/migration-cli";
6
6
 
@@ -1,6 +1,6 @@
1
1
  import { _ as dropColumn, a as addEnumValues, b as setDefault, c as renameType, d as addForeignKey, f as addPrimaryKey, g as alterColumnType, h as addColumn, i as dropIndex, l as createExtension, m as dropConstraint, n as dropTable, o as createEnumType, p as addUnique, r as createIndex, s as dropEnumType, t as createTable, u as createSchema, v as dropDefault, x as setNotNull, y as dropNotNull } from "./tables-BmdW_FWO.mjs";
2
- import { t as dataTransform } from "./data-transform-VfEGzXWt.mjs";
3
- import { t as PostgresMigration } from "./postgres-migration-qtmtbONe.mjs";
2
+ import { t as dataTransform } from "./data-transform-Be_i_DBc.mjs";
3
+ import { t as PostgresMigration } from "./postgres-migration-BS9vQW97.mjs";
4
4
  import { placeholder } from "@prisma-next/errors/migration";
5
5
  import { MigrationCLI } from "@prisma-next/cli/migration-cli";
6
6
 
@@ -1 +1 @@
1
- {"version":3,"file":"op-factory-call-C3bWXKSP.d.mts","names":[],"sources":["../src/core/migrations/op-factory-call.ts"],"sourcesContent":[],"mappings":"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"}
1
+ {"version":3,"file":"op-factory-call-C3bWXKSP.d.mts","names":[],"sources":["../src/core/migrations/op-factory-call.ts"],"sourcesContent":[],"mappings":"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"}
package/dist/pack.d.mts CHANGED
@@ -1,4 +1,4 @@
1
- import { t as CodecTypes } from "./codecs-D-F2KJqt.mjs";
1
+ import { t as CodecTypes } from "./codecs-B03dFv94.mjs";
2
2
 
3
3
  //#region src/core/descriptor-meta.d.ts
4
4
  declare const postgresTargetDescriptorMetaBase: {
@@ -96,14 +96,33 @@ declare const postgresTargetDescriptorMetaBase: {
96
96
  readonly nativeType: "timestamptz";
97
97
  };
98
98
  };
99
- readonly createdAt: {
100
- readonly kind: "fieldPreset";
101
- readonly output: {
102
- readonly codecId: "pg/timestamptz@1";
103
- readonly nativeType: "timestamptz";
104
- readonly default: {
105
- readonly kind: "function";
106
- readonly expression: "now()";
99
+ readonly temporal: {
100
+ readonly createdAt: {
101
+ readonly kind: "fieldPreset";
102
+ readonly output: {
103
+ readonly codecId: "pg/timestamptz@1";
104
+ readonly nativeType: "timestamptz";
105
+ readonly default: {
106
+ readonly kind: "function";
107
+ readonly expression: "now()";
108
+ };
109
+ };
110
+ };
111
+ readonly updatedAt: {
112
+ readonly kind: "fieldPreset";
113
+ readonly output: {
114
+ readonly codecId: "pg/timestamptz@1";
115
+ readonly nativeType: "timestamptz";
116
+ readonly executionDefaults: {
117
+ readonly onCreate: {
118
+ readonly kind: "generator";
119
+ readonly id: "timestampNow";
120
+ };
121
+ readonly onUpdate: {
122
+ readonly kind: "generator";
123
+ readonly id: "timestampNow";
124
+ };
125
+ };
107
126
  };
108
127
  };
109
128
  };
@@ -1 +1 @@
1
- {"version":3,"file":"pack.d.mts","names":[],"sources":["../src/core/descriptor-meta.ts"],"sourcesContent":[],"mappings":";;;cAGM;;EAAA,SAAA,QAAA,EAAA,KAAA;EAaO,SAAA,QAAA,EAAA,UAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;cAAA,qCAAqC;0BACxB"}
1
+ {"version":3,"file":"pack.d.mts","names":[],"sources":["../src/core/descriptor-meta.ts"],"sourcesContent":[],"mappings":";;;cAGM;;EAAA,SAAA,QAAA,EAAA,KAAA;EAaO,SAAA,QAAA,EAAA,UAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;cAAA,qCAAqC;0BACxB"}