@prisma/cli 3.0.0-beta.1 → 3.0.0-beta.11
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 +5 -3
- package/dist/adapters/git.js +8 -3
- package/dist/adapters/local-state.js +12 -4
- package/dist/adapters/mock-api.js +81 -2
- package/dist/adapters/token-storage.js +64 -23
- package/dist/cli.js +18 -3
- package/dist/cli2.js +9 -5
- package/dist/commands/app/index.js +84 -59
- package/dist/commands/branch/index.js +2 -27
- package/dist/commands/database/index.js +159 -0
- package/dist/commands/env.js +8 -4
- package/dist/controllers/app-env-api.js +54 -0
- package/dist/controllers/app-env-file.js +181 -0
- package/dist/controllers/app-env.js +286 -131
- package/dist/controllers/app.js +699 -244
- package/dist/controllers/auth.js +8 -8
- package/dist/controllers/branch.js +78 -48
- package/dist/controllers/database.js +318 -0
- package/dist/controllers/project.js +156 -85
- package/dist/lib/app/branch-database-deploy.js +325 -0
- package/dist/lib/app/branch-database.js +215 -0
- package/dist/lib/app/bun-project.js +12 -5
- package/dist/lib/app/compute-config.js +147 -0
- package/dist/lib/app/deploy-output.js +10 -1
- package/dist/lib/app/deploy-plan.js +58 -0
- package/dist/lib/app/env-config.js +1 -1
- package/dist/lib/app/env-file.js +82 -0
- package/dist/lib/app/env-vars.js +28 -2
- package/dist/lib/app/local-dev.js +8 -49
- package/dist/lib/app/preview-branch-database.js +102 -0
- package/dist/lib/app/preview-build-settings.js +376 -0
- package/dist/lib/app/preview-build.js +314 -97
- package/dist/lib/app/preview-provider.js +178 -65
- package/dist/lib/app/production-deploy-gate.js +161 -0
- package/dist/lib/auth/auth-ops.js +30 -21
- package/dist/lib/auth/guard.js +3 -2
- package/dist/lib/auth/login.js +116 -14
- package/dist/lib/database/provider.js +167 -0
- package/dist/lib/diagnostics.js +15 -0
- package/dist/lib/fs/home-path.js +24 -0
- package/dist/lib/git/local-branch.js +53 -0
- package/dist/lib/git/local-status.js +57 -0
- package/dist/lib/project/interactive-setup.js +1 -1
- package/dist/lib/project/local-pin.js +182 -33
- package/dist/lib/project/resolution.js +204 -50
- package/dist/lib/project/setup.js +66 -19
- package/dist/output/patterns.js +1 -1
- package/dist/presenters/app-env.js +149 -14
- package/dist/presenters/app.js +178 -23
- package/dist/presenters/branch.js +37 -102
- package/dist/presenters/database.js +274 -0
- package/dist/presenters/project.js +57 -39
- package/dist/presenters/verbose-context.js +64 -0
- package/dist/shell/command-meta.js +103 -13
- package/dist/shell/command-runner.js +57 -19
- package/dist/shell/diagnostics-output.js +57 -0
- package/dist/shell/errors.js +12 -1
- package/dist/shell/help.js +30 -20
- package/dist/shell/output.js +10 -1
- package/dist/shell/runtime.js +11 -7
- package/dist/shell/ui.js +42 -3
- package/dist/shell/update-check.js +247 -0
- package/dist/use-cases/branch.js +20 -68
- package/dist/use-cases/create-cli-gateways.js +2 -17
- package/dist/use-cases/project.js +2 -1
- package/package.json +26 -10
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
import { CliError, usageError } from "../../shell/errors.js";
|
|
2
|
-
import "
|
|
2
|
+
import { shortenHomePath } from "../fs/home-path.js";
|
|
3
3
|
import { LOCAL_RESOLUTION_PIN_RELATIVE_PATH, ensureLocalResolutionPinGitignore, writeLocalResolutionPin } from "./local-pin.js";
|
|
4
|
+
import "../../shell/command-arguments.js";
|
|
4
5
|
import { projectAmbiguousError, projectNotFoundError } from "./resolution.js";
|
|
6
|
+
import path from "node:path";
|
|
7
|
+
import { Result, matchError } from "better-result";
|
|
5
8
|
//#region src/lib/project/setup.ts
|
|
6
9
|
function isValidProjectSetupName(projectName) {
|
|
7
10
|
return projectName.trim().length > 0;
|
|
@@ -16,27 +19,70 @@ function resolveProjectForSetup(projectRef, projects, workspace) {
|
|
|
16
19
|
if (matches.length > 1) throw projectAmbiguousError(projectRef, matches);
|
|
17
20
|
throw projectNotFoundError(projectRef, workspace);
|
|
18
21
|
}
|
|
19
|
-
async function bindProjectToDirectory(context, workspace, project, action) {
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
22
|
+
async function bindProjectToDirectory(context, workspace, project, action, directory = context.runtime.cwd) {
|
|
23
|
+
return Result.gen(async function* () {
|
|
24
|
+
yield* Result.await(writeLocalResolutionPin(directory, {
|
|
25
|
+
workspaceId: workspace.id,
|
|
26
|
+
projectId: project.id
|
|
27
|
+
}, context.runtime.signal));
|
|
28
|
+
yield* Result.await(ensureLocalResolutionPinGitignore(directory, context.runtime.signal));
|
|
29
|
+
return Result.ok({
|
|
30
|
+
workspace,
|
|
31
|
+
project,
|
|
32
|
+
directory: formatSetupDirectory(directory, context),
|
|
33
|
+
localPin: {
|
|
34
|
+
path: LOCAL_RESOLUTION_PIN_RELATIVE_PATH,
|
|
35
|
+
written: true
|
|
36
|
+
},
|
|
37
|
+
action
|
|
38
|
+
});
|
|
23
39
|
});
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
localPin: {
|
|
30
|
-
path: LOCAL_RESOLUTION_PIN_RELATIVE_PATH,
|
|
31
|
-
written: true
|
|
40
|
+
}
|
|
41
|
+
function projectDirectoryBindingErrorToCliError(error) {
|
|
42
|
+
return matchError(error, {
|
|
43
|
+
LocalResolutionPinSerializationError: (error) => {
|
|
44
|
+
throw error;
|
|
32
45
|
},
|
|
33
|
-
|
|
34
|
-
|
|
46
|
+
LocalResolutionPinWriteAbortedError: (error) => {
|
|
47
|
+
throw error;
|
|
48
|
+
},
|
|
49
|
+
LocalResolutionPinWriteFailedError: (error) => localStateWriteFailedError(error, {
|
|
50
|
+
why: `The CLI could not write ${LOCAL_RESOLUTION_PIN_RELATIVE_PATH}.`,
|
|
51
|
+
meta: {
|
|
52
|
+
pinPath: error.pinPath,
|
|
53
|
+
operation: error.operation
|
|
54
|
+
}
|
|
55
|
+
}),
|
|
56
|
+
LocalResolutionPinGitignoreUpdateAbortedError: (error) => {
|
|
57
|
+
throw error;
|
|
58
|
+
},
|
|
59
|
+
LocalResolutionPinGitignoreUpdateFailedError: (error) => localStateWriteFailedError(error, {
|
|
60
|
+
why: "The CLI could not update .gitignore to keep local Project binding state out of git.",
|
|
61
|
+
meta: {
|
|
62
|
+
gitignorePath: error.gitignorePath,
|
|
63
|
+
operation: error.operation
|
|
64
|
+
}
|
|
65
|
+
})
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
function localStateWriteFailedError(error, options) {
|
|
69
|
+
return new CliError({
|
|
70
|
+
code: "LOCAL_STATE_WRITE_FAILED",
|
|
71
|
+
domain: "project",
|
|
72
|
+
summary: "Could not save local Project binding",
|
|
73
|
+
why: options.why,
|
|
74
|
+
fix: "Check that this directory is writable and that .prisma/local.json and .gitignore are not blocked by directories or permissions, then retry.",
|
|
75
|
+
debug: formatDebugDetails(error.cause),
|
|
76
|
+
meta: options.meta,
|
|
77
|
+
exitCode: 1,
|
|
78
|
+
nextSteps: ["prisma-cli project link <id-or-name>", "prisma-cli app deploy --project <id-or-name>"]
|
|
79
|
+
});
|
|
35
80
|
}
|
|
36
81
|
function toProjectSummary(project) {
|
|
37
82
|
return {
|
|
38
83
|
id: project.id,
|
|
39
|
-
name: project.name
|
|
84
|
+
name: project.name,
|
|
85
|
+
...project.url ? { url: project.url } : {}
|
|
40
86
|
};
|
|
41
87
|
}
|
|
42
88
|
function projectSetupNameRequiredError(command) {
|
|
@@ -65,8 +111,9 @@ function projectCreateFailedError(error, projectName, workspace, options) {
|
|
|
65
111
|
nextSteps: options.nextSteps
|
|
66
112
|
});
|
|
67
113
|
}
|
|
68
|
-
function formatSetupDirectory(
|
|
69
|
-
|
|
114
|
+
function formatSetupDirectory(directory, context) {
|
|
115
|
+
if (path.resolve(directory) !== path.resolve(context.runtime.cwd)) return shortenHomePath(directory, context.runtime.env);
|
|
116
|
+
const basename = directory.split(/[\\/]/).filter(Boolean).pop();
|
|
70
117
|
return basename ? `./${basename}` : ".";
|
|
71
118
|
}
|
|
72
119
|
function extractHttpStatus(error) {
|
|
@@ -85,4 +132,4 @@ function formatDebugDetails(error) {
|
|
|
85
132
|
return typeof error === "string" ? error : null;
|
|
86
133
|
}
|
|
87
134
|
//#endregion
|
|
88
|
-
export { bindProjectToDirectory, isValidProjectSetupName, projectCreateFailedError, projectSetupNameRequiredError, resolveProjectForSetup, toProjectSummary, validateProjectSetupNameText };
|
|
135
|
+
export { bindProjectToDirectory, isValidProjectSetupName, projectCreateFailedError, projectDirectoryBindingErrorToCliError, projectSetupNameRequiredError, resolveProjectForSetup, toProjectSummary, validateProjectSetupNameText };
|
package/dist/output/patterns.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { maskValue, padDisplay, renderSummaryLine } from "../shell/ui.js";
|
|
2
1
|
import { formatDescriptorLabel } from "../shell/command-meta.js";
|
|
2
|
+
import { maskValue, padDisplay, renderSummaryLine } from "../shell/ui.js";
|
|
3
3
|
import stringWidth from "string-width";
|
|
4
4
|
//#region src/output/patterns.ts
|
|
5
5
|
function renderList(input, ui) {
|
|
@@ -1,11 +1,117 @@
|
|
|
1
|
+
import { renderVerboseBlock } from "../shell/ui.js";
|
|
1
2
|
import { renderList, renderShow, serializeList } from "../output/patterns.js";
|
|
3
|
+
import { renderResolvedProjectContextBlock, stripVerboseContext } from "./verbose-context.js";
|
|
2
4
|
//#region src/presenters/app-env.ts
|
|
3
5
|
function scopeLabel(scope) {
|
|
4
6
|
if (scope.kind === "role") return scope.role ?? "unknown";
|
|
7
|
+
if (scope.kind === "overview") return "overview";
|
|
5
8
|
return `branch:${scope.branchName ?? scope.branchId ?? "unknown"}`;
|
|
6
9
|
}
|
|
10
|
+
function listTargetLabel(result) {
|
|
11
|
+
const target = result.target;
|
|
12
|
+
if (target.source === "overview") return "overview";
|
|
13
|
+
if (target.branchName) {
|
|
14
|
+
const suffix = target.branchExists === false ? " (not created yet)" : "";
|
|
15
|
+
return `branch:${target.branchName} -> ${target.envMap}${suffix}`;
|
|
16
|
+
}
|
|
17
|
+
return scopeLabel(result.scope);
|
|
18
|
+
}
|
|
19
|
+
function renderEnvVerboseBlocks(context, result) {
|
|
20
|
+
return [...renderEnvResolvedContextBlock(context, result.verboseContext), ...renderEnvTargetBlock(context, result)];
|
|
21
|
+
}
|
|
22
|
+
function renderEnvResolvedContextBlock(context, verboseContext) {
|
|
23
|
+
return renderResolvedProjectContextBlock(context.ui, verboseContext);
|
|
24
|
+
}
|
|
25
|
+
function renderEnvTargetBlock(context, result) {
|
|
26
|
+
return renderVerboseBlock(context.ui, envTargetRows(result), { title: "Env target" });
|
|
27
|
+
}
|
|
28
|
+
function envTargetRows(result) {
|
|
29
|
+
return [
|
|
30
|
+
{
|
|
31
|
+
key: "project id",
|
|
32
|
+
value: result.projectId,
|
|
33
|
+
tone: "dim"
|
|
34
|
+
},
|
|
35
|
+
{
|
|
36
|
+
key: "scope",
|
|
37
|
+
value: scopeLabel(result.scope)
|
|
38
|
+
},
|
|
39
|
+
...envListTargetRows(result),
|
|
40
|
+
...envFileRows(result),
|
|
41
|
+
{
|
|
42
|
+
key: "keys",
|
|
43
|
+
value: formatKeyNames(envResultKeys(result)),
|
|
44
|
+
tone: envResultKeys(result).length > 0 ? "default" : "dim"
|
|
45
|
+
}
|
|
46
|
+
];
|
|
47
|
+
}
|
|
48
|
+
function envListTargetRows(result) {
|
|
49
|
+
if (!("target" in result)) return [];
|
|
50
|
+
return [
|
|
51
|
+
{
|
|
52
|
+
key: "target source",
|
|
53
|
+
value: result.target.source
|
|
54
|
+
},
|
|
55
|
+
{
|
|
56
|
+
key: "env map",
|
|
57
|
+
value: result.target.envMap
|
|
58
|
+
},
|
|
59
|
+
...result.target.branchName ? [{
|
|
60
|
+
key: "branch",
|
|
61
|
+
value: result.target.branchName
|
|
62
|
+
}] : [],
|
|
63
|
+
...result.target.branchId ? [{
|
|
64
|
+
key: "branch id",
|
|
65
|
+
value: result.target.branchId,
|
|
66
|
+
tone: "dim"
|
|
67
|
+
}] : [],
|
|
68
|
+
...result.target.branchExists === false ? [{
|
|
69
|
+
key: "branch state",
|
|
70
|
+
value: "not created yet",
|
|
71
|
+
tone: "warning"
|
|
72
|
+
}] : []
|
|
73
|
+
];
|
|
74
|
+
}
|
|
75
|
+
function envFileRows(result) {
|
|
76
|
+
if (!("file" in result) || !result.file) return [];
|
|
77
|
+
return [{
|
|
78
|
+
key: "file",
|
|
79
|
+
value: result.file.path
|
|
80
|
+
}, {
|
|
81
|
+
key: "file count",
|
|
82
|
+
value: String(result.file.count)
|
|
83
|
+
}];
|
|
84
|
+
}
|
|
85
|
+
function envResultKeys(result) {
|
|
86
|
+
if ("variables" in result && result.variables) return result.variables.map((variable) => variable.key).sort((left, right) => left.localeCompare(right));
|
|
87
|
+
if ("variable" in result && result.variable) return [result.variable.key];
|
|
88
|
+
if ("key" in result) return [result.key];
|
|
89
|
+
return [];
|
|
90
|
+
}
|
|
91
|
+
function formatKeyNames(keys) {
|
|
92
|
+
return keys.length > 0 ? keys.join(", ") : "none";
|
|
93
|
+
}
|
|
7
94
|
function renderEnvAdd(context, descriptor, result) {
|
|
8
|
-
|
|
95
|
+
if (result.variables !== void 0) {
|
|
96
|
+
const lines = renderList({
|
|
97
|
+
title: "Setting new environment variables from file.",
|
|
98
|
+
descriptor,
|
|
99
|
+
parentContext: {
|
|
100
|
+
key: "target",
|
|
101
|
+
value: `${scopeLabel(result.scope)} from ${result.file.path}`
|
|
102
|
+
},
|
|
103
|
+
items: result.variables.map((variable) => ({
|
|
104
|
+
noun: "variable",
|
|
105
|
+
label: `${variable.key} (${variable.source})`,
|
|
106
|
+
id: variable.id,
|
|
107
|
+
status: variable.isManagedBySystem ? "default" : null
|
|
108
|
+
})),
|
|
109
|
+
emptyMessage: "No environment variables imported."
|
|
110
|
+
}, context.ui);
|
|
111
|
+
lines.push(...renderEnvVerboseBlocks(context, result));
|
|
112
|
+
return lines;
|
|
113
|
+
}
|
|
114
|
+
const lines = renderShow({
|
|
9
115
|
title: "Setting a new environment variable.",
|
|
10
116
|
descriptor,
|
|
11
117
|
fields: [
|
|
@@ -33,12 +139,33 @@ function renderEnvAdd(context, descriptor, result) {
|
|
|
33
139
|
}
|
|
34
140
|
]
|
|
35
141
|
}, context.ui);
|
|
142
|
+
lines.push(...renderEnvVerboseBlocks(context, result));
|
|
143
|
+
return lines;
|
|
36
144
|
}
|
|
37
145
|
function serializeEnvAdd(result) {
|
|
38
|
-
return result;
|
|
146
|
+
return stripVerboseContext(result);
|
|
39
147
|
}
|
|
40
148
|
function renderEnvUpdate(context, descriptor, result) {
|
|
41
|
-
|
|
149
|
+
if (result.variables !== void 0) {
|
|
150
|
+
const lines = renderList({
|
|
151
|
+
title: "Replacing environment variable values from file.",
|
|
152
|
+
descriptor,
|
|
153
|
+
parentContext: {
|
|
154
|
+
key: "target",
|
|
155
|
+
value: `${scopeLabel(result.scope)} from ${result.file.path}`
|
|
156
|
+
},
|
|
157
|
+
items: result.variables.map((variable) => ({
|
|
158
|
+
noun: "variable",
|
|
159
|
+
label: `${variable.key} (${variable.source})`,
|
|
160
|
+
id: variable.id,
|
|
161
|
+
status: variable.isManagedBySystem ? "default" : null
|
|
162
|
+
})),
|
|
163
|
+
emptyMessage: "No environment variables updated."
|
|
164
|
+
}, context.ui);
|
|
165
|
+
lines.push(...renderEnvVerboseBlocks(context, result));
|
|
166
|
+
return lines;
|
|
167
|
+
}
|
|
168
|
+
const lines = renderShow({
|
|
42
169
|
title: "Replacing the environment variable's value.",
|
|
43
170
|
descriptor,
|
|
44
171
|
fields: [
|
|
@@ -66,17 +193,19 @@ function renderEnvUpdate(context, descriptor, result) {
|
|
|
66
193
|
}
|
|
67
194
|
]
|
|
68
195
|
}, context.ui);
|
|
196
|
+
lines.push(...renderEnvVerboseBlocks(context, result));
|
|
197
|
+
return lines;
|
|
69
198
|
}
|
|
70
199
|
function serializeEnvUpdate(result) {
|
|
71
|
-
return result;
|
|
200
|
+
return stripVerboseContext(result);
|
|
72
201
|
}
|
|
73
202
|
function renderEnvList(context, descriptor, result) {
|
|
74
|
-
|
|
203
|
+
const lines = renderList({
|
|
75
204
|
title: "Listing environment variables for the selected scope.",
|
|
76
205
|
descriptor,
|
|
77
206
|
parentContext: {
|
|
78
|
-
key: "
|
|
79
|
-
value:
|
|
207
|
+
key: "target",
|
|
208
|
+
value: listTargetLabel(result)
|
|
80
209
|
},
|
|
81
210
|
items: result.variables.map((variable) => ({
|
|
82
211
|
noun: "variable",
|
|
@@ -86,25 +215,29 @@ function renderEnvList(context, descriptor, result) {
|
|
|
86
215
|
})),
|
|
87
216
|
emptyMessage: "No environment variables defined in this scope."
|
|
88
217
|
}, context.ui);
|
|
218
|
+
lines.push(...renderEnvVerboseBlocks(context, result));
|
|
219
|
+
return lines;
|
|
89
220
|
}
|
|
90
221
|
function serializeEnvList(result) {
|
|
222
|
+
const serializable = stripVerboseContext(result);
|
|
91
223
|
return {
|
|
92
|
-
projectId:
|
|
93
|
-
scope:
|
|
224
|
+
projectId: serializable.projectId,
|
|
225
|
+
scope: serializable.scope,
|
|
226
|
+
target: serializable.target,
|
|
94
227
|
...serializeList({
|
|
95
|
-
context: {
|
|
96
|
-
items:
|
|
228
|
+
context: { target: listTargetLabel(serializable) },
|
|
229
|
+
items: serializable.variables.map((variable) => ({
|
|
97
230
|
noun: "variable",
|
|
98
231
|
label: `${variable.key} (${variable.source})`,
|
|
99
232
|
id: variable.id,
|
|
100
233
|
status: variable.isManagedBySystem ? "default" : null
|
|
101
234
|
}))
|
|
102
235
|
}),
|
|
103
|
-
variables:
|
|
236
|
+
variables: serializable.variables
|
|
104
237
|
};
|
|
105
238
|
}
|
|
106
239
|
function renderEnvRm(context, descriptor, result) {
|
|
107
|
-
|
|
240
|
+
const lines = renderShow({
|
|
108
241
|
title: "Removing the environment variable from the scope.",
|
|
109
242
|
descriptor,
|
|
110
243
|
fields: [
|
|
@@ -122,9 +255,11 @@ function renderEnvRm(context, descriptor, result) {
|
|
|
122
255
|
}
|
|
123
256
|
]
|
|
124
257
|
}, context.ui);
|
|
258
|
+
lines.push(...renderEnvVerboseBlocks(context, result));
|
|
259
|
+
return lines;
|
|
125
260
|
}
|
|
126
261
|
function serializeEnvRm(result) {
|
|
127
|
-
return result;
|
|
262
|
+
return stripVerboseContext(result);
|
|
128
263
|
}
|
|
129
264
|
//#endregion
|
|
130
265
|
export { renderEnvAdd, renderEnvList, renderEnvRm, renderEnvUpdate, serializeEnvAdd, serializeEnvList, serializeEnvRm, serializeEnvUpdate };
|
package/dist/presenters/app.js
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
|
+
import { renderVerboseBlock } from "../shell/ui.js";
|
|
1
2
|
import { renderDeployOutputRows } from "../lib/app/deploy-output.js";
|
|
2
3
|
import { formatDomainFailureFix } from "../lib/app/domain-guidance.js";
|
|
3
4
|
import { renderList, renderShow, serializeList } from "../output/patterns.js";
|
|
5
|
+
import { renderResolvedProjectContextBlock, stripVerboseContext } from "./verbose-context.js";
|
|
4
6
|
//#region src/presenters/app.ts
|
|
5
7
|
function renderAppBuild(context, descriptor, result) {
|
|
6
8
|
return renderShow({
|
|
@@ -26,27 +28,167 @@ function renderAppBuild(context, descriptor, result) {
|
|
|
26
28
|
function serializeAppBuild(result) {
|
|
27
29
|
return result;
|
|
28
30
|
}
|
|
29
|
-
function renderAppDeploy(context, descriptor, result) {
|
|
31
|
+
function renderAppDeploy(context, descriptor, result, options) {
|
|
32
|
+
const logsCommand = options?.logsTarget ? `prisma-cli app logs ${options.logsTarget}` : "prisma-cli app logs";
|
|
30
33
|
return [
|
|
31
34
|
`Live in ${formatDuration(result.durationMs)}`,
|
|
32
35
|
...result.deployment.url ? [context.ui.link(result.deployment.url)] : [],
|
|
36
|
+
...renderBranchDatabaseDeploySummary(context, result),
|
|
33
37
|
"",
|
|
34
38
|
...renderDeployOutputRows(context.ui, [{
|
|
35
39
|
label: "Logs",
|
|
36
|
-
value:
|
|
37
|
-
}])
|
|
40
|
+
value: logsCommand
|
|
41
|
+
}]),
|
|
42
|
+
...renderDeployResolvedContextBlock(context, result),
|
|
43
|
+
...renderDeploySettingsBlock(context, result)
|
|
38
44
|
];
|
|
39
45
|
}
|
|
46
|
+
function isAppDeployAllResult(result) {
|
|
47
|
+
return "deployments" in result;
|
|
48
|
+
}
|
|
49
|
+
function renderAppDeployAll(context, descriptor, result) {
|
|
50
|
+
const lines = [];
|
|
51
|
+
for (const deployment of result.deployments) {
|
|
52
|
+
lines.push(deployment.target);
|
|
53
|
+
lines.push(...renderAppDeploy(context, descriptor, deployment.result, { logsTarget: deployment.target }).map((line) => line ? ` ${line}` : line));
|
|
54
|
+
lines.push("");
|
|
55
|
+
}
|
|
56
|
+
lines.push(...renderDeployOutputRows(context.ui, result.deployments.map((deployment) => ({
|
|
57
|
+
label: deployment.target,
|
|
58
|
+
value: deployment.result.deployment.url ?? deployment.result.deployment.id
|
|
59
|
+
}))));
|
|
60
|
+
return lines;
|
|
61
|
+
}
|
|
62
|
+
function serializeAppDeployAll(result) {
|
|
63
|
+
return {
|
|
64
|
+
count: result.deployments.length,
|
|
65
|
+
deployments: result.deployments.map((deployment) => ({
|
|
66
|
+
target: deployment.target,
|
|
67
|
+
...serializeAppDeploy(deployment.result)
|
|
68
|
+
}))
|
|
69
|
+
};
|
|
70
|
+
}
|
|
40
71
|
function serializeAppDeploy(result) {
|
|
41
|
-
const { localPin: _localPin, ...serialized } = result;
|
|
42
|
-
|
|
72
|
+
const { deploySettings, localPin: _localPin, ...serialized } = result;
|
|
73
|
+
const { id: _branchId, ...branch } = serialized.branch;
|
|
74
|
+
return {
|
|
75
|
+
...serialized,
|
|
76
|
+
branch,
|
|
77
|
+
deploySettings: {
|
|
78
|
+
config: deploySettings.config,
|
|
79
|
+
buildCommand: deploySettings.buildCommand,
|
|
80
|
+
outputDirectory: deploySettings.outputDirectory
|
|
81
|
+
}
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
function renderBranchDatabaseDeploySummary(context, result) {
|
|
85
|
+
if (!result.branchDatabase || result.branchDatabase.status !== "created") return [];
|
|
86
|
+
return ["", ...renderDeployOutputRows(context.ui, [{
|
|
87
|
+
label: "Database",
|
|
88
|
+
value: result.branchDatabase.database?.name ?? "created"
|
|
89
|
+
}, {
|
|
90
|
+
label: "Env",
|
|
91
|
+
value: result.branchDatabase.envVars.join(", ")
|
|
92
|
+
}])];
|
|
43
93
|
}
|
|
44
94
|
function formatDuration(durationMs) {
|
|
45
95
|
if (durationMs < 1e3) return `${durationMs}ms`;
|
|
46
96
|
return `${(durationMs / 1e3).toFixed(1)}s`;
|
|
47
97
|
}
|
|
98
|
+
function renderDeployResolvedContextBlock(context, result) {
|
|
99
|
+
return renderResolvedProjectContextBlock(context.ui, {
|
|
100
|
+
workspace: result.workspace,
|
|
101
|
+
project: result.project,
|
|
102
|
+
resolution: result.resolution,
|
|
103
|
+
branch: {
|
|
104
|
+
id: result.branch.id,
|
|
105
|
+
name: result.branch.name,
|
|
106
|
+
kind: result.branch.kind
|
|
107
|
+
}
|
|
108
|
+
}, { extraRows: [
|
|
109
|
+
{
|
|
110
|
+
key: "app",
|
|
111
|
+
value: result.app.name
|
|
112
|
+
},
|
|
113
|
+
{
|
|
114
|
+
key: "app id",
|
|
115
|
+
value: result.app.id,
|
|
116
|
+
tone: "dim"
|
|
117
|
+
},
|
|
118
|
+
{
|
|
119
|
+
key: "deployment id",
|
|
120
|
+
value: result.deployment.id,
|
|
121
|
+
tone: "dim"
|
|
122
|
+
},
|
|
123
|
+
{
|
|
124
|
+
key: "deployment status",
|
|
125
|
+
value: result.deployment.status
|
|
126
|
+
},
|
|
127
|
+
...result.localPin ? [{
|
|
128
|
+
key: "local pin",
|
|
129
|
+
value: result.localPin.path
|
|
130
|
+
}] : [],
|
|
131
|
+
{
|
|
132
|
+
key: "deploy duration",
|
|
133
|
+
value: formatDuration(result.durationMs)
|
|
134
|
+
}
|
|
135
|
+
] });
|
|
136
|
+
}
|
|
137
|
+
function renderDeploySettingsBlock(context, result) {
|
|
138
|
+
return renderVerboseBlock(context.ui, [...deploySettingsRows(result.deploySettings), ...branchDatabaseRows(result.branchDatabase)], { title: "Deploy settings" });
|
|
139
|
+
}
|
|
140
|
+
function deploySettingsRows(settings) {
|
|
141
|
+
return [
|
|
142
|
+
{
|
|
143
|
+
key: "framework",
|
|
144
|
+
value: `${settings.framework.name} (${settings.framework.buildType})`
|
|
145
|
+
},
|
|
146
|
+
{
|
|
147
|
+
key: "framework source",
|
|
148
|
+
value: settings.framework.source,
|
|
149
|
+
tone: "dim"
|
|
150
|
+
},
|
|
151
|
+
{
|
|
152
|
+
key: "entrypoint",
|
|
153
|
+
value: settings.entrypoint ?? "derived from build output",
|
|
154
|
+
tone: settings.entrypoint ? "default" : "dim"
|
|
155
|
+
},
|
|
156
|
+
{
|
|
157
|
+
key: "http port",
|
|
158
|
+
value: String(settings.httpPort)
|
|
159
|
+
},
|
|
160
|
+
{
|
|
161
|
+
key: "region",
|
|
162
|
+
value: settings.region ?? "existing app region",
|
|
163
|
+
tone: settings.region ? "default" : "dim"
|
|
164
|
+
},
|
|
165
|
+
{
|
|
166
|
+
key: "env vars",
|
|
167
|
+
value: formatEnvVarNames(settings.envVars),
|
|
168
|
+
tone: settings.envVars.length > 0 ? "default" : "dim"
|
|
169
|
+
}
|
|
170
|
+
];
|
|
171
|
+
}
|
|
172
|
+
function branchDatabaseRows(branchDatabase) {
|
|
173
|
+
if (!branchDatabase) return [{
|
|
174
|
+
key: "branch db",
|
|
175
|
+
value: "not configured",
|
|
176
|
+
tone: "dim"
|
|
177
|
+
}];
|
|
178
|
+
return [{
|
|
179
|
+
key: "branch db",
|
|
180
|
+
value: branchDatabase.status === "created" ? `created${branchDatabase.database ? ` (${branchDatabase.database.name})` : ""}` : `skipped${branchDatabase.reason ? ` (${branchDatabase.reason})` : ""}`,
|
|
181
|
+
tone: branchDatabase.status === "created" ? "success" : "dim"
|
|
182
|
+
}, ...branchDatabase.envVars.length > 0 ? [{
|
|
183
|
+
key: "branch db env",
|
|
184
|
+
value: branchDatabase.envVars.join(", ")
|
|
185
|
+
}] : []];
|
|
186
|
+
}
|
|
187
|
+
function formatEnvVarNames(envVars) {
|
|
188
|
+
return envVars.length > 0 ? envVars.join(", ") : "none";
|
|
189
|
+
}
|
|
48
190
|
function renderAppListDeploys(context, descriptor, result) {
|
|
49
|
-
|
|
191
|
+
const lines = renderList({
|
|
50
192
|
title: "Listing deployments for the selected app.",
|
|
51
193
|
descriptor,
|
|
52
194
|
parentContext: {
|
|
@@ -61,20 +203,23 @@ function renderAppListDeploys(context, descriptor, result) {
|
|
|
61
203
|
})),
|
|
62
204
|
emptyMessage: result.app ? "No deployments found." : "No apps found."
|
|
63
205
|
}, context.ui);
|
|
206
|
+
lines.push(...renderResolvedProjectContextBlock(context.ui, result.verboseContext));
|
|
207
|
+
return lines;
|
|
64
208
|
}
|
|
65
209
|
function serializeAppListDeploys(result) {
|
|
66
|
-
|
|
67
|
-
|
|
210
|
+
const { verboseContext: _verboseContext, ...serializable } = result;
|
|
211
|
+
if (!serializable.app) return {
|
|
212
|
+
projectId: serializable.projectId,
|
|
68
213
|
app: null,
|
|
69
214
|
items: [],
|
|
70
215
|
count: 0
|
|
71
216
|
};
|
|
72
217
|
return {
|
|
73
|
-
projectId:
|
|
74
|
-
app:
|
|
218
|
+
projectId: serializable.projectId,
|
|
219
|
+
app: serializable.app,
|
|
75
220
|
...serializeList({
|
|
76
|
-
context: { app:
|
|
77
|
-
items:
|
|
221
|
+
context: { app: serializable.app.name },
|
|
222
|
+
items: serializable.deployments.map((deployment) => ({
|
|
78
223
|
noun: "deployment",
|
|
79
224
|
label: deployment.id,
|
|
80
225
|
id: deployment.id,
|
|
@@ -84,7 +229,7 @@ function serializeAppListDeploys(result) {
|
|
|
84
229
|
};
|
|
85
230
|
}
|
|
86
231
|
function renderAppShow(context, descriptor, result) {
|
|
87
|
-
|
|
232
|
+
const lines = renderShow({
|
|
88
233
|
title: "Showing the selected app state.",
|
|
89
234
|
descriptor,
|
|
90
235
|
fields: [
|
|
@@ -114,9 +259,11 @@ function renderAppShow(context, descriptor, result) {
|
|
|
114
259
|
}
|
|
115
260
|
]
|
|
116
261
|
}, context.ui);
|
|
262
|
+
lines.push(...renderResolvedProjectContextBlock(context.ui, result.verboseContext));
|
|
263
|
+
return lines;
|
|
117
264
|
}
|
|
118
265
|
function serializeAppShow(result) {
|
|
119
|
-
return result;
|
|
266
|
+
return stripVerboseContext(result);
|
|
120
267
|
}
|
|
121
268
|
function renderAppShowDeploy(context, descriptor, result) {
|
|
122
269
|
return renderShow({
|
|
@@ -158,7 +305,7 @@ function serializeAppShowDeploy(result) {
|
|
|
158
305
|
return result;
|
|
159
306
|
}
|
|
160
307
|
function renderAppOpen(context, descriptor, result) {
|
|
161
|
-
|
|
308
|
+
const lines = renderShow({
|
|
162
309
|
title: result.opened ? "Opening the live URL for the selected app." : "Resolving the live URL for the selected app.",
|
|
163
310
|
descriptor,
|
|
164
311
|
fields: [
|
|
@@ -182,9 +329,11 @@ function renderAppOpen(context, descriptor, result) {
|
|
|
182
329
|
}
|
|
183
330
|
]
|
|
184
331
|
}, context.ui);
|
|
332
|
+
lines.push(...renderResolvedProjectContextBlock(context.ui, result.verboseContext));
|
|
333
|
+
return lines;
|
|
185
334
|
}
|
|
186
335
|
function serializeAppOpen(result) {
|
|
187
|
-
return result;
|
|
336
|
+
return stripVerboseContext(result);
|
|
188
337
|
}
|
|
189
338
|
function renderAppDomainAdd(context, descriptor, result) {
|
|
190
339
|
return renderShow({
|
|
@@ -286,7 +435,7 @@ function serializeAppDomainRetry(result) {
|
|
|
286
435
|
return result;
|
|
287
436
|
}
|
|
288
437
|
function renderAppPromote(context, descriptor, result) {
|
|
289
|
-
|
|
438
|
+
const lines = renderShow({
|
|
290
439
|
title: "Switching the live deployment for the selected app.",
|
|
291
440
|
descriptor,
|
|
292
441
|
fields: [
|
|
@@ -324,12 +473,14 @@ function renderAppPromote(context, descriptor, result) {
|
|
|
324
473
|
}
|
|
325
474
|
]
|
|
326
475
|
}, context.ui);
|
|
476
|
+
lines.push(...renderResolvedProjectContextBlock(context.ui, result.verboseContext));
|
|
477
|
+
return lines;
|
|
327
478
|
}
|
|
328
479
|
function serializeAppPromote(result) {
|
|
329
|
-
return result;
|
|
480
|
+
return stripVerboseContext(result);
|
|
330
481
|
}
|
|
331
482
|
function renderAppRollback(context, descriptor, result) {
|
|
332
|
-
|
|
483
|
+
const lines = renderShow({
|
|
333
484
|
title: "Restoring the selected app to an earlier deployment.",
|
|
334
485
|
descriptor,
|
|
335
486
|
fields: [
|
|
@@ -372,9 +523,11 @@ function renderAppRollback(context, descriptor, result) {
|
|
|
372
523
|
}] : []
|
|
373
524
|
]
|
|
374
525
|
}, context.ui);
|
|
526
|
+
lines.push(...renderResolvedProjectContextBlock(context.ui, result.verboseContext));
|
|
527
|
+
return lines;
|
|
375
528
|
}
|
|
376
529
|
function serializeAppRollback(result) {
|
|
377
|
-
return result;
|
|
530
|
+
return stripVerboseContext(result);
|
|
378
531
|
}
|
|
379
532
|
function renderAppRun(_context, _descriptor, _result) {
|
|
380
533
|
return [];
|
|
@@ -383,7 +536,7 @@ function serializeAppRun(result) {
|
|
|
383
536
|
return result;
|
|
384
537
|
}
|
|
385
538
|
function renderAppRemove(context, descriptor, result) {
|
|
386
|
-
|
|
539
|
+
const lines = renderShow({
|
|
387
540
|
title: "Removing the selected app.",
|
|
388
541
|
descriptor,
|
|
389
542
|
fields: [
|
|
@@ -402,9 +555,11 @@ function renderAppRemove(context, descriptor, result) {
|
|
|
402
555
|
}
|
|
403
556
|
]
|
|
404
557
|
}, context.ui);
|
|
558
|
+
lines.push(...renderResolvedProjectContextBlock(context.ui, result.verboseContext));
|
|
559
|
+
return lines;
|
|
405
560
|
}
|
|
406
561
|
function serializeAppRemove(result) {
|
|
407
|
-
return result;
|
|
562
|
+
return stripVerboseContext(result);
|
|
408
563
|
}
|
|
409
564
|
function toneForStatus(status) {
|
|
410
565
|
if (status === "running" || status === "ready" || status === "healthy") return "success";
|
|
@@ -488,4 +643,4 @@ function formatRecentDeployments(deployments) {
|
|
|
488
643
|
return deployments.map((deployment) => `${deployment.id}${deployment.live ? " (live)" : ""}`).join(", ");
|
|
489
644
|
}
|
|
490
645
|
//#endregion
|
|
491
|
-
export { renderAppBuild, renderAppDeploy, renderAppDomainAdd, renderAppDomainRemove, renderAppDomainRetry, renderAppDomainShow, renderAppListDeploys, renderAppOpen, renderAppPromote, renderAppRemove, renderAppRollback, renderAppRun, renderAppShow, renderAppShowDeploy, serializeAppBuild, serializeAppDeploy, serializeAppDomainAdd, serializeAppDomainRemove, serializeAppDomainRetry, serializeAppDomainShow, serializeAppListDeploys, serializeAppOpen, serializeAppPromote, serializeAppRemove, serializeAppRollback, serializeAppRun, serializeAppShow, serializeAppShowDeploy };
|
|
646
|
+
export { isAppDeployAllResult, renderAppBuild, renderAppDeploy, renderAppDeployAll, renderAppDomainAdd, renderAppDomainRemove, renderAppDomainRetry, renderAppDomainShow, renderAppListDeploys, renderAppOpen, renderAppPromote, renderAppRemove, renderAppRollback, renderAppRun, renderAppShow, renderAppShowDeploy, serializeAppBuild, serializeAppDeploy, serializeAppDeployAll, serializeAppDomainAdd, serializeAppDomainRemove, serializeAppDomainRetry, serializeAppDomainShow, serializeAppListDeploys, serializeAppOpen, serializeAppPromote, serializeAppRemove, serializeAppRollback, serializeAppRun, serializeAppShow, serializeAppShowDeploy };
|