@prisma/cli 3.0.0-beta.1 → 3.0.0-beta.10

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 (61) 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 +63 -22
  6. package/dist/cli.js +17 -2
  7. package/dist/cli2.js +7 -3
  8. package/dist/commands/app/index.js +22 -10
  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 +283 -129
  15. package/dist/controllers/app.js +247 -106
  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 +153 -82
  20. package/dist/lib/app/branch-database-deploy.js +373 -0
  21. package/dist/lib/app/branch-database.js +316 -0
  22. package/dist/lib/app/bun-project.js +12 -5
  23. package/dist/lib/app/deploy-output.js +10 -1
  24. package/dist/lib/app/env-config.js +1 -1
  25. package/dist/lib/app/env-file.js +82 -0
  26. package/dist/lib/app/env-vars.js +28 -2
  27. package/dist/lib/app/local-dev.js +34 -18
  28. package/dist/lib/app/preview-branch-database.js +102 -0
  29. package/dist/lib/app/preview-build-settings.js +385 -0
  30. package/dist/lib/app/preview-build.js +272 -81
  31. package/dist/lib/app/preview-provider.js +163 -54
  32. package/dist/lib/app/production-deploy-gate.js +161 -0
  33. package/dist/lib/auth/auth-ops.js +30 -21
  34. package/dist/lib/auth/guard.js +3 -2
  35. package/dist/lib/auth/login.js +109 -14
  36. package/dist/lib/database/provider.js +167 -0
  37. package/dist/lib/diagnostics.js +15 -0
  38. package/dist/lib/git/local-branch.js +41 -0
  39. package/dist/lib/git/local-status.js +57 -0
  40. package/dist/lib/project/interactive-setup.js +1 -1
  41. package/dist/lib/project/local-pin.js +182 -33
  42. package/dist/lib/project/resolution.js +203 -49
  43. package/dist/lib/project/setup.js +59 -15
  44. package/dist/presenters/app-env.js +149 -14
  45. package/dist/presenters/app.js +170 -20
  46. package/dist/presenters/branch.js +37 -102
  47. package/dist/presenters/database.js +274 -0
  48. package/dist/presenters/project.js +63 -39
  49. package/dist/presenters/verbose-context.js +64 -0
  50. package/dist/shell/command-meta.js +103 -13
  51. package/dist/shell/command-runner.js +34 -6
  52. package/dist/shell/diagnostics-output.js +63 -0
  53. package/dist/shell/errors.js +12 -1
  54. package/dist/shell/output.js +10 -1
  55. package/dist/shell/runtime.js +3 -3
  56. package/dist/shell/ui.js +23 -1
  57. package/dist/shell/update-check.js +247 -0
  58. package/dist/use-cases/branch.js +20 -68
  59. package/dist/use-cases/create-cli-gateways.js +2 -17
  60. package/dist/use-cases/project.js +2 -1
  61. package/package.json +12 -10
@@ -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({
@@ -30,23 +32,158 @@ function renderAppDeploy(context, descriptor, result) {
30
32
  return [
31
33
  `Live in ${formatDuration(result.durationMs)}`,
32
34
  ...result.deployment.url ? [context.ui.link(result.deployment.url)] : [],
35
+ ...renderBranchDatabaseDeploySummary(context, result),
33
36
  "",
34
37
  ...renderDeployOutputRows(context.ui, [{
35
38
  label: "Logs",
36
39
  value: "prisma-cli app logs"
37
- }])
40
+ }]),
41
+ ...renderDeployResolvedContextBlock(context, result),
42
+ ...renderDeploySettingsBlock(context, result)
38
43
  ];
39
44
  }
40
45
  function serializeAppDeploy(result) {
41
- const { localPin: _localPin, ...serialized } = result;
42
- return serialized;
46
+ const { deploySettings, localPin: _localPin, ...serialized } = result;
47
+ const { id: _branchId, ...branch } = serialized.branch;
48
+ return {
49
+ ...serialized,
50
+ branch,
51
+ deploySettings: {
52
+ config: deploySettings.config,
53
+ buildCommand: deploySettings.buildCommand,
54
+ outputDirectory: deploySettings.outputDirectory
55
+ }
56
+ };
57
+ }
58
+ function renderBranchDatabaseDeploySummary(context, result) {
59
+ if (!result.branchDatabase || result.branchDatabase.status !== "created") return [];
60
+ return ["", ...renderDeployOutputRows(context.ui, [
61
+ {
62
+ label: "Database",
63
+ value: result.branchDatabase.database?.name ?? "created"
64
+ },
65
+ {
66
+ label: "Env",
67
+ value: result.branchDatabase.envVars.join(", ")
68
+ },
69
+ ...result.branchDatabase.schema ? [{
70
+ label: "Schema",
71
+ value: formatBranchDatabaseSchemaCommand(result.branchDatabase.schema.command)
72
+ }] : []
73
+ ])];
74
+ }
75
+ function formatBranchDatabaseSchemaCommand(command) {
76
+ switch (command) {
77
+ case "migrate-deploy": return "prisma migrate deploy";
78
+ case "db-push": return "prisma db push";
79
+ case "prisma-next-db-init": return "prisma-next db init";
80
+ }
43
81
  }
44
82
  function formatDuration(durationMs) {
45
83
  if (durationMs < 1e3) return `${durationMs}ms`;
46
84
  return `${(durationMs / 1e3).toFixed(1)}s`;
47
85
  }
86
+ function renderDeployResolvedContextBlock(context, result) {
87
+ return renderResolvedProjectContextBlock(context.ui, {
88
+ workspace: result.workspace,
89
+ project: result.project,
90
+ resolution: result.resolution,
91
+ branch: {
92
+ id: result.branch.id,
93
+ name: result.branch.name,
94
+ kind: result.branch.kind
95
+ }
96
+ }, { extraRows: [
97
+ {
98
+ key: "app",
99
+ value: result.app.name
100
+ },
101
+ {
102
+ key: "app id",
103
+ value: result.app.id,
104
+ tone: "dim"
105
+ },
106
+ {
107
+ key: "deployment id",
108
+ value: result.deployment.id,
109
+ tone: "dim"
110
+ },
111
+ {
112
+ key: "deployment status",
113
+ value: result.deployment.status
114
+ },
115
+ ...result.localPin ? [{
116
+ key: "local pin",
117
+ value: result.localPin.path
118
+ }] : [],
119
+ {
120
+ key: "deploy duration",
121
+ value: formatDuration(result.durationMs)
122
+ }
123
+ ] });
124
+ }
125
+ function renderDeploySettingsBlock(context, result) {
126
+ return renderVerboseBlock(context.ui, [...deploySettingsRows(result.deploySettings), ...branchDatabaseRows(result.branchDatabase)], { title: "Deploy settings" });
127
+ }
128
+ function deploySettingsRows(settings) {
129
+ return [
130
+ {
131
+ key: "framework",
132
+ value: `${settings.framework.name} (${settings.framework.buildType})`
133
+ },
134
+ {
135
+ key: "framework source",
136
+ value: settings.framework.source,
137
+ tone: "dim"
138
+ },
139
+ {
140
+ key: "entrypoint",
141
+ value: settings.entrypoint ?? "derived from build output",
142
+ tone: settings.entrypoint ? "default" : "dim"
143
+ },
144
+ {
145
+ key: "http port",
146
+ value: String(settings.httpPort)
147
+ },
148
+ {
149
+ key: "region",
150
+ value: settings.region ?? "existing app region",
151
+ tone: settings.region ? "default" : "dim"
152
+ },
153
+ {
154
+ key: "env vars",
155
+ value: formatEnvVarNames(settings.envVars),
156
+ tone: settings.envVars.length > 0 ? "default" : "dim"
157
+ }
158
+ ];
159
+ }
160
+ function branchDatabaseRows(branchDatabase) {
161
+ if (!branchDatabase) return [{
162
+ key: "branch db",
163
+ value: "not configured",
164
+ tone: "dim"
165
+ }];
166
+ return [
167
+ {
168
+ key: "branch db",
169
+ value: branchDatabase.status === "created" ? `created${branchDatabase.database ? ` (${branchDatabase.database.name})` : ""}` : `skipped${branchDatabase.reason ? ` (${branchDatabase.reason})` : ""}`,
170
+ tone: branchDatabase.status === "created" ? "success" : "dim"
171
+ },
172
+ ...branchDatabase.envVars.length > 0 ? [{
173
+ key: "branch db env",
174
+ value: branchDatabase.envVars.join(", ")
175
+ }] : [],
176
+ ...branchDatabase.schema ? [{
177
+ key: "branch db schema",
178
+ value: `${formatBranchDatabaseSchemaCommand(branchDatabase.schema.command)} (${branchDatabase.schema.source}, ${branchDatabase.schema.path})`
179
+ }] : []
180
+ ];
181
+ }
182
+ function formatEnvVarNames(envVars) {
183
+ return envVars.length > 0 ? envVars.join(", ") : "none";
184
+ }
48
185
  function renderAppListDeploys(context, descriptor, result) {
49
- return renderList({
186
+ const lines = renderList({
50
187
  title: "Listing deployments for the selected app.",
51
188
  descriptor,
52
189
  parentContext: {
@@ -61,20 +198,23 @@ function renderAppListDeploys(context, descriptor, result) {
61
198
  })),
62
199
  emptyMessage: result.app ? "No deployments found." : "No apps found."
63
200
  }, context.ui);
201
+ lines.push(...renderResolvedProjectContextBlock(context.ui, result.verboseContext));
202
+ return lines;
64
203
  }
65
204
  function serializeAppListDeploys(result) {
66
- if (!result.app) return {
67
- projectId: result.projectId,
205
+ const { verboseContext: _verboseContext, ...serializable } = result;
206
+ if (!serializable.app) return {
207
+ projectId: serializable.projectId,
68
208
  app: null,
69
209
  items: [],
70
210
  count: 0
71
211
  };
72
212
  return {
73
- projectId: result.projectId,
74
- app: result.app,
213
+ projectId: serializable.projectId,
214
+ app: serializable.app,
75
215
  ...serializeList({
76
- context: { app: result.app.name },
77
- items: result.deployments.map((deployment) => ({
216
+ context: { app: serializable.app.name },
217
+ items: serializable.deployments.map((deployment) => ({
78
218
  noun: "deployment",
79
219
  label: deployment.id,
80
220
  id: deployment.id,
@@ -84,7 +224,7 @@ function serializeAppListDeploys(result) {
84
224
  };
85
225
  }
86
226
  function renderAppShow(context, descriptor, result) {
87
- return renderShow({
227
+ const lines = renderShow({
88
228
  title: "Showing the selected app state.",
89
229
  descriptor,
90
230
  fields: [
@@ -114,9 +254,11 @@ function renderAppShow(context, descriptor, result) {
114
254
  }
115
255
  ]
116
256
  }, context.ui);
257
+ lines.push(...renderResolvedProjectContextBlock(context.ui, result.verboseContext));
258
+ return lines;
117
259
  }
118
260
  function serializeAppShow(result) {
119
- return result;
261
+ return stripVerboseContext(result);
120
262
  }
121
263
  function renderAppShowDeploy(context, descriptor, result) {
122
264
  return renderShow({
@@ -158,7 +300,7 @@ function serializeAppShowDeploy(result) {
158
300
  return result;
159
301
  }
160
302
  function renderAppOpen(context, descriptor, result) {
161
- return renderShow({
303
+ const lines = renderShow({
162
304
  title: result.opened ? "Opening the live URL for the selected app." : "Resolving the live URL for the selected app.",
163
305
  descriptor,
164
306
  fields: [
@@ -182,9 +324,11 @@ function renderAppOpen(context, descriptor, result) {
182
324
  }
183
325
  ]
184
326
  }, context.ui);
327
+ lines.push(...renderResolvedProjectContextBlock(context.ui, result.verboseContext));
328
+ return lines;
185
329
  }
186
330
  function serializeAppOpen(result) {
187
- return result;
331
+ return stripVerboseContext(result);
188
332
  }
189
333
  function renderAppDomainAdd(context, descriptor, result) {
190
334
  return renderShow({
@@ -286,7 +430,7 @@ function serializeAppDomainRetry(result) {
286
430
  return result;
287
431
  }
288
432
  function renderAppPromote(context, descriptor, result) {
289
- return renderShow({
433
+ const lines = renderShow({
290
434
  title: "Switching the live deployment for the selected app.",
291
435
  descriptor,
292
436
  fields: [
@@ -324,12 +468,14 @@ function renderAppPromote(context, descriptor, result) {
324
468
  }
325
469
  ]
326
470
  }, context.ui);
471
+ lines.push(...renderResolvedProjectContextBlock(context.ui, result.verboseContext));
472
+ return lines;
327
473
  }
328
474
  function serializeAppPromote(result) {
329
- return result;
475
+ return stripVerboseContext(result);
330
476
  }
331
477
  function renderAppRollback(context, descriptor, result) {
332
- return renderShow({
478
+ const lines = renderShow({
333
479
  title: "Restoring the selected app to an earlier deployment.",
334
480
  descriptor,
335
481
  fields: [
@@ -372,9 +518,11 @@ function renderAppRollback(context, descriptor, result) {
372
518
  }] : []
373
519
  ]
374
520
  }, context.ui);
521
+ lines.push(...renderResolvedProjectContextBlock(context.ui, result.verboseContext));
522
+ return lines;
375
523
  }
376
524
  function serializeAppRollback(result) {
377
- return result;
525
+ return stripVerboseContext(result);
378
526
  }
379
527
  function renderAppRun(_context, _descriptor, _result) {
380
528
  return [];
@@ -383,7 +531,7 @@ function serializeAppRun(result) {
383
531
  return result;
384
532
  }
385
533
  function renderAppRemove(context, descriptor, result) {
386
- return renderShow({
534
+ const lines = renderShow({
387
535
  title: "Removing the selected app.",
388
536
  descriptor,
389
537
  fields: [
@@ -402,9 +550,11 @@ function renderAppRemove(context, descriptor, result) {
402
550
  }
403
551
  ]
404
552
  }, context.ui);
553
+ lines.push(...renderResolvedProjectContextBlock(context.ui, result.verboseContext));
554
+ return lines;
405
555
  }
406
556
  function serializeAppRemove(result) {
407
- return result;
557
+ return stripVerboseContext(result);
408
558
  }
409
559
  function toneForStatus(status) {
410
560
  if (status === "running" || status === "ready" || status === "healthy") return "success";
@@ -1,111 +1,46 @@
1
- import { renderList, renderMutate, renderShow, serializeList } from "../output/patterns.js";
1
+ import { formatColumns } from "../shell/ui.js";
2
+ import { formatDescriptorLabel } from "../shell/command-meta.js";
3
+ import { renderResolvedProjectContextBlock } from "./verbose-context.js";
2
4
  //#region src/presenters/branch.ts
3
5
  function renderBranchList(context, descriptor, result) {
4
- return renderList({
5
- title: "Listing branches for the resolved project.",
6
- descriptor,
7
- parentContext: {
8
- key: "project",
9
- value: result.projectName ?? "not resolved"
10
- },
11
- items: result.branches.map((branch) => ({
12
- noun: "branch",
13
- label: branch.name,
14
- id: branch.id,
15
- status: branch.active ? "active" : null
16
- })),
17
- emptyMessage: "No branches found."
18
- }, context.ui);
6
+ const ui = context.ui;
7
+ const lines = [`${ui.strong(formatDescriptorLabel(descriptor))} ${ui.dim("→")} ${ui.dim("Listing branches for the resolved project.")}`, ""];
8
+ const rail = ui.dim("│");
9
+ lines.push(`${rail} ${ui.accent("project:")} ${result.projectName}`);
10
+ lines.push(rail);
11
+ if (result.branches.length === 0) {
12
+ lines.push(`${rail} ${ui.dim("No branches found.")}`);
13
+ lines.push(...renderBranchResolvedContextBlock(context, result));
14
+ return lines;
15
+ }
16
+ const widths = [
17
+ Math.max(4, ...result.branches.map((branch) => branch.name.length)),
18
+ Math.max(4, ...result.branches.map((branch) => branch.role.length)),
19
+ Math.max(7, ...result.branches.map((branch) => branch.envMap.length))
20
+ ];
21
+ lines.push(`${rail} ${ui.accent(formatColumns([
22
+ "Name",
23
+ "Role",
24
+ "Env map"
25
+ ], widths))}`);
26
+ for (const branch of result.branches) lines.push(`${rail} ${formatColumns([
27
+ branch.name,
28
+ branch.role,
29
+ branch.envMap
30
+ ], widths)}`);
31
+ lines.push(...renderBranchResolvedContextBlock(context, result));
32
+ return lines;
19
33
  }
20
34
  function serializeBranchList(result) {
21
- return serializeList({
22
- context: { project: result.projectName ?? "not resolved" },
23
- items: result.branches.map((branch) => ({
24
- noun: "branch",
25
- label: branch.name,
26
- id: branch.id,
27
- status: branch.active ? "active" : null
28
- }))
29
- });
30
- }
31
- function serializeBranchShow(result) {
35
+ const { verboseContext: _verboseContext, ...serializable } = result;
32
36
  return {
33
- projectId: result.projectId,
34
- projectName: result.projectName,
35
- branch: {
36
- name: result.branch.name,
37
- kind: result.branch.kind,
38
- active: result.branch.active,
39
- remoteState: result.branch.remoteState,
40
- liveDeployment: result.branch.liveDeployment
41
- }
37
+ projectId: serializable.projectId,
38
+ projectName: serializable.projectName,
39
+ branches: serializable.branches
42
40
  };
43
41
  }
44
- function renderBranchShow(context, descriptor, result) {
45
- const fields = [
46
- {
47
- key: "project",
48
- value: result.projectName ?? "not resolved",
49
- tone: result.projectName ? "default" : "dim"
50
- },
51
- {
52
- key: "branch",
53
- value: result.branch.name,
54
- tone: result.branch.active ? "success" : "default"
55
- },
56
- {
57
- key: "kind",
58
- value: result.branch.kind
59
- }
60
- ];
61
- if (result.branch.liveDeployment) {
62
- fields.push({
63
- key: "status",
64
- value: result.branch.liveDeployment.status,
65
- tone: toneForDeploymentStatus(result.branch.liveDeployment.status)
66
- });
67
- if (result.branch.liveDeployment.url) fields.push({
68
- key: "url",
69
- value: result.branch.liveDeployment.url,
70
- tone: "link"
71
- });
72
- } else if (!result.branch.remoteState) fields.push({
73
- key: "remote state",
74
- value: "not created yet",
75
- tone: "dim"
76
- });
77
- return renderShow({
78
- title: "Showing the current active branch context.",
79
- descriptor,
80
- fields
81
- }, context.ui);
82
- }
83
- function toneForDeploymentStatus(status) {
84
- if (status === "ready" || status === "active" || status === "healthy") return "success";
85
- if (status === "pending" || status === "building" || status === "starting") return "warning";
86
- if (status === "failed" || status === "error") return "error";
87
- return "default";
88
- }
89
- function renderBranchUse(context, descriptor, result) {
90
- return renderMutate({
91
- title: "Changing the local default branch context.",
92
- descriptor,
93
- context: [{
94
- key: "project",
95
- value: result.projectName ?? "not resolved",
96
- tone: result.projectName ? "default" : "dim"
97
- }, {
98
- key: "branch",
99
- value: result.branch.name
100
- }],
101
- operationDescription: "Applying active branch change",
102
- operationCount: 1,
103
- details: ["Active branch updated in local CLI state for this repo."],
104
- alerts: result.branch.kind === "production" ? [{
105
- tone: "warning",
106
- text: "Production is protected and durable. Use with care"
107
- }] : void 0
108
- }, context.ui);
42
+ function renderBranchResolvedContextBlock(context, result) {
43
+ return renderResolvedProjectContextBlock(context.ui, result.verboseContext);
109
44
  }
110
45
  //#endregion
111
- export { renderBranchList, renderBranchShow, renderBranchUse, serializeBranchList, serializeBranchShow };
46
+ export { renderBranchList, serializeBranchList };