@prisma/cli 3.0.0-dev.41.1 → 3.0.0-dev.42.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.
- package/dist/controllers/app.js +47 -21
- package/dist/controllers/project.js +35 -7
- package/dist/lib/project/resolution.js +41 -2
- package/dist/lib/project/setup.js +2 -4
- package/dist/presenters/project.js +29 -44
- package/dist/shell/command-arguments.js +6 -0
- package/dist/shell/command-runner.js +4 -2
- package/dist/shell/errors.js +2 -0
- package/dist/shell/output.js +3 -1
- package/package.json +1 -1
package/dist/controllers/app.js
CHANGED
|
@@ -11,9 +11,10 @@ import { parseEnvAssignments } from "../lib/app/env-vars.js";
|
|
|
11
11
|
import { renderDeployOutputRows } from "../lib/app/deploy-output.js";
|
|
12
12
|
import { readBunPackageEntrypoint, readBunPackageJson } from "../lib/app/bun-project.js";
|
|
13
13
|
import { DEFAULT_LOCAL_DEV_PORT, resolveLocalBuildType, runLocalApp } from "../lib/app/local-dev.js";
|
|
14
|
+
import { formatCommandArgument } from "../shell/command-arguments.js";
|
|
14
15
|
import { LOCAL_RESOLUTION_PIN_RELATIVE_PATH, readLocalResolutionPin } from "../lib/project/local-pin.js";
|
|
15
|
-
import { inferTargetName, projectNotFoundError, resolveDurablePlatformMapping, resolveProjectTarget, sortProjects } from "../lib/project/resolution.js";
|
|
16
|
-
import { bindProjectToDirectory,
|
|
16
|
+
import { buildProjectSetupNextActions, inferTargetName, projectNotFoundError, resolveDurablePlatformMapping, resolveProjectTarget, sortProjects } from "../lib/project/resolution.js";
|
|
17
|
+
import { bindProjectToDirectory, projectCreateFailedError, projectSetupNameRequiredError, resolveProjectForSetup, toProjectSummary } from "../lib/project/setup.js";
|
|
17
18
|
import { PREVIEW_BUILD_TYPES, RESOLVED_PREVIEW_BUILD_TYPES, executePreviewBuild } from "../lib/app/preview-build.js";
|
|
18
19
|
import { PREVIEW_DEFAULT_REGION } from "../lib/app/preview-interaction.js";
|
|
19
20
|
import { createPreviewDeployProgress, createPreviewDeployProgressState, createPreviewPromoteProgress } from "../lib/app/preview-progress.js";
|
|
@@ -1796,24 +1797,41 @@ function deployFailedError(summary, error, nextSteps) {
|
|
|
1796
1797
|
function appDeployFailedError(error, progress) {
|
|
1797
1798
|
const why = error instanceof Error ? error.message : String(error);
|
|
1798
1799
|
const debug = formatDebugDetails(error);
|
|
1799
|
-
if (progress.buildStarted && !progress.buildCompleted)
|
|
1800
|
-
|
|
1801
|
-
|
|
1802
|
-
|
|
1803
|
-
|
|
1804
|
-
|
|
1805
|
-
|
|
1806
|
-
|
|
1807
|
-
|
|
1808
|
-
|
|
1809
|
-
"",
|
|
1810
|
-
|
|
1811
|
-
"",
|
|
1812
|
-
|
|
1813
|
-
]
|
|
1814
|
-
|
|
1815
|
-
|
|
1816
|
-
|
|
1800
|
+
if (progress.buildStarted && !progress.buildCompleted) {
|
|
1801
|
+
const standaloneOutputFailure = isNextStandaloneOutputFailure(why);
|
|
1802
|
+
const fix = standaloneOutputFailure ? "Add output: \"standalone\" to next.config.*, then rerun deploy." : "Inspect the build output above, fix the error, and redeploy.";
|
|
1803
|
+
const nextSteps = standaloneOutputFailure ? ["Add output: \"standalone\" to next.config.*, then rerun prisma-cli app deploy"] : [];
|
|
1804
|
+
const nextActions = standaloneOutputFailure ? [{
|
|
1805
|
+
kind: "edit-file",
|
|
1806
|
+
journey: "deploy-app",
|
|
1807
|
+
label: "Add Next.js standalone output",
|
|
1808
|
+
reason: "Prisma Compute needs Next.js standalone output to build a deployable server artifact."
|
|
1809
|
+
}, {
|
|
1810
|
+
kind: "run-command",
|
|
1811
|
+
journey: "deploy-app",
|
|
1812
|
+
label: "Rerun deploy",
|
|
1813
|
+
command: "prisma-cli app deploy"
|
|
1814
|
+
}] : [];
|
|
1815
|
+
return new CliError({
|
|
1816
|
+
code: "BUILD_FAILED",
|
|
1817
|
+
domain: "app",
|
|
1818
|
+
summary: "Build failed locally.",
|
|
1819
|
+
why,
|
|
1820
|
+
fix,
|
|
1821
|
+
debug,
|
|
1822
|
+
meta: { phase: "build" },
|
|
1823
|
+
humanLines: [
|
|
1824
|
+
"Build failed locally.",
|
|
1825
|
+
"",
|
|
1826
|
+
`✗ Built ${why}`,
|
|
1827
|
+
"",
|
|
1828
|
+
`Fix: ${fix}`
|
|
1829
|
+
],
|
|
1830
|
+
exitCode: 1,
|
|
1831
|
+
nextSteps,
|
|
1832
|
+
nextActions
|
|
1833
|
+
});
|
|
1834
|
+
}
|
|
1817
1835
|
if (!progress.buildStarted) return deployFailedError("App deploy failed", error, ["prisma-cli app deploy"]);
|
|
1818
1836
|
const phaseHeadline = progress.containerLive ? "The deployment started, but the app is not ready yet." : "Deploy failed after the build completed.";
|
|
1819
1837
|
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."];
|
|
@@ -1896,9 +1914,17 @@ function projectSetupRequiredError(projects, suggestedName) {
|
|
|
1896
1914
|
"prisma-cli project list",
|
|
1897
1915
|
"prisma-cli app deploy --project <id-or-name>",
|
|
1898
1916
|
createCommand
|
|
1899
|
-
]
|
|
1917
|
+
],
|
|
1918
|
+
nextActions: buildProjectSetupNextActions({
|
|
1919
|
+
commandName: "app deploy",
|
|
1920
|
+
createCommand,
|
|
1921
|
+
reason: "This directory is not linked to a Prisma Project. Ask the user which Project to use before deploying; package and directory names are setup suggestions only."
|
|
1922
|
+
})
|
|
1900
1923
|
});
|
|
1901
1924
|
}
|
|
1925
|
+
function isNextStandaloneOutputFailure(message) {
|
|
1926
|
+
return /next\.?js/i.test(message) && /standalone output/i.test(message);
|
|
1927
|
+
}
|
|
1902
1928
|
function noDeploymentsError(summary, why) {
|
|
1903
1929
|
return new CliError({
|
|
1904
1930
|
code: "NO_DEPLOYMENTS",
|
|
@@ -2,7 +2,8 @@ import { CliError, authRequiredError, featureUnavailableError, usageError, works
|
|
|
2
2
|
import { renderSummaryLine } from "../shell/ui.js";
|
|
3
3
|
import { canPrompt } from "../shell/runtime.js";
|
|
4
4
|
import { requireComputeAuth } from "../lib/auth/guard.js";
|
|
5
|
-
import {
|
|
5
|
+
import { readLocalResolutionPin } from "../lib/project/local-pin.js";
|
|
6
|
+
import { buildProjectSetupNextActions, inspectProjectBinding, resolveProjectTarget, sortProjects } from "../lib/project/resolution.js";
|
|
6
7
|
import { bindProjectToDirectory, isValidProjectSetupName, projectCreateFailedError, projectSetupNameRequiredError, resolveProjectForSetup, toProjectSummary } from "../lib/project/setup.js";
|
|
7
8
|
import { createPreviewAppProvider } from "../lib/app/preview-provider.js";
|
|
8
9
|
import { createCliUseCaseGateways } from "../use-cases/create-cli-gateways.js";
|
|
@@ -16,6 +17,12 @@ const GITHUB_INSTALL_POLL_TIMEOUT_MS = 12e4;
|
|
|
16
17
|
function isRealMode(context) {
|
|
17
18
|
return !context.runtime.fixturePath && !context.runtime.env.PRISMA_CLI_MOCK_FIXTURE_PATH;
|
|
18
19
|
}
|
|
20
|
+
async function readProjectListLocalBinding(cwd, workspace, projects) {
|
|
21
|
+
const pin = await readLocalResolutionPin(cwd);
|
|
22
|
+
if (pin.kind === "present") return pin.pin.workspaceId === workspace.id && projects.some((project) => project.id === pin.pin.projectId) ? { status: "linked" } : { status: "invalid" };
|
|
23
|
+
if (pin.kind === "invalid") return { status: "invalid" };
|
|
24
|
+
return { status: "not-linked" };
|
|
25
|
+
}
|
|
19
26
|
async function runProjectList(context) {
|
|
20
27
|
const authState = await requireAuthenticatedAuthState(context);
|
|
21
28
|
const workspace = authState.workspace;
|
|
@@ -23,31 +30,52 @@ async function runProjectList(context) {
|
|
|
23
30
|
if (isRealMode(context)) {
|
|
24
31
|
const client = await requireComputeAuth(context.runtime.env);
|
|
25
32
|
if (!client) throw authRequiredError();
|
|
33
|
+
const projects = sortProjects(await listRealWorkspaceProjects(client, workspace));
|
|
34
|
+
const localBinding = await readProjectListLocalBinding(context.runtime.cwd, workspace, projects);
|
|
35
|
+
const nextActions = buildProjectListNextActions(localBinding);
|
|
26
36
|
return {
|
|
27
37
|
command: "project.list",
|
|
28
38
|
result: {
|
|
29
39
|
workspace,
|
|
30
|
-
projects:
|
|
40
|
+
projects: projects.map(toProjectSummary),
|
|
41
|
+
localBinding
|
|
31
42
|
},
|
|
32
43
|
warnings: [],
|
|
33
|
-
nextSteps: []
|
|
44
|
+
nextSteps: [],
|
|
45
|
+
nextActions
|
|
34
46
|
};
|
|
35
47
|
}
|
|
48
|
+
const result = await createProjectUseCases(createCliUseCaseGateways(context)).list(authState);
|
|
49
|
+
const localBinding = await readProjectListLocalBinding(context.runtime.cwd, workspace, result.projects);
|
|
50
|
+
const nextActions = buildProjectListNextActions(localBinding);
|
|
36
51
|
return {
|
|
37
52
|
command: "project.list",
|
|
38
|
-
result:
|
|
53
|
+
result: {
|
|
54
|
+
...result,
|
|
55
|
+
localBinding
|
|
56
|
+
},
|
|
39
57
|
warnings: [],
|
|
40
|
-
nextSteps: []
|
|
58
|
+
nextSteps: [],
|
|
59
|
+
nextActions
|
|
41
60
|
};
|
|
42
61
|
}
|
|
62
|
+
function buildProjectListNextActions(localBinding) {
|
|
63
|
+
return localBinding?.status === "linked" ? [] : buildProjectSetupNextActions({ reason: localBinding?.status === "invalid" ? "This directory has an invalid local Project binding. Ask the user which Prisma Project to link before running Project-scoped commands." : "This directory is not linked to a Prisma Project. Project list shows available Projects, but none is selected for this directory." });
|
|
64
|
+
}
|
|
43
65
|
async function runProjectShow(context, explicitProject) {
|
|
44
66
|
const workspace = (await requireAuthenticatedAuthState(context)).workspace;
|
|
45
67
|
if (!workspace) throw workspaceRequiredError();
|
|
68
|
+
const result = isRealMode(context) ? await resolveProjectShowInRealMode(context, workspace, explicitProject) : await resolveProjectShowInFixtureMode(context, workspace, explicitProject);
|
|
46
69
|
return {
|
|
47
70
|
command: "project.show",
|
|
48
|
-
result
|
|
71
|
+
result,
|
|
49
72
|
warnings: [],
|
|
50
|
-
nextSteps: []
|
|
73
|
+
nextSteps: [],
|
|
74
|
+
nextActions: result.project === null ? buildProjectSetupNextActions({
|
|
75
|
+
commandName: "project show",
|
|
76
|
+
suggestedProjectName: result.suggestedProjectName,
|
|
77
|
+
reason: "This directory is not linked to a Prisma Project. Package and directory names can suggest setup defaults, but they do not select a Project."
|
|
78
|
+
}) : []
|
|
51
79
|
};
|
|
52
80
|
}
|
|
53
81
|
async function runProjectCreate(context, projectName) {
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { CliError } from "../../shell/errors.js";
|
|
2
|
+
import { formatCommandArgument } from "../../shell/command-arguments.js";
|
|
2
3
|
import { LOCAL_RESOLUTION_PIN_RELATIVE_PATH, readLocalResolutionPin } from "./local-pin.js";
|
|
3
4
|
import { readFile } from "node:fs/promises";
|
|
4
5
|
import path from "node:path";
|
|
@@ -20,6 +21,7 @@ async function inspectProjectBinding(options) {
|
|
|
20
21
|
return {
|
|
21
22
|
workspace: options.workspace,
|
|
22
23
|
project: null,
|
|
24
|
+
localBinding: { status: "not-linked" },
|
|
23
25
|
resolution: { projectSource: "unbound" },
|
|
24
26
|
...await buildProjectSetupSuggestion({
|
|
25
27
|
cwd: options.context.runtime.cwd,
|
|
@@ -89,8 +91,45 @@ async function projectSetupRequiredError(options) {
|
|
|
89
91
|
fix: "Link the directory to an existing Project, or pass --project <id-or-name> for this command.",
|
|
90
92
|
meta: { ...suggestion },
|
|
91
93
|
exitCode: 1,
|
|
92
|
-
nextSteps: ["prisma-cli project list", ...suggestion.recoveryCommands]
|
|
94
|
+
nextSteps: ["prisma-cli project list", ...suggestion.recoveryCommands],
|
|
95
|
+
nextActions: buildProjectSetupNextActions({
|
|
96
|
+
commandName: options.commandName,
|
|
97
|
+
suggestedProjectName: suggestion.suggestedProjectName
|
|
98
|
+
})
|
|
99
|
+
});
|
|
100
|
+
}
|
|
101
|
+
function buildProjectSetupNextActions(options = {}) {
|
|
102
|
+
const recoveryCommands = buildProjectRecoveryCommands(options.commandName);
|
|
103
|
+
const linkCommand = recoveryCommands[0] ?? "prisma-cli project link <id-or-name>";
|
|
104
|
+
const retryCommand = recoveryCommands[1];
|
|
105
|
+
const actions = [{
|
|
106
|
+
kind: "user-choice",
|
|
107
|
+
journey: "project-setup",
|
|
108
|
+
label: "Ask the user which Prisma Project this directory should use",
|
|
109
|
+
commands: ["prisma-cli project list", ...recoveryCommands],
|
|
110
|
+
reason: options.reason ?? "This directory is not linked to a Prisma Project. Package and directory names are suggestions only, not a safe Project selection."
|
|
111
|
+
}, {
|
|
112
|
+
kind: "run-command",
|
|
113
|
+
journey: "project-setup",
|
|
114
|
+
label: "Link the chosen Project",
|
|
115
|
+
command: linkCommand,
|
|
116
|
+
reason: "Linking writes the durable local Project binding for this directory."
|
|
117
|
+
}];
|
|
118
|
+
const createCommand = options.createCommand ?? (options.suggestedProjectName ? `prisma-cli project create ${formatCommandArgument(options.suggestedProjectName)}` : void 0);
|
|
119
|
+
if (createCommand) actions.push({
|
|
120
|
+
kind: "run-command",
|
|
121
|
+
journey: "project-setup",
|
|
122
|
+
label: "Create and link a new Project",
|
|
123
|
+
command: createCommand,
|
|
124
|
+
reason: "Use this when the user wants a new Prisma Project instead of an existing one."
|
|
125
|
+
});
|
|
126
|
+
if (options.commandName) actions.push({
|
|
127
|
+
kind: "run-command",
|
|
128
|
+
journey: "recover",
|
|
129
|
+
label: "Retry with an explicit Project",
|
|
130
|
+
command: retryCommand ?? `prisma-cli ${options.commandName} --project <id-or-name>`
|
|
93
131
|
});
|
|
132
|
+
return actions;
|
|
94
133
|
}
|
|
95
134
|
async function readPackageName(cwd) {
|
|
96
135
|
try {
|
|
@@ -187,4 +226,4 @@ function toProjectSummary(project) {
|
|
|
187
226
|
};
|
|
188
227
|
}
|
|
189
228
|
//#endregion
|
|
190
|
-
export { inferTargetName, inspectProjectBinding, projectAmbiguousError, projectNotFoundError, resolveDurablePlatformMapping, resolveProjectTarget, sortProjects };
|
|
229
|
+
export { buildProjectSetupNextActions, inferTargetName, inspectProjectBinding, projectAmbiguousError, projectNotFoundError, resolveDurablePlatformMapping, resolveProjectTarget, sortProjects };
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { CliError, usageError } from "../../shell/errors.js";
|
|
2
|
+
import "../../shell/command-arguments.js";
|
|
2
3
|
import { LOCAL_RESOLUTION_PIN_RELATIVE_PATH, ensureLocalResolutionPinGitignore, writeLocalResolutionPin } from "./local-pin.js";
|
|
3
4
|
import { projectAmbiguousError, projectNotFoundError } from "./resolution.js";
|
|
4
5
|
//#region src/lib/project/setup.ts
|
|
@@ -60,9 +61,6 @@ function projectCreateFailedError(error, projectName, workspace, options) {
|
|
|
60
61
|
nextSteps: options.nextSteps
|
|
61
62
|
});
|
|
62
63
|
}
|
|
63
|
-
function formatCommandArgument(value) {
|
|
64
|
-
return /^[A-Za-z0-9._/-]+$/.test(value) ? value : JSON.stringify(value);
|
|
65
|
-
}
|
|
66
64
|
function formatSetupDirectory(cwd) {
|
|
67
65
|
const basename = cwd.split(/[\\/]/).filter(Boolean).pop();
|
|
68
66
|
return basename ? `./${basename}` : ".";
|
|
@@ -83,4 +81,4 @@ function formatDebugDetails(error) {
|
|
|
83
81
|
return typeof error === "string" ? error : null;
|
|
84
82
|
}
|
|
85
83
|
//#endregion
|
|
86
|
-
export { bindProjectToDirectory,
|
|
84
|
+
export { bindProjectToDirectory, isValidProjectSetupName, projectCreateFailedError, projectSetupNameRequiredError, resolveProjectForSetup, toProjectSummary };
|
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
import { renderSummaryLine } from "../shell/ui.js";
|
|
1
|
+
import { renderNextSteps, renderSummaryLine } from "../shell/ui.js";
|
|
2
|
+
import { formatCommandArgument } from "../shell/command-arguments.js";
|
|
2
3
|
import { renderList, renderMutate, renderShow, serializeList } from "../output/patterns.js";
|
|
3
4
|
//#region src/presenters/project.ts
|
|
4
5
|
function renderProjectList(context, descriptor, result) {
|
|
5
|
-
|
|
6
|
+
const lines = renderList({
|
|
6
7
|
title: "Listing projects for the authenticated workspace.",
|
|
7
8
|
descriptor,
|
|
8
9
|
parentContext: {
|
|
@@ -17,46 +18,40 @@ function renderProjectList(context, descriptor, result) {
|
|
|
17
18
|
})),
|
|
18
19
|
emptyMessage: "No projects found."
|
|
19
20
|
}, context.ui);
|
|
21
|
+
if (result.localBinding?.status === "not-linked" || result.localBinding?.status === "invalid") lines.push(...renderNextSteps(["Link the chosen Project: prisma-cli project link <id-or-name>"]));
|
|
22
|
+
return lines;
|
|
20
23
|
}
|
|
21
24
|
function serializeProjectList(result) {
|
|
22
|
-
return
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
25
|
+
return {
|
|
26
|
+
...serializeList({
|
|
27
|
+
context: { workspace: result.workspace.name },
|
|
28
|
+
items: result.projects.map((project) => ({
|
|
29
|
+
noun: "project",
|
|
30
|
+
label: project.name,
|
|
31
|
+
id: project.id,
|
|
32
|
+
status: null
|
|
33
|
+
}))
|
|
34
|
+
}),
|
|
35
|
+
localBinding: result.localBinding ?? null
|
|
36
|
+
};
|
|
31
37
|
}
|
|
32
38
|
function renderProjectShow(context, descriptor, result) {
|
|
33
|
-
if (result.project === null)
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
{
|
|
39
|
+
if (result.project === null) {
|
|
40
|
+
const lines = renderShow({
|
|
41
|
+
title: "This directory is not linked to a Prisma Project.",
|
|
42
|
+
descriptor,
|
|
43
|
+
fields: [{
|
|
38
44
|
key: "workspace",
|
|
39
45
|
value: result.workspace.name
|
|
40
|
-
},
|
|
41
|
-
{
|
|
46
|
+
}, {
|
|
42
47
|
key: "project",
|
|
43
|
-
value: "
|
|
48
|
+
value: "Not linked",
|
|
44
49
|
tone: "warning"
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
{
|
|
51
|
-
key: "match",
|
|
52
|
-
value: formatCandidateList(result.candidates)
|
|
53
|
-
},
|
|
54
|
-
{
|
|
55
|
-
key: "next",
|
|
56
|
-
value: result.recoveryCommands[0] ?? "prisma-cli project link <id-or-name>"
|
|
57
|
-
}
|
|
58
|
-
]
|
|
59
|
-
}, context.ui);
|
|
50
|
+
}]
|
|
51
|
+
}, context.ui);
|
|
52
|
+
lines.push(...renderNextSteps(["Link an existing Project: prisma-cli project link <id-or-name>", `Create a new Project: prisma-cli project create ${formatCommandArgument(result.suggestedProjectName)}`]));
|
|
53
|
+
return lines;
|
|
54
|
+
}
|
|
60
55
|
return renderShow({
|
|
61
56
|
title: "Showing this directory's Project binding.",
|
|
62
57
|
descriptor,
|
|
@@ -149,16 +144,6 @@ function formatProjectSource(source) {
|
|
|
149
144
|
case "unbound": return "unbound";
|
|
150
145
|
}
|
|
151
146
|
}
|
|
152
|
-
function formatSuggestionSource(source) {
|
|
153
|
-
switch (source) {
|
|
154
|
-
case "package-name": return "package name";
|
|
155
|
-
case "directory-name": return "directory name";
|
|
156
|
-
}
|
|
157
|
-
}
|
|
158
|
-
function formatCandidateList(candidates) {
|
|
159
|
-
if (candidates.length === 0) return "none";
|
|
160
|
-
return candidates.map((project) => project.name).join(", ");
|
|
161
|
-
}
|
|
162
147
|
function formatGitConnectionDetail(status) {
|
|
163
148
|
switch (status) {
|
|
164
149
|
case "active": return "GitHub branch automation is active for this project.";
|
|
@@ -47,7 +47,8 @@ async function runStreamingCommand(runtime, commandName, options, handler) {
|
|
|
47
47
|
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
48
48
|
result: null,
|
|
49
49
|
warnings: [],
|
|
50
|
-
nextSteps: []
|
|
50
|
+
nextSteps: [],
|
|
51
|
+
nextActions: []
|
|
51
52
|
});
|
|
52
53
|
} catch (error) {
|
|
53
54
|
const cliError = toCliError(error);
|
|
@@ -58,7 +59,8 @@ async function runStreamingCommand(runtime, commandName, options, handler) {
|
|
|
58
59
|
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
59
60
|
error: cliErrorToJson(cliError),
|
|
60
61
|
warnings: [],
|
|
61
|
-
nextSteps: cliError.nextSteps
|
|
62
|
+
nextSteps: cliError.nextSteps,
|
|
63
|
+
nextActions: cliError.nextActions
|
|
62
64
|
});
|
|
63
65
|
else writeHumanError(context.output, context.ui, cliError, { trace: flags.trace });
|
|
64
66
|
process.exitCode = cliError.exitCode;
|
package/dist/shell/errors.js
CHANGED
|
@@ -12,6 +12,7 @@ var CliError = class extends Error {
|
|
|
12
12
|
docsUrl;
|
|
13
13
|
exitCode;
|
|
14
14
|
nextSteps;
|
|
15
|
+
nextActions;
|
|
15
16
|
humanLines;
|
|
16
17
|
constructor(options) {
|
|
17
18
|
super(options.summary);
|
|
@@ -28,6 +29,7 @@ var CliError = class extends Error {
|
|
|
28
29
|
this.docsUrl = options.docsUrl ?? null;
|
|
29
30
|
this.exitCode = options.exitCode ?? 1;
|
|
30
31
|
this.nextSteps = options.nextSteps ?? [];
|
|
32
|
+
this.nextActions = options.nextActions ?? [];
|
|
31
33
|
this.humanLines = options.humanLines && options.humanLines.length > 0 ? [...options.humanLines] : null;
|
|
32
34
|
}
|
|
33
35
|
};
|
package/dist/shell/output.js
CHANGED
|
@@ -3,6 +3,7 @@ import { renderNextSteps, renderSummaryLine } from "./ui.js";
|
|
|
3
3
|
function writeJsonSuccess(output, success) {
|
|
4
4
|
output.stdout.write(`${JSON.stringify({
|
|
5
5
|
ok: true,
|
|
6
|
+
nextActions: [],
|
|
6
7
|
...success
|
|
7
8
|
}, null, 2)}\n`);
|
|
8
9
|
}
|
|
@@ -28,7 +29,8 @@ function writeJsonError(output, command, error) {
|
|
|
28
29
|
command,
|
|
29
30
|
error: cliErrorToJson(error),
|
|
30
31
|
warnings: [],
|
|
31
|
-
nextSteps: error.nextSteps
|
|
32
|
+
nextSteps: error.nextSteps,
|
|
33
|
+
nextActions: error.nextActions
|
|
32
34
|
}, null, 2)}\n`);
|
|
33
35
|
}
|
|
34
36
|
function writeHumanLines(output, lines) {
|