@prisma-next/target-sqlite 0.5.0-dev.67 → 0.5.0-dev.69

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 (32) hide show
  1. package/dist/control.mjs +120 -52
  2. package/dist/control.mjs.map +1 -1
  3. package/dist/migration.d.mts +11 -1
  4. package/dist/migration.d.mts.map +1 -1
  5. package/dist/migration.mjs +13 -1
  6. package/dist/migration.mjs.map +1 -1
  7. package/dist/{op-factory-call-DvewDQ7a.mjs → op-factory-call-DRKKURAO.mjs} +30 -2
  8. package/dist/{op-factory-call-DvewDQ7a.mjs.map → op-factory-call-DRKKURAO.mjs.map} +1 -1
  9. package/dist/{op-factory-call-DzKIrTLj.d.mts → op-factory-call-FrU2vXqw.d.mts} +21 -3
  10. package/dist/{op-factory-call-DzKIrTLj.d.mts.map → op-factory-call-FrU2vXqw.d.mts.map} +1 -1
  11. package/dist/op-factory-call.d.mts +2 -2
  12. package/dist/op-factory-call.mjs +2 -2
  13. package/dist/{planner-CIjeXa04.mjs → planner-C94LJeIM.mjs} +11 -5
  14. package/dist/{planner-CIjeXa04.mjs.map → planner-C94LJeIM.mjs.map} +1 -1
  15. package/dist/{planner-produced-sqlite-migration-IZZt7TRg.d.mts → planner-produced-sqlite-migration-BblR19lI.d.mts} +2 -2
  16. package/dist/{planner-produced-sqlite-migration-IZZt7TRg.d.mts.map → planner-produced-sqlite-migration-BblR19lI.d.mts.map} +1 -1
  17. package/dist/planner-produced-sqlite-migration.d.mts +1 -1
  18. package/dist/planner.d.mts +1 -1
  19. package/dist/planner.d.mts.map +1 -1
  20. package/dist/planner.mjs +1 -1
  21. package/dist/render-ops.d.mts +1 -1
  22. package/dist/{statement-builders-DMT4ltXR.mjs → statement-builders-Dne-LkAV.mjs} +4 -4
  23. package/dist/statement-builders-Dne-LkAV.mjs.map +1 -0
  24. package/dist/statement-builders.mjs +1 -1
  25. package/package.json +17 -17
  26. package/src/core/migrations/op-factory-call.ts +38 -1
  27. package/src/core/migrations/operations/raw.ts +12 -0
  28. package/src/core/migrations/planner.ts +30 -2
  29. package/src/core/migrations/runner.ts +164 -75
  30. package/src/exports/migration.ts +1 -0
  31. package/src/exports/op-factory-call.ts +1 -0
  32. package/dist/statement-builders-DMT4ltXR.mjs.map +0 -1
@@ -1,6 +1,7 @@
1
1
  import type { ContractMarkerRecord } from '@prisma-next/contract/types';
2
2
  import type {
3
3
  MigrationOperationPolicy,
4
+ MultiSpaceRunnerResult,
4
5
  SqlControlFamilyInstance,
5
6
  SqlMigrationPlanContractInfo,
6
7
  SqlMigrationPlanOperation,
@@ -9,13 +10,16 @@ import type {
9
10
  SqlMigrationRunnerExecuteOptions,
10
11
  SqlMigrationRunnerFailure,
11
12
  SqlMigrationRunnerResult,
13
+ SqlMigrationRunnerSuccessValue,
12
14
  } from '@prisma-next/family-sql/control';
13
15
  import { runnerFailure, runnerSuccess } from '@prisma-next/family-sql/control';
14
16
  import { verifySqlSchema } from '@prisma-next/family-sql/schema-verify';
15
17
  import { type ContractMarkerRow, parseContractMarkerRow } from '@prisma-next/family-sql/verify';
18
+ import type { ControlDriverInstance } from '@prisma-next/framework-components/control';
19
+ import { APP_SPACE_ID } from '@prisma-next/framework-components/control';
16
20
  import { ifDefined } from '@prisma-next/utils/defined';
17
21
  import type { Result } from '@prisma-next/utils/result';
18
- import { ok, okVoid } from '@prisma-next/utils/result';
22
+ import { notOk, ok, okVoid } from '@prisma-next/utils/result';
19
23
  import { parseSqliteDefault } from '../default-normalizer';
20
24
  import { normalizeSqliteNativeType } from '../native-type-normalizer';
21
25
  import type { SqlitePlanTargetDetails } from './planner-target-details';
@@ -47,14 +51,10 @@ class SqliteMigrationRunner implements SqlMigrationRunner<SqlitePlanTargetDetail
47
51
  options.plan.destination,
48
52
  options.destinationContract,
49
53
  );
50
- if (!destinationCheck.ok) {
51
- return destinationCheck;
52
- }
54
+ if (!destinationCheck.ok) return destinationCheck;
53
55
 
54
56
  const policyCheck = this.enforcePolicyCompatibility(options.policy, options.plan.operations);
55
- if (!policyCheck.ok) {
56
- return policyCheck;
57
- }
57
+ if (!policyCheck.ok) return policyCheck;
58
58
 
59
59
  // SQLite recreate-table drops and rebuilds the table. If foreign_keys is ON,
60
60
  // dropping a referenced parent cascade-deletes child rows; we must disable FK
@@ -70,92 +70,180 @@ class SqliteMigrationRunner implements SqlMigrationRunner<SqlitePlanTargetDetail
70
70
  await this.beginExclusiveTransaction(driver);
71
71
  let committed = false;
72
72
  try {
73
- const ensureResult = await this.ensureControlTables(driver);
74
- if (!ensureResult.ok) {
75
- return ensureResult;
76
- }
77
- const existingMarker = await this.readMarker(driver, options.plan.spaceId);
73
+ const result = await this.executeOnConnection(options);
74
+ if (!result.ok) return result;
78
75
 
79
- const markerCheck = this.ensureMarkerCompatibility(existingMarker, options.plan);
80
- if (!markerCheck.ok) {
81
- return markerCheck;
76
+ if (fkWasEnabled) {
77
+ const fkIntegrityCheck = await this.verifyForeignKeyIntegrity(driver);
78
+ if (!fkIntegrityCheck.ok) return fkIntegrityCheck;
82
79
  }
83
80
 
84
- const markerAtDestination = this.markerMatchesDestination(existingMarker, options.plan);
85
- const isSelfEdge =
86
- options.plan.origin?.storageHash === options.plan.destination.storageHash;
87
- const skipOperations = markerAtDestination && options.plan.origin != null && !isSelfEdge;
88
-
89
- let operationsExecuted: number;
90
- let executedOperations: readonly SqlMigrationPlanOperation<SqlitePlanTargetDetails>[];
91
-
92
- if (skipOperations) {
93
- operationsExecuted = 0;
94
- executedOperations = [];
95
- } else {
96
- const applyResult = await this.applyPlan(driver, options);
97
- if (!applyResult.ok) {
98
- return applyResult;
99
- }
100
- operationsExecuted = applyResult.value.operationsExecuted;
101
- executedOperations = applyResult.value.executedOperations;
81
+ await this.commitTransaction(driver);
82
+ committed = true;
83
+ return result;
84
+ } finally {
85
+ if (!committed) {
86
+ await this.rollbackTransaction(driver);
102
87
  }
88
+ }
89
+ } finally {
90
+ if (fkWasEnabled) {
91
+ await driver.query('PRAGMA foreign_keys = ON');
92
+ }
93
+ }
94
+ }
103
95
 
104
- const schemaIR = await this.family.introspect({
105
- driver,
106
- contract: options.destinationContract,
107
- });
96
+ /**
97
+ * Apply the plan against an already-open connection without managing
98
+ * the transaction lifecycle. The caller owns BEGIN/COMMIT/ROLLBACK
99
+ * and any connection-level setup (FK pragma toggle, FK integrity
100
+ * check). Used by the per-space runner orchestration to fan out
101
+ * across contract spaces inside one outer transaction.
102
+ */
103
+ async executeOnConnection(
104
+ options: SqlMigrationRunnerExecuteOptions<SqlitePlanTargetDetails>,
105
+ ): Promise<SqlMigrationRunnerResult> {
106
+ const driver = options.driver;
107
+ if (options.space !== undefined && options.space !== options.plan.spaceId) {
108
+ throw new Error(
109
+ `SqlMigrationRunner: options.space (${options.space}) does not match plan.spaceId (${options.plan.spaceId})`,
110
+ );
111
+ }
112
+ const space = options.plan.spaceId;
108
113
 
109
- const schemaVerifyResult = verifySqlSchema({
110
- contract: options.destinationContract,
111
- schema: schemaIR,
112
- strict: options.strictVerification ?? true,
113
- context: options.context ?? {},
114
- typeMetadataRegistry: this.family.typeMetadataRegistry,
115
- frameworkComponents: options.frameworkComponents,
116
- normalizeDefault: parseSqliteDefault,
117
- normalizeNativeType: normalizeSqliteNativeType,
114
+ const destinationCheck = this.ensurePlanMatchesDestinationContract(
115
+ options.plan.destination,
116
+ options.destinationContract,
117
+ );
118
+ if (!destinationCheck.ok) return destinationCheck;
119
+
120
+ const policyCheck = this.enforcePolicyCompatibility(options.policy, options.plan.operations);
121
+ if (!policyCheck.ok) return policyCheck;
122
+
123
+ const ensureResult = await this.ensureControlTables(driver);
124
+ if (!ensureResult.ok) return ensureResult;
125
+ const existingMarker = await this.readMarker(driver, space);
126
+
127
+ const markerCheck = this.ensureMarkerCompatibility(existingMarker, options.plan);
128
+ if (!markerCheck.ok) return markerCheck;
129
+
130
+ const markerAtDestination = this.markerMatchesDestination(existingMarker, options.plan);
131
+ const isSelfEdge = options.plan.origin?.storageHash === options.plan.destination.storageHash;
132
+ const skipOperations = markerAtDestination && options.plan.origin != null && !isSelfEdge;
133
+
134
+ let operationsExecuted: number;
135
+ let executedOperations: readonly SqlMigrationPlanOperation<SqlitePlanTargetDetails>[];
136
+
137
+ if (skipOperations) {
138
+ operationsExecuted = 0;
139
+ executedOperations = [];
140
+ } else {
141
+ const applyResult = await this.applyPlan(driver, options);
142
+ if (!applyResult.ok) return applyResult;
143
+ operationsExecuted = applyResult.value.operationsExecuted;
144
+ executedOperations = applyResult.value.executedOperations;
145
+ }
146
+
147
+ if (space === APP_SPACE_ID) {
148
+ const schemaIR = await this.family.introspect({
149
+ driver,
150
+ contract: options.destinationContract,
151
+ });
152
+
153
+ const schemaVerifyResult = verifySqlSchema({
154
+ contract: options.destinationContract,
155
+ schema: schemaIR,
156
+ strict: options.strictVerification ?? true,
157
+ context: options.context ?? {},
158
+ typeMetadataRegistry: this.family.typeMetadataRegistry,
159
+ frameworkComponents: options.frameworkComponents,
160
+ normalizeDefault: parseSqliteDefault,
161
+ normalizeNativeType: normalizeSqliteNativeType,
162
+ });
163
+ if (!schemaVerifyResult.ok) {
164
+ return runnerFailure('SCHEMA_VERIFY_FAILED', schemaVerifyResult.summary, {
165
+ why: 'The resulting database schema does not satisfy the destination contract.',
166
+ meta: { issues: schemaVerifyResult.schema.issues },
118
167
  });
119
- if (!schemaVerifyResult.ok) {
120
- return runnerFailure('SCHEMA_VERIFY_FAILED', schemaVerifyResult.summary, {
121
- why: 'The resulting database schema does not satisfy the destination contract.',
122
- meta: {
123
- issues: schemaVerifyResult.schema.issues,
124
- },
125
- });
126
- }
168
+ }
169
+ }
127
170
 
128
- // Self-edge no-op detection: a self-edge migration whose ops had no
129
- // ops to begin with and brings no new invariants produced no
130
- // observable change. Skip the marker + ledger writes so an idempotent
131
- // re-apply of a self-edge data transform doesn't churn updatedAt or
132
- // pile up empty ledger entries. db update no-ops still write a
133
- // ledger entry as audit trail.
134
- const incomingInvariants = options.plan.providedInvariants;
135
- const existingInvariants = new Set(existingMarker?.invariants ?? []);
136
- const incomingIsSubsetOfExisting = incomingInvariants.every((id) =>
137
- existingInvariants.has(id),
138
- );
139
- const isSelfEdgeNoOp = isSelfEdge && operationsExecuted === 0 && incomingIsSubsetOfExisting;
171
+ // Self-edge no-op detection: see Postgres runner for the rationale
172
+ // (kept symmetric across both targets).
173
+ const incomingInvariants = options.plan.providedInvariants;
174
+ const existingInvariants = new Set(existingMarker?.invariants ?? []);
175
+ const incomingIsSubsetOfExisting = incomingInvariants.every((id) => existingInvariants.has(id));
176
+ const isSelfEdgeNoOp = isSelfEdge && operationsExecuted === 0 && incomingIsSubsetOfExisting;
177
+
178
+ if (!isSelfEdgeNoOp) {
179
+ await this.upsertMarker(driver, options, existingMarker, space);
180
+ await this.recordLedgerEntry(driver, options, existingMarker, executedOperations);
181
+ }
182
+
183
+ return runnerSuccess({
184
+ operationsPlanned: options.plan.operations.length,
185
+ operationsExecuted,
186
+ });
187
+ }
188
+
189
+ async executeAcrossSpaces(options: {
190
+ readonly driver: ControlDriverInstance<'sql', string>;
191
+ readonly perSpaceOptions: ReadonlyArray<
192
+ SqlMigrationRunnerExecuteOptions<SqlitePlanTargetDetails>
193
+ >;
194
+ }): Promise<MultiSpaceRunnerResult> {
195
+ const driver = options.driver;
196
+ const perSpaceOptions = options.perSpaceOptions;
140
197
 
141
- if (!isSelfEdgeNoOp) {
142
- await this.upsertMarker(driver, options, existingMarker);
143
- await this.recordLedgerEntry(driver, options, existingMarker, executedOperations);
198
+ if (perSpaceOptions.length === 0) {
199
+ return ok({ perSpaceResults: [] });
200
+ }
201
+
202
+ // FK pragma toggle and the FK integrity check both span the outer
203
+ // transaction — see `execute(...)` for the full rationale.
204
+ const fkWasEnabled = await this.readForeignKeysEnabled(driver);
205
+ if (fkWasEnabled) {
206
+ await driver.query('PRAGMA foreign_keys = OFF');
207
+ }
208
+
209
+ try {
210
+ await this.beginExclusiveTransaction(driver);
211
+ let committed = false;
212
+ try {
213
+ const perSpaceResults: Array<{
214
+ space: string;
215
+ value: SqlMigrationRunnerSuccessValue;
216
+ }> = [];
217
+ let lastProcessedSpace: string | undefined;
218
+ for (const spaceOptions of perSpaceOptions) {
219
+ const space = spaceOptions.space ?? spaceOptions.plan.spaceId;
220
+ const result = await this.executeOnConnection({ ...spaceOptions, driver, space });
221
+ if (!result.ok) {
222
+ return notOk({ ...result.failure, failingSpace: space });
223
+ }
224
+ perSpaceResults.push({ space, value: result.value });
225
+ lastProcessedSpace = space;
144
226
  }
145
227
 
146
228
  if (fkWasEnabled) {
147
229
  const fkIntegrityCheck = await this.verifyForeignKeyIntegrity(driver);
148
230
  if (!fkIntegrityCheck.ok) {
149
- return fkIntegrityCheck;
231
+ // Post-loop integrity violations cannot be attributed to a
232
+ // single per-space step (the cumulative effect of all
233
+ // applied plans was needed to reveal the broken
234
+ // reference). Surface the last successfully-applied space
235
+ // so operators can investigate from the most recent
236
+ // migration first.
237
+ return notOk({
238
+ ...fkIntegrityCheck.failure,
239
+ failingSpace: lastProcessedSpace ?? APP_SPACE_ID,
240
+ });
150
241
  }
151
242
  }
152
243
 
153
244
  await this.commitTransaction(driver);
154
245
  committed = true;
155
- return runnerSuccess({
156
- operationsPlanned: options.plan.operations.length,
157
- operationsExecuted,
158
- });
246
+ return ok({ perSpaceResults });
159
247
  } finally {
160
248
  if (!committed) {
161
249
  await this.rollbackTransaction(driver);
@@ -560,6 +648,7 @@ class SqliteMigrationRunner implements SqlMigrationRunner<SqlitePlanTargetDetail
560
648
  driver: SqlMigrationRunnerExecuteOptions<SqlitePlanTargetDetails>['driver'],
561
649
  options: SqlMigrationRunnerExecuteOptions<SqlitePlanTargetDetails>,
562
650
  existingMarker: ContractMarkerRecord | null,
651
+ space: string,
563
652
  ): Promise<void> {
564
653
  // SQLite has no native array type, so we can't merge invariants in SQL
565
654
  // the way Postgres does. Merge client-side under the runner's
@@ -568,7 +657,7 @@ class SqliteMigrationRunner implements SqlMigrationRunner<SqlitePlanTargetDetail
568
657
  for (const inv of options.plan.providedInvariants) merged.add(inv);
569
658
  const invariants = Array.from(merged).sort();
570
659
  const writeStatements = buildWriteMarkerStatements({
571
- space: options.plan.spaceId,
660
+ space,
572
661
  storageHash: options.plan.destination.storageHash,
573
662
  profileHash:
574
663
  options.plan.destination.profileHash ??
@@ -15,6 +15,7 @@ export {
15
15
  dataTransform,
16
16
  } from '../core/migrations/operations/data-transform';
17
17
  export { createIndex, dropIndex } from '../core/migrations/operations/indexes';
18
+ export { rawSql } from '../core/migrations/operations/raw';
18
19
  export { createTable, dropTable, recreateTable } from '../core/migrations/operations/tables';
19
20
  // Target-owned base class for migrations. Aliased to `Migration` so
20
21
  // user-edited migration.ts files (and the renderer's scaffold) read as
@@ -6,6 +6,7 @@ export {
6
6
  DropColumnCall,
7
7
  DropIndexCall,
8
8
  DropTableCall,
9
+ RawSqlCall,
9
10
  RecreateTableCall,
10
11
  type SqliteOpFactoryCall,
11
12
  } from '../core/migrations/op-factory-call';
@@ -1 +0,0 @@
1
- {"version":3,"file":"statement-builders-DMT4ltXR.mjs","names":[],"sources":["../src/core/migrations/statement-builders.ts"],"sourcesContent":["import { APP_SPACE_ID } from '@prisma-next/framework-components/control';\n\nexport { APP_SPACE_ID };\n\nexport interface SqlStatement {\n readonly sql: string;\n readonly params: readonly unknown[];\n}\n\nexport const MARKER_TABLE_NAME = '_prisma_marker';\nexport const LEDGER_TABLE_NAME = '_prisma_ledger';\n\n/**\n * Control tables the runner creates/manages. The planner must not drop these\n * when reconciling \"extra\" tables against the contract.\n */\nexport const CONTROL_TABLE_NAMES: ReadonlySet<string> = new Set([\n MARKER_TABLE_NAME,\n LEDGER_TABLE_NAME,\n]);\n\n/**\n * Schema for `_prisma_marker`. The `space TEXT PRIMARY KEY` shape\n * supports one row per loaded contract space (`'app'`,\n * `'<extension-id>'`, …); brand-new databases create this shape\n * directly. The migration runner detects pre-1.0 single-row markers\n * (no `space` column) at boot and fails with a structured\n * `LEGACY_MARKER_SHAPE` error rather than auto-rebuilding the table —\n * see `specs/framework-mechanism.spec.md § 2`.\n */\nexport const ensureMarkerTableStatement: SqlStatement = {\n sql: `CREATE TABLE IF NOT EXISTS _prisma_marker (\n space TEXT NOT NULL PRIMARY KEY DEFAULT '${APP_SPACE_ID}',\n core_hash TEXT NOT NULL,\n profile_hash TEXT NOT NULL,\n contract_json TEXT,\n canonical_version INTEGER,\n updated_at TEXT NOT NULL DEFAULT (datetime('now')),\n app_tag TEXT,\n meta TEXT NOT NULL DEFAULT '{}',\n invariants TEXT NOT NULL DEFAULT '[]'\n )`,\n params: [],\n};\n\nexport const ensureLedgerTableStatement: SqlStatement = {\n sql: `CREATE TABLE IF NOT EXISTS _prisma_ledger (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n created_at TEXT NOT NULL DEFAULT (datetime('now')),\n origin_core_hash TEXT,\n origin_profile_hash TEXT,\n destination_core_hash TEXT NOT NULL,\n destination_profile_hash TEXT,\n contract_json_before TEXT,\n contract_json_after TEXT,\n operations TEXT NOT NULL\n )`,\n params: [],\n};\n\nexport function readMarkerStatement(space: string): SqlStatement {\n return {\n sql: `SELECT\n core_hash,\n profile_hash,\n contract_json,\n canonical_version,\n updated_at,\n app_tag,\n meta,\n invariants\n FROM _prisma_marker\n WHERE space = ?`,\n params: [space],\n };\n}\n\nexport interface WriteMarkerInput {\n /**\n * Logical space identifier for this marker row. Required at every\n * call site so the type system surfaces every place that needs to\n * thread the value (rather than letting an `?? APP_SPACE_ID`\n * fall-through silently collapse multi-space markers onto the\n * `'app'` row). App-plan callers pass {@link APP_SPACE_ID}\n * (`'app'`); per-extension callers pass the extension's space id.\n */\n readonly space: string;\n readonly storageHash: string;\n readonly profileHash: string;\n readonly contractJson?: unknown;\n readonly canonicalVersion?: number | null;\n readonly appTag?: string | null;\n readonly meta?: Record<string, unknown>;\n /**\n * Invariants to write into `marker.invariants`. Stored as a JSON-encoded\n * TEXT array — SQLite has no native array type. The runner is responsible\n * for merging with the existing column (no SQL-side merge here, unlike\n * Postgres) before passing them in: BEGIN EXCLUSIVE on the migration\n * transaction makes the read-then-merge-then-write sequence safe.\n */\n readonly invariants: readonly string[];\n}\n\nexport function buildWriteMarkerStatements(input: WriteMarkerInput): {\n readonly insert: SqlStatement;\n readonly update: SqlStatement;\n} {\n const params: readonly unknown[] = [\n input.space,\n input.storageHash,\n input.profileHash,\n jsonParam(input.contractJson),\n input.canonicalVersion ?? null,\n input.appTag ?? null,\n jsonParam(input.meta ?? {}),\n jsonParam(input.invariants),\n ];\n\n return {\n insert: {\n sql: `INSERT INTO _prisma_marker (\n space,\n core_hash,\n profile_hash,\n contract_json,\n canonical_version,\n updated_at,\n app_tag,\n meta,\n invariants\n ) VALUES (\n ?,\n ?,\n ?,\n ?,\n ?,\n datetime('now'),\n ?,\n ?,\n ?\n )`,\n params,\n },\n update: {\n sql: `UPDATE _prisma_marker SET\n core_hash = ?,\n profile_hash = ?,\n contract_json = ?,\n canonical_version = ?,\n updated_at = datetime('now'),\n app_tag = ?,\n meta = ?,\n invariants = ?\n WHERE space = ?`,\n params: [\n input.storageHash,\n input.profileHash,\n jsonParam(input.contractJson),\n input.canonicalVersion ?? null,\n input.appTag ?? null,\n jsonParam(input.meta ?? {}),\n jsonParam(input.invariants),\n input.space,\n ],\n },\n };\n}\n\nexport interface LedgerInsertInput {\n readonly originStorageHash?: string | null;\n readonly originProfileHash?: string | null;\n readonly destinationStorageHash: string;\n readonly destinationProfileHash?: string | null;\n readonly contractJsonBefore?: unknown;\n readonly contractJsonAfter?: unknown;\n readonly operations: unknown;\n}\n\nexport function buildLedgerInsertStatement(input: LedgerInsertInput): SqlStatement {\n return {\n sql: `INSERT INTO _prisma_ledger (\n origin_core_hash,\n origin_profile_hash,\n destination_core_hash,\n destination_profile_hash,\n contract_json_before,\n contract_json_after,\n operations\n ) VALUES (\n ?,\n ?,\n ?,\n ?,\n ?,\n ?,\n ?\n )`,\n params: [\n input.originStorageHash ?? null,\n input.originProfileHash ?? null,\n input.destinationStorageHash,\n input.destinationProfileHash ?? null,\n jsonParam(input.contractJsonBefore),\n jsonParam(input.contractJsonAfter),\n jsonParam(input.operations),\n ],\n };\n}\n\nfunction jsonParam(value: unknown): string {\n return JSON.stringify(value ?? null);\n}\n"],"mappings":";;AASA,MAAa,oBAAoB;AACjC,MAAa,oBAAoB;;;;;AAMjC,MAAa,sBAA2C,IAAI,IAAI,CAC9D,mBACA,kBACD,CAAC;;;;;;;;;;AAWF,MAAa,6BAA2C;CACtD,KAAK;+CACwC,aAAa;;;;;;;;;;CAU1D,QAAQ,EAAE;CACX;AAED,MAAa,6BAA2C;CACtD,KAAK;;;;;;;;;;;CAWL,QAAQ,EAAE;CACX;AAED,SAAgB,oBAAoB,OAA6B;CAC/D,OAAO;EACL,KAAK;;;;;;;;;;;EAWL,QAAQ,CAAC,MAAM;EAChB;;AA6BH,SAAgB,2BAA2B,OAGzC;CAYA,OAAO;EACL,QAAQ;GACN,KAAK;;;;;;;;;;;;;;;;;;;;;GAqBL,QAAA;IAjCF,MAAM;IACN,MAAM;IACN,MAAM;IACN,UAAU,MAAM,aAAa;IAC7B,MAAM,oBAAoB;IAC1B,MAAM,UAAU;IAChB,UAAU,MAAM,QAAQ,EAAE,CAAC;IAC3B,UAAU,MAAM,WAAW;IA0BnB;GACP;EACD,QAAQ;GACN,KAAK;;;;;;;;;;GAUL,QAAQ;IACN,MAAM;IACN,MAAM;IACN,UAAU,MAAM,aAAa;IAC7B,MAAM,oBAAoB;IAC1B,MAAM,UAAU;IAChB,UAAU,MAAM,QAAQ,EAAE,CAAC;IAC3B,UAAU,MAAM,WAAW;IAC3B,MAAM;IACP;GACF;EACF;;AAaH,SAAgB,2BAA2B,OAAwC;CACjF,OAAO;EACL,KAAK;;;;;;;;;;;;;;;;;EAiBL,QAAQ;GACN,MAAM,qBAAqB;GAC3B,MAAM,qBAAqB;GAC3B,MAAM;GACN,MAAM,0BAA0B;GAChC,UAAU,MAAM,mBAAmB;GACnC,UAAU,MAAM,kBAAkB;GAClC,UAAU,MAAM,WAAW;GAC5B;EACF;;AAGH,SAAS,UAAU,OAAwB;CACzC,OAAO,KAAK,UAAU,SAAS,KAAK"}