@prisma/cli 3.0.0-alpha.7 → 3.0.0-alpha.8

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.
@@ -8,13 +8,14 @@ import { confirmPrompt, selectPrompt, textPrompt } from "../shell/prompt.js";
8
8
  import { requireComputeAuth } from "../lib/auth/guard.js";
9
9
  import { readAuthState } from "../lib/auth/auth-ops.js";
10
10
  import { parseEnvAssignments } from "../lib/app/env-vars.js";
11
+ import { renderDeployOutputRows } from "../lib/app/deploy-output.js";
11
12
  import { readBunPackageJson } from "../lib/app/bun-project.js";
12
13
  import { DEFAULT_LOCAL_DEV_PORT, resolveLocalBuildType, runLocalApp } from "../lib/app/local-dev.js";
13
14
  import { inferTargetName, projectNotFoundError, resolveProjectTarget } from "../lib/project/resolution.js";
14
15
  import { LOCAL_RESOLUTION_PIN_RELATIVE_PATH, ensureLocalResolutionPinGitignore, readLocalResolutionPin, writeLocalResolutionPin } from "../lib/project/local-pin.js";
15
16
  import { PREVIEW_BUILD_TYPES, RESOLVED_PREVIEW_BUILD_TYPES, executePreviewBuild } from "../lib/app/preview-build.js";
16
17
  import { PREVIEW_DEFAULT_REGION } from "../lib/app/preview-interaction.js";
17
- import { createPreviewDeployProgress, createPreviewPromoteProgress, createPreviewUpdateEnvProgress } from "../lib/app/preview-progress.js";
18
+ import { createPreviewDeployProgress, createPreviewDeployProgressState, createPreviewPromoteProgress, createPreviewUpdateEnvProgress } from "../lib/app/preview-progress.js";
18
19
  import { createPreviewAppProvider } from "../lib/app/preview-provider.js";
19
20
  import { createSelectPromptPort } from "./select-prompt-port.js";
20
21
  import { requireAuthenticatedAuthState } from "./auth.js";
@@ -123,7 +124,6 @@ async function runAppDeploy(context, appName, options) {
123
124
  });
124
125
  await maybeRenderDeploySetupBlock(context, {
125
126
  firstDeploy: selectedApp.firstDeploy,
126
- showSubsequentAnnotations: skipLocalPin,
127
127
  workspaceName: target.workspace.name,
128
128
  projectName: target.project.name,
129
129
  projectAnnotation: annotationForProjectResolution(target.resolution),
@@ -147,6 +147,17 @@ async function runAppDeploy(context, appName, options) {
147
147
  const buildType = framework.buildType;
148
148
  assertSupportedEntrypoint(buildType, options?.entrypoint, "deploy");
149
149
  const portMapping = parseDeployPortMapping(String(runtime.port));
150
+ const shouldWriteLocalPin = firstDeploy && !skipLocalPin;
151
+ if (shouldWriteLocalPin) {
152
+ await writeLocalResolutionPin(context.runtime.cwd, {
153
+ workspaceId: target.workspace.id,
154
+ projectId: target.project.id
155
+ });
156
+ await ensureLocalResolutionPinGitignore(context.runtime.cwd);
157
+ maybeRenderLocalPinBound(context, target.project.name);
158
+ }
159
+ const progressState = createPreviewDeployProgressState();
160
+ const deployStartedAt = Date.now();
150
161
  const deployResult = await provider.deployApp({
151
162
  cwd: context.runtime.cwd,
152
163
  projectId,
@@ -159,23 +170,16 @@ async function runAppDeploy(context, appName, options) {
159
170
  portMapping,
160
171
  envVars,
161
172
  interaction: void 0,
162
- progress: createPreviewDeployProgress(context.output.stderr, !context.flags.json && !context.flags.quiet)
173
+ progress: createPreviewDeployProgress(context.output.stderr, context.ui, !context.flags.json && !context.flags.quiet, progressState)
163
174
  }).catch((error) => {
164
- throw deployFailedError("App deploy failed", error, ["prisma-cli app list-deploys"]);
175
+ throw appDeployFailedError(error, progressState);
165
176
  });
177
+ const deployDurationMs = Date.now() - deployStartedAt;
166
178
  await context.stateStore.setSelectedApp(projectId, {
167
179
  id: deployResult.app.id,
168
180
  name: deployResult.app.name
169
181
  });
170
182
  await context.stateStore.setKnownLiveDeployment(projectId, deployResult.app.id, deployResult.deployment.id);
171
- const shouldWriteLocalPin = firstDeploy && !skipLocalPin;
172
- if (shouldWriteLocalPin) {
173
- await writeLocalResolutionPin(context.runtime.cwd, {
174
- workspaceId: target.workspace.id,
175
- projectId: target.project.id
176
- });
177
- await ensureLocalResolutionPinGitignore(context.runtime.cwd);
178
- }
179
183
  return {
180
184
  command: "app.deploy",
181
185
  result: {
@@ -188,6 +192,7 @@ async function runAppDeploy(context, appName, options) {
188
192
  name: deployResult.app.name
189
193
  },
190
194
  deployment: deployResult.deployment,
195
+ durationMs: deployDurationMs,
191
196
  localPin: shouldWriteLocalPin ? {
192
197
  path: LOCAL_RESOLUTION_PIN_RELATIVE_PATH,
193
198
  written: true
@@ -1054,9 +1059,10 @@ async function resolveDeployProjectContext(context, client, provider, explicitPr
1054
1059
  }
1055
1060
  }, branch);
1056
1061
  }
1057
- if (options.localPin.kind === "present") {
1058
- if (options.localPin.pin.workspaceId !== workspace.id) throw localResolutionPinStaleError();
1059
- const project = projects.find((candidate) => candidate.id === options.localPin.pin.projectId);
1062
+ const localPin = options.localPin;
1063
+ if (localPin.kind === "present") {
1064
+ if (localPin.pin.workspaceId !== workspace.id) throw localResolutionPinStaleError();
1065
+ const project = projects.find((candidate) => candidate.id === localPin.pin.projectId);
1060
1066
  if (!project) throw localResolutionPinStaleError();
1061
1067
  return withDeployBranch({
1062
1068
  workspace,
@@ -1257,7 +1263,12 @@ function frameworkNotDetectedError(cwd, requestedFramework) {
1257
1263
  }
1258
1264
  async function maybeRenderDeploySetupBlock(context, details) {
1259
1265
  if (context.flags.json || context.flags.quiet) return;
1260
- const title = `${details.firstDeploy ? "Set up" : "Deploying"} ${formatDeployDirectory(context.runtime.cwd)}`;
1266
+ const directory = formatDeployDirectory(context.runtime.cwd);
1267
+ if (!details.firstDeploy) {
1268
+ context.output.stderr.write(`Deploying ${directory} to ${details.projectName} / ${details.branchName} / ${details.appName}\n\n`);
1269
+ return;
1270
+ }
1271
+ const title = `Setting up your local directory ${formatLocalDirectory(context.runtime.cwd, context.runtime.env)}`;
1261
1272
  const rows = details.firstDeploy ? [
1262
1273
  {
1263
1274
  label: "Workspace",
@@ -1266,61 +1277,41 @@ async function maybeRenderDeploySetupBlock(context, details) {
1266
1277
  {
1267
1278
  label: "Project",
1268
1279
  value: details.projectName,
1269
- annotation: details.projectAnnotation
1280
+ origin: details.projectAnnotation
1270
1281
  },
1271
1282
  {
1272
1283
  label: "Branch",
1273
1284
  value: details.branchName,
1274
- annotation: details.branchAnnotation
1285
+ origin: details.branchAnnotation
1275
1286
  },
1276
1287
  {
1277
1288
  label: "App",
1278
1289
  value: details.appName,
1279
- annotation: details.appAnnotation
1290
+ origin: details.appAnnotation
1280
1291
  },
1281
1292
  {
1282
1293
  label: "Framework",
1283
1294
  value: details.framework.displayName,
1284
- annotation: details.framework.annotation
1295
+ origin: details.framework.annotation
1285
1296
  },
1286
1297
  {
1287
1298
  label: "Runtime",
1288
1299
  value: `HTTP ${details.runtime.port}`,
1289
- annotation: details.runtime.annotation
1300
+ origin: details.runtime.annotation
1290
1301
  }
1291
- ] : [
1292
- {
1293
- label: "Workspace",
1294
- value: details.workspaceName
1295
- },
1296
- {
1297
- label: "Project",
1298
- value: details.projectName,
1299
- annotation: details.showSubsequentAnnotations ? details.projectAnnotation : void 0
1300
- },
1301
- {
1302
- label: "Branch",
1303
- value: details.branchName,
1304
- annotation: details.showSubsequentAnnotations ? details.branchAnnotation : void 0
1305
- },
1306
- {
1307
- label: "App",
1308
- value: details.appName,
1309
- annotation: details.showSubsequentAnnotations ? details.appAnnotation : void 0
1310
- }
1311
- ];
1312
- const lines = details.firstDeploy ? [
1302
+ ] : [];
1303
+ const lines = [
1313
1304
  title,
1314
1305
  "",
1315
- ...renderDeploySetupRows(context, rows),
1316
- ""
1317
- ] : [
1318
- title,
1319
- ...renderDeploySetupRows(context, rows),
1306
+ ...renderDeployOutputRows(context.ui, rows),
1320
1307
  ""
1321
1308
  ];
1322
1309
  context.output.stderr.write(`${lines.join("\n")}\n`);
1323
1310
  }
1311
+ function maybeRenderLocalPinBound(context, projectName) {
1312
+ if (context.flags.json || context.flags.quiet) return;
1313
+ context.output.stderr.write(`This directory is now linked to project ${projectName}.\n\n`);
1314
+ }
1324
1315
  async function maybeCustomizeDeploySettings(context, options) {
1325
1316
  if (!options.firstDeploy || context.flags.yes || options.explicitFramework || options.explicitBuildType || options.explicitHttpPort || !canPrompt(context)) return {
1326
1317
  framework: options.framework,
@@ -1364,19 +1355,16 @@ async function maybeCustomizeDeploySettings(context, options) {
1364
1355
  value: `HTTP ${runtime.port}`,
1365
1356
  annotation: runtime.annotation
1366
1357
  } : null].filter((row) => Boolean(row));
1367
- if (changedRows.length > 0 && !context.flags.quiet && !context.flags.json) context.output.stderr.write(`${renderDeploySetupRows(context, changedRows).join("\n")}\n\n`);
1358
+ if (changedRows.length > 0 && !context.flags.quiet && !context.flags.json) context.output.stderr.write(`${renderDeployOutputRows(context.ui, changedRows.map((row) => ({
1359
+ label: row.label,
1360
+ value: row.value,
1361
+ origin: row.annotation
1362
+ }))).join("\n")}\n\n`);
1368
1363
  return {
1369
1364
  framework,
1370
1365
  runtime
1371
1366
  };
1372
1367
  }
1373
- function renderDeploySetupRows(context, rows) {
1374
- const labelWidth = Math.max(...rows.map((row) => row.label.length));
1375
- const valueWidth = Math.max(...rows.map((row) => row.value.length));
1376
- return rows.map((row) => {
1377
- return ` ${row.label.padEnd(labelWidth)} ${row.value.padEnd(valueWidth)}${row.annotation ? ` ${context.ui.dim(row.annotation)}` : ""}`.trimEnd();
1378
- });
1379
- }
1380
1368
  function annotationForProjectResolution(resolution) {
1381
1369
  switch (resolution.projectSource) {
1382
1370
  case "explicit": return "set by --project";
@@ -1410,6 +1398,15 @@ function formatDeployDirectory(cwd) {
1410
1398
  const basename = path.basename(cwd);
1411
1399
  return basename ? `./${basename}` : ".";
1412
1400
  }
1401
+ function formatLocalDirectory(cwd, env) {
1402
+ const resolved = path.resolve(cwd);
1403
+ const home = env.HOME ? path.resolve(env.HOME) : null;
1404
+ if (home && (resolved === home || resolved.startsWith(`${home}${path.sep}`))) {
1405
+ const relative = path.relative(home, resolved);
1406
+ return relative ? `~/${relative}` : "~";
1407
+ }
1408
+ return resolved;
1409
+ }
1413
1410
  async function readCurrentWorkspaceId(context) {
1414
1411
  const state = await context.stateStore.read();
1415
1412
  if (state.auth?.workspaceId) return state.auth.workspaceId;
@@ -1467,6 +1464,67 @@ function deployFailedError(summary, error, nextSteps) {
1467
1464
  nextSteps
1468
1465
  });
1469
1466
  }
1467
+ function appDeployFailedError(error, progress) {
1468
+ const why = error instanceof Error ? error.message : String(error);
1469
+ const debug = formatDebugDetails(error);
1470
+ if (progress.buildStarted && !progress.buildCompleted) return new CliError({
1471
+ code: "BUILD_FAILED",
1472
+ domain: "app",
1473
+ summary: "Build failed locally.",
1474
+ why,
1475
+ fix: "Inspect the build output above, fix the error, and redeploy.",
1476
+ debug,
1477
+ meta: { phase: "build" },
1478
+ humanLines: [
1479
+ "Build failed locally.",
1480
+ "",
1481
+ `✗ Built ${why}`,
1482
+ "",
1483
+ "Fix: Inspect the build output above, fix the error, and redeploy."
1484
+ ],
1485
+ exitCode: 1,
1486
+ nextSteps: []
1487
+ });
1488
+ if (!progress.buildStarted) return deployFailedError("App deploy failed", error, ["prisma-cli app deploy"]);
1489
+ const phaseHeadline = progress.containerLive ? "The deployment started, but the app is not ready yet." : "Deploy failed after the build completed.";
1490
+ const recoveryLines = progress.versionId ? ["See what happened", `prisma-cli app logs --deployment ${progress.versionId}`] : ["Fix", "Retry the command, or rerun with --trace for more detailed diagnostics."];
1491
+ const urlLines = progress.deploymentUrl ? [
1492
+ "",
1493
+ "URL",
1494
+ progress.deploymentUrl
1495
+ ] : [];
1496
+ const humanLines = progress.containerLive ? [
1497
+ phaseHeadline,
1498
+ "",
1499
+ "This is usually a missing env var, a failed DB connection,",
1500
+ "or a crash on startup.",
1501
+ "",
1502
+ ...recoveryLines,
1503
+ ...urlLines
1504
+ ] : [
1505
+ phaseHeadline,
1506
+ "",
1507
+ progress.uploadCompleted ? "The artifact uploaded, but the deployment did not start." : progress.archiveReady ? "The app built locally, but the artifact did not finish uploading." : "The app built locally, but the deployment did not start.",
1508
+ "",
1509
+ ...recoveryLines
1510
+ ];
1511
+ return new CliError({
1512
+ code: "DEPLOY_FAILED",
1513
+ domain: "app",
1514
+ summary: phaseHeadline,
1515
+ why,
1516
+ fix: progress.versionId ? `Inspect logs with prisma-cli app logs --deployment ${progress.versionId}.` : "Retry the command, or rerun with --trace for more detailed diagnostics.",
1517
+ debug,
1518
+ meta: {
1519
+ phase: progress.containerLive ? "runtime_ready" : "deploy",
1520
+ deploymentId: progress.versionId,
1521
+ deploymentUrl: progress.deploymentUrl
1522
+ },
1523
+ humanLines,
1524
+ exitCode: 1,
1525
+ nextSteps: []
1526
+ });
1527
+ }
1470
1528
  function localResolutionPinStaleError() {
1471
1529
  return new CliError({
1472
1530
  code: "LOCAL_STATE_STALE",
@@ -0,0 +1,15 @@
1
+ import { padDisplay } from "../../shell/ui.js";
2
+ //#region src/lib/app/deploy-output.ts
3
+ const DEPLOY_OUTPUT_MIN_LABEL_WIDTH = 9;
4
+ const DEPLOY_OUTPUT_MIN_VALUE_WIDTH = 9;
5
+ function renderDeployOutputRows(ui, rows) {
6
+ if (rows.length === 0) return [];
7
+ const labelWidth = Math.max(DEPLOY_OUTPUT_MIN_LABEL_WIDTH, ...rows.map((row) => row.label.length));
8
+ const valueWidth = Math.max(DEPLOY_OUTPUT_MIN_VALUE_WIDTH, ...rows.map((row) => row.value?.length ?? 0));
9
+ return rows.map((row) => {
10
+ if (!row.value) return ` ${row.label}`;
11
+ return ` ${padDisplay(row.label, labelWidth)} ${padDisplay(ui.strong(row.value), valueWidth)}${row.origin ? ` ${ui.dim(`· ${row.origin}`)}` : ""}`.trimEnd();
12
+ });
13
+ }
14
+ //#endregion
15
+ export { renderDeployOutputRows };
@@ -1,83 +1,68 @@
1
+ import { renderDeployOutputRows } from "./deploy-output.js";
1
2
  //#region src/lib/app/preview-progress.ts
2
- function createPreviewDeployProgress(output, enabled) {
3
- if (!enabled) return;
3
+ function createPreviewDeployProgressState() {
4
+ return {
5
+ buildStarted: false,
6
+ buildCompleted: false,
7
+ archiveReady: false,
8
+ uploadCompleted: false,
9
+ versionId: null,
10
+ startRequested: false,
11
+ containerLive: false,
12
+ deploymentUrl: null,
13
+ promotedUrl: null
14
+ };
15
+ }
16
+ function createPreviewDeployProgress(output, ui, enabled, state = createPreviewDeployProgressState()) {
4
17
  const write = (line) => {
18
+ if (!enabled) return;
5
19
  output.write(`${line}\n`);
6
20
  };
21
+ const writeRows = (rows) => {
22
+ for (const line of renderDeployOutputRows(ui, rows)) write(line);
23
+ };
7
24
  return {
8
25
  onBuildStart() {
9
- write("Building application...");
26
+ state.buildStarted = true;
27
+ write("Building locally...");
10
28
  },
11
29
  onBuildComplete() {
12
- write("Build complete.");
13
- },
14
- onArchiveCreating() {
15
- write("Creating deployment artifact...");
30
+ state.buildCompleted = true;
16
31
  },
17
32
  onArchiveReady(byteLength) {
18
- write(`Artifact ready (${(byteLength / 1024).toFixed(1)} KB).`);
33
+ state.archiveReady = true;
34
+ writeRows([{
35
+ label: "Built",
36
+ value: formatArtifactSize(byteLength)
37
+ }]);
38
+ },
39
+ onUploadStart() {
40
+ write("Uploading...");
19
41
  },
20
42
  onVersionCreated(versionId) {
21
- write(`Deployment ${versionId} created.`);
43
+ state.versionId = versionId;
22
44
  },
23
45
  onUploadComplete() {
24
- write("Upload complete.");
46
+ state.uploadCompleted = true;
47
+ writeRows([{ label: "Uploaded" }]);
25
48
  },
26
49
  onStartRequested() {
27
- write("Starting deployment...");
28
- },
29
- onStatusChange(status) {
30
- write(`Status: ${status}`);
50
+ state.startRequested = true;
51
+ write("Deploying...");
31
52
  },
32
53
  onRunning(url) {
33
- if (url) {
34
- write(`Deployment is running at ${url}.`);
35
- return;
36
- }
37
- write("Deployment is running.");
38
- },
39
- onPromoteStart() {
40
- write("Promoting deployment...");
54
+ state.containerLive = true;
55
+ state.deploymentUrl = url;
56
+ writeRows([{ label: "Deployed" }]);
41
57
  },
42
58
  onPromoted(url) {
43
- if (url) {
44
- write(`Promoted to ${url}.`);
45
- return;
46
- }
47
- write("Promotion complete.");
48
- },
49
- onPromoteFailed(error) {
50
- write(`Promotion failed${error?.message ? `: ${error.message}` : "."}`);
51
- },
52
- onOldVersionStopping(versionId) {
53
- write(`Stopping previous deployment ${versionId}...`);
54
- },
55
- onOldVersionStopped(versionId) {
56
- write(`Previous deployment ${versionId} stopped.`);
57
- },
58
- onOldVersionStopFailed(versionId) {
59
- write(`Failed to stop previous deployment ${versionId} (non-fatal).`);
60
- },
61
- onOldVersionDeleting(versionId) {
62
- write(`Deleting previous deployment ${versionId}...`);
63
- },
64
- onOldVersionDeleted(versionId) {
65
- write(`Previous deployment ${versionId} deleted.`);
66
- },
67
- onOldVersionDeleteFailed(versionId) {
68
- write(`Failed to delete previous deployment ${versionId} (non-fatal).`);
69
- },
70
- onCleanupDanglingVersion(versionId) {
71
- write(`Cleaning up deployment ${versionId}...`);
72
- },
73
- onCleanupDanglingVersionComplete(versionId) {
74
- write(`Deployment ${versionId} cleaned up.`);
75
- },
76
- onCleanupDanglingVersionFailed(versionId) {
77
- write(`Failed to clean up deployment ${versionId}.`);
59
+ state.promotedUrl = url;
78
60
  }
79
61
  };
80
62
  }
63
+ function formatArtifactSize(byteLength) {
64
+ return `${(byteLength / 1024 / 1024).toFixed(1)} MB`;
65
+ }
81
66
  function createPreviewPromoteProgress(output, enabled) {
82
67
  if (!enabled) return;
83
68
  const write = (line) => {
@@ -136,4 +121,4 @@ function createPreviewUpdateEnvProgress(output, enabled) {
136
121
  };
137
122
  }
138
123
  //#endregion
139
- export { createPreviewDeployProgress, createPreviewPromoteProgress, createPreviewUpdateEnvProgress };
124
+ export { createPreviewDeployProgress, createPreviewDeployProgressState, createPreviewPromoteProgress, createPreviewUpdateEnvProgress };
@@ -1,3 +1,4 @@
1
+ import { renderDeployOutputRows } from "../lib/app/deploy-output.js";
1
2
  import { renderList, renderShow, serializeList } from "../output/patterns.js";
2
3
  //#region src/presenters/app.ts
3
4
  function renderAppBuild(context, descriptor, result) {
@@ -25,49 +26,24 @@ function serializeAppBuild(result) {
25
26
  return result;
26
27
  }
27
28
  function renderAppDeploy(context, descriptor, result) {
28
- const lines = renderShow({
29
- title: "Deploying the selected app.",
30
- descriptor,
31
- fields: [
32
- {
33
- key: "workspace",
34
- value: result.workspace.name
35
- },
36
- {
37
- key: "project",
38
- value: result.project.name
39
- },
40
- {
41
- key: "branch",
42
- value: result.branch.name
43
- },
44
- {
45
- key: "app",
46
- value: result.app.name
47
- },
48
- {
49
- key: "deployment",
50
- value: result.deployment.id
51
- },
52
- {
53
- key: "status",
54
- value: result.deployment.status,
55
- tone: toneForStatus(result.deployment.status)
56
- },
57
- ...result.deployment.url ? [{
58
- key: "url",
59
- value: result.deployment.url,
60
- tone: "link"
61
- }] : []
62
- ]
63
- }, context.ui);
64
- if (result.localPin?.written) lines.push(`Bound this directory in ${result.localPin.path}. Subsequent commands target the same Project.`);
65
- return lines;
29
+ return [
30
+ `Live in ${formatDuration(result.durationMs)}`,
31
+ ...result.deployment.url ? [context.ui.link(result.deployment.url)] : [],
32
+ "",
33
+ ...renderDeployOutputRows(context.ui, [{
34
+ label: "Logs",
35
+ value: "prisma-cli app logs"
36
+ }])
37
+ ];
66
38
  }
67
39
  function serializeAppDeploy(result) {
68
40
  const { localPin: _localPin, ...serialized } = result;
69
41
  return serialized;
70
42
  }
43
+ function formatDuration(durationMs) {
44
+ if (durationMs < 1e3) return `${durationMs}ms`;
45
+ return `${(durationMs / 1e3).toFixed(1)}s`;
46
+ }
71
47
  function renderAppUpdateEnv(context, descriptor, result) {
72
48
  return renderShow({
73
49
  title: "Updating environment variables for the selected app.",
@@ -12,6 +12,7 @@ var CliError = class extends Error {
12
12
  docsUrl;
13
13
  exitCode;
14
14
  nextSteps;
15
+ humanLines;
15
16
  constructor(options) {
16
17
  super(options.summary);
17
18
  this.name = "CliError";
@@ -27,6 +28,7 @@ var CliError = class extends Error {
27
28
  this.docsUrl = options.docsUrl ?? null;
28
29
  this.exitCode = options.exitCode ?? 1;
29
30
  this.nextSteps = options.nextSteps ?? [];
31
+ this.humanLines = options.humanLines && options.humanLines.length > 0 ? [...options.humanLines] : null;
30
32
  }
31
33
  };
32
34
  function usageError(summary, why, fix, nextSteps = [], domain = "cli") {
@@ -36,6 +36,17 @@ function writeHumanLines(output, lines) {
36
36
  output.stderr.write(`${lines.join("\n")}\n`);
37
37
  }
38
38
  function writeHumanError(output, ui, error, options) {
39
+ if (error.humanLines && error.humanLines.length > 0) {
40
+ const lines = [...error.humanLines];
41
+ if (options.trace && error.debug) {
42
+ lines.push("");
43
+ lines.push("Trace:");
44
+ lines.push(...error.debug.trimEnd().split("\n"));
45
+ }
46
+ lines.push(...renderNextSteps(error.nextSteps));
47
+ writeHumanLines(output, lines);
48
+ return;
49
+ }
39
50
  const lines = [renderSummaryLine(ui, "error", `${error.summary} [${error.code}]`)];
40
51
  if (error.where) lines.push(...["", `Where: ${error.where}`]);
41
52
  if (error.why) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@prisma/cli",
3
- "version": "3.0.0-alpha.7",
3
+ "version": "3.0.0-alpha.8",
4
4
  "description": "Preview of the unified Prisma CLI.",
5
5
  "type": "module",
6
6
  "bin": {