@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.
Files changed (66) hide show
  1. package/README.md +5 -3
  2. package/dist/adapters/git.js +8 -3
  3. package/dist/adapters/local-state.js +12 -4
  4. package/dist/adapters/mock-api.js +81 -2
  5. package/dist/adapters/token-storage.js +64 -23
  6. package/dist/cli.js +18 -3
  7. package/dist/cli2.js +9 -5
  8. package/dist/commands/app/index.js +84 -59
  9. package/dist/commands/branch/index.js +2 -27
  10. package/dist/commands/database/index.js +159 -0
  11. package/dist/commands/env.js +8 -4
  12. package/dist/controllers/app-env-api.js +54 -0
  13. package/dist/controllers/app-env-file.js +181 -0
  14. package/dist/controllers/app-env.js +286 -131
  15. package/dist/controllers/app.js +699 -244
  16. package/dist/controllers/auth.js +8 -8
  17. package/dist/controllers/branch.js +78 -48
  18. package/dist/controllers/database.js +318 -0
  19. package/dist/controllers/project.js +156 -85
  20. package/dist/lib/app/branch-database-deploy.js +325 -0
  21. package/dist/lib/app/branch-database.js +215 -0
  22. package/dist/lib/app/bun-project.js +12 -5
  23. package/dist/lib/app/compute-config.js +147 -0
  24. package/dist/lib/app/deploy-output.js +10 -1
  25. package/dist/lib/app/deploy-plan.js +58 -0
  26. package/dist/lib/app/env-config.js +1 -1
  27. package/dist/lib/app/env-file.js +82 -0
  28. package/dist/lib/app/env-vars.js +28 -2
  29. package/dist/lib/app/local-dev.js +8 -49
  30. package/dist/lib/app/preview-branch-database.js +102 -0
  31. package/dist/lib/app/preview-build-settings.js +376 -0
  32. package/dist/lib/app/preview-build.js +314 -97
  33. package/dist/lib/app/preview-provider.js +178 -65
  34. package/dist/lib/app/production-deploy-gate.js +161 -0
  35. package/dist/lib/auth/auth-ops.js +30 -21
  36. package/dist/lib/auth/guard.js +3 -2
  37. package/dist/lib/auth/login.js +116 -14
  38. package/dist/lib/database/provider.js +167 -0
  39. package/dist/lib/diagnostics.js +15 -0
  40. package/dist/lib/fs/home-path.js +24 -0
  41. package/dist/lib/git/local-branch.js +53 -0
  42. package/dist/lib/git/local-status.js +57 -0
  43. package/dist/lib/project/interactive-setup.js +1 -1
  44. package/dist/lib/project/local-pin.js +182 -33
  45. package/dist/lib/project/resolution.js +204 -50
  46. package/dist/lib/project/setup.js +66 -19
  47. package/dist/output/patterns.js +1 -1
  48. package/dist/presenters/app-env.js +149 -14
  49. package/dist/presenters/app.js +178 -23
  50. package/dist/presenters/branch.js +37 -102
  51. package/dist/presenters/database.js +274 -0
  52. package/dist/presenters/project.js +57 -39
  53. package/dist/presenters/verbose-context.js +64 -0
  54. package/dist/shell/command-meta.js +103 -13
  55. package/dist/shell/command-runner.js +57 -19
  56. package/dist/shell/diagnostics-output.js +57 -0
  57. package/dist/shell/errors.js +12 -1
  58. package/dist/shell/help.js +30 -20
  59. package/dist/shell/output.js +10 -1
  60. package/dist/shell/runtime.js +11 -7
  61. package/dist/shell/ui.js +42 -3
  62. package/dist/shell/update-check.js +247 -0
  63. package/dist/use-cases/branch.js +20 -68
  64. package/dist/use-cases/create-cli-gateways.js +2 -17
  65. package/dist/use-cases/project.js +2 -1
  66. package/package.json +26 -10
@@ -1,7 +1,10 @@
1
1
  import { CliError, usageError } from "../../shell/errors.js";
2
- import "../../shell/command-arguments.js";
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
- await writeLocalResolutionPin(context.runtime.cwd, {
21
- workspaceId: workspace.id,
22
- projectId: project.id
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
- await ensureLocalResolutionPinGitignore(context.runtime.cwd);
25
- return {
26
- workspace,
27
- project,
28
- directory: formatSetupDirectory(context.runtime.cwd),
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
- action
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(cwd) {
69
- const basename = cwd.split(/[\\/]/).filter(Boolean).pop();
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 };
@@ -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
- return renderShow({
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
- return renderShow({
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
- return renderList({
203
+ const lines = renderList({
75
204
  title: "Listing environment variables for the selected scope.",
76
205
  descriptor,
77
206
  parentContext: {
78
- key: "scope",
79
- value: scopeLabel(result.scope)
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: result.projectId,
93
- scope: result.scope,
224
+ projectId: serializable.projectId,
225
+ scope: serializable.scope,
226
+ target: serializable.target,
94
227
  ...serializeList({
95
- context: { scope: scopeLabel(result.scope) },
96
- items: result.variables.map((variable) => ({
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: result.variables
236
+ variables: serializable.variables
104
237
  };
105
238
  }
106
239
  function renderEnvRm(context, descriptor, result) {
107
- return renderShow({
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 };
@@ -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: "prisma-cli app logs"
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
- return serialized;
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
- return renderList({
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
- if (!result.app) return {
67
- projectId: result.projectId,
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: result.projectId,
74
- app: result.app,
218
+ projectId: serializable.projectId,
219
+ app: serializable.app,
75
220
  ...serializeList({
76
- context: { app: result.app.name },
77
- items: result.deployments.map((deployment) => ({
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
- return renderShow({
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
- return renderShow({
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
- return renderShow({
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
- return renderShow({
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
- return renderShow({
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 };