@prisma/cli 3.0.0-dev.62.1 → 3.0.0-dev.65.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,64 @@
1
+ import { renderVerboseBlock } from "../shell/ui.js";
2
+ //#region src/presenters/verbose-context.ts
3
+ function renderResolvedProjectContextBlock(ui, context, options = {}) {
4
+ if (!context) return [];
5
+ return renderVerboseBlock(ui, [...projectResolutionRows(context), ...options.extraRows ?? []], { title: options.title ?? "Resolved context" });
6
+ }
7
+ function projectResolutionRows(context) {
8
+ return [
9
+ {
10
+ key: "workspace",
11
+ value: context.workspace.name
12
+ },
13
+ {
14
+ key: "workspace id",
15
+ value: context.workspace.id,
16
+ tone: "dim"
17
+ },
18
+ {
19
+ key: "project",
20
+ value: context.project.name
21
+ },
22
+ {
23
+ key: "project id",
24
+ value: context.project.id,
25
+ tone: "dim"
26
+ },
27
+ {
28
+ key: "project source",
29
+ value: formatProjectSource(context.resolution.projectSource)
30
+ },
31
+ ...context.resolution.targetName ? [{
32
+ key: "target name",
33
+ value: formatTargetName(context.resolution)
34
+ }] : [],
35
+ ...context.branch ? [{
36
+ key: "branch",
37
+ value: `${context.branch.name} (${context.branch.kind})`
38
+ }, ...context.branch.id ? [{
39
+ key: "branch id",
40
+ value: context.branch.id,
41
+ tone: "dim"
42
+ }] : []] : []
43
+ ];
44
+ }
45
+ function stripVerboseContext(result) {
46
+ const { verboseContext: _verboseContext, ...serialized } = result;
47
+ return serialized;
48
+ }
49
+ function formatProjectSource(source) {
50
+ switch (source) {
51
+ case "explicit": return "--project";
52
+ case "env": return "environment";
53
+ case "local-pin": return ".prisma/local.json";
54
+ case "platform-mapping": return "platform mapping";
55
+ case "created": return "created";
56
+ case "prompt": return "prompt";
57
+ case "unbound": return "unbound";
58
+ }
59
+ }
60
+ function formatTargetName(resolution) {
61
+ return resolution.targetNameSource ? `${resolution.targetName} (${resolution.targetNameSource})` : String(resolution.targetName);
62
+ }
63
+ //#endregion
64
+ export { renderResolvedProjectContextBlock, stripVerboseContext };
@@ -3,6 +3,8 @@ import { cliErrorToJson, writeHumanError, writeHumanLines, writeJsonError, write
3
3
  import { getCommandDescriptor } from "./command-meta.js";
4
4
  import { resolveGlobalFlags } from "./global-flags.js";
5
5
  import { createCommandContext } from "./runtime.js";
6
+ import { collectCommandDiagnostics } from "../lib/diagnostics.js";
7
+ import { renderCommandDiagnostics } from "./diagnostics-output.js";
6
8
  import { AuthError } from "@prisma/management-api-sdk";
7
9
  //#region src/shell/command-runner.ts
8
10
  function toCliError(error, runtime) {
@@ -19,6 +21,7 @@ async function runCommand(runtime, commandName, options, handler, presenter) {
19
21
  const flags = resolveGlobalFlags(runtime.argv, options);
20
22
  const context = await createCommandContext(runtime, flags);
21
23
  const descriptor = getCommandDescriptor(commandName);
24
+ const startedAt = Date.now();
22
25
  try {
23
26
  const success = await handler(context);
24
27
  if (flags.json) {
@@ -29,7 +32,12 @@ async function runCommand(runtime, commandName, options, handler, presenter) {
29
32
  return;
30
33
  }
31
34
  if (flags.quiet) return;
32
- writeHumanLines(context.output, presenter.renderHuman(context, descriptor, success.result));
35
+ const rendered = presenter.renderHuman(context, descriptor, success.result);
36
+ const diagnostics = await renderBestEffortCommandDiagnostics(context, {
37
+ enabled: flags.verbose && rendered.length > 0,
38
+ durationMs: Date.now() - startedAt
39
+ });
40
+ writeHumanLines(context.output, [...rendered, ...diagnostics]);
33
41
  } catch (error) {
34
42
  const cliError = toCliError(error, runtime);
35
43
  if (cliError) {
@@ -41,6 +49,14 @@ async function runCommand(runtime, commandName, options, handler, presenter) {
41
49
  throw error;
42
50
  }
43
51
  }
52
+ async function renderBestEffortCommandDiagnostics(context, options) {
53
+ if (!options.enabled) return [];
54
+ try {
55
+ return renderCommandDiagnostics(context, await collectCommandDiagnostics(context, { durationMs: options.durationMs }));
56
+ } catch {
57
+ return [];
58
+ }
59
+ }
44
60
  async function runStreamingCommand(runtime, commandName, options, handler) {
45
61
  const flags = resolveGlobalFlags(runtime.argv, options);
46
62
  const context = await createCommandContext(runtime, flags);
@@ -0,0 +1,63 @@
1
+ import { renderVerboseBlock } from "./ui.js";
2
+ import path from "node:path";
3
+ //#region src/shell/diagnostics-output.ts
4
+ function renderCommandDiagnostics(context, diagnostics, rows = [], options = {}) {
5
+ if (!diagnostics) return [];
6
+ const { env } = context.runtime;
7
+ const git = diagnostics.git;
8
+ return renderVerboseBlock(context.ui, [
9
+ ...rows,
10
+ ...diagnostics.durationMs === void 0 ? [] : [{
11
+ key: "duration",
12
+ value: formatDuration(diagnostics.durationMs)
13
+ }],
14
+ {
15
+ key: "cwd",
16
+ value: formatLocalPath(diagnostics.cwd, env)
17
+ },
18
+ {
19
+ key: "state file",
20
+ value: formatLocalPath(diagnostics.stateFilePath, env)
21
+ },
22
+ ...git ? [
23
+ {
24
+ key: "git ref",
25
+ value: git.ref ?? "detached",
26
+ tone: git.ref ? "default" : "dim"
27
+ },
28
+ {
29
+ key: "git sha",
30
+ value: git.sha ?? "unknown",
31
+ tone: git.sha ? "default" : "dim"
32
+ },
33
+ {
34
+ key: "git dirty",
35
+ value: formatDirtyState(git.dirty),
36
+ tone: git.dirty ? "warning" : "dim"
37
+ }
38
+ ] : [{
39
+ key: "git",
40
+ value: "not detected",
41
+ tone: "dim"
42
+ }]
43
+ ], { title: options.title ?? "Local context" });
44
+ }
45
+ function formatLocalPath(value, env) {
46
+ const resolved = path.resolve(value);
47
+ const home = env.HOME ? path.resolve(env.HOME) : null;
48
+ if (home && (resolved === home || resolved.startsWith(`${home}${path.sep}`))) {
49
+ const relative = path.relative(home, resolved);
50
+ return relative ? `~/${relative}` : "~";
51
+ }
52
+ return resolved;
53
+ }
54
+ function formatDirtyState(dirty) {
55
+ if (dirty === null) return "unknown";
56
+ return dirty ? "yes" : "no";
57
+ }
58
+ function formatDuration(durationMs) {
59
+ if (durationMs < 1e3) return `${durationMs}ms`;
60
+ return `${(durationMs / 1e3).toFixed(1)}s`;
61
+ }
62
+ //#endregion
63
+ export { renderCommandDiagnostics };
@@ -23,6 +23,15 @@ function cliErrorToJson(error) {
23
23
  docsUrl: error.docsUrl
24
24
  };
25
25
  }
26
+ function formatUnexpectedError(error, trace) {
27
+ const debug = error instanceof Error ? error.stack ?? error.message : String(error);
28
+ if (trace) return `${debug}\n`;
29
+ return [
30
+ `Unexpected CLI error: ${error instanceof Error && error.message ? error.message : String(error)}`,
31
+ "More: Re-run with --trace for deeper diagnostics",
32
+ ""
33
+ ].join("\n");
34
+ }
26
35
  function writeJsonError(output, command, error) {
27
36
  output.stdout.write(`${JSON.stringify({
28
37
  ok: false,
@@ -70,4 +79,4 @@ function writeHumanError(output, ui, error, options) {
70
79
  writeHumanLines(output, lines);
71
80
  }
72
81
  //#endregion
73
- export { cliErrorToJson, writeHumanError, writeHumanLines, writeJsonError, writeJsonEvent, writeJsonSuccess };
82
+ export { cliErrorToJson, formatUnexpectedError, writeHumanError, writeHumanLines, writeJsonError, writeJsonEvent, writeJsonSuccess };
@@ -48,4 +48,4 @@ function canPrompt(context) {
48
48
  return Boolean(context.runtime.stdin.isTTY && context.runtime.stderr.isTTY);
49
49
  }
50
50
  //#endregion
51
- export { canPrompt, configureRuntimeCommand, createCommandContext };
51
+ export { canPrompt, configureRuntimeCommand, createCommandContext, resolveStateDir };
package/dist/shell/ui.js CHANGED
@@ -48,6 +48,17 @@ function renderNextSteps(steps) {
48
48
  ...steps.map((step) => `- ${step}`)
49
49
  ];
50
50
  }
51
+ function renderVerboseBlock(ui, rows, options = {}) {
52
+ if (!ui.verbose || rows.length === 0) return [];
53
+ const title = options.title ?? "Details";
54
+ const keyWidth = Math.max(...rows.map((row) => stringWidth(`${row.key}:`)));
55
+ const rail = ui.dim("│");
56
+ return [
57
+ "",
58
+ `${ui.dim(title)}:`,
59
+ ...rows.map((row) => `${rail} ${ui.accent(padDisplay(`${row.key}:`, keyWidth))} ${formatVerboseValue(ui, row)}`)
60
+ ];
61
+ }
51
62
  function formatColumns(columns, widths) {
52
63
  return columns.map((value, index) => padDisplay(value, widths[index])).join(" ").trimEnd();
53
64
  }
@@ -76,5 +87,13 @@ function formatHeaderValue(ui, row) {
76
87
  if (row.tone === "link") return ui.link(value);
77
88
  return value;
78
89
  }
90
+ function formatVerboseValue(ui, row) {
91
+ const value = row.sensitive ? maskValue(row.value) : row.value;
92
+ if (row.tone === "dim") return ui.dim(value);
93
+ if (row.tone === "success") return ui.success(value);
94
+ if (row.tone === "warning") return ui.warning(value);
95
+ if (row.tone === "link") return ui.link(value);
96
+ return value;
97
+ }
79
98
  //#endregion
80
- export { createShellUi, formatColumns, maskValue, padDisplay, renderCommandHeader, renderNextSteps, renderSummaryLine, wrapText };
99
+ export { createShellUi, formatColumns, maskValue, padDisplay, renderCommandHeader, renderNextSteps, renderSummaryLine, renderVerboseBlock, wrapText };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@prisma/cli",
3
- "version": "3.0.0-dev.62.1",
3
+ "version": "3.0.0-dev.65.1",
4
4
  "description": "Command-line interface for the Prisma Developer Platform.",
5
5
  "type": "module",
6
6
  "bin": {
@@ -36,9 +36,9 @@
36
36
  "license": "Apache-2.0",
37
37
  "dependencies": {
38
38
  "@clack/prompts": "^1.5.0",
39
- "@prisma/compute-sdk": "^0.20.0",
39
+ "@prisma/compute-sdk": "^0.21.0",
40
40
  "@prisma/credentials-store": "^7.8.0",
41
- "@prisma/management-api-sdk": "^1.35.0",
41
+ "@prisma/management-api-sdk": "^1.37.0",
42
42
  "c12": "4.0.0-beta.5",
43
43
  "colorette": "^2.0.20",
44
44
  "commander": "^14.0.3",