@prisma/cli 3.0.0-alpha.9 → 3.0.0-beta.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.
@@ -1,4 +1,5 @@
1
1
  import { renderDeployOutputRows } from "../lib/app/deploy-output.js";
2
+ import { formatDomainFailureFix } from "../lib/app/domain-guidance.js";
2
3
  import { renderList, renderShow, serializeList } from "../output/patterns.js";
3
4
  //#region src/presenters/app.ts
4
5
  function renderAppBuild(context, descriptor, result) {
@@ -44,74 +45,6 @@ function formatDuration(durationMs) {
44
45
  if (durationMs < 1e3) return `${durationMs}ms`;
45
46
  return `${(durationMs / 1e3).toFixed(1)}s`;
46
47
  }
47
- function renderAppUpdateEnv(context, descriptor, result) {
48
- return renderShow({
49
- title: "Updating environment variables for the selected app.",
50
- descriptor,
51
- fields: [
52
- {
53
- key: "project",
54
- value: result.projectId
55
- },
56
- {
57
- key: "app",
58
- value: result.app.name
59
- },
60
- {
61
- key: "deployment",
62
- value: result.deployment.id
63
- },
64
- {
65
- key: "status",
66
- value: result.deployment.status,
67
- tone: toneForStatus(result.deployment.status)
68
- },
69
- ...result.deployment.url ? [{
70
- key: "url",
71
- value: result.deployment.url,
72
- tone: "link"
73
- }] : [],
74
- {
75
- key: "variables",
76
- value: formatVariableNames(result.variables),
77
- tone: result.variables.length > 0 ? "default" : "dim"
78
- }
79
- ]
80
- }, context.ui);
81
- }
82
- function serializeAppUpdateEnv(result) {
83
- return result;
84
- }
85
- function renderAppListEnv(context, descriptor, result) {
86
- return renderShow({
87
- title: "Listing environment variables for the selected app.",
88
- descriptor,
89
- fields: [
90
- {
91
- key: "project",
92
- value: result.projectId
93
- },
94
- {
95
- key: "app",
96
- value: result.app?.name ?? "not selected",
97
- tone: result.app ? "default" : "dim"
98
- },
99
- {
100
- key: "deployment",
101
- value: result.deployment?.id ?? "none",
102
- tone: result.deployment ? toneForStatus(result.deployment.status) : "dim"
103
- },
104
- {
105
- key: "variables",
106
- value: formatVariableNames(result.variables),
107
- tone: result.variables.length > 0 ? "default" : "dim"
108
- }
109
- ]
110
- }, context.ui);
111
- }
112
- function serializeAppListEnv(result) {
113
- return result;
114
- }
115
48
  function renderAppListDeploys(context, descriptor, result) {
116
49
  return renderList({
117
50
  title: "Listing deployments for the selected app.",
@@ -253,6 +186,105 @@ function renderAppOpen(context, descriptor, result) {
253
186
  function serializeAppOpen(result) {
254
187
  return result;
255
188
  }
189
+ function renderAppDomainAdd(context, descriptor, result) {
190
+ return renderShow({
191
+ title: result.existing ? "Showing the existing custom domain for the selected app." : "Adding a custom domain to the selected app.",
192
+ descriptor,
193
+ fields: [
194
+ ...domainTargetFields(result),
195
+ {
196
+ key: "hostname",
197
+ value: result.domain.hostname
198
+ },
199
+ {
200
+ key: "status",
201
+ value: result.domain.status,
202
+ tone: toneForDomainStatus(result.domain.status)
203
+ },
204
+ ...domainDnsFields(result.domain)
205
+ ]
206
+ }, context.ui);
207
+ }
208
+ function serializeAppDomainAdd(result) {
209
+ return result;
210
+ }
211
+ function renderAppDomainShow(context, descriptor, result) {
212
+ return renderShow({
213
+ title: "Showing custom domain status.",
214
+ descriptor,
215
+ fields: [
216
+ ...domainTargetFields(result),
217
+ {
218
+ key: "hostname",
219
+ value: result.domain.hostname
220
+ },
221
+ {
222
+ key: "status",
223
+ value: result.domain.status,
224
+ tone: toneForDomainStatus(result.domain.status)
225
+ },
226
+ ...domainFailureFields(result.domain),
227
+ {
228
+ key: "cert expires",
229
+ value: formatOptionalUtcDate(result.domain.certExpiresAt),
230
+ tone: result.domain.certExpiresAt ? "default" : "dim"
231
+ },
232
+ {
233
+ key: "created",
234
+ value: formatUtcDate(result.domain.createdAt),
235
+ tone: "dim"
236
+ },
237
+ ...domainDnsFields(result.domain)
238
+ ]
239
+ }, context.ui);
240
+ }
241
+ function serializeAppDomainShow(result) {
242
+ return result;
243
+ }
244
+ function renderAppDomainRemove(context, descriptor, result) {
245
+ return renderShow({
246
+ title: "Removing a custom domain from the selected app.",
247
+ descriptor,
248
+ fields: [
249
+ ...domainTargetFields(result),
250
+ {
251
+ key: "hostname",
252
+ value: result.hostname
253
+ },
254
+ {
255
+ key: "removed",
256
+ value: result.removed ? "yes" : "no",
257
+ tone: result.removed ? "success" : "dim"
258
+ }
259
+ ]
260
+ }, context.ui);
261
+ }
262
+ function serializeAppDomainRemove(result) {
263
+ return result;
264
+ }
265
+ function renderAppDomainRetry(context, descriptor, result) {
266
+ return renderShow({
267
+ title: "Retrying custom domain verification.",
268
+ descriptor,
269
+ fields: [
270
+ ...domainTargetFields(result),
271
+ {
272
+ key: "hostname",
273
+ value: result.domain.hostname
274
+ },
275
+ {
276
+ key: "status",
277
+ value: result.domain.status,
278
+ tone: toneForDomainStatus(result.domain.status)
279
+ },
280
+ ...domainFailureFields(result.domain),
281
+ ...domainDnsFields(result.domain)
282
+ ]
283
+ }, context.ui);
284
+ }
285
+ function serializeAppDomainRetry(result) {
286
+ return result;
287
+ }
256
288
  function renderAppPromote(context, descriptor, result) {
257
289
  return renderShow({
258
290
  title: "Switching the live deployment for the selected app.",
@@ -380,13 +412,80 @@ function toneForStatus(status) {
380
412
  if (status === "failed" || status === "error") return "error";
381
413
  return "default";
382
414
  }
415
+ function toneForDomainStatus(status) {
416
+ if (status === "active") return "success";
417
+ if (status === "failed") return "error";
418
+ if (status === "pending_dns" || status === "verifying" || status === "provisioning_tls" || status === "verified_routing_blocked") return "warning";
419
+ return "default";
420
+ }
421
+ function domainTargetFields(result) {
422
+ return [
423
+ {
424
+ key: "workspace",
425
+ value: result.workspace.name
426
+ },
427
+ {
428
+ key: "project",
429
+ value: result.project.name
430
+ },
431
+ {
432
+ key: "branch",
433
+ value: result.branch.name
434
+ },
435
+ {
436
+ key: "app",
437
+ value: result.app.name
438
+ }
439
+ ];
440
+ }
441
+ function domainDnsFields(domain) {
442
+ const records = domain.dnsRecords;
443
+ if (records.length === 0) return [{
444
+ key: "dns record",
445
+ value: "not provided by platform",
446
+ tone: "dim"
447
+ }];
448
+ return [{
449
+ key: "dns record",
450
+ value: records.map((record) => {
451
+ const ttl = record.ttl ? ` ttl ${record.ttl}` : "";
452
+ return `${record.type} ${record.name} -> ${record.value}${ttl}`;
453
+ }).join(", ")
454
+ }];
455
+ }
456
+ function formatDomainFailure(domain) {
457
+ if (!domain.failureReason) return domain.failureCategory ?? "none";
458
+ return domain.failureCategory ? `${domain.failureCategory} - ${domain.failureReason}` : domain.failureReason;
459
+ }
460
+ function domainFailureFields(domain) {
461
+ const tone = hasDomainFailure(domain) ? "error" : "dim";
462
+ return [{
463
+ key: "failure",
464
+ value: formatDomainFailure(domain),
465
+ tone
466
+ }, ...domainFixFields(domain)];
467
+ }
468
+ function hasDomainFailure(domain) {
469
+ return Boolean(domain.failureCategory || domain.failureReason);
470
+ }
471
+ function domainFixFields(domain) {
472
+ const fix = formatDomainFailureFix(domain);
473
+ return fix ? [{
474
+ key: "fix",
475
+ value: fix
476
+ }] : [];
477
+ }
478
+ function formatOptionalUtcDate(value) {
479
+ return value ? formatUtcDate(value) : "-";
480
+ }
481
+ function formatUtcDate(value) {
482
+ const date = new Date(value);
483
+ if (Number.isNaN(date.getTime())) return value;
484
+ return `${date.getUTCFullYear()}-${String(date.getUTCMonth() + 1).padStart(2, "0")}-${String(date.getUTCDate()).padStart(2, "0")} ${String(date.getUTCHours()).padStart(2, "0")}:${String(date.getUTCMinutes()).padStart(2, "0")} UTC`;
485
+ }
383
486
  function formatRecentDeployments(deployments) {
384
487
  if (deployments.length === 0) return "none";
385
488
  return deployments.map((deployment) => `${deployment.id}${deployment.live ? " (live)" : ""}`).join(", ");
386
489
  }
387
- function formatVariableNames(variables) {
388
- if (variables.length === 0) return "none";
389
- return variables.join(", ");
390
- }
391
490
  //#endregion
392
- export { renderAppBuild, renderAppDeploy, renderAppListDeploys, renderAppListEnv, renderAppOpen, renderAppPromote, renderAppRemove, renderAppRollback, renderAppRun, renderAppShow, renderAppShowDeploy, renderAppUpdateEnv, serializeAppBuild, serializeAppDeploy, serializeAppListDeploys, serializeAppListEnv, serializeAppOpen, serializeAppPromote, serializeAppRemove, serializeAppRollback, serializeAppRun, serializeAppShow, serializeAppShowDeploy, serializeAppUpdateEnv };
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 };
@@ -7,9 +7,10 @@ function renderAuthSuccess(context, descriptor, command, result) {
7
7
  key: "provider",
8
8
  value: providerLabel(result.provider)
9
9
  });
10
- if (result.user) rows.push({
10
+ const userLabel = authUserLabel(result);
11
+ if (userLabel) rows.push({
11
12
  key: "user",
12
- value: result.user.email
13
+ value: userLabel
13
14
  });
14
15
  if (result.workspace?.name) rows.push({
15
16
  key: "workspace",
@@ -45,10 +46,7 @@ function renderAuthSuccess(context, descriptor, command, result) {
45
46
  value: "signed in",
46
47
  tone: "success"
47
48
  },
48
- ...result.user ? [{
49
- key: "user",
50
- value: result.user.email
51
- }] : [],
49
+ ...authUserRows(result),
52
50
  ...result.provider ? [{
53
51
  key: "provider",
54
52
  value: providerLabel(result.provider)
@@ -69,5 +67,20 @@ function providerLabel(provider) {
69
67
  if (provider === "google") return "Google";
70
68
  return "";
71
69
  }
70
+ function authUserLabel(result) {
71
+ return result.user?.email ?? credentialUserLabel(result);
72
+ }
73
+ function authUserRows(result) {
74
+ const userLabel = authUserLabel(result);
75
+ return userLabel ? [{
76
+ key: "user",
77
+ value: userLabel
78
+ }] : [];
79
+ }
80
+ function credentialUserLabel(result) {
81
+ if (result.credential?.type === "service_token") return result.credential.name ? `<service token: ${result.credential.name}>` : "<service token>";
82
+ if (result.credential?.type === "management_token") return result.credential.name ? `<management token: ${result.credential.name}>` : "<management token>";
83
+ return null;
84
+ }
72
85
  //#endregion
73
86
  export { renderAuthSuccess };
@@ -1,7 +1,9 @@
1
+ import { renderNextSteps, renderSummaryLine } from "../shell/ui.js";
2
+ import { formatCommandArgument } from "../shell/command-arguments.js";
1
3
  import { renderList, renderMutate, renderShow, serializeList } from "../output/patterns.js";
2
4
  //#region src/presenters/project.ts
3
5
  function renderProjectList(context, descriptor, result) {
4
- return renderList({
6
+ const lines = renderList({
5
7
  title: "Listing projects for the authenticated workspace.",
6
8
  descriptor,
7
9
  parentContext: {
@@ -16,21 +18,42 @@ function renderProjectList(context, descriptor, result) {
16
18
  })),
17
19
  emptyMessage: "No projects found."
18
20
  }, context.ui);
21
+ if (result.localBinding?.status === "not-linked" || result.localBinding?.status === "invalid") lines.push(...renderNextSteps(["Link an existing Project you choose: prisma-cli project link <id-or-name>", "Create a new Project: prisma-cli project create <name>"]));
22
+ return lines;
19
23
  }
20
24
  function serializeProjectList(result) {
21
- return serializeList({
22
- context: { workspace: result.workspace.name },
23
- items: result.projects.map((project) => ({
24
- noun: "project",
25
- label: project.name,
26
- id: project.id,
27
- status: null
28
- }))
29
- });
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
+ };
30
37
  }
31
38
  function renderProjectShow(context, descriptor, result) {
39
+ if (result.project === null) {
40
+ const lines = renderShow({
41
+ title: "This directory is not linked to a Prisma Project.",
42
+ descriptor,
43
+ fields: [{
44
+ key: "workspace",
45
+ value: result.workspace.name
46
+ }, {
47
+ key: "project",
48
+ value: "Not linked",
49
+ tone: "warning"
50
+ }]
51
+ }, context.ui);
52
+ lines.push(...renderNextSteps(["Link an existing Project you choose: prisma-cli project link <id-or-name>", `Create a new Project: prisma-cli project create ${formatCommandArgument(result.suggestedProjectName)}`]));
53
+ return lines;
54
+ }
32
55
  return renderShow({
33
- title: "Showing the project Prisma resolves for this directory.",
56
+ title: "Showing this directory's Project binding.",
34
57
  descriptor,
35
58
  fields: [
36
59
  {
@@ -51,6 +74,14 @@ function renderProjectShow(context, descriptor, result) {
51
74
  function serializeProjectShow(result) {
52
75
  return result;
53
76
  }
77
+ function renderProjectSetup(context, _descriptor, result) {
78
+ const lines = result.action === "created" ? [renderSummaryLine(context.ui, "success", `Created Project "${result.project.name}"`)] : [];
79
+ lines.push(renderSummaryLine(context.ui, "success", `Linked "${result.directory}" to Project "${result.project.name}"`), `Saved ${result.localPin.path}`);
80
+ return lines;
81
+ }
82
+ function serializeProjectSetup(result) {
83
+ return result;
84
+ }
54
85
  function renderGitConnect(context, descriptor, result) {
55
86
  const connection = result.repositoryConnection;
56
87
  return renderMutate({
@@ -108,11 +139,9 @@ function formatProjectSource(source) {
108
139
  case "env": return "environment";
109
140
  case "local-pin": return "local pin";
110
141
  case "platform-mapping": return "platform mapping";
111
- case "remembered-local": return "remembered local context";
112
- case "package-name": return "package name";
113
- case "directory-name": return "directory name";
114
142
  case "created": return "created";
115
143
  case "prompt": return "prompt";
144
+ case "unbound": return "unbound";
116
145
  }
117
146
  }
118
147
  function formatGitConnectionDetail(status) {
@@ -124,4 +153,4 @@ function formatGitConnectionDetail(status) {
124
153
  }
125
154
  }
126
155
  //#endregion
127
- export { renderGitConnect, renderGitDisconnect, renderProjectList, renderProjectShow, serializeProjectList, serializeProjectShow };
156
+ export { renderGitConnect, renderGitDisconnect, renderProjectList, renderProjectSetup, renderProjectShow, serializeProjectList, serializeProjectSetup, serializeProjectShow };
@@ -0,0 +1,6 @@
1
+ //#region src/shell/command-arguments.ts
2
+ function formatCommandArgument(value) {
3
+ return /^[A-Za-z0-9._/-]+$/.test(value) && !value.startsWith("-") ? value : `'${value.replace(/'/g, "'\\''")}'`;
4
+ }
5
+ //#endregion
6
+ export { formatCommandArgument };
@@ -54,7 +54,11 @@ const DESCRIPTORS = [
54
54
  id: "project",
55
55
  path: ["prisma", "project"],
56
56
  description: "Manage and inspect your Prisma projects",
57
- examples: ["prisma-cli project list", "prisma-cli project show"]
57
+ examples: [
58
+ "prisma-cli project list",
59
+ "prisma-cli project link proj_123",
60
+ "prisma-cli project create my-app"
61
+ ]
58
62
  },
59
63
  {
60
64
  id: "app",
@@ -91,9 +95,33 @@ const DESCRIPTORS = [
91
95
  "project",
92
96
  "show"
93
97
  ],
94
- description: "Show which project is active for this directory",
98
+ description: "Show this directory's Project binding",
95
99
  examples: ["prisma-cli project show", "prisma-cli project show --project proj_123 --json"]
96
100
  },
101
+ {
102
+ id: "project.create",
103
+ path: [
104
+ "prisma",
105
+ "project",
106
+ "create"
107
+ ],
108
+ description: "Create a Project and link this directory",
109
+ examples: ["prisma-cli project create my-app", "prisma-cli project create my-app --json"]
110
+ },
111
+ {
112
+ id: "project.link",
113
+ path: [
114
+ "prisma",
115
+ "project",
116
+ "link"
117
+ ],
118
+ description: "Link this directory to a Project",
119
+ examples: [
120
+ "prisma-cli project link",
121
+ "prisma-cli project link proj_123",
122
+ "prisma-cli project link \"Acme Dashboard\" --json"
123
+ ]
124
+ },
97
125
  {
98
126
  id: "git.connect",
99
127
  path: [
@@ -180,52 +208,106 @@ const DESCRIPTORS = [
180
208
  "deploy"
181
209
  ],
182
210
  description: "Creates a new deployment for the app",
211
+ longDescription: "Agent skills for guided Next.js deploys are available from the Prisma CLI skill cluster.",
183
212
  examples: [
184
213
  "prisma-cli app deploy",
214
+ "prisma-cli app deploy --project proj_123",
215
+ "prisma-cli app deploy --create-project my-app --yes",
185
216
  "prisma-cli app deploy --app my-app --env DATABASE_URL=postgresql://example",
186
217
  "prisma-cli app deploy --app my-app --framework nextjs --http-port 3000",
187
- "prisma-cli app deploy --branch feat-login --framework hono"
218
+ "prisma-cli app deploy --branch feat-login --framework hono",
219
+ "pnpm dlx skills@latest add prisma/prisma-cli/skills#cli-v<cli-version> --all",
220
+ "prisma-cli app deploy --framework bun --entry src/server.ts"
188
221
  ]
189
222
  },
190
223
  {
191
- id: "app.update-env",
224
+ id: "app.show",
225
+ path: [
226
+ "prisma",
227
+ "app",
228
+ "show"
229
+ ],
230
+ description: "Show the app and its current deployment",
231
+ examples: ["prisma-cli app show", "prisma-cli app show --app hello-world"]
232
+ },
233
+ {
234
+ id: "app.open",
192
235
  path: [
193
236
  "prisma",
194
237
  "app",
195
- "update-env"
238
+ "open"
196
239
  ],
197
- description: "Create a new deployment with updated environment variables.",
198
- examples: ["prisma-cli app update-env --env DATABASE_URL=postgresql://example", "prisma-cli app update-env --app hello-world --env DATABASE_URL=postgresql://another"]
240
+ description: "Open the app's live URL",
241
+ examples: ["prisma-cli app open", "prisma-cli app open --app hello-world"]
199
242
  },
200
243
  {
201
- id: "app.list-env",
244
+ id: "app.domain",
202
245
  path: [
203
246
  "prisma",
204
247
  "app",
205
- "list-env"
248
+ "domain"
206
249
  ],
207
- description: "List environment variable names for the selected app.",
208
- examples: ["prisma-cli app list-env", "prisma-cli app list-env --app hello-world"]
250
+ description: "Manage custom domains for an app",
251
+ examples: [
252
+ "prisma-cli app domain add shop.acme.com",
253
+ "prisma-cli app domain wait shop.acme.com --timeout 15m",
254
+ "prisma-cli app domain retry shop.acme.com"
255
+ ]
209
256
  },
210
257
  {
211
- id: "app.show",
258
+ id: "app.domain.add",
212
259
  path: [
213
260
  "prisma",
214
261
  "app",
262
+ "domain",
263
+ "add"
264
+ ],
265
+ description: "Register a custom domain on the app's production branch",
266
+ examples: ["prisma-cli app domain add shop.acme.com"]
267
+ },
268
+ {
269
+ id: "app.domain.show",
270
+ path: [
271
+ "prisma",
272
+ "app",
273
+ "domain",
215
274
  "show"
216
275
  ],
217
- description: "Show the app and its current deployment",
218
- examples: ["prisma-cli app show", "prisma-cli app show --app hello-world"]
276
+ description: "Show custom domain status and certificate details",
277
+ examples: ["prisma-cli app domain show shop.acme.com"]
219
278
  },
220
279
  {
221
- id: "app.open",
280
+ id: "app.domain.remove",
222
281
  path: [
223
282
  "prisma",
224
283
  "app",
225
- "open"
284
+ "domain",
285
+ "remove"
226
286
  ],
227
- description: "Open the app's live URL",
228
- examples: ["prisma-cli app open", "prisma-cli app open --app hello-world"]
287
+ description: "Detach a custom domain from the app",
288
+ examples: ["prisma-cli app domain remove shop.acme.com --yes"]
289
+ },
290
+ {
291
+ id: "app.domain.retry",
292
+ path: [
293
+ "prisma",
294
+ "app",
295
+ "domain",
296
+ "retry"
297
+ ],
298
+ description: "Retry custom domain DNS verification and TLS provisioning",
299
+ examples: ["prisma-cli app domain retry shop.acme.com"]
300
+ },
301
+ {
302
+ id: "app.domain.wait",
303
+ path: [
304
+ "prisma",
305
+ "app",
306
+ "domain",
307
+ "wait"
308
+ ],
309
+ description: "Wait until a custom domain is active or failed",
310
+ examples: ["prisma-cli app domain wait shop.acme.com", "prisma-cli app domain wait shop.acme.com --timeout 0 --json"]
229
311
  },
230
312
  {
231
313
  id: "app.logs",
@@ -298,7 +380,8 @@ const DESCRIPTORS = [
298
380
  examples: [
299
381
  "prisma-cli project env list --role production",
300
382
  "prisma-cli project env add STRIPE_KEY=sk_test_xxx --role production",
301
- "prisma-cli project env rm STRIPE_KEY --role preview"
383
+ "prisma-cli project env add DATABASE_URL=postgresql://branch --branch feature/foo",
384
+ "prisma-cli project env remove STRIPE_KEY --role preview"
302
385
  ]
303
386
  },
304
387
  {
@@ -313,6 +396,7 @@ const DESCRIPTORS = [
313
396
  examples: [
314
397
  "prisma-cli project env add STRIPE_KEY=sk_test_xxx --role production",
315
398
  "prisma-cli project env add STRIPE_KEY=sk_test_xxx --role preview",
399
+ "prisma-cli project env add DATABASE_URL=postgresql://branch --branch feature/foo",
316
400
  "API_URL=https://api.example prisma-cli project env add API_URL --project proj_123 --role preview"
317
401
  ]
318
402
  },
@@ -325,7 +409,11 @@ const DESCRIPTORS = [
325
409
  "update"
326
410
  ],
327
411
  description: "Replace an existing environment variable's value.",
328
- examples: ["prisma-cli project env update STRIPE_KEY=sk_new_xxx --role production", "prisma-cli project env update STRIPE_KEY=sk_new_xxx --role preview"]
412
+ examples: [
413
+ "prisma-cli project env update STRIPE_KEY=sk_new_xxx --role production",
414
+ "prisma-cli project env update STRIPE_KEY=sk_new_xxx --role preview",
415
+ "prisma-cli project env update DATABASE_URL=postgresql://branch --branch feature/foo"
416
+ ]
329
417
  },
330
418
  {
331
419
  id: "project.env.list",
@@ -336,18 +424,26 @@ const DESCRIPTORS = [
336
424
  "list"
337
425
  ],
338
426
  description: "List environment variable metadata for a scope (no values).",
339
- examples: ["prisma-cli project env list --role production", "prisma-cli project env list --role preview"]
427
+ examples: [
428
+ "prisma-cli project env list --role production",
429
+ "prisma-cli project env list --role preview",
430
+ "prisma-cli project env list --branch feature/foo"
431
+ ]
340
432
  },
341
433
  {
342
- id: "project.env.rm",
434
+ id: "project.env.remove",
343
435
  path: [
344
436
  "prisma",
345
437
  "project",
346
438
  "env",
347
- "rm"
439
+ "remove"
348
440
  ],
349
441
  description: "Remove an environment variable from a scope.",
350
- examples: ["prisma-cli project env rm STRIPE_KEY --role production", "prisma-cli project env rm STRIPE_KEY --role preview"]
442
+ examples: [
443
+ "prisma-cli project env remove STRIPE_KEY --role production",
444
+ "prisma-cli project env remove STRIPE_KEY --role preview",
445
+ "prisma-cli project env remove DATABASE_URL --branch feature/foo"
446
+ ]
351
447
  }
352
448
  ];
353
449
  const DESCRIPTORS_BY_ID = new Map(DESCRIPTORS.map((descriptor) => [descriptor.id, descriptor]));