@prisma-next/cli 0.3.0-dev.53 → 0.3.0-dev.54
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +24 -0
- package/dist/cli.mjs +5 -3
- package/dist/cli.mjs.map +1 -1
- package/dist/{client-BSZKpZTF.mjs → client-B7f4PZZ1.mjs} +367 -170
- package/dist/client-B7f4PZZ1.mjs.map +1 -0
- package/dist/commands/contract-emit.d.mts.map +1 -1
- package/dist/commands/contract-emit.mjs +7 -6
- package/dist/commands/contract-emit.mjs.map +1 -1
- package/dist/commands/db-init.d.mts.map +1 -1
- package/dist/commands/db-init.mjs +28 -76
- package/dist/commands/db-init.mjs.map +1 -1
- package/dist/commands/db-introspect.d.mts.map +1 -1
- package/dist/commands/db-introspect.mjs +12 -17
- package/dist/commands/db-introspect.mjs.map +1 -1
- package/dist/commands/db-schema-verify.d.mts.map +1 -1
- package/dist/commands/db-schema-verify.mjs +5 -4
- package/dist/commands/db-schema-verify.mjs.map +1 -1
- package/dist/commands/db-sign.d.mts.map +1 -1
- package/dist/commands/db-sign.mjs +6 -5
- package/dist/commands/db-sign.mjs.map +1 -1
- package/dist/commands/db-update.d.mts +7 -0
- package/dist/commands/db-update.d.mts.map +1 -0
- package/dist/commands/db-update.mjs +120 -0
- package/dist/commands/db-update.mjs.map +1 -0
- package/dist/commands/db-verify.d.mts.map +1 -1
- package/dist/commands/db-verify.mjs +5 -4
- package/dist/commands/db-verify.mjs.map +1 -1
- package/dist/{config-loader-BJ8HsEdA.mjs → config-loader-DqKf1qSa.mjs} +1 -1
- package/dist/{config-loader-BJ8HsEdA.mjs.map → config-loader-DqKf1qSa.mjs.map} +1 -1
- package/dist/config-loader.mjs +1 -1
- package/dist/exports/control-api.d.mts +96 -6
- package/dist/exports/control-api.d.mts.map +1 -1
- package/dist/exports/control-api.mjs +2 -2
- package/dist/exports/index.mjs +1 -3
- package/dist/exports/index.mjs.map +1 -1
- package/dist/migration-command-scaffold-BELw_do2.mjs +95 -0
- package/dist/migration-command-scaffold-BELw_do2.mjs.map +1 -0
- package/dist/{result-handler-BZPY7HX4.mjs → result-handler-BhmrXIvT.mjs} +63 -13
- package/dist/result-handler-BhmrXIvT.mjs.map +1 -0
- package/package.json +16 -12
- package/src/cli.ts +5 -0
- package/src/commands/contract-emit.ts +22 -6
- package/src/commands/db-init.ts +89 -197
- package/src/commands/db-introspect.ts +4 -8
- package/src/commands/db-schema-verify.ts +11 -2
- package/src/commands/db-sign.ts +13 -4
- package/src/commands/db-update.ts +220 -0
- package/src/commands/db-verify.ts +11 -2
- package/src/control-api/client.ts +109 -145
- package/src/control-api/errors.ts +9 -0
- package/src/control-api/operations/db-init.ts +39 -34
- package/src/control-api/operations/db-update.ts +221 -0
- package/src/control-api/operations/extract-sql-ddl.ts +47 -0
- package/src/control-api/operations/migration-helpers.ts +49 -0
- package/src/control-api/types.ts +104 -4
- package/src/exports/control-api.ts +5 -0
- package/src/utils/cli-errors.ts +2 -0
- package/src/utils/command-helpers.ts +81 -3
- package/src/utils/migration-command-scaffold.ts +189 -0
- package/src/utils/output.ts +43 -13
- package/dist/client-BSZKpZTF.mjs.map +0 -1
- package/dist/result-handler-BZPY7HX4.mjs.map +0 -1
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { CliStructuredError, errorConfigValidation, errorContractConfigMissing as errorContractConfigMissing$1, errorContractValidationFailed, errorDatabaseConnectionRequired, errorDriverRequired, errorFileNotFound, errorHashMismatch, errorJsonFormatNotSupported, errorMarkerMissing, errorMigrationPlanningFailed, errorRuntime, errorTargetMigrationNotSupported, errorTargetMismatch, errorUnexpected as errorUnexpected$1 } from "@prisma-next/core-control-plane/errors";
|
|
1
|
+
import { CliStructuredError, errorConfigValidation, errorContractConfigMissing as errorContractConfigMissing$1, errorContractValidationFailed, errorDatabaseConnectionRequired, errorDestructiveChanges, errorDriverRequired, errorFileNotFound, errorHashMismatch, errorJsonFormatNotSupported, errorMarkerMissing, errorMigrationPlanningFailed, errorRunnerFailed, errorRuntime, errorTargetMigrationNotSupported, errorTargetMismatch, errorUnexpected as errorUnexpected$1 } from "@prisma-next/core-control-plane/errors";
|
|
2
2
|
import { notOk, ok } from "@prisma-next/utils/result";
|
|
3
3
|
import { createControlPlaneStack } from "@prisma-next/core-control-plane/stack";
|
|
4
4
|
import { ifDefined } from "@prisma-next/utils/defined";
|
|
@@ -57,6 +57,81 @@ function assertFrameworkComponentsCompatible(expectedFamilyId, expectedTargetId,
|
|
|
57
57
|
return frameworkComponents;
|
|
58
58
|
}
|
|
59
59
|
|
|
60
|
+
//#endregion
|
|
61
|
+
//#region src/control-api/errors.ts
|
|
62
|
+
var ContractValidationError = class extends Error {
|
|
63
|
+
cause;
|
|
64
|
+
constructor(message, cause) {
|
|
65
|
+
super(message);
|
|
66
|
+
this.name = "ContractValidationError";
|
|
67
|
+
this.cause = cause;
|
|
68
|
+
}
|
|
69
|
+
};
|
|
70
|
+
|
|
71
|
+
//#endregion
|
|
72
|
+
//#region src/control-api/operations/extract-sql-ddl.ts
|
|
73
|
+
function isDdlStatement(sqlStatement) {
|
|
74
|
+
const trimmed = sqlStatement.trim().toLowerCase();
|
|
75
|
+
return trimmed.startsWith("create ") || trimmed.startsWith("alter ") || trimmed.startsWith("drop ");
|
|
76
|
+
}
|
|
77
|
+
function hasExecuteSteps(operation) {
|
|
78
|
+
const candidate = operation;
|
|
79
|
+
if (!("execute" in candidate) || !Array.isArray(candidate["execute"])) return false;
|
|
80
|
+
return candidate["execute"].every((step) => typeof step === "object" && step !== null && "sql" in step);
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Extracts a best-effort SQL DDL preview for CLI plan output.
|
|
84
|
+
* This helper is presentation-only and is never used to decide migration correctness.
|
|
85
|
+
*/
|
|
86
|
+
function extractSqlDdl(operations) {
|
|
87
|
+
const statements = [];
|
|
88
|
+
for (const operation of operations) {
|
|
89
|
+
if (!hasExecuteSteps(operation)) continue;
|
|
90
|
+
for (const step of operation.execute) if (typeof step.sql === "string" && isDdlStatement(step.sql)) statements.push(step.sql.trim());
|
|
91
|
+
}
|
|
92
|
+
return statements;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
//#endregion
|
|
96
|
+
//#region src/control-api/operations/migration-helpers.ts
|
|
97
|
+
/**
|
|
98
|
+
* Strips operation objects to their public shape (id, label, operationClass).
|
|
99
|
+
* Used at the API boundary to avoid leaking internal fields (precheck, execute, postcheck, etc.).
|
|
100
|
+
*/
|
|
101
|
+
function stripOperations(operations) {
|
|
102
|
+
return operations.map((op) => ({
|
|
103
|
+
id: op.id,
|
|
104
|
+
label: op.label,
|
|
105
|
+
operationClass: op.operationClass
|
|
106
|
+
}));
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* Creates per-operation progress callbacks for the runner.
|
|
110
|
+
* Returns undefined when no onProgress callback is provided.
|
|
111
|
+
*/
|
|
112
|
+
function createOperationCallbacks(onProgress, action, parentSpanId) {
|
|
113
|
+
if (!onProgress) return;
|
|
114
|
+
return {
|
|
115
|
+
onOperationStart: (op) => {
|
|
116
|
+
onProgress({
|
|
117
|
+
action,
|
|
118
|
+
kind: "spanStart",
|
|
119
|
+
spanId: `operation:${op.id}`,
|
|
120
|
+
parentSpanId,
|
|
121
|
+
label: op.label
|
|
122
|
+
});
|
|
123
|
+
},
|
|
124
|
+
onOperationComplete: (op) => {
|
|
125
|
+
onProgress({
|
|
126
|
+
action,
|
|
127
|
+
kind: "spanEnd",
|
|
128
|
+
spanId: `operation:${op.id}`,
|
|
129
|
+
outcome: "ok"
|
|
130
|
+
});
|
|
131
|
+
}
|
|
132
|
+
};
|
|
133
|
+
}
|
|
134
|
+
|
|
60
135
|
//#endregion
|
|
61
136
|
//#region src/control-api/operations/db-init.ts
|
|
62
137
|
/**
|
|
@@ -128,7 +203,7 @@ async function executeDbInit(options) {
|
|
|
128
203
|
action: "dbInit",
|
|
129
204
|
kind: "spanStart",
|
|
130
205
|
spanId: checkMarkerSpanId,
|
|
131
|
-
label: "Checking
|
|
206
|
+
label: "Checking database signature"
|
|
132
207
|
});
|
|
133
208
|
const existingMarker = await familyInstance.readMarker({ driver });
|
|
134
209
|
if (existingMarker) {
|
|
@@ -142,16 +217,18 @@ async function executeDbInit(options) {
|
|
|
142
217
|
return ok({
|
|
143
218
|
mode,
|
|
144
219
|
plan: { operations: [] },
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
220
|
+
destination: {
|
|
221
|
+
storageHash: migrationPlan.destination.storageHash,
|
|
222
|
+
...ifDefined("profileHash", migrationPlan.destination.profileHash)
|
|
223
|
+
},
|
|
224
|
+
...ifDefined("execution", mode === "apply" ? {
|
|
225
|
+
operationsPlanned: 0,
|
|
226
|
+
operationsExecuted: 0
|
|
227
|
+
} : void 0),
|
|
228
|
+
...ifDefined("marker", mode === "apply" ? {
|
|
229
|
+
storageHash: existingMarker.storageHash,
|
|
230
|
+
profileHash: existingMarker.profileHash
|
|
231
|
+
} : void 0),
|
|
155
232
|
summary: "Database already at target contract state"
|
|
156
233
|
});
|
|
157
234
|
}
|
|
@@ -183,11 +260,21 @@ async function executeDbInit(options) {
|
|
|
183
260
|
spanId: checkMarkerSpanId,
|
|
184
261
|
outcome: "ok"
|
|
185
262
|
});
|
|
186
|
-
if (mode === "plan")
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
263
|
+
if (mode === "plan") {
|
|
264
|
+
const planSql = familyInstance.familyId === "sql" ? extractSqlDdl(migrationPlan.operations) : void 0;
|
|
265
|
+
return ok({
|
|
266
|
+
mode: "plan",
|
|
267
|
+
plan: {
|
|
268
|
+
operations: stripOperations(migrationPlan.operations),
|
|
269
|
+
...ifDefined("sql", planSql)
|
|
270
|
+
},
|
|
271
|
+
destination: {
|
|
272
|
+
storageHash: migrationPlan.destination.storageHash,
|
|
273
|
+
...ifDefined("profileHash", migrationPlan.destination.profileHash)
|
|
274
|
+
},
|
|
275
|
+
summary: `Planned ${migrationPlan.operations.length} operation(s)`
|
|
276
|
+
});
|
|
277
|
+
}
|
|
191
278
|
const applySpanId = "apply";
|
|
192
279
|
onProgress?.({
|
|
193
280
|
action: "dbInit",
|
|
@@ -195,31 +282,13 @@ async function executeDbInit(options) {
|
|
|
195
282
|
spanId: applySpanId,
|
|
196
283
|
label: "Applying migration plan"
|
|
197
284
|
});
|
|
198
|
-
const callbacks = onProgress
|
|
199
|
-
onOperationStart: (op) => {
|
|
200
|
-
onProgress({
|
|
201
|
-
action: "dbInit",
|
|
202
|
-
kind: "spanStart",
|
|
203
|
-
spanId: `operation:${op.id}`,
|
|
204
|
-
parentSpanId: applySpanId,
|
|
205
|
-
label: op.label
|
|
206
|
-
});
|
|
207
|
-
},
|
|
208
|
-
onOperationComplete: (op) => {
|
|
209
|
-
onProgress({
|
|
210
|
-
action: "dbInit",
|
|
211
|
-
kind: "spanEnd",
|
|
212
|
-
spanId: `operation:${op.id}`,
|
|
213
|
-
outcome: "ok"
|
|
214
|
-
});
|
|
215
|
-
}
|
|
216
|
-
} : void 0;
|
|
285
|
+
const callbacks = createOperationCallbacks(onProgress, "dbInit", applySpanId);
|
|
217
286
|
const runnerResult = await runner.execute({
|
|
218
287
|
plan: migrationPlan,
|
|
219
288
|
driver,
|
|
220
289
|
destinationContract: contractIR,
|
|
221
290
|
policy,
|
|
222
|
-
...callbacks
|
|
291
|
+
...ifDefined("callbacks", callbacks),
|
|
223
292
|
executionChecks: {
|
|
224
293
|
prechecks: false,
|
|
225
294
|
postchecks: false,
|
|
@@ -251,7 +320,170 @@ async function executeDbInit(options) {
|
|
|
251
320
|
});
|
|
252
321
|
return ok({
|
|
253
322
|
mode: "apply",
|
|
254
|
-
plan: { operations: migrationPlan.operations },
|
|
323
|
+
plan: { operations: stripOperations(migrationPlan.operations) },
|
|
324
|
+
destination: {
|
|
325
|
+
storageHash: migrationPlan.destination.storageHash,
|
|
326
|
+
...ifDefined("profileHash", migrationPlan.destination.profileHash)
|
|
327
|
+
},
|
|
328
|
+
execution: {
|
|
329
|
+
operationsPlanned: execution.operationsPlanned,
|
|
330
|
+
operationsExecuted: execution.operationsExecuted
|
|
331
|
+
},
|
|
332
|
+
marker: migrationPlan.destination.profileHash ? {
|
|
333
|
+
storageHash: migrationPlan.destination.storageHash,
|
|
334
|
+
profileHash: migrationPlan.destination.profileHash
|
|
335
|
+
} : { storageHash: migrationPlan.destination.storageHash },
|
|
336
|
+
summary: `Applied ${execution.operationsExecuted} operation(s), database signed`
|
|
337
|
+
});
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
//#endregion
|
|
341
|
+
//#region src/control-api/operations/db-update.ts
|
|
342
|
+
const DB_UPDATE_POLICY = { allowedOperationClasses: [
|
|
343
|
+
"additive",
|
|
344
|
+
"widening",
|
|
345
|
+
"destructive"
|
|
346
|
+
] };
|
|
347
|
+
/**
|
|
348
|
+
* Executes the db update operation: introspect → plan → (optionally) apply → marker.
|
|
349
|
+
*
|
|
350
|
+
* db update is a pure reconciliation command: it introspects the live schema, plans the diff
|
|
351
|
+
* to the destination contract, and applies operations. The marker is bookkeeping only — written
|
|
352
|
+
* after apply so that `verify` and `db init` can reference it, but never read or validated
|
|
353
|
+
* by db update itself. The runner creates the marker table if it does not exist.
|
|
354
|
+
*/
|
|
355
|
+
async function executeDbUpdate(options) {
|
|
356
|
+
const { driver, familyInstance, contractIR, mode, migrations, frameworkComponents, onProgress } = options;
|
|
357
|
+
const planner = migrations.createPlanner(familyInstance);
|
|
358
|
+
const runner = migrations.createRunner(familyInstance);
|
|
359
|
+
const introspectSpanId = "introspect";
|
|
360
|
+
onProgress?.({
|
|
361
|
+
action: "dbUpdate",
|
|
362
|
+
kind: "spanStart",
|
|
363
|
+
spanId: introspectSpanId,
|
|
364
|
+
label: "Introspecting database schema"
|
|
365
|
+
});
|
|
366
|
+
const schemaIR = await familyInstance.introspect({ driver });
|
|
367
|
+
onProgress?.({
|
|
368
|
+
action: "dbUpdate",
|
|
369
|
+
kind: "spanEnd",
|
|
370
|
+
spanId: introspectSpanId,
|
|
371
|
+
outcome: "ok"
|
|
372
|
+
});
|
|
373
|
+
const policy = DB_UPDATE_POLICY;
|
|
374
|
+
const planSpanId = "plan";
|
|
375
|
+
onProgress?.({
|
|
376
|
+
action: "dbUpdate",
|
|
377
|
+
kind: "spanStart",
|
|
378
|
+
spanId: planSpanId,
|
|
379
|
+
label: "Planning migration"
|
|
380
|
+
});
|
|
381
|
+
const plannerResult = await planner.plan({
|
|
382
|
+
contract: contractIR,
|
|
383
|
+
schema: schemaIR,
|
|
384
|
+
policy,
|
|
385
|
+
frameworkComponents
|
|
386
|
+
});
|
|
387
|
+
if (plannerResult.kind === "failure") {
|
|
388
|
+
onProgress?.({
|
|
389
|
+
action: "dbUpdate",
|
|
390
|
+
kind: "spanEnd",
|
|
391
|
+
spanId: planSpanId,
|
|
392
|
+
outcome: "error"
|
|
393
|
+
});
|
|
394
|
+
return notOk({
|
|
395
|
+
code: "PLANNING_FAILED",
|
|
396
|
+
summary: "Migration planning failed due to conflicts",
|
|
397
|
+
conflicts: plannerResult.conflicts,
|
|
398
|
+
why: void 0,
|
|
399
|
+
meta: void 0
|
|
400
|
+
});
|
|
401
|
+
}
|
|
402
|
+
onProgress?.({
|
|
403
|
+
action: "dbUpdate",
|
|
404
|
+
kind: "spanEnd",
|
|
405
|
+
spanId: planSpanId,
|
|
406
|
+
outcome: "ok"
|
|
407
|
+
});
|
|
408
|
+
const migrationPlan = plannerResult.plan;
|
|
409
|
+
if (mode === "plan") {
|
|
410
|
+
const planSql = familyInstance.familyId === "sql" ? extractSqlDdl(migrationPlan.operations) : void 0;
|
|
411
|
+
return ok({
|
|
412
|
+
mode: "plan",
|
|
413
|
+
plan: {
|
|
414
|
+
operations: stripOperations(migrationPlan.operations),
|
|
415
|
+
...planSql !== void 0 ? { sql: planSql } : {}
|
|
416
|
+
},
|
|
417
|
+
destination: {
|
|
418
|
+
storageHash: migrationPlan.destination.storageHash,
|
|
419
|
+
...ifDefined("profileHash", migrationPlan.destination.profileHash)
|
|
420
|
+
},
|
|
421
|
+
summary: `Planned ${migrationPlan.operations.length} operation(s)`
|
|
422
|
+
});
|
|
423
|
+
}
|
|
424
|
+
if (!options.acceptDataLoss) {
|
|
425
|
+
const destructiveOps = migrationPlan.operations.filter((op) => op.operationClass === "destructive").map((op) => ({
|
|
426
|
+
id: op.id,
|
|
427
|
+
label: op.label
|
|
428
|
+
}));
|
|
429
|
+
if (destructiveOps.length > 0) return notOk({
|
|
430
|
+
code: "DESTRUCTIVE_CHANGES",
|
|
431
|
+
summary: `Planned ${destructiveOps.length} destructive operation(s) that require confirmation`,
|
|
432
|
+
why: "Use --plan to preview destructive operations, then re-run with --accept-data-loss to apply",
|
|
433
|
+
conflicts: void 0,
|
|
434
|
+
meta: { destructiveOperations: destructiveOps }
|
|
435
|
+
});
|
|
436
|
+
}
|
|
437
|
+
const applySpanId = "apply";
|
|
438
|
+
onProgress?.({
|
|
439
|
+
action: "dbUpdate",
|
|
440
|
+
kind: "spanStart",
|
|
441
|
+
spanId: applySpanId,
|
|
442
|
+
label: "Applying migration plan"
|
|
443
|
+
});
|
|
444
|
+
const callbacks = createOperationCallbacks(onProgress, "dbUpdate", applySpanId);
|
|
445
|
+
const runnerResult = await runner.execute({
|
|
446
|
+
plan: migrationPlan,
|
|
447
|
+
driver,
|
|
448
|
+
destinationContract: contractIR,
|
|
449
|
+
policy,
|
|
450
|
+
...callbacks ? { callbacks } : {},
|
|
451
|
+
executionChecks: {
|
|
452
|
+
prechecks: false,
|
|
453
|
+
postchecks: false,
|
|
454
|
+
idempotencyChecks: false
|
|
455
|
+
},
|
|
456
|
+
frameworkComponents
|
|
457
|
+
});
|
|
458
|
+
if (!runnerResult.ok) {
|
|
459
|
+
onProgress?.({
|
|
460
|
+
action: "dbUpdate",
|
|
461
|
+
kind: "spanEnd",
|
|
462
|
+
spanId: applySpanId,
|
|
463
|
+
outcome: "error"
|
|
464
|
+
});
|
|
465
|
+
return notOk({
|
|
466
|
+
code: "RUNNER_FAILED",
|
|
467
|
+
summary: runnerResult.failure.summary,
|
|
468
|
+
why: runnerResult.failure.why,
|
|
469
|
+
meta: runnerResult.failure.meta,
|
|
470
|
+
conflicts: void 0
|
|
471
|
+
});
|
|
472
|
+
}
|
|
473
|
+
const execution = runnerResult.value;
|
|
474
|
+
onProgress?.({
|
|
475
|
+
action: "dbUpdate",
|
|
476
|
+
kind: "spanEnd",
|
|
477
|
+
spanId: applySpanId,
|
|
478
|
+
outcome: "ok"
|
|
479
|
+
});
|
|
480
|
+
return ok({
|
|
481
|
+
mode: "apply",
|
|
482
|
+
plan: { operations: stripOperations(migrationPlan.operations) },
|
|
483
|
+
destination: {
|
|
484
|
+
storageHash: migrationPlan.destination.storageHash,
|
|
485
|
+
...ifDefined("profileHash", migrationPlan.destination.profileHash)
|
|
486
|
+
},
|
|
255
487
|
execution: {
|
|
256
488
|
operationsPlanned: execution.operationsPlanned,
|
|
257
489
|
operationsExecuted: execution.operationsExecuted
|
|
@@ -260,7 +492,7 @@ async function executeDbInit(options) {
|
|
|
260
492
|
storageHash: migrationPlan.destination.storageHash,
|
|
261
493
|
profileHash: migrationPlan.destination.profileHash
|
|
262
494
|
} : { storageHash: migrationPlan.destination.storageHash },
|
|
263
|
-
summary: `Applied ${execution.operationsExecuted} operation(s),
|
|
495
|
+
summary: execution.operationsExecuted === 0 ? "Database already matches contract, signature updated" : `Applied ${execution.operationsExecuted} operation(s), signature updated`
|
|
264
496
|
});
|
|
265
497
|
}
|
|
266
498
|
|
|
@@ -336,40 +568,47 @@ var ControlClientImpl = class {
|
|
|
336
568
|
frameworkComponents: this.frameworkComponents
|
|
337
569
|
};
|
|
338
570
|
}
|
|
339
|
-
async
|
|
340
|
-
|
|
341
|
-
|
|
571
|
+
async connectWithProgress(connection, action, onProgress) {
|
|
572
|
+
if (connection === void 0) return;
|
|
573
|
+
onProgress?.({
|
|
574
|
+
action,
|
|
575
|
+
kind: "spanStart",
|
|
576
|
+
spanId: "connect",
|
|
577
|
+
label: "Connecting to database..."
|
|
578
|
+
});
|
|
579
|
+
try {
|
|
580
|
+
await this.connect(connection);
|
|
342
581
|
onProgress?.({
|
|
343
|
-
action
|
|
344
|
-
kind: "
|
|
582
|
+
action,
|
|
583
|
+
kind: "spanEnd",
|
|
345
584
|
spanId: "connect",
|
|
346
|
-
|
|
585
|
+
outcome: "ok"
|
|
347
586
|
});
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
} catch (error) {
|
|
357
|
-
onProgress?.({
|
|
358
|
-
action: "verify",
|
|
359
|
-
kind: "spanEnd",
|
|
360
|
-
spanId: "connect",
|
|
361
|
-
outcome: "error"
|
|
362
|
-
});
|
|
363
|
-
throw error;
|
|
364
|
-
}
|
|
587
|
+
} catch (error) {
|
|
588
|
+
onProgress?.({
|
|
589
|
+
action,
|
|
590
|
+
kind: "spanEnd",
|
|
591
|
+
spanId: "connect",
|
|
592
|
+
outcome: "error"
|
|
593
|
+
});
|
|
594
|
+
throw error;
|
|
365
595
|
}
|
|
596
|
+
}
|
|
597
|
+
async verify(options) {
|
|
598
|
+
const { onProgress } = options;
|
|
599
|
+
await this.connectWithProgress(options.connection, "verify", onProgress);
|
|
366
600
|
const { driver, familyInstance } = await this.ensureConnected();
|
|
367
|
-
|
|
601
|
+
let contractIR;
|
|
602
|
+
try {
|
|
603
|
+
contractIR = familyInstance.validateContractIR(options.contractIR);
|
|
604
|
+
} catch (error) {
|
|
605
|
+
throw new ContractValidationError(error instanceof Error ? error.message : String(error), error);
|
|
606
|
+
}
|
|
368
607
|
onProgress?.({
|
|
369
608
|
action: "verify",
|
|
370
609
|
kind: "spanStart",
|
|
371
610
|
spanId: "verify",
|
|
372
|
-
label: "Verifying
|
|
611
|
+
label: "Verifying database signature..."
|
|
373
612
|
});
|
|
374
613
|
try {
|
|
375
614
|
const result = await familyInstance.verify({
|
|
@@ -397,33 +636,14 @@ var ControlClientImpl = class {
|
|
|
397
636
|
}
|
|
398
637
|
async schemaVerify(options) {
|
|
399
638
|
const { onProgress } = options;
|
|
400
|
-
|
|
401
|
-
onProgress?.({
|
|
402
|
-
action: "schemaVerify",
|
|
403
|
-
kind: "spanStart",
|
|
404
|
-
spanId: "connect",
|
|
405
|
-
label: "Connecting to database..."
|
|
406
|
-
});
|
|
407
|
-
try {
|
|
408
|
-
await this.connect(options.connection);
|
|
409
|
-
onProgress?.({
|
|
410
|
-
action: "schemaVerify",
|
|
411
|
-
kind: "spanEnd",
|
|
412
|
-
spanId: "connect",
|
|
413
|
-
outcome: "ok"
|
|
414
|
-
});
|
|
415
|
-
} catch (error) {
|
|
416
|
-
onProgress?.({
|
|
417
|
-
action: "schemaVerify",
|
|
418
|
-
kind: "spanEnd",
|
|
419
|
-
spanId: "connect",
|
|
420
|
-
outcome: "error"
|
|
421
|
-
});
|
|
422
|
-
throw error;
|
|
423
|
-
}
|
|
424
|
-
}
|
|
639
|
+
await this.connectWithProgress(options.connection, "schemaVerify", onProgress);
|
|
425
640
|
const { driver, familyInstance, frameworkComponents } = await this.ensureConnected();
|
|
426
|
-
|
|
641
|
+
let contractIR;
|
|
642
|
+
try {
|
|
643
|
+
contractIR = familyInstance.validateContractIR(options.contractIR);
|
|
644
|
+
} catch (error) {
|
|
645
|
+
throw new ContractValidationError(error instanceof Error ? error.message : String(error), error);
|
|
646
|
+
}
|
|
427
647
|
onProgress?.({
|
|
428
648
|
action: "schemaVerify",
|
|
429
649
|
kind: "spanStart",
|
|
@@ -457,33 +677,14 @@ var ControlClientImpl = class {
|
|
|
457
677
|
}
|
|
458
678
|
async sign(options) {
|
|
459
679
|
const { onProgress } = options;
|
|
460
|
-
|
|
461
|
-
onProgress?.({
|
|
462
|
-
action: "sign",
|
|
463
|
-
kind: "spanStart",
|
|
464
|
-
spanId: "connect",
|
|
465
|
-
label: "Connecting to database..."
|
|
466
|
-
});
|
|
467
|
-
try {
|
|
468
|
-
await this.connect(options.connection);
|
|
469
|
-
onProgress?.({
|
|
470
|
-
action: "sign",
|
|
471
|
-
kind: "spanEnd",
|
|
472
|
-
spanId: "connect",
|
|
473
|
-
outcome: "ok"
|
|
474
|
-
});
|
|
475
|
-
} catch (error) {
|
|
476
|
-
onProgress?.({
|
|
477
|
-
action: "sign",
|
|
478
|
-
kind: "spanEnd",
|
|
479
|
-
spanId: "connect",
|
|
480
|
-
outcome: "error"
|
|
481
|
-
});
|
|
482
|
-
throw error;
|
|
483
|
-
}
|
|
484
|
-
}
|
|
680
|
+
await this.connectWithProgress(options.connection, "sign", onProgress);
|
|
485
681
|
const { driver, familyInstance } = await this.ensureConnected();
|
|
486
|
-
|
|
682
|
+
let contractIR;
|
|
683
|
+
try {
|
|
684
|
+
contractIR = familyInstance.validateContractIR(options.contractIR);
|
|
685
|
+
} catch (error) {
|
|
686
|
+
throw new ContractValidationError(error instanceof Error ? error.message : String(error), error);
|
|
687
|
+
}
|
|
487
688
|
onProgress?.({
|
|
488
689
|
action: "sign",
|
|
489
690
|
kind: "spanStart",
|
|
@@ -516,70 +717,50 @@ var ControlClientImpl = class {
|
|
|
516
717
|
}
|
|
517
718
|
async dbInit(options) {
|
|
518
719
|
const { onProgress } = options;
|
|
519
|
-
|
|
520
|
-
onProgress?.({
|
|
521
|
-
action: "dbInit",
|
|
522
|
-
kind: "spanStart",
|
|
523
|
-
spanId: "connect",
|
|
524
|
-
label: "Connecting to database..."
|
|
525
|
-
});
|
|
526
|
-
try {
|
|
527
|
-
await this.connect(options.connection);
|
|
528
|
-
onProgress?.({
|
|
529
|
-
action: "dbInit",
|
|
530
|
-
kind: "spanEnd",
|
|
531
|
-
spanId: "connect",
|
|
532
|
-
outcome: "ok"
|
|
533
|
-
});
|
|
534
|
-
} catch (error) {
|
|
535
|
-
onProgress?.({
|
|
536
|
-
action: "dbInit",
|
|
537
|
-
kind: "spanEnd",
|
|
538
|
-
spanId: "connect",
|
|
539
|
-
outcome: "error"
|
|
540
|
-
});
|
|
541
|
-
throw error;
|
|
542
|
-
}
|
|
543
|
-
}
|
|
720
|
+
await this.connectWithProgress(options.connection, "dbInit", onProgress);
|
|
544
721
|
const { driver, familyInstance, frameworkComponents } = await this.ensureConnected();
|
|
545
722
|
if (!this.options.target.migrations) throw new Error(`Target "${this.options.target.targetId}" does not support migrations`);
|
|
723
|
+
let contractIR;
|
|
724
|
+
try {
|
|
725
|
+
contractIR = familyInstance.validateContractIR(options.contractIR);
|
|
726
|
+
} catch (error) {
|
|
727
|
+
throw new ContractValidationError(error instanceof Error ? error.message : String(error), error);
|
|
728
|
+
}
|
|
546
729
|
return executeDbInit({
|
|
547
730
|
driver,
|
|
548
731
|
familyInstance,
|
|
549
|
-
contractIR
|
|
732
|
+
contractIR,
|
|
733
|
+
mode: options.mode,
|
|
734
|
+
migrations: this.options.target.migrations,
|
|
735
|
+
frameworkComponents,
|
|
736
|
+
...ifDefined("onProgress", onProgress)
|
|
737
|
+
});
|
|
738
|
+
}
|
|
739
|
+
async dbUpdate(options) {
|
|
740
|
+
const { onProgress } = options;
|
|
741
|
+
await this.connectWithProgress(options.connection, "dbUpdate", onProgress);
|
|
742
|
+
const { driver, familyInstance, frameworkComponents } = await this.ensureConnected();
|
|
743
|
+
if (!this.options.target.migrations) throw new Error(`Target "${this.options.target.targetId}" does not support migrations`);
|
|
744
|
+
let contractIR;
|
|
745
|
+
try {
|
|
746
|
+
contractIR = familyInstance.validateContractIR(options.contractIR);
|
|
747
|
+
} catch (error) {
|
|
748
|
+
throw new ContractValidationError(error instanceof Error ? error.message : String(error), error);
|
|
749
|
+
}
|
|
750
|
+
return executeDbUpdate({
|
|
751
|
+
driver,
|
|
752
|
+
familyInstance,
|
|
753
|
+
contractIR,
|
|
550
754
|
mode: options.mode,
|
|
551
755
|
migrations: this.options.target.migrations,
|
|
552
756
|
frameworkComponents,
|
|
553
|
-
...
|
|
757
|
+
...ifDefined("acceptDataLoss", options.acceptDataLoss),
|
|
758
|
+
...ifDefined("onProgress", onProgress)
|
|
554
759
|
});
|
|
555
760
|
}
|
|
556
761
|
async introspect(options) {
|
|
557
762
|
const onProgress = options?.onProgress;
|
|
558
|
-
|
|
559
|
-
onProgress?.({
|
|
560
|
-
action: "introspect",
|
|
561
|
-
kind: "spanStart",
|
|
562
|
-
spanId: "connect",
|
|
563
|
-
label: "Connecting to database..."
|
|
564
|
-
});
|
|
565
|
-
try {
|
|
566
|
-
await this.connect(options.connection);
|
|
567
|
-
onProgress?.({
|
|
568
|
-
action: "introspect",
|
|
569
|
-
kind: "spanEnd",
|
|
570
|
-
spanId: "connect",
|
|
571
|
-
outcome: "ok"
|
|
572
|
-
});
|
|
573
|
-
} catch (error) {
|
|
574
|
-
onProgress?.({
|
|
575
|
-
action: "introspect",
|
|
576
|
-
kind: "spanEnd",
|
|
577
|
-
spanId: "connect",
|
|
578
|
-
outcome: "error"
|
|
579
|
-
});
|
|
580
|
-
throw error;
|
|
581
|
-
}
|
|
582
|
-
}
|
|
763
|
+
await this.connectWithProgress(options?.connection, "introspect", onProgress);
|
|
583
764
|
const { driver, familyInstance } = await this.ensureConnected();
|
|
584
765
|
options?.schema;
|
|
585
766
|
onProgress?.({
|
|
@@ -675,6 +856,22 @@ var ControlClientImpl = class {
|
|
|
675
856
|
label: "Emitting contract..."
|
|
676
857
|
});
|
|
677
858
|
try {
|
|
859
|
+
try {
|
|
860
|
+
this.familyInstance.validateContractIR(contractRaw);
|
|
861
|
+
} catch (error) {
|
|
862
|
+
onProgress?.({
|
|
863
|
+
action: "emit",
|
|
864
|
+
kind: "spanEnd",
|
|
865
|
+
spanId: "emit",
|
|
866
|
+
outcome: "error"
|
|
867
|
+
});
|
|
868
|
+
return notOk({
|
|
869
|
+
code: "CONTRACT_VALIDATION_FAILED",
|
|
870
|
+
summary: "Contract validation failed",
|
|
871
|
+
why: error instanceof Error ? error.message : String(error),
|
|
872
|
+
meta: void 0
|
|
873
|
+
});
|
|
874
|
+
}
|
|
678
875
|
const emitResult = await this.familyInstance.emitContract({ contractIR: contractRaw });
|
|
679
876
|
onProgress?.({
|
|
680
877
|
action: "emit",
|
|
@@ -707,5 +904,5 @@ var ControlClientImpl = class {
|
|
|
707
904
|
};
|
|
708
905
|
|
|
709
906
|
//#endregion
|
|
710
|
-
export {
|
|
711
|
-
//# sourceMappingURL=client-
|
|
907
|
+
export { errorTargetMismatch as _, errorContractValidationFailed as a, errorDriverRequired as c, errorJsonFormatNotSupported as d, errorMarkerMissing as f, errorTargetMigrationNotSupported as g, errorRuntime as h, errorContractConfigMissing$1 as i, errorFileNotFound as l, errorRunnerFailed as m, ContractValidationError as n, errorDatabaseConnectionRequired as o, errorMigrationPlanningFailed as p, CliStructuredError as r, errorDestructiveChanges as s, createControlClient as t, errorHashMismatch as u, errorUnexpected$1 as v };
|
|
908
|
+
//# sourceMappingURL=client-B7f4PZZ1.mjs.map
|