@prisma/cli 3.0.0-alpha.0 → 3.0.0-alpha.2

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.
@@ -6,7 +6,7 @@ import { requireComputeAuth } from "../lib/auth/guard.js";
6
6
  import { parseEnvAssignments } from "../lib/app/env-vars.js";
7
7
  import { DEFAULT_LOCAL_DEV_PORT, resolveLocalBuildType, runLocalApp } from "../lib/app/local-dev.js";
8
8
  import { projectNotFoundError } from "../use-cases/project.js";
9
- import { executePreviewBuild } from "../lib/app/preview-build.js";
9
+ import { PREVIEW_BUILD_TYPES, RESOLVED_PREVIEW_BUILD_TYPES, executePreviewBuild } from "../lib/app/preview-build.js";
10
10
  import { PREVIEW_DEFAULT_REGION, createPreviewDeployInteraction } from "../lib/app/preview-interaction.js";
11
11
  import { createPreviewDeployProgress, createPreviewPromoteProgress, createPreviewUpdateEnvProgress } from "../lib/app/preview-progress.js";
12
12
  import { createPreviewAppProvider } from "../lib/app/preview-provider.js";
@@ -20,12 +20,11 @@ function isRealMode(context) {
20
20
  async function runAppBuild(context, entrypoint, requestedBuildType) {
21
21
  const buildType = normalizeBuildType(requestedBuildType);
22
22
  assertSupportedEntrypoint(buildType, entrypoint, "build");
23
- const resolvedBuildType = await requireLocalBuildType(context, buildType, "build");
24
23
  try {
25
24
  const { artifact, buildType: actualBuildType } = await executePreviewBuild({
26
25
  appPath: context.runtime.cwd,
27
26
  entrypoint,
28
- buildType: resolvedBuildType
27
+ buildType
29
28
  });
30
29
  return {
31
30
  command: "app.build",
@@ -35,14 +34,15 @@ async function runAppBuild(context, entrypoint, requestedBuildType) {
35
34
  buildType: actualBuildType
36
35
  },
37
36
  warnings: [],
38
- nextSteps: ["prisma app deploy"]
37
+ nextSteps: ["prisma-cli app deploy"]
39
38
  };
40
39
  } catch (error) {
40
+ if (buildType === "auto" && isAutoBuildDetectionError(error)) throw usageError("App build requires an explicit framework when detection is ambiguous", `This preview auto-detects clear project shapes for ${RESOLVED_PREVIEW_BUILD_TYPES.map(formatBuildTypeName).join(", ")}.`, "Pass a supported --build-type value, or pass --entry <path> for a Bun app.", getBuildTypeExamples("build"), "app");
41
41
  throw buildFailedError("Local app build failed", error);
42
42
  }
43
43
  }
44
44
  async function runAppRun(context, entrypoint, requestedBuildType, requestedPort) {
45
- if (context.flags.json) throw usageError("App run does not support --json", "This command streams the framework dev server directly and cannot return structured JSON.", "Rerun without --json to pass framework logs through directly.", ["prisma app run"], "app");
45
+ if (context.flags.json) throw usageError("App run does not support --json", "This command streams the framework dev server directly and cannot return structured JSON.", "Rerun without --json to pass framework logs through directly.", ["prisma-cli app run"], "app");
46
46
  const buildType = normalizeBuildType(requestedBuildType);
47
47
  assertSupportedEntrypoint(buildType, entrypoint, "run");
48
48
  const port = parseLocalPort(requestedPort);
@@ -95,7 +95,7 @@ async function runAppDeploy(context, appName, options) {
95
95
  interaction: selectedApp.useInteractiveSelection ? createPreviewDeployInteraction(context) : void 0,
96
96
  progress: createPreviewDeployProgress(context.output.stderr, !context.flags.json && !context.flags.quiet)
97
97
  }).catch((error) => {
98
- throw deployFailedError("App deploy failed", error, ["prisma app list-deploys"]);
98
+ throw deployFailedError("App deploy failed", error, ["prisma-cli app list-deploys"]);
99
99
  });
100
100
  await context.stateStore.setSelectedApp(projectId, {
101
101
  id: deployResult.app.id,
@@ -113,7 +113,7 @@ async function runAppDeploy(context, appName, options) {
113
113
  deployment: deployResult.deployment
114
114
  },
115
115
  warnings: [],
116
- nextSteps: ["prisma app list-deploys", `prisma app show-deploy ${deployResult.deployment.id}`]
116
+ nextSteps: ["prisma-cli app list-deploys", `prisma-cli app show-deploy ${deployResult.deployment.id}`]
117
117
  };
118
118
  }
119
119
  async function runAppUpdateEnv(context, appName, envAssignments) {
@@ -127,7 +127,7 @@ async function runAppUpdateEnv(context, appName, envAssignments) {
127
127
  const selectedApp = await resolveExistingAppSelection(context, projectId, await listApps(context, provider, projectId), appName);
128
128
  if (!selectedApp) throw noDeploymentsError("No deployments available to update environment variables", "The linked project does not have any deployed app yet.");
129
129
  const deploymentsResult = await provider.listDeployments(selectedApp.id).catch((error) => {
130
- throw deployFailedError("Failed to inspect app deployments", error, ["prisma app list-deploys"]);
130
+ throw deployFailedError("Failed to inspect app deployments", error, ["prisma-cli app list-deploys"]);
131
131
  });
132
132
  if (deploymentsResult.deployments.length === 0) throw noDeploymentsError("No deployments available to update environment variables", `The selected app "${deploymentsResult.app.name}" does not have any deployments yet.`);
133
133
  const updateResult = await provider.updateAppEnv({
@@ -136,7 +136,7 @@ async function runAppUpdateEnv(context, appName, envAssignments) {
136
136
  progress: createPreviewUpdateEnvProgress(context.output.stderr, !context.flags.json && !context.flags.quiet),
137
137
  promoteProgress: createPreviewPromoteProgress(context.output.stderr, !context.flags.json && !context.flags.quiet)
138
138
  }).catch((error) => {
139
- throw deployFailedError("Failed to update app environment variables", error, ["prisma app list-env"]);
139
+ throw deployFailedError("Failed to update app environment variables", error, ["prisma-cli app list-env"]);
140
140
  });
141
141
  await context.stateStore.setSelectedApp(projectId, {
142
142
  id: updateResult.app.id,
@@ -155,7 +155,7 @@ async function runAppUpdateEnv(context, appName, envAssignments) {
155
155
  variables: updateResult.variables
156
156
  },
157
157
  warnings: [],
158
- nextSteps: ["prisma app list-env", `prisma app show-deploy ${updateResult.deployment.id}`]
158
+ nextSteps: ["prisma-cli app list-env", `prisma-cli app show-deploy ${updateResult.deployment.id}`]
159
159
  };
160
160
  }
161
161
  async function runAppListEnv(context, appName) {
@@ -172,10 +172,10 @@ async function runAppListEnv(context, appName) {
172
172
  variables: []
173
173
  },
174
174
  warnings: [],
175
- nextSteps: ["prisma app deploy"]
175
+ nextSteps: ["prisma-cli app deploy"]
176
176
  };
177
177
  const deploymentsResult = await provider.listDeployments(selectedApp.id).catch((error) => {
178
- throw deployFailedError("Failed to inspect app deployments", error, ["prisma app list-deploys"]);
178
+ throw deployFailedError("Failed to inspect app deployments", error, ["prisma-cli app list-deploys"]);
179
179
  });
180
180
  const knownLiveDeploymentId = await context.stateStore.readKnownLiveDeployment(projectId, deploymentsResult.app.id);
181
181
  const missingKnownLiveDeploymentId = knownLiveDeploymentId && !deploymentsResult.deployments.some((candidate) => candidate.id === knownLiveDeploymentId) ? knownLiveDeploymentId : null;
@@ -191,7 +191,7 @@ async function runAppListEnv(context, appName) {
191
191
  appId: deploymentsResult.app.id,
192
192
  deploymentId: missingKnownLiveDeploymentId
193
193
  }).catch((error) => {
194
- throw deployFailedError("Failed to inspect app environment variables", error, ["prisma app list-deploys"]);
194
+ throw deployFailedError("Failed to inspect app environment variables", error, ["prisma-cli app list-deploys"]);
195
195
  });
196
196
  return {
197
197
  command: "app.list-env",
@@ -205,7 +205,7 @@ async function runAppListEnv(context, appName) {
205
205
  variables: envResult.variables
206
206
  },
207
207
  warnings: [],
208
- nextSteps: [`prisma app show-deploy ${envResult.deployment.id}`]
208
+ nextSteps: [`prisma-cli app show-deploy ${envResult.deployment.id}`]
209
209
  };
210
210
  }
211
211
  if (!deployment) return {
@@ -220,13 +220,13 @@ async function runAppListEnv(context, appName) {
220
220
  variables: []
221
221
  },
222
222
  warnings: [],
223
- nextSteps: ["prisma app deploy"]
223
+ nextSteps: ["prisma-cli app deploy"]
224
224
  };
225
225
  const envResult = await provider.listAppEnvNames({
226
226
  appId: deploymentsResult.app.id,
227
227
  deploymentId: deployment.id
228
228
  }).catch((error) => {
229
- throw deployFailedError("Failed to inspect app environment variables", error, ["prisma app list-deploys"]);
229
+ throw deployFailedError("Failed to inspect app environment variables", error, ["prisma-cli app list-deploys"]);
230
230
  });
231
231
  return {
232
232
  command: "app.list-env",
@@ -243,7 +243,7 @@ async function runAppListEnv(context, appName) {
243
243
  variables: envResult.variables
244
244
  },
245
245
  warnings: [],
246
- nextSteps: deployment.id ? [`prisma app show-deploy ${deployment.id}`] : ["prisma app deploy"]
246
+ nextSteps: deployment.id ? [`prisma-cli app show-deploy ${deployment.id}`] : ["prisma-cli app deploy"]
247
247
  };
248
248
  }
249
249
  async function runAppListDeploys(context, appName) {
@@ -259,10 +259,10 @@ async function runAppListDeploys(context, appName) {
259
259
  deployments: []
260
260
  },
261
261
  warnings: [],
262
- nextSteps: ["prisma app deploy"]
262
+ nextSteps: ["prisma-cli app deploy"]
263
263
  };
264
264
  const deploymentsResult = await provider.listDeployments(selectedApp.id).catch((error) => {
265
- throw deployFailedError("Failed to list app deployments", error, ["prisma app deploy"]);
265
+ throw deployFailedError("Failed to list app deployments", error, ["prisma-cli app deploy"]);
266
266
  });
267
267
  const currentLiveDeploymentId = await resolveCurrentLiveDeploymentId(context, projectId, deploymentsResult.app, deploymentsResult.deployments);
268
268
  const deployments = applyLiveDeploymentHint(deploymentsResult.deployments, currentLiveDeploymentId).slice().sort((left, right) => right.createdAt.localeCompare(left.createdAt) || right.id.localeCompare(left.id));
@@ -281,7 +281,7 @@ async function runAppListDeploys(context, appName) {
281
281
  deployments
282
282
  },
283
283
  warnings: [],
284
- nextSteps: deployments.length > 0 ? [`prisma app show-deploy ${deployments[0]?.id}`] : ["prisma app deploy"]
284
+ nextSteps: deployments.length > 0 ? [`prisma-cli app show-deploy ${deployments[0]?.id}`] : ["prisma-cli app deploy"]
285
285
  };
286
286
  }
287
287
  async function runAppShow(context, appName) {
@@ -299,10 +299,10 @@ async function runAppShow(context, appName) {
299
299
  recentDeployments: []
300
300
  },
301
301
  warnings: [],
302
- nextSteps: ["prisma app deploy"]
302
+ nextSteps: ["prisma-cli app deploy"]
303
303
  };
304
304
  const deploymentsResult = await provider.listDeployments(selectedApp.id).catch((error) => {
305
- throw deployFailedError("Failed to inspect app", error, ["prisma app list-deploys"]);
305
+ throw deployFailedError("Failed to inspect app", error, ["prisma-cli app list-deploys"]);
306
306
  });
307
307
  const currentLiveDeploymentId = await resolveCurrentLiveDeploymentId(context, projectId, deploymentsResult.app, deploymentsResult.deployments);
308
308
  const deployments = applyLiveDeploymentHint(deploymentsResult.deployments, currentLiveDeploymentId).slice().sort((left, right) => right.createdAt.localeCompare(left.createdAt) || right.id.localeCompare(left.id));
@@ -330,16 +330,16 @@ async function runAppShow(context, appName) {
330
330
  async function runAppShowDeploy(context, deploymentId) {
331
331
  ensurePreviewAppMode(context);
332
332
  const deployment = await (await requirePreviewAppProvider(context)).showDeployment(deploymentId).catch((error) => {
333
- throw deployFailedError("Failed to show deployment", error, ["prisma app list-deploys"]);
333
+ throw deployFailedError("Failed to show deployment", error, ["prisma-cli app list-deploys"]);
334
334
  });
335
335
  if (!deployment) throw new CliError({
336
336
  code: "DEPLOYMENT_NOT_FOUND",
337
337
  domain: "app",
338
338
  summary: `Deployment "${deploymentId}" not found`,
339
339
  why: "The requested deployment does not exist or is no longer available.",
340
- fix: "Run prisma app list-deploys to choose an available deployment id.",
340
+ fix: "Run prisma-cli app list-deploys to choose an available deployment id.",
341
341
  exitCode: 1,
342
- nextSteps: ["prisma app list-deploys"]
342
+ nextSteps: ["prisma-cli app list-deploys"]
343
343
  });
344
344
  const linkedProjectId = deployment?.app ? await readLinkedProjectId(context.runtime.cwd) : null;
345
345
  const knownLiveDeploymentId = deployment?.app && linkedProjectId ? await context.stateStore.readKnownLiveDeployment(linkedProjectId, deployment.app.id) : null;
@@ -367,7 +367,7 @@ async function runAppOpen(context, appName) {
367
367
  const selectedApp = await resolveExistingAppSelection(context, projectId, await listApps(context, provider, projectId), appName);
368
368
  if (!selectedApp) throw noDeploymentsError("No deployments available to open", "The linked project does not have any deployed app yet.");
369
369
  const deploymentsResult = await provider.listDeployments(selectedApp.id).catch((error) => {
370
- throw deployFailedError("Failed to resolve app URL", error, ["prisma app show"]);
370
+ throw deployFailedError("Failed to resolve app URL", error, ["prisma-cli app show"]);
371
371
  });
372
372
  const currentLiveDeploymentId = await resolveCurrentLiveDeploymentId(context, projectId, deploymentsResult.app, deploymentsResult.deployments);
373
373
  const deployments = applyLiveDeploymentHint(deploymentsResult.deployments, currentLiveDeploymentId).slice().sort((left, right) => right.createdAt.localeCompare(left.createdAt) || right.id.localeCompare(left.id));
@@ -377,7 +377,7 @@ async function runAppOpen(context, appName) {
377
377
  name: deploymentsResult.app.name
378
378
  });
379
379
  if (!liveDeployment) throw noDeploymentsError("No deployments available to open", `The selected app "${deploymentsResult.app.name}" does not have any deployments yet.`);
380
- if (!deploymentsResult.app.liveUrl) throw featureUnavailableError("Live URL is not available for the selected app", "Deployments exist, but the provider does not expose a stable live service URL for this app yet.", "Run prisma app show to inspect the current deployment state and try again after the app reports a live URL.", ["prisma app show"], "app");
380
+ if (!deploymentsResult.app.liveUrl) throw featureUnavailableError("Live URL is not available for the selected app", "Deployments exist, but the provider does not expose a stable live service URL for this app yet.", "Run prisma-cli app show to inspect the current deployment state and try again after the app reports a live URL.", ["prisma-cli app show"], "app");
381
381
  const shouldOpen = canPrompt(context);
382
382
  if (shouldOpen) await open(deploymentsResult.app.liveUrl);
383
383
  return {
@@ -392,7 +392,7 @@ async function runAppOpen(context, appName) {
392
392
  opened: shouldOpen
393
393
  },
394
394
  warnings: [],
395
- nextSteps: ["prisma app show", `prisma app show-deploy ${liveDeployment.id}`]
395
+ nextSteps: ["prisma-cli app show", `prisma-cli app show-deploy ${liveDeployment.id}`]
396
396
  };
397
397
  }
398
398
  async function runAppLogs(context, _appName, _deploymentId) {
@@ -405,7 +405,7 @@ async function runAppPromote(context, deploymentId, appName) {
405
405
  const provider = await requirePreviewAppProvider(context);
406
406
  const selectedApp = await requireReleaseAppSelection(context, projectId, await listApps(context, provider, projectId), appName, "promote");
407
407
  const deploymentsResult = await provider.listDeployments(selectedApp.id).catch((error) => {
408
- throw deployFailedError("Failed to list app deployments", error, ["prisma app list-deploys"]);
408
+ throw deployFailedError("Failed to list app deployments", error, ["prisma-cli app list-deploys"]);
409
409
  });
410
410
  const currentLiveDeploymentId = await resolveCurrentLiveDeploymentId(context, projectId, deploymentsResult.app, deploymentsResult.deployments);
411
411
  const targetDeployment = requireDeploymentForApp(deploymentsResult.deployments, deploymentId, selectedApp.name);
@@ -419,7 +419,7 @@ async function runAppPromote(context, deploymentId, appName) {
419
419
  deploymentId: targetDeployment.id,
420
420
  progress: createPreviewPromoteProgress(context.output.stderr, !context.flags.json && !context.flags.quiet)
421
421
  }).catch((error) => {
422
- throw deployFailedError("Failed to promote deployment", error, ["prisma app list-deploys"]);
422
+ throw deployFailedError("Failed to promote deployment", error, ["prisma-cli app list-deploys"]);
423
423
  });
424
424
  await context.stateStore.setKnownLiveDeployment(projectId, deploymentsResult.app.id, targetDeployment.id);
425
425
  return {
@@ -437,7 +437,7 @@ async function runAppPromote(context, deploymentId, appName) {
437
437
  }
438
438
  },
439
439
  warnings: targetAlreadyLive ? ["The selected deployment is already live for this app."] : [],
440
- nextSteps: ["prisma app list-deploys", `prisma app show-deploy ${targetDeployment.id}`]
440
+ nextSteps: ["prisma-cli app list-deploys", `prisma-cli app show-deploy ${targetDeployment.id}`]
441
441
  };
442
442
  }
443
443
  async function runAppRollback(context, appName, deploymentId) {
@@ -446,7 +446,7 @@ async function runAppRollback(context, appName, deploymentId) {
446
446
  const provider = await requirePreviewAppProvider(context);
447
447
  const selectedApp = await requireReleaseAppSelection(context, projectId, await listApps(context, provider, projectId), appName, "rollback");
448
448
  const deploymentsResult = await provider.listDeployments(selectedApp.id).catch((error) => {
449
- throw deployFailedError("Failed to list app deployments", error, ["prisma app list-deploys"]);
449
+ throw deployFailedError("Failed to list app deployments", error, ["prisma-cli app list-deploys"]);
450
450
  });
451
451
  const currentLiveDeploymentId = await resolveCurrentLiveDeploymentId(context, projectId, deploymentsResult.app, deploymentsResult.deployments);
452
452
  const currentLiveDeployment = currentLiveDeploymentId ? deploymentsResult.deployments.find((deployment) => deployment.id === currentLiveDeploymentId) ?? null : null;
@@ -461,7 +461,7 @@ async function runAppRollback(context, appName, deploymentId) {
461
461
  deploymentId: targetDeployment.id,
462
462
  progress: createPreviewPromoteProgress(context.output.stderr, !context.flags.json && !context.flags.quiet)
463
463
  }).catch((error) => {
464
- throw deployFailedError("Failed to roll back deployment", error, ["prisma app list-deploys"]);
464
+ throw deployFailedError("Failed to roll back deployment", error, ["prisma-cli app list-deploys"]);
465
465
  });
466
466
  await context.stateStore.setKnownLiveDeployment(projectId, deploymentsResult.app.id, targetDeployment.id);
467
467
  return {
@@ -480,7 +480,7 @@ async function runAppRollback(context, appName, deploymentId) {
480
480
  previousLiveDeploymentId: currentLiveDeployment?.id ?? null
481
481
  },
482
482
  warnings: targetAlreadyLive ? ["The selected deployment is already live for this app."] : [],
483
- nextSteps: ["prisma app list-deploys", `prisma app show-deploy ${targetDeployment.id}`]
483
+ nextSteps: ["prisma-cli app list-deploys", `prisma-cli app show-deploy ${targetDeployment.id}`]
484
484
  };
485
485
  }
486
486
  async function runAppRemove(context, appName) {
@@ -490,7 +490,7 @@ async function runAppRemove(context, appName) {
490
490
  const selectedApp = await requireReleaseAppSelection(context, projectId, await listApps(context, provider, projectId), appName, "remove");
491
491
  await confirmAppRemoval(context, selectedApp);
492
492
  const removedApp = await provider.removeApp(selectedApp.id).catch((error) => {
493
- throw removeFailedError("Failed to remove app", error, ["prisma app show", "prisma app list-deploys"]);
493
+ throw removeFailedError("Failed to remove app", error, ["prisma-cli app show", "prisma-cli app list-deploys"]);
494
494
  });
495
495
  const warnings = await cleanupRemovedAppState(context, projectId, removedApp.id);
496
496
  return {
@@ -504,7 +504,7 @@ async function runAppRemove(context, appName) {
504
504
  removed: true
505
505
  },
506
506
  warnings,
507
- nextSteps: ["prisma app deploy", "prisma app list-deploys"]
507
+ nextSteps: ["prisma-cli app deploy", "prisma-cli app list-deploys"]
508
508
  };
509
509
  }
510
510
  async function resolveDeploySelection(context, projectId, apps, explicitAppName) {
@@ -527,25 +527,25 @@ async function resolveDeploySelection(context, projectId, apps, explicitAppName)
527
527
  appId: matched.id,
528
528
  useInteractiveSelection: false
529
529
  };
530
- if (!canPrompt(context)) throw usageError("Saved app selection is no longer available", "The locally selected app could not be found in the linked project.", "Pass --app <name>, or rerun prisma app deploy in a TTY to choose or create an app again.", ["prisma app deploy"], "app");
530
+ if (!canPrompt(context)) throw usageError("Saved app selection is no longer available", "The locally selected app could not be found in the linked project.", "Pass --app <name>, or rerun prisma-cli app deploy in a TTY to choose or create an app again.", ["prisma-cli app deploy"], "app");
531
531
  }
532
- if (!canPrompt(context)) throw usageError("App deploy requires an app selection in non-interactive mode", "This command cannot choose or create an app in the current mode.", "Pass --app <name>, or rerun prisma app deploy in a TTY to choose or create an app.", ["prisma app deploy --app hello-world"], "app");
532
+ if (!canPrompt(context)) throw usageError("App deploy requires an app selection in non-interactive mode", "This command cannot choose or create an app in the current mode.", "Pass --app <name>, or rerun prisma-cli app deploy in a TTY to choose or create an app.", ["prisma-cli app deploy --app hello-world"], "app");
533
533
  return { useInteractiveSelection: true };
534
534
  }
535
535
  async function resolveExistingAppSelection(context, projectId, apps, explicitAppName) {
536
536
  if (explicitAppName) {
537
537
  const matched = findAppByName(apps, explicitAppName);
538
- if (!matched) throw usageError("Selected app does not exist in the linked project", `The app "${explicitAppName}" could not be found in linked project "${projectId}".`, "Pass the name of an existing app, or rerun prisma app list-deploys in a TTY to choose one.", ["prisma app list-deploys"], "app");
538
+ if (!matched) throw usageError("Selected app does not exist in the linked project", `The app "${explicitAppName}" could not be found in linked project "${projectId}".`, "Pass the name of an existing app, or rerun prisma-cli app list-deploys in a TTY to choose one.", ["prisma-cli app list-deploys"], "app");
539
539
  return matched;
540
540
  }
541
541
  const savedSelection = await context.stateStore.readSelectedApp(projectId);
542
542
  if (savedSelection) {
543
543
  const matched = apps.find((app) => app.id === savedSelection.id) ?? findAppByName(apps, savedSelection.name);
544
544
  if (matched) return matched;
545
- if (!canPrompt(context)) throw usageError("Saved app selection is no longer available", "The locally selected app could not be found in the linked project.", "Pass --app <name>, or rerun prisma app list-deploys in a TTY to choose an available app.", ["prisma app list-deploys"], "app");
545
+ if (!canPrompt(context)) throw usageError("Saved app selection is no longer available", "The locally selected app could not be found in the linked project.", "Pass --app <name>, or rerun prisma-cli app list-deploys in a TTY to choose an available app.", ["prisma-cli app list-deploys"], "app");
546
546
  }
547
547
  if (apps.length === 0) return null;
548
- if (!canPrompt(context)) throw usageError("App selection required in non-interactive mode", "This command cannot choose an app in the current mode.", "Pass --app <name>, or rerun prisma app list-deploys in a TTY to choose an app.", ["prisma app list-deploys"], "app");
548
+ if (!canPrompt(context)) throw usageError("App selection required in non-interactive mode", "This command cannot choose an app in the current mode.", "Pass --app <name>, or rerun prisma-cli app list-deploys in a TTY to choose an app.", ["prisma-cli app list-deploys"], "app");
549
549
  const selectedId = await createSelectPromptPort(context).select({
550
550
  message: "Select an app",
551
551
  choices: sortApps(apps).map((app) => ({
@@ -558,7 +558,7 @@ async function resolveExistingAppSelection(context, projectId, apps, explicitApp
558
558
  async function requireReleaseAppSelection(context, projectId, apps, explicitAppName, commandName) {
559
559
  const selectedApp = await resolveExistingAppSelection(context, projectId, apps, explicitAppName);
560
560
  if (selectedApp) return selectedApp;
561
- throw usageError(`App ${commandName} requires an existing app`, "The linked project does not have an app that can be selected for this command.", `Deploy an app first, or rerun prisma app ${commandName} with --app <name> after an app exists.`, ["prisma app deploy", "prisma app list-deploys"], "app");
561
+ throw usageError(`App ${commandName} requires an existing app`, "The linked project does not have an app that can be selected for this command.", `Deploy an app first, or rerun prisma-cli app ${commandName} with --app <name> after an app exists.`, ["prisma-cli app deploy", "prisma-cli app list-deploys"], "app");
562
562
  }
563
563
  async function confirmAppRemoval(context, app) {
564
564
  if (context.flags.yes) return;
@@ -567,9 +567,9 @@ async function confirmAppRemoval(context, app) {
567
567
  domain: "app",
568
568
  summary: "App remove requires confirmation in the current mode",
569
569
  why: "This command is destructive and cannot prompt for confirmation in the current mode.",
570
- fix: `Pass --yes to confirm removal of "${app.name}", or rerun prisma app remove in an interactive TTY.`,
570
+ fix: `Pass --yes to confirm removal of "${app.name}", or rerun prisma-cli app remove in an interactive TTY.`,
571
571
  exitCode: 1,
572
- nextSteps: [`prisma app remove --app ${app.name} --yes`]
572
+ nextSteps: [`prisma-cli app remove --app ${app.name} --yes`]
573
573
  });
574
574
  await textPrompt({
575
575
  input: context.runtime.stdin,
@@ -601,9 +601,9 @@ function requireDeploymentForApp(deployments, deploymentId, appName) {
601
601
  domain: "app",
602
602
  summary: `Deployment "${deploymentId}" not found for app "${appName}"`,
603
603
  why: "The requested deployment does not belong to the resolved app or is no longer available.",
604
- fix: "Run prisma app list-deploys to choose an available deployment id for this app.",
604
+ fix: "Run prisma-cli app list-deploys to choose an available deployment id for this app.",
605
605
  exitCode: 1,
606
- nextSteps: ["prisma app list-deploys"]
606
+ nextSteps: ["prisma-cli app list-deploys"]
607
607
  });
608
608
  }
609
609
  async function resolveCurrentLiveDeploymentId(context, projectId, app, deployments) {
@@ -616,10 +616,10 @@ async function resolveCurrentLiveDeploymentId(context, projectId, app, deploymen
616
616
  }
617
617
  function buildAppShowNextSteps(liveUrl, liveDeployment, deployments) {
618
618
  const nextSteps = [];
619
- if (liveUrl) nextSteps.push("prisma app open");
620
- if (liveDeployment) nextSteps.push(`prisma app show-deploy ${liveDeployment.id}`);
621
- else if (deployments[0]) nextSteps.push(`prisma app show-deploy ${deployments[0].id}`);
622
- else nextSteps.push("prisma app deploy");
619
+ if (liveUrl) nextSteps.push("prisma-cli app open");
620
+ if (liveDeployment) nextSteps.push(`prisma-cli app show-deploy ${liveDeployment.id}`);
621
+ else if (deployments[0]) nextSteps.push(`prisma-cli app show-deploy ${deployments[0].id}`);
622
+ else nextSteps.push("prisma-cli app deploy");
623
623
  return nextSteps;
624
624
  }
625
625
  function applyLiveDeploymentHint(deployments, currentLiveDeploymentId) {
@@ -640,24 +640,24 @@ function resolveRollbackTarget(deployments, currentLiveDeploymentId) {
640
640
  domain: "app",
641
641
  summary: "No previous deployment available for rollback",
642
642
  why: "The selected app does not have an earlier deployment to switch back to.",
643
- fix: "Deploy a second version first, or rerun prisma app rollback --to <deployment-id> for a specific earlier deployment.",
643
+ fix: "Deploy a second version first, or rerun prisma-cli app rollback --to <deployment-id> for a specific earlier deployment.",
644
644
  exitCode: 1,
645
- nextSteps: ["prisma app deploy", "prisma app list-deploys"]
645
+ nextSteps: ["prisma-cli app deploy", "prisma-cli app list-deploys"]
646
646
  });
647
647
  }
648
648
  async function listApps(context, provider, projectId) {
649
649
  return provider.listApps(projectId).then(sortApps).catch((error) => {
650
- if (isMissingProjectError(error)) throw projectNotFoundError(`The linked project "${projectId}" does not exist in the authenticated workspace or is no longer accessible.`, "Run prisma project show to inspect the current link, then relink the repo or rerun prisma app deploy to bootstrap a new project.", [
651
- "prisma project show",
652
- "prisma project link",
653
- "prisma app deploy"
650
+ if (isMissingProjectError(error)) throw projectNotFoundError(`The linked project "${projectId}" does not exist in the authenticated workspace or is no longer accessible.`, "Run prisma-cli project show to inspect the current link, then relink the repo or rerun prisma-cli app deploy to bootstrap a new project.", [
651
+ "prisma-cli project show",
652
+ "prisma-cli project link",
653
+ "prisma-cli app deploy"
654
654
  ]);
655
- throw deployFailedError("Failed to list apps", error, ["prisma project show"]);
655
+ throw deployFailedError("Failed to list apps", error, ["prisma-cli project show"]);
656
656
  });
657
657
  }
658
658
  async function requirePreviewAppProvider(context) {
659
659
  const client = await requireComputeAuth(context.runtime.env);
660
- if (!client) throw authRequiredError(["prisma auth login"]);
660
+ if (!client) throw authRequiredError(["prisma-cli auth login"]);
661
661
  return createPreviewAppProvider(client);
662
662
  }
663
663
  async function requireLinkedProjectId(context) {
@@ -667,9 +667,9 @@ async function requireLinkedProjectId(context) {
667
667
  domain: "project",
668
668
  summary: "Project link required",
669
669
  why: "This command needs a linked project for the current repo.",
670
- fix: "Run prisma project link before deploying or inspecting app deployments.",
670
+ fix: "Run prisma-cli project link before deploying or inspecting app deployments.",
671
671
  exitCode: 1,
672
- nextSteps: ["prisma project link"]
672
+ nextSteps: ["prisma-cli project link"]
673
673
  });
674
674
  return projectId;
675
675
  }
@@ -679,13 +679,13 @@ async function resolveProjectIdForDeploy(context, provider) {
679
679
  await assertProjectLinkWritableForDeploy(context);
680
680
  const projectName = path.basename(context.runtime.cwd);
681
681
  const project = await provider.createProject({ name: projectName }).catch((error) => {
682
- throw deployFailedError("Failed to create project for first deploy", error, ["prisma app deploy"]);
682
+ throw deployFailedError("Failed to create project for first deploy", error, ["prisma-cli app deploy"]);
683
683
  });
684
684
  try {
685
685
  await writeLinkedProjectId(context.runtime.cwd, project.id);
686
686
  } catch (error) {
687
687
  const cause = error instanceof Error ? error.message : String(error);
688
- throw deployFailedError("Failed to link created project", `Project "${project.name}" (${project.id}) was created remotely but could not be linked locally: ${cause}`, ["prisma project show", "prisma app deploy"]);
688
+ throw deployFailedError("Failed to link created project", `Project "${project.name}" (${project.id}) was created remotely but could not be linked locally: ${cause}`, ["prisma-cli project show", "prisma-cli app deploy"]);
689
689
  }
690
690
  return project.id;
691
691
  }
@@ -693,41 +693,49 @@ async function assertProjectLinkWritableForDeploy(context) {
693
693
  try {
694
694
  await assertLinkedProjectIdWritable(context.runtime.cwd);
695
695
  } catch (error) {
696
- if (error instanceof UnsafeConfigWriteError) throw usageError("Project bootstrap requires a writable Prisma config", error.message, "Update prisma.config.ts to use a recognizable project field, or remove it and rerun prisma app deploy.", ["prisma app deploy --app hello-world"], "app");
696
+ if (error instanceof UnsafeConfigWriteError) throw usageError("Project bootstrap requires a writable Prisma config", error.message, "Update prisma.config.ts to use a recognizable project field, or remove it and rerun prisma-cli app deploy.", ["prisma-cli app deploy --app hello-world"], "app");
697
697
  throw error;
698
698
  }
699
699
  }
700
700
  function normalizeBuildType(requestedBuildType) {
701
701
  if (!requestedBuildType) return "auto";
702
- if (requestedBuildType === "auto" || requestedBuildType === "bun" || requestedBuildType === "nextjs") return requestedBuildType;
703
- throw usageError(`Unsupported build type "${requestedBuildType}"`, "Only auto, bun, and nextjs are supported in the current preview.", "Pass --build-type auto, --build-type bun, or --build-type nextjs.", ["prisma app build --build-type nextjs", "prisma app build --build-type bun --entry server.ts"], "app");
702
+ if (isPreviewBuildType(requestedBuildType)) return requestedBuildType;
703
+ throw usageError(`Unsupported build type "${requestedBuildType}"`, `Only ${PREVIEW_BUILD_TYPES.join(", ")} are supported in the current preview.`, "Pass a supported --build-type value.", getBuildTypeExamples("build"), "app");
704
+ }
705
+ function isPreviewBuildType(value) {
706
+ return PREVIEW_BUILD_TYPES.includes(value);
707
+ }
708
+ function getBuildTypeExamples(commandName) {
709
+ return RESOLVED_PREVIEW_BUILD_TYPES.map((buildType) => {
710
+ return `prisma-cli app ${commandName} --build-type ${buildType}${buildType === "bun" ? " --entry server.ts" : ""}`;
711
+ });
704
712
  }
705
713
  function assertSupportedEntrypoint(buildType, entrypoint, commandName) {
706
- if (buildType === "nextjs" && entrypoint) throw usageError(`App ${commandName} does not accept --entry with --build-type nextjs`, "Next.js apps do not use an entrypoint flag in the current preview.", `Remove --entry, or rerun prisma app ${commandName} with --build-type bun when you want to target a Bun entrypoint directly.`, [`prisma app ${commandName} --build-type nextjs`, `prisma app ${commandName} --build-type bun --entry server.ts`], "app");
714
+ if (buildType !== "auto" && buildType !== "bun" && entrypoint) throw usageError(`App ${commandName} does not accept --entry with --build-type ${buildType}`, `${formatBuildTypeName(buildType)} apps do not use an entrypoint flag in the current preview.`, `Remove --entry, or rerun prisma-cli app ${commandName} with --build-type bun when you want to target a Bun entrypoint directly.`, [`prisma-cli app ${commandName} --build-type ${buildType}`, `prisma-cli app ${commandName} --build-type bun --entry server.ts`], "app");
707
715
  }
708
716
  async function requireLocalBuildType(context, buildType, commandName) {
709
717
  const resolvedBuildType = await resolveLocalBuildType(context.runtime.cwd, buildType);
710
718
  if (resolvedBuildType) return resolvedBuildType;
711
- throw usageError(`App ${commandName} requires an explicit framework when detection is ambiguous`, "This preview only auto-detects clear Next.js or Bun project shapes.", "Pass --build-type nextjs for a Next.js app, or pass --build-type bun with --entry <path> for a Bun app.", [`prisma app ${commandName} --build-type nextjs`, `prisma app ${commandName} --build-type bun --entry server.ts`], "app");
719
+ throw usageError(`App ${commandName} requires an explicit framework when detection is ambiguous`, "This preview only starts local dev servers for clear Next.js or Bun project shapes.", "Pass --build-type nextjs for a Next.js app, or pass --build-type bun with --entry <path> for a Bun app.", [`prisma-cli app ${commandName} --build-type nextjs`, `prisma-cli app ${commandName} --build-type bun --entry server.ts`], "app");
712
720
  }
713
721
  function parseLocalPort(requestedPort) {
714
722
  if (!requestedPort) return DEFAULT_LOCAL_DEV_PORT;
715
723
  const port = Number.parseInt(requestedPort, 10);
716
- if (!Number.isInteger(port) || port <= 0 || port > 65535) throw usageError(`Invalid port "${requestedPort}"`, "Port must be an integer between 1 and 65535.", "Pass --port <number> with a valid local port value.", ["prisma app run --port 3000"], "app");
724
+ if (!Number.isInteger(port) || port <= 0 || port > 65535) throw usageError(`Invalid port "${requestedPort}"`, "Port must be an integer between 1 and 65535.", "Pass --port <number> with a valid local port value.", ["prisma-cli app run --port 3000"], "app");
717
725
  return port;
718
726
  }
719
727
  function parseDeployPortMapping(requestedPort) {
720
728
  if (!requestedPort) return;
721
729
  const port = Number.parseInt(requestedPort, 10);
722
- if (!Number.isInteger(port) || port <= 0 || port > 65535) throw usageError(`Invalid HTTP port "${requestedPort}"`, "HTTP port must be an integer between 1 and 65535.", "Pass --http-port <number> with a valid port value.", ["prisma app deploy --http-port 3000"], "app");
730
+ if (!Number.isInteger(port) || port <= 0 || port > 65535) throw usageError(`Invalid HTTP port "${requestedPort}"`, "HTTP port must be an integer between 1 and 65535.", "Pass --http-port <number> with a valid port value.", ["prisma-cli app deploy --http-port 3000"], "app");
723
731
  return { http: port };
724
732
  }
725
733
  function ensurePreviewAppMode(context) {
726
734
  if (isRealMode(context)) return;
727
- throw featureUnavailableError("App commands are not available in fixture mode", "Preview app commands require live app deployment integration.", "Rerun without fixture mode enabled to use preview app deployment workflows.", ["prisma auth login", "prisma project link"], "app");
735
+ throw featureUnavailableError("App commands are not available in fixture mode", "Preview app commands require live app deployment integration.", "Rerun without fixture mode enabled to use preview app deployment workflows.", ["prisma-cli auth login", "prisma-cli project link"], "app");
728
736
  }
729
737
  function blockedPreviewAppCommandError(summary, why) {
730
- return featureUnavailableError(summary, why, "Use prisma app show, prisma app open, prisma app deploy, or prisma app list-deploys in the current preview.", ["prisma app show", "prisma app list-deploys"], "app");
738
+ return featureUnavailableError(summary, why, "Use prisma-cli app show, prisma-cli app open, prisma-cli app deploy, or prisma-cli app list-deploys in the current preview.", ["prisma-cli app show", "prisma-cli app list-deploys"], "app");
731
739
  }
732
740
  function deployFailedError(summary, error, nextSteps) {
733
741
  return new CliError({
@@ -747,9 +755,9 @@ function noDeploymentsError(summary, why) {
747
755
  domain: "app",
748
756
  summary,
749
757
  why,
750
- fix: "Run prisma app deploy first, or use prisma app show to inspect the current app state.",
758
+ fix: "Run prisma-cli app deploy first, or use prisma-cli app show to inspect the current app state.",
751
759
  exitCode: 1,
752
- nextSteps: ["prisma app deploy", "prisma app show"]
760
+ nextSteps: ["prisma-cli app deploy", "prisma-cli app show"]
753
761
  });
754
762
  }
755
763
  function buildFailedError(summary, error) {
@@ -758,10 +766,10 @@ function buildFailedError(summary, error) {
758
766
  domain: "app",
759
767
  summary,
760
768
  why: error instanceof Error ? error.message : String(error),
761
- fix: "Inspect the framework output, fix the build issue, and rerun prisma app build.",
769
+ fix: "Inspect the framework output, fix the build issue, and rerun prisma-cli app build.",
762
770
  debug: formatDebugDetails(error),
763
771
  exitCode: 1,
764
- nextSteps: ["prisma app build", "prisma app deploy"]
772
+ nextSteps: ["prisma-cli app build", "prisma-cli app deploy"]
765
773
  });
766
774
  }
767
775
  function runFailedError(summary, error, exitCode = 1) {
@@ -770,14 +778,27 @@ function runFailedError(summary, error, exitCode = 1) {
770
778
  domain: "app",
771
779
  summary,
772
780
  why: error instanceof Error ? error.message : String(error),
773
- fix: "Inspect the framework output above, fix the issue, and rerun prisma app run.",
781
+ fix: "Inspect the framework output above, fix the issue, and rerun prisma-cli app run.",
774
782
  exitCode,
775
- nextSteps: ["prisma app run"]
783
+ nextSteps: ["prisma-cli app run"]
776
784
  });
777
785
  }
778
786
  function formatFrameworkName(framework) {
779
787
  return framework === "nextjs" ? "Next.js" : "Bun";
780
788
  }
789
+ function isAutoBuildDetectionError(error) {
790
+ return error instanceof Error && error.message.startsWith("Entrypoint is required.");
791
+ }
792
+ function formatBuildTypeName(buildType) {
793
+ switch (buildType) {
794
+ case "nextjs": return "Next.js";
795
+ case "nuxt": return "Nuxt";
796
+ case "astro": return "Astro";
797
+ case "tanstack-start": return "TanStack Start";
798
+ case "bun": return "Bun";
799
+ case "auto": return "Auto";
800
+ }
801
+ }
781
802
  function removeFailedError(summary, error, nextSteps) {
782
803
  return new CliError({
783
804
  code: "REMOVE_FAILED",
@@ -14,7 +14,7 @@ async function runAuthLogin(context, options) {
14
14
  await performLogin(context.runtime.env);
15
15
  result = await readAuthState(context.runtime.env);
16
16
  } else result = await loginWithSelectionFlow(context, createAuthUseCases(createCliUseCaseGateways(context)), options);
17
- return createAuthSuccess("auth.login", result, ["prisma auth whoami", "prisma project list"]);
17
+ return createAuthSuccess("auth.login", result, ["prisma-cli auth whoami", "prisma-cli project list"]);
18
18
  }
19
19
  async function runAuthLogout(context) {
20
20
  let result;
@@ -22,13 +22,13 @@ async function runAuthLogout(context) {
22
22
  await performLogout(context.runtime.env);
23
23
  result = await readAuthState(context.runtime.env);
24
24
  } else result = await createAuthUseCases(createCliUseCaseGateways(context)).logout();
25
- return createAuthSuccess("auth.logout", result, ["prisma auth login"]);
25
+ return createAuthSuccess("auth.logout", result, ["prisma-cli auth login"]);
26
26
  }
27
27
  async function runAuthWhoAmI(context) {
28
28
  let result;
29
29
  if (isRealMode(context)) result = await readAuthState(context.runtime.env);
30
30
  else result = await createAuthUseCases(createCliUseCaseGateways(context)).whoami();
31
- return createAuthSuccess("auth.whoami", result, result.authenticated ? [] : ["prisma auth login"]);
31
+ return createAuthSuccess("auth.whoami", result, result.authenticated ? [] : ["prisma-cli auth login"]);
32
32
  }
33
33
  async function requireAuthenticatedAuthState(context) {
34
34
  if (isRealMode(context)) {
@@ -59,7 +59,7 @@ async function resolveLoginSelection(useCases, prompt, options) {
59
59
  };
60
60
  }
61
61
  async function selectProvider(useCases, prompt) {
62
- if (!prompt) throw nonInteractiveLoginError("Re-run prisma auth login in a TTY, or provide --provider and --user, and --workspace when required.");
62
+ if (!prompt) throw nonInteractiveLoginError("Re-run prisma-cli auth login in a TTY, or provide --provider and --user, and --workspace when required.");
63
63
  const providers = await useCases.listProviders();
64
64
  return prompt.select({
65
65
  message: "Select a provider",
@@ -71,7 +71,7 @@ async function selectProvider(useCases, prompt) {
71
71
  }
72
72
  async function selectUser(useCases, prompt, provider) {
73
73
  const users = await useCases.listUsersForProvider(provider);
74
- if (!prompt) throw nonInteractiveLoginError("Re-run prisma auth login in a TTY, or provide --provider and --user, and --workspace when required.");
74
+ if (!prompt) throw nonInteractiveLoginError("Re-run prisma-cli auth login in a TTY, or provide --provider and --user, and --workspace when required.");
75
75
  return prompt.select({
76
76
  message: "Select a user",
77
77
  choices: users.map((user) => ({
@@ -83,7 +83,7 @@ async function selectUser(useCases, prompt, provider) {
83
83
  async function selectWorkspace(useCases, prompt, userId) {
84
84
  const workspaces = await useCases.listWorkspacesForUser(userId);
85
85
  if (workspaces.length === 1) return workspaces[0];
86
- if (!prompt) throw usageError("Login requires explicit selectors in non-interactive mode", "The selected mock user belongs to more than one workspace and the shell cannot prompt in the current mode.", "Re-run prisma auth login in a TTY, or provide --workspace.", ["prisma auth login"], "auth");
86
+ if (!prompt) throw usageError("Login requires explicit selectors in non-interactive mode", "The selected mock user belongs to more than one workspace and the shell cannot prompt in the current mode.", "Re-run prisma-cli auth login in a TTY, or provide --workspace.", ["prisma-cli auth login"], "auth");
87
87
  return prompt.select({
88
88
  message: "Select a workspace",
89
89
  choices: workspaces.map((workspace) => ({
@@ -93,7 +93,7 @@ async function selectWorkspace(useCases, prompt, userId) {
93
93
  });
94
94
  }
95
95
  function nonInteractiveLoginError(fix) {
96
- return usageError("Login requires explicit selectors in non-interactive mode", "The fixture mode cannot prompt in the current mode.", fix, ["prisma auth login"], "auth");
96
+ return usageError("Login requires explicit selectors in non-interactive mode", "The fixture mode cannot prompt in the current mode.", fix, ["prisma-cli auth login"], "auth");
97
97
  }
98
98
  function createAuthSuccess(command, result, nextSteps) {
99
99
  return {