@prisma/cli 3.0.0-alpha.1 → 3.0.0-alpha.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -16
- package/dist/cli2.js +2 -0
- package/dist/commands/app/index.js +4 -3
- package/dist/commands/auth/index.js +2 -1
- package/dist/commands/branch/index.js +2 -1
- package/dist/commands/env.js +71 -0
- package/dist/commands/project/index.js +4 -1
- package/dist/controllers/app-env.js +221 -0
- package/dist/controllers/app.js +234 -78
- package/dist/controllers/auth.js +7 -7
- package/dist/controllers/branch.js +5 -5
- package/dist/controllers/project.js +14 -14
- package/dist/lib/app/env-config.js +46 -0
- package/dist/lib/app/env-vars.js +4 -4
- package/dist/lib/app/preview-provider.js +15 -2
- package/dist/lib/auth/auth-ops.js +6 -6
- package/dist/lib/auth/login.js +115 -4
- package/dist/output/patterns.js +15 -17
- package/dist/presenters/app-env.js +129 -0
- package/dist/presenters/auth.js +2 -2
- package/dist/shell/command-meta.js +115 -88
- package/dist/shell/command-runner.js +32 -2
- package/dist/shell/errors.js +2 -2
- package/dist/shell/global-flags.js +12 -1
- package/dist/shell/help.js +8 -7
- package/dist/shell/output.js +18 -12
- package/dist/shell/runtime.js +1 -1
- package/dist/shell/ui.js +19 -1
- package/dist/use-cases/auth.js +5 -5
- package/dist/use-cases/create-cli-gateways.js +1 -1
- package/dist/use-cases/project.js +2 -2
- package/package.json +2 -2
package/dist/controllers/app.js
CHANGED
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
import { UnsafeConfigWriteError, assertLinkedProjectIdWritable, readLinkedProjectId, writeLinkedProjectId } from "../adapters/config.js";
|
|
2
|
+
import { SERVICE_TOKEN_ENV_VAR, getApiBaseUrl } from "../lib/auth/client.js";
|
|
3
|
+
import { FileTokenStorage } from "../adapters/token-storage.js";
|
|
2
4
|
import { CliError, authRequiredError, featureUnavailableError, usageError } from "../shell/errors.js";
|
|
5
|
+
import { renderCommandHeader } from "../shell/ui.js";
|
|
6
|
+
import { writeJsonEvent } from "../shell/output.js";
|
|
3
7
|
import { canPrompt } from "../shell/runtime.js";
|
|
4
8
|
import { textPrompt } from "../shell/prompt.js";
|
|
5
9
|
import { requireComputeAuth } from "../lib/auth/guard.js";
|
|
@@ -34,7 +38,7 @@ async function runAppBuild(context, entrypoint, requestedBuildType) {
|
|
|
34
38
|
buildType: actualBuildType
|
|
35
39
|
},
|
|
36
40
|
warnings: [],
|
|
37
|
-
nextSteps: ["prisma app deploy"]
|
|
41
|
+
nextSteps: ["prisma-cli app deploy"]
|
|
38
42
|
};
|
|
39
43
|
} catch (error) {
|
|
40
44
|
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");
|
|
@@ -42,7 +46,7 @@ async function runAppBuild(context, entrypoint, requestedBuildType) {
|
|
|
42
46
|
}
|
|
43
47
|
}
|
|
44
48
|
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");
|
|
49
|
+
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
50
|
const buildType = normalizeBuildType(requestedBuildType);
|
|
47
51
|
assertSupportedEntrypoint(buildType, entrypoint, "run");
|
|
48
52
|
const port = parseLocalPort(requestedPort);
|
|
@@ -95,7 +99,7 @@ async function runAppDeploy(context, appName, options) {
|
|
|
95
99
|
interaction: selectedApp.useInteractiveSelection ? createPreviewDeployInteraction(context) : void 0,
|
|
96
100
|
progress: createPreviewDeployProgress(context.output.stderr, !context.flags.json && !context.flags.quiet)
|
|
97
101
|
}).catch((error) => {
|
|
98
|
-
throw deployFailedError("App deploy failed", error, ["prisma app list-deploys"]);
|
|
102
|
+
throw deployFailedError("App deploy failed", error, ["prisma-cli app list-deploys"]);
|
|
99
103
|
});
|
|
100
104
|
await context.stateStore.setSelectedApp(projectId, {
|
|
101
105
|
id: deployResult.app.id,
|
|
@@ -113,11 +117,12 @@ async function runAppDeploy(context, appName, options) {
|
|
|
113
117
|
deployment: deployResult.deployment
|
|
114
118
|
},
|
|
115
119
|
warnings: [],
|
|
116
|
-
nextSteps: ["prisma app list-deploys", `prisma app show-deploy ${deployResult.deployment.id}`]
|
|
120
|
+
nextSteps: ["prisma-cli app list-deploys", `prisma-cli app show-deploy ${deployResult.deployment.id}`]
|
|
117
121
|
};
|
|
118
122
|
}
|
|
119
123
|
async function runAppUpdateEnv(context, appName, envAssignments) {
|
|
120
124
|
ensurePreviewAppMode(context);
|
|
125
|
+
emitLegacyEnvDeprecationWarning(context, "app update-env", "project env add");
|
|
121
126
|
const envVars = parseEnvAssignments(envAssignments, {
|
|
122
127
|
commandName: "update-env",
|
|
123
128
|
requireAtLeastOne: true
|
|
@@ -127,7 +132,7 @@ async function runAppUpdateEnv(context, appName, envAssignments) {
|
|
|
127
132
|
const selectedApp = await resolveExistingAppSelection(context, projectId, await listApps(context, provider, projectId), appName);
|
|
128
133
|
if (!selectedApp) throw noDeploymentsError("No deployments available to update environment variables", "The linked project does not have any deployed app yet.");
|
|
129
134
|
const deploymentsResult = await provider.listDeployments(selectedApp.id).catch((error) => {
|
|
130
|
-
throw deployFailedError("Failed to inspect app deployments", error, ["prisma app list-deploys"]);
|
|
135
|
+
throw deployFailedError("Failed to inspect app deployments", error, ["prisma-cli app list-deploys"]);
|
|
131
136
|
});
|
|
132
137
|
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
138
|
const updateResult = await provider.updateAppEnv({
|
|
@@ -136,7 +141,7 @@ async function runAppUpdateEnv(context, appName, envAssignments) {
|
|
|
136
141
|
progress: createPreviewUpdateEnvProgress(context.output.stderr, !context.flags.json && !context.flags.quiet),
|
|
137
142
|
promoteProgress: createPreviewPromoteProgress(context.output.stderr, !context.flags.json && !context.flags.quiet)
|
|
138
143
|
}).catch((error) => {
|
|
139
|
-
throw deployFailedError("Failed to update app environment variables", error, ["prisma app list-env"]);
|
|
144
|
+
throw deployFailedError("Failed to update app environment variables", error, ["prisma-cli app list-env"]);
|
|
140
145
|
});
|
|
141
146
|
await context.stateStore.setSelectedApp(projectId, {
|
|
142
147
|
id: updateResult.app.id,
|
|
@@ -155,11 +160,12 @@ async function runAppUpdateEnv(context, appName, envAssignments) {
|
|
|
155
160
|
variables: updateResult.variables
|
|
156
161
|
},
|
|
157
162
|
warnings: [],
|
|
158
|
-
nextSteps: ["prisma app list-env", `prisma app show-deploy ${updateResult.deployment.id}`]
|
|
163
|
+
nextSteps: ["prisma-cli app list-env", `prisma-cli app show-deploy ${updateResult.deployment.id}`]
|
|
159
164
|
};
|
|
160
165
|
}
|
|
161
166
|
async function runAppListEnv(context, appName) {
|
|
162
167
|
ensurePreviewAppMode(context);
|
|
168
|
+
emitLegacyEnvDeprecationWarning(context, "app list-env", "project env list");
|
|
163
169
|
const projectId = await requireLinkedProjectId(context);
|
|
164
170
|
const provider = await requirePreviewAppProvider(context);
|
|
165
171
|
const selectedApp = await resolveExistingAppSelection(context, projectId, await listApps(context, provider, projectId), appName);
|
|
@@ -172,10 +178,10 @@ async function runAppListEnv(context, appName) {
|
|
|
172
178
|
variables: []
|
|
173
179
|
},
|
|
174
180
|
warnings: [],
|
|
175
|
-
nextSteps: ["prisma app deploy"]
|
|
181
|
+
nextSteps: ["prisma-cli app deploy"]
|
|
176
182
|
};
|
|
177
183
|
const deploymentsResult = await provider.listDeployments(selectedApp.id).catch((error) => {
|
|
178
|
-
throw deployFailedError("Failed to inspect app deployments", error, ["prisma app list-deploys"]);
|
|
184
|
+
throw deployFailedError("Failed to inspect app deployments", error, ["prisma-cli app list-deploys"]);
|
|
179
185
|
});
|
|
180
186
|
const knownLiveDeploymentId = await context.stateStore.readKnownLiveDeployment(projectId, deploymentsResult.app.id);
|
|
181
187
|
const missingKnownLiveDeploymentId = knownLiveDeploymentId && !deploymentsResult.deployments.some((candidate) => candidate.id === knownLiveDeploymentId) ? knownLiveDeploymentId : null;
|
|
@@ -191,7 +197,7 @@ async function runAppListEnv(context, appName) {
|
|
|
191
197
|
appId: deploymentsResult.app.id,
|
|
192
198
|
deploymentId: missingKnownLiveDeploymentId
|
|
193
199
|
}).catch((error) => {
|
|
194
|
-
throw deployFailedError("Failed to inspect app environment variables", error, ["prisma app list-deploys"]);
|
|
200
|
+
throw deployFailedError("Failed to inspect app environment variables", error, ["prisma-cli app list-deploys"]);
|
|
195
201
|
});
|
|
196
202
|
return {
|
|
197
203
|
command: "app.list-env",
|
|
@@ -205,7 +211,7 @@ async function runAppListEnv(context, appName) {
|
|
|
205
211
|
variables: envResult.variables
|
|
206
212
|
},
|
|
207
213
|
warnings: [],
|
|
208
|
-
nextSteps: [`prisma app show-deploy ${envResult.deployment.id}`]
|
|
214
|
+
nextSteps: [`prisma-cli app show-deploy ${envResult.deployment.id}`]
|
|
209
215
|
};
|
|
210
216
|
}
|
|
211
217
|
if (!deployment) return {
|
|
@@ -220,13 +226,13 @@ async function runAppListEnv(context, appName) {
|
|
|
220
226
|
variables: []
|
|
221
227
|
},
|
|
222
228
|
warnings: [],
|
|
223
|
-
nextSteps: ["prisma app deploy"]
|
|
229
|
+
nextSteps: ["prisma-cli app deploy"]
|
|
224
230
|
};
|
|
225
231
|
const envResult = await provider.listAppEnvNames({
|
|
226
232
|
appId: deploymentsResult.app.id,
|
|
227
233
|
deploymentId: deployment.id
|
|
228
234
|
}).catch((error) => {
|
|
229
|
-
throw deployFailedError("Failed to inspect app environment variables", error, ["prisma app list-deploys"]);
|
|
235
|
+
throw deployFailedError("Failed to inspect app environment variables", error, ["prisma-cli app list-deploys"]);
|
|
230
236
|
});
|
|
231
237
|
return {
|
|
232
238
|
command: "app.list-env",
|
|
@@ -243,7 +249,7 @@ async function runAppListEnv(context, appName) {
|
|
|
243
249
|
variables: envResult.variables
|
|
244
250
|
},
|
|
245
251
|
warnings: [],
|
|
246
|
-
nextSteps: deployment.id ? [`prisma app show-deploy ${deployment.id}`] : ["prisma app deploy"]
|
|
252
|
+
nextSteps: deployment.id ? [`prisma-cli app show-deploy ${deployment.id}`] : ["prisma-cli app deploy"]
|
|
247
253
|
};
|
|
248
254
|
}
|
|
249
255
|
async function runAppListDeploys(context, appName) {
|
|
@@ -259,10 +265,10 @@ async function runAppListDeploys(context, appName) {
|
|
|
259
265
|
deployments: []
|
|
260
266
|
},
|
|
261
267
|
warnings: [],
|
|
262
|
-
nextSteps: ["prisma app deploy"]
|
|
268
|
+
nextSteps: ["prisma-cli app deploy"]
|
|
263
269
|
};
|
|
264
270
|
const deploymentsResult = await provider.listDeployments(selectedApp.id).catch((error) => {
|
|
265
|
-
throw deployFailedError("Failed to list app deployments", error, ["prisma app deploy"]);
|
|
271
|
+
throw deployFailedError("Failed to list app deployments", error, ["prisma-cli app deploy"]);
|
|
266
272
|
});
|
|
267
273
|
const currentLiveDeploymentId = await resolveCurrentLiveDeploymentId(context, projectId, deploymentsResult.app, deploymentsResult.deployments);
|
|
268
274
|
const deployments = applyLiveDeploymentHint(deploymentsResult.deployments, currentLiveDeploymentId).slice().sort((left, right) => right.createdAt.localeCompare(left.createdAt) || right.id.localeCompare(left.id));
|
|
@@ -281,7 +287,7 @@ async function runAppListDeploys(context, appName) {
|
|
|
281
287
|
deployments
|
|
282
288
|
},
|
|
283
289
|
warnings: [],
|
|
284
|
-
nextSteps: deployments.length > 0 ? [`prisma app show-deploy ${deployments[0]?.id}`] : ["prisma app deploy"]
|
|
290
|
+
nextSteps: deployments.length > 0 ? [`prisma-cli app show-deploy ${deployments[0]?.id}`] : ["prisma-cli app deploy"]
|
|
285
291
|
};
|
|
286
292
|
}
|
|
287
293
|
async function runAppShow(context, appName) {
|
|
@@ -299,10 +305,10 @@ async function runAppShow(context, appName) {
|
|
|
299
305
|
recentDeployments: []
|
|
300
306
|
},
|
|
301
307
|
warnings: [],
|
|
302
|
-
nextSteps: ["prisma app deploy"]
|
|
308
|
+
nextSteps: ["prisma-cli app deploy"]
|
|
303
309
|
};
|
|
304
310
|
const deploymentsResult = await provider.listDeployments(selectedApp.id).catch((error) => {
|
|
305
|
-
throw deployFailedError("Failed to inspect app", error, ["prisma app list-deploys"]);
|
|
311
|
+
throw deployFailedError("Failed to inspect app", error, ["prisma-cli app list-deploys"]);
|
|
306
312
|
});
|
|
307
313
|
const currentLiveDeploymentId = await resolveCurrentLiveDeploymentId(context, projectId, deploymentsResult.app, deploymentsResult.deployments);
|
|
308
314
|
const deployments = applyLiveDeploymentHint(deploymentsResult.deployments, currentLiveDeploymentId).slice().sort((left, right) => right.createdAt.localeCompare(left.createdAt) || right.id.localeCompare(left.id));
|
|
@@ -330,16 +336,16 @@ async function runAppShow(context, appName) {
|
|
|
330
336
|
async function runAppShowDeploy(context, deploymentId) {
|
|
331
337
|
ensurePreviewAppMode(context);
|
|
332
338
|
const deployment = await (await requirePreviewAppProvider(context)).showDeployment(deploymentId).catch((error) => {
|
|
333
|
-
throw deployFailedError("Failed to show deployment", error, ["prisma app list-deploys"]);
|
|
339
|
+
throw deployFailedError("Failed to show deployment", error, ["prisma-cli app list-deploys"]);
|
|
334
340
|
});
|
|
335
341
|
if (!deployment) throw new CliError({
|
|
336
342
|
code: "DEPLOYMENT_NOT_FOUND",
|
|
337
343
|
domain: "app",
|
|
338
344
|
summary: `Deployment "${deploymentId}" not found`,
|
|
339
345
|
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.",
|
|
346
|
+
fix: "Run prisma-cli app list-deploys to choose an available deployment id.",
|
|
341
347
|
exitCode: 1,
|
|
342
|
-
nextSteps: ["prisma app list-deploys"]
|
|
348
|
+
nextSteps: ["prisma-cli app list-deploys"]
|
|
343
349
|
});
|
|
344
350
|
const linkedProjectId = deployment?.app ? await readLinkedProjectId(context.runtime.cwd) : null;
|
|
345
351
|
const knownLiveDeploymentId = deployment?.app && linkedProjectId ? await context.stateStore.readKnownLiveDeployment(linkedProjectId, deployment.app.id) : null;
|
|
@@ -367,7 +373,7 @@ async function runAppOpen(context, appName) {
|
|
|
367
373
|
const selectedApp = await resolveExistingAppSelection(context, projectId, await listApps(context, provider, projectId), appName);
|
|
368
374
|
if (!selectedApp) throw noDeploymentsError("No deployments available to open", "The linked project does not have any deployed app yet.");
|
|
369
375
|
const deploymentsResult = await provider.listDeployments(selectedApp.id).catch((error) => {
|
|
370
|
-
throw deployFailedError("Failed to resolve app URL", error, ["prisma app show"]);
|
|
376
|
+
throw deployFailedError("Failed to resolve app URL", error, ["prisma-cli app show"]);
|
|
371
377
|
});
|
|
372
378
|
const currentLiveDeploymentId = await resolveCurrentLiveDeploymentId(context, projectId, deploymentsResult.app, deploymentsResult.deployments);
|
|
373
379
|
const deployments = applyLiveDeploymentHint(deploymentsResult.deployments, currentLiveDeploymentId).slice().sort((left, right) => right.createdAt.localeCompare(left.createdAt) || right.id.localeCompare(left.id));
|
|
@@ -377,7 +383,7 @@ async function runAppOpen(context, appName) {
|
|
|
377
383
|
name: deploymentsResult.app.name
|
|
378
384
|
});
|
|
379
385
|
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");
|
|
386
|
+
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
387
|
const shouldOpen = canPrompt(context);
|
|
382
388
|
if (shouldOpen) await open(deploymentsResult.app.liveUrl);
|
|
383
389
|
return {
|
|
@@ -392,12 +398,133 @@ async function runAppOpen(context, appName) {
|
|
|
392
398
|
opened: shouldOpen
|
|
393
399
|
},
|
|
394
400
|
warnings: [],
|
|
395
|
-
nextSteps: ["prisma app show", `prisma app show-deploy ${liveDeployment.id}`]
|
|
401
|
+
nextSteps: ["prisma-cli app show", `prisma-cli app show-deploy ${liveDeployment.id}`]
|
|
396
402
|
};
|
|
397
403
|
}
|
|
398
|
-
async function runAppLogs(context,
|
|
404
|
+
async function runAppLogs(context, appName, deploymentId) {
|
|
399
405
|
ensurePreviewAppMode(context);
|
|
400
|
-
|
|
406
|
+
const projectId = await requireLinkedProjectId(context);
|
|
407
|
+
const provider = await requirePreviewAppProvider(context);
|
|
408
|
+
const target = deploymentId ? await resolveExplicitLogDeployment(context, provider, projectId, appName, deploymentId) : await resolveLiveLogDeployment(context, provider, projectId, appName);
|
|
409
|
+
if (!context.flags.json && !context.flags.quiet) {
|
|
410
|
+
const lines = renderCommandHeader(context.ui, {
|
|
411
|
+
commandLabel: "app logs",
|
|
412
|
+
description: "Streaming logs for the selected deployment.",
|
|
413
|
+
docsPath: "docs/product/command-spec.md#prisma-cli-app-logs---app-name---deployment-id",
|
|
414
|
+
rows: [
|
|
415
|
+
{
|
|
416
|
+
key: "project",
|
|
417
|
+
value: projectId
|
|
418
|
+
},
|
|
419
|
+
{
|
|
420
|
+
key: "app",
|
|
421
|
+
value: target.app.name
|
|
422
|
+
},
|
|
423
|
+
{
|
|
424
|
+
key: "deployment",
|
|
425
|
+
value: target.deployment.id
|
|
426
|
+
}
|
|
427
|
+
]
|
|
428
|
+
});
|
|
429
|
+
if (lines.length > 0) context.output.stderr.write(`${lines.join("\n")}\n`);
|
|
430
|
+
}
|
|
431
|
+
await provider.streamDeploymentLogs({
|
|
432
|
+
deploymentId: target.deployment.id,
|
|
433
|
+
onRecord: (record) => writeLogRecord(context, record)
|
|
434
|
+
}).catch((error) => {
|
|
435
|
+
throw deployFailedError("Failed to stream app logs", error, [`prisma-cli app show-deploy ${target.deployment.id}`, "prisma-cli app list-deploys"]);
|
|
436
|
+
});
|
|
437
|
+
}
|
|
438
|
+
async function resolveExplicitLogDeployment(context, provider, projectId, appName, deploymentId) {
|
|
439
|
+
if (appName) {
|
|
440
|
+
const selectedApp = await resolveExistingAppSelection(context, projectId, await listApps(context, provider, projectId), appName);
|
|
441
|
+
if (!selectedApp) throw noDeploymentsError("No deployments available to stream logs", "The linked project does not have any deployed app yet.");
|
|
442
|
+
const deploymentsResult = await provider.listDeployments(selectedApp.id).catch((error) => {
|
|
443
|
+
throw deployFailedError("Failed to list app deployments", error, ["prisma-cli app list-deploys"]);
|
|
444
|
+
});
|
|
445
|
+
const deployment = requireDeploymentForApp(deploymentsResult.deployments, deploymentId, selectedApp.name);
|
|
446
|
+
await context.stateStore.setSelectedApp(projectId, {
|
|
447
|
+
id: deploymentsResult.app.id,
|
|
448
|
+
name: deploymentsResult.app.name
|
|
449
|
+
});
|
|
450
|
+
return {
|
|
451
|
+
app: deploymentsResult.app,
|
|
452
|
+
deployment
|
|
453
|
+
};
|
|
454
|
+
}
|
|
455
|
+
const shown = await provider.showDeployment(deploymentId).catch((error) => {
|
|
456
|
+
throw deployFailedError("Failed to show deployment", error, ["prisma-cli app list-deploys"]);
|
|
457
|
+
});
|
|
458
|
+
if (!shown) throw new CliError({
|
|
459
|
+
code: "DEPLOYMENT_NOT_FOUND",
|
|
460
|
+
domain: "app",
|
|
461
|
+
summary: `Deployment "${deploymentId}" not found`,
|
|
462
|
+
why: "The requested deployment does not exist or is no longer available.",
|
|
463
|
+
fix: "Run prisma-cli app list-deploys to choose an available deployment id.",
|
|
464
|
+
exitCode: 1,
|
|
465
|
+
nextSteps: ["prisma-cli app list-deploys"]
|
|
466
|
+
});
|
|
467
|
+
if (!shown.app) throw new CliError({
|
|
468
|
+
code: "DEPLOYMENT_NOT_FOUND",
|
|
469
|
+
domain: "app",
|
|
470
|
+
summary: `Deployment "${deploymentId}" is not attached to an app`,
|
|
471
|
+
why: "The requested deployment could be found, but its app could not be resolved.",
|
|
472
|
+
fix: "Run prisma-cli app list-deploys to choose an available deployment id for the selected app.",
|
|
473
|
+
exitCode: 1,
|
|
474
|
+
nextSteps: ["prisma-cli app list-deploys"]
|
|
475
|
+
});
|
|
476
|
+
const linkedProjectApp = (await listApps(context, provider, projectId)).find((app) => app.id === shown.app?.id);
|
|
477
|
+
if (!linkedProjectApp) throw new CliError({
|
|
478
|
+
code: "DEPLOYMENT_NOT_FOUND",
|
|
479
|
+
domain: "app",
|
|
480
|
+
summary: `Deployment "${deploymentId}" not found in the linked project`,
|
|
481
|
+
why: "The requested deployment does not belong to an app in the linked project.",
|
|
482
|
+
fix: "Run prisma-cli app list-deploys to choose an available deployment id for this project.",
|
|
483
|
+
exitCode: 1,
|
|
484
|
+
nextSteps: ["prisma-cli app list-deploys"]
|
|
485
|
+
});
|
|
486
|
+
await context.stateStore.setSelectedApp(projectId, {
|
|
487
|
+
id: linkedProjectApp.id,
|
|
488
|
+
name: linkedProjectApp.name
|
|
489
|
+
});
|
|
490
|
+
return {
|
|
491
|
+
app: linkedProjectApp,
|
|
492
|
+
deployment: shown.deployment
|
|
493
|
+
};
|
|
494
|
+
}
|
|
495
|
+
async function resolveLiveLogDeployment(context, provider, projectId, appName) {
|
|
496
|
+
const selectedApp = await resolveExistingAppSelection(context, projectId, await listApps(context, provider, projectId), appName);
|
|
497
|
+
if (!selectedApp) throw noDeploymentsError("No deployments available to stream logs", "The linked project does not have any deployed app yet.");
|
|
498
|
+
const deploymentsResult = await provider.listDeployments(selectedApp.id).catch((error) => {
|
|
499
|
+
throw deployFailedError("Failed to list app deployments", error, ["prisma-cli app list-deploys"]);
|
|
500
|
+
});
|
|
501
|
+
const currentLiveDeploymentId = await resolveCurrentLiveDeploymentId(context, projectId, deploymentsResult.app, deploymentsResult.deployments);
|
|
502
|
+
const deployments = applyLiveDeploymentHint(deploymentsResult.deployments, currentLiveDeploymentId);
|
|
503
|
+
const deployment = currentLiveDeploymentId ? deployments.find((candidate) => candidate.id === currentLiveDeploymentId) ?? null : null;
|
|
504
|
+
await context.stateStore.setSelectedApp(projectId, {
|
|
505
|
+
id: deploymentsResult.app.id,
|
|
506
|
+
name: deploymentsResult.app.name
|
|
507
|
+
});
|
|
508
|
+
if (!deployment) throw noDeploymentsError("No deployments available to stream logs", `The selected app "${deploymentsResult.app.name}" does not have any deployments yet.`);
|
|
509
|
+
return {
|
|
510
|
+
app: deploymentsResult.app,
|
|
511
|
+
deployment
|
|
512
|
+
};
|
|
513
|
+
}
|
|
514
|
+
function writeLogRecord(context, record) {
|
|
515
|
+
if (context.flags.json) {
|
|
516
|
+
writeJsonEvent(context.output, {
|
|
517
|
+
type: record.type,
|
|
518
|
+
command: "app.logs",
|
|
519
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
520
|
+
data: record
|
|
521
|
+
});
|
|
522
|
+
return;
|
|
523
|
+
}
|
|
524
|
+
if (record.type === "log") {
|
|
525
|
+
context.output.stdout.write(record.text);
|
|
526
|
+
if (!record.text.endsWith("\n")) context.output.stdout.write("\n");
|
|
527
|
+
}
|
|
401
528
|
}
|
|
402
529
|
async function runAppPromote(context, deploymentId, appName) {
|
|
403
530
|
ensurePreviewAppMode(context);
|
|
@@ -405,7 +532,7 @@ async function runAppPromote(context, deploymentId, appName) {
|
|
|
405
532
|
const provider = await requirePreviewAppProvider(context);
|
|
406
533
|
const selectedApp = await requireReleaseAppSelection(context, projectId, await listApps(context, provider, projectId), appName, "promote");
|
|
407
534
|
const deploymentsResult = await provider.listDeployments(selectedApp.id).catch((error) => {
|
|
408
|
-
throw deployFailedError("Failed to list app deployments", error, ["prisma app list-deploys"]);
|
|
535
|
+
throw deployFailedError("Failed to list app deployments", error, ["prisma-cli app list-deploys"]);
|
|
409
536
|
});
|
|
410
537
|
const currentLiveDeploymentId = await resolveCurrentLiveDeploymentId(context, projectId, deploymentsResult.app, deploymentsResult.deployments);
|
|
411
538
|
const targetDeployment = requireDeploymentForApp(deploymentsResult.deployments, deploymentId, selectedApp.name);
|
|
@@ -419,7 +546,7 @@ async function runAppPromote(context, deploymentId, appName) {
|
|
|
419
546
|
deploymentId: targetDeployment.id,
|
|
420
547
|
progress: createPreviewPromoteProgress(context.output.stderr, !context.flags.json && !context.flags.quiet)
|
|
421
548
|
}).catch((error) => {
|
|
422
|
-
throw deployFailedError("Failed to promote deployment", error, ["prisma app list-deploys"]);
|
|
549
|
+
throw deployFailedError("Failed to promote deployment", error, ["prisma-cli app list-deploys"]);
|
|
423
550
|
});
|
|
424
551
|
await context.stateStore.setKnownLiveDeployment(projectId, deploymentsResult.app.id, targetDeployment.id);
|
|
425
552
|
return {
|
|
@@ -437,7 +564,7 @@ async function runAppPromote(context, deploymentId, appName) {
|
|
|
437
564
|
}
|
|
438
565
|
},
|
|
439
566
|
warnings: targetAlreadyLive ? ["The selected deployment is already live for this app."] : [],
|
|
440
|
-
nextSteps: ["prisma app list-deploys", `prisma app show-deploy ${targetDeployment.id}`]
|
|
567
|
+
nextSteps: ["prisma-cli app list-deploys", `prisma-cli app show-deploy ${targetDeployment.id}`]
|
|
441
568
|
};
|
|
442
569
|
}
|
|
443
570
|
async function runAppRollback(context, appName, deploymentId) {
|
|
@@ -446,7 +573,7 @@ async function runAppRollback(context, appName, deploymentId) {
|
|
|
446
573
|
const provider = await requirePreviewAppProvider(context);
|
|
447
574
|
const selectedApp = await requireReleaseAppSelection(context, projectId, await listApps(context, provider, projectId), appName, "rollback");
|
|
448
575
|
const deploymentsResult = await provider.listDeployments(selectedApp.id).catch((error) => {
|
|
449
|
-
throw deployFailedError("Failed to list app deployments", error, ["prisma app list-deploys"]);
|
|
576
|
+
throw deployFailedError("Failed to list app deployments", error, ["prisma-cli app list-deploys"]);
|
|
450
577
|
});
|
|
451
578
|
const currentLiveDeploymentId = await resolveCurrentLiveDeploymentId(context, projectId, deploymentsResult.app, deploymentsResult.deployments);
|
|
452
579
|
const currentLiveDeployment = currentLiveDeploymentId ? deploymentsResult.deployments.find((deployment) => deployment.id === currentLiveDeploymentId) ?? null : null;
|
|
@@ -461,7 +588,7 @@ async function runAppRollback(context, appName, deploymentId) {
|
|
|
461
588
|
deploymentId: targetDeployment.id,
|
|
462
589
|
progress: createPreviewPromoteProgress(context.output.stderr, !context.flags.json && !context.flags.quiet)
|
|
463
590
|
}).catch((error) => {
|
|
464
|
-
throw deployFailedError("Failed to roll back deployment", error, ["prisma app list-deploys"]);
|
|
591
|
+
throw deployFailedError("Failed to roll back deployment", error, ["prisma-cli app list-deploys"]);
|
|
465
592
|
});
|
|
466
593
|
await context.stateStore.setKnownLiveDeployment(projectId, deploymentsResult.app.id, targetDeployment.id);
|
|
467
594
|
return {
|
|
@@ -480,7 +607,7 @@ async function runAppRollback(context, appName, deploymentId) {
|
|
|
480
607
|
previousLiveDeploymentId: currentLiveDeployment?.id ?? null
|
|
481
608
|
},
|
|
482
609
|
warnings: targetAlreadyLive ? ["The selected deployment is already live for this app."] : [],
|
|
483
|
-
nextSteps: ["prisma app list-deploys", `prisma app show-deploy ${targetDeployment.id}`]
|
|
610
|
+
nextSteps: ["prisma-cli app list-deploys", `prisma-cli app show-deploy ${targetDeployment.id}`]
|
|
484
611
|
};
|
|
485
612
|
}
|
|
486
613
|
async function runAppRemove(context, appName) {
|
|
@@ -490,7 +617,7 @@ async function runAppRemove(context, appName) {
|
|
|
490
617
|
const selectedApp = await requireReleaseAppSelection(context, projectId, await listApps(context, provider, projectId), appName, "remove");
|
|
491
618
|
await confirmAppRemoval(context, selectedApp);
|
|
492
619
|
const removedApp = await provider.removeApp(selectedApp.id).catch((error) => {
|
|
493
|
-
throw removeFailedError("Failed to remove app", error, ["prisma app show", "prisma app list-deploys"]);
|
|
620
|
+
throw removeFailedError("Failed to remove app", error, ["prisma-cli app show", "prisma-cli app list-deploys"]);
|
|
494
621
|
});
|
|
495
622
|
const warnings = await cleanupRemovedAppState(context, projectId, removedApp.id);
|
|
496
623
|
return {
|
|
@@ -504,7 +631,7 @@ async function runAppRemove(context, appName) {
|
|
|
504
631
|
removed: true
|
|
505
632
|
},
|
|
506
633
|
warnings,
|
|
507
|
-
nextSteps: ["prisma app deploy", "prisma app list-deploys"]
|
|
634
|
+
nextSteps: ["prisma-cli app deploy", "prisma-cli app list-deploys"]
|
|
508
635
|
};
|
|
509
636
|
}
|
|
510
637
|
async function resolveDeploySelection(context, projectId, apps, explicitAppName) {
|
|
@@ -527,25 +654,25 @@ async function resolveDeploySelection(context, projectId, apps, explicitAppName)
|
|
|
527
654
|
appId: matched.id,
|
|
528
655
|
useInteractiveSelection: false
|
|
529
656
|
};
|
|
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");
|
|
657
|
+
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
658
|
}
|
|
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");
|
|
659
|
+
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
660
|
return { useInteractiveSelection: true };
|
|
534
661
|
}
|
|
535
662
|
async function resolveExistingAppSelection(context, projectId, apps, explicitAppName) {
|
|
536
663
|
if (explicitAppName) {
|
|
537
664
|
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");
|
|
665
|
+
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
666
|
return matched;
|
|
540
667
|
}
|
|
541
668
|
const savedSelection = await context.stateStore.readSelectedApp(projectId);
|
|
542
669
|
if (savedSelection) {
|
|
543
670
|
const matched = apps.find((app) => app.id === savedSelection.id) ?? findAppByName(apps, savedSelection.name);
|
|
544
671
|
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");
|
|
672
|
+
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
673
|
}
|
|
547
674
|
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");
|
|
675
|
+
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
676
|
const selectedId = await createSelectPromptPort(context).select({
|
|
550
677
|
message: "Select an app",
|
|
551
678
|
choices: sortApps(apps).map((app) => ({
|
|
@@ -558,7 +685,7 @@ async function resolveExistingAppSelection(context, projectId, apps, explicitApp
|
|
|
558
685
|
async function requireReleaseAppSelection(context, projectId, apps, explicitAppName, commandName) {
|
|
559
686
|
const selectedApp = await resolveExistingAppSelection(context, projectId, apps, explicitAppName);
|
|
560
687
|
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");
|
|
688
|
+
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
689
|
}
|
|
563
690
|
async function confirmAppRemoval(context, app) {
|
|
564
691
|
if (context.flags.yes) return;
|
|
@@ -567,9 +694,9 @@ async function confirmAppRemoval(context, app) {
|
|
|
567
694
|
domain: "app",
|
|
568
695
|
summary: "App remove requires confirmation in the current mode",
|
|
569
696
|
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.`,
|
|
697
|
+
fix: `Pass --yes to confirm removal of "${app.name}", or rerun prisma-cli app remove in an interactive TTY.`,
|
|
571
698
|
exitCode: 1,
|
|
572
|
-
nextSteps: [`prisma app remove --app ${app.name} --yes`]
|
|
699
|
+
nextSteps: [`prisma-cli app remove --app ${app.name} --yes`]
|
|
573
700
|
});
|
|
574
701
|
await textPrompt({
|
|
575
702
|
input: context.runtime.stdin,
|
|
@@ -601,9 +728,9 @@ function requireDeploymentForApp(deployments, deploymentId, appName) {
|
|
|
601
728
|
domain: "app",
|
|
602
729
|
summary: `Deployment "${deploymentId}" not found for app "${appName}"`,
|
|
603
730
|
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.",
|
|
731
|
+
fix: "Run prisma-cli app list-deploys to choose an available deployment id for this app.",
|
|
605
732
|
exitCode: 1,
|
|
606
|
-
nextSteps: ["prisma app list-deploys"]
|
|
733
|
+
nextSteps: ["prisma-cli app list-deploys"]
|
|
607
734
|
});
|
|
608
735
|
}
|
|
609
736
|
async function resolveCurrentLiveDeploymentId(context, projectId, app, deployments) {
|
|
@@ -616,10 +743,10 @@ async function resolveCurrentLiveDeploymentId(context, projectId, app, deploymen
|
|
|
616
743
|
}
|
|
617
744
|
function buildAppShowNextSteps(liveUrl, liveDeployment, deployments) {
|
|
618
745
|
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");
|
|
746
|
+
if (liveUrl) nextSteps.push("prisma-cli app open");
|
|
747
|
+
if (liveDeployment) nextSteps.push(`prisma-cli app show-deploy ${liveDeployment.id}`);
|
|
748
|
+
else if (deployments[0]) nextSteps.push(`prisma-cli app show-deploy ${deployments[0].id}`);
|
|
749
|
+
else nextSteps.push("prisma-cli app deploy");
|
|
623
750
|
return nextSteps;
|
|
624
751
|
}
|
|
625
752
|
function applyLiveDeploymentHint(deployments, currentLiveDeploymentId) {
|
|
@@ -640,25 +767,41 @@ function resolveRollbackTarget(deployments, currentLiveDeploymentId) {
|
|
|
640
767
|
domain: "app",
|
|
641
768
|
summary: "No previous deployment available for rollback",
|
|
642
769
|
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.",
|
|
770
|
+
fix: "Deploy a second version first, or rerun prisma-cli app rollback --to <deployment-id> for a specific earlier deployment.",
|
|
644
771
|
exitCode: 1,
|
|
645
|
-
nextSteps: ["prisma app deploy", "prisma app list-deploys"]
|
|
772
|
+
nextSteps: ["prisma-cli app deploy", "prisma-cli app list-deploys"]
|
|
646
773
|
});
|
|
647
774
|
}
|
|
648
775
|
async function listApps(context, provider, projectId) {
|
|
649
776
|
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"
|
|
777
|
+
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.", [
|
|
778
|
+
"prisma-cli project show",
|
|
779
|
+
"prisma-cli project link",
|
|
780
|
+
"prisma-cli app deploy"
|
|
654
781
|
]);
|
|
655
|
-
throw deployFailedError("Failed to list apps", error, ["prisma project show"]);
|
|
782
|
+
throw deployFailedError("Failed to list apps", error, ["prisma-cli project show"]);
|
|
656
783
|
});
|
|
657
784
|
}
|
|
658
785
|
async function requirePreviewAppProvider(context) {
|
|
659
786
|
const client = await requireComputeAuth(context.runtime.env);
|
|
660
|
-
if (!client) throw authRequiredError(["prisma auth login"]);
|
|
661
|
-
return createPreviewAppProvider(client);
|
|
787
|
+
if (!client) throw authRequiredError(["prisma-cli auth login"]);
|
|
788
|
+
return createPreviewAppProvider(client, createPreviewLogAuthOptions(context.runtime.env));
|
|
789
|
+
}
|
|
790
|
+
function createPreviewLogAuthOptions(env) {
|
|
791
|
+
const rawToken = env[SERVICE_TOKEN_ENV_VAR]?.trim();
|
|
792
|
+
if (rawToken) return {
|
|
793
|
+
baseUrl: getApiBaseUrl(env),
|
|
794
|
+
getToken: async () => rawToken
|
|
795
|
+
};
|
|
796
|
+
const tokenStorage = new FileTokenStorage(env);
|
|
797
|
+
return {
|
|
798
|
+
baseUrl: getApiBaseUrl(env),
|
|
799
|
+
getToken: async () => {
|
|
800
|
+
const tokens = await tokenStorage.getTokens();
|
|
801
|
+
if (!tokens) throw new Error("Authentication token is no longer available. Run prisma-cli auth login and try again.");
|
|
802
|
+
return tokens.accessToken;
|
|
803
|
+
}
|
|
804
|
+
};
|
|
662
805
|
}
|
|
663
806
|
async function requireLinkedProjectId(context) {
|
|
664
807
|
const projectId = await readLinkedProjectId(context.runtime.cwd);
|
|
@@ -667,9 +810,9 @@ async function requireLinkedProjectId(context) {
|
|
|
667
810
|
domain: "project",
|
|
668
811
|
summary: "Project link required",
|
|
669
812
|
why: "This command needs a linked project for the current repo.",
|
|
670
|
-
fix: "Run prisma project link before deploying or inspecting app deployments.",
|
|
813
|
+
fix: "Run prisma-cli project link before deploying or inspecting app deployments.",
|
|
671
814
|
exitCode: 1,
|
|
672
|
-
nextSteps: ["prisma project link"]
|
|
815
|
+
nextSteps: ["prisma-cli project link"]
|
|
673
816
|
});
|
|
674
817
|
return projectId;
|
|
675
818
|
}
|
|
@@ -679,13 +822,13 @@ async function resolveProjectIdForDeploy(context, provider) {
|
|
|
679
822
|
await assertProjectLinkWritableForDeploy(context);
|
|
680
823
|
const projectName = path.basename(context.runtime.cwd);
|
|
681
824
|
const project = await provider.createProject({ name: projectName }).catch((error) => {
|
|
682
|
-
throw deployFailedError("Failed to create project for first deploy", error, ["prisma app deploy"]);
|
|
825
|
+
throw deployFailedError("Failed to create project for first deploy", error, ["prisma-cli app deploy"]);
|
|
683
826
|
});
|
|
684
827
|
try {
|
|
685
828
|
await writeLinkedProjectId(context.runtime.cwd, project.id);
|
|
686
829
|
} catch (error) {
|
|
687
830
|
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"]);
|
|
831
|
+
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
832
|
}
|
|
690
833
|
return project.id;
|
|
691
834
|
}
|
|
@@ -693,7 +836,7 @@ async function assertProjectLinkWritableForDeploy(context) {
|
|
|
693
836
|
try {
|
|
694
837
|
await assertLinkedProjectIdWritable(context.runtime.cwd);
|
|
695
838
|
} 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");
|
|
839
|
+
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
840
|
throw error;
|
|
698
841
|
}
|
|
699
842
|
}
|
|
@@ -707,35 +850,32 @@ function isPreviewBuildType(value) {
|
|
|
707
850
|
}
|
|
708
851
|
function getBuildTypeExamples(commandName) {
|
|
709
852
|
return RESOLVED_PREVIEW_BUILD_TYPES.map((buildType) => {
|
|
710
|
-
return `prisma app ${commandName} --build-type ${buildType}${buildType === "bun" ? " --entry server.ts" : ""}`;
|
|
853
|
+
return `prisma-cli app ${commandName} --build-type ${buildType}${buildType === "bun" ? " --entry server.ts" : ""}`;
|
|
711
854
|
});
|
|
712
855
|
}
|
|
713
856
|
function assertSupportedEntrypoint(buildType, entrypoint, commandName) {
|
|
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 app ${commandName} with --build-type bun when you want to target a Bun entrypoint directly.`, [`prisma app ${commandName} --build-type ${buildType}`, `prisma app ${commandName} --build-type bun --entry server.ts`], "app");
|
|
857
|
+
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");
|
|
715
858
|
}
|
|
716
859
|
async function requireLocalBuildType(context, buildType, commandName) {
|
|
717
860
|
const resolvedBuildType = await resolveLocalBuildType(context.runtime.cwd, buildType);
|
|
718
861
|
if (resolvedBuildType) return resolvedBuildType;
|
|
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 app ${commandName} --build-type nextjs`, `prisma app ${commandName} --build-type bun --entry server.ts`], "app");
|
|
862
|
+
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");
|
|
720
863
|
}
|
|
721
864
|
function parseLocalPort(requestedPort) {
|
|
722
865
|
if (!requestedPort) return DEFAULT_LOCAL_DEV_PORT;
|
|
723
866
|
const port = Number.parseInt(requestedPort, 10);
|
|
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 app run --port 3000"], "app");
|
|
867
|
+
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");
|
|
725
868
|
return port;
|
|
726
869
|
}
|
|
727
870
|
function parseDeployPortMapping(requestedPort) {
|
|
728
871
|
if (!requestedPort) return;
|
|
729
872
|
const port = Number.parseInt(requestedPort, 10);
|
|
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 app deploy --http-port 3000"], "app");
|
|
873
|
+
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");
|
|
731
874
|
return { http: port };
|
|
732
875
|
}
|
|
733
876
|
function ensurePreviewAppMode(context) {
|
|
734
877
|
if (isRealMode(context)) return;
|
|
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 auth login", "prisma project link"], "app");
|
|
736
|
-
}
|
|
737
|
-
function blockedPreviewAppCommandError(summary, why) {
|
|
738
|
-
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");
|
|
878
|
+
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");
|
|
739
879
|
}
|
|
740
880
|
function deployFailedError(summary, error, nextSteps) {
|
|
741
881
|
return new CliError({
|
|
@@ -755,9 +895,9 @@ function noDeploymentsError(summary, why) {
|
|
|
755
895
|
domain: "app",
|
|
756
896
|
summary,
|
|
757
897
|
why,
|
|
758
|
-
fix: "Run prisma app deploy first, or use prisma app show to inspect the current app state.",
|
|
898
|
+
fix: "Run prisma-cli app deploy first, or use prisma-cli app show to inspect the current app state.",
|
|
759
899
|
exitCode: 1,
|
|
760
|
-
nextSteps: ["prisma app deploy", "prisma app show"]
|
|
900
|
+
nextSteps: ["prisma-cli app deploy", "prisma-cli app show"]
|
|
761
901
|
});
|
|
762
902
|
}
|
|
763
903
|
function buildFailedError(summary, error) {
|
|
@@ -766,10 +906,10 @@ function buildFailedError(summary, error) {
|
|
|
766
906
|
domain: "app",
|
|
767
907
|
summary,
|
|
768
908
|
why: error instanceof Error ? error.message : String(error),
|
|
769
|
-
fix: "Inspect the framework output, fix the build issue, and rerun prisma app build.",
|
|
909
|
+
fix: "Inspect the framework output, fix the build issue, and rerun prisma-cli app build.",
|
|
770
910
|
debug: formatDebugDetails(error),
|
|
771
911
|
exitCode: 1,
|
|
772
|
-
nextSteps: ["prisma app build", "prisma app deploy"]
|
|
912
|
+
nextSteps: ["prisma-cli app build", "prisma-cli app deploy"]
|
|
773
913
|
});
|
|
774
914
|
}
|
|
775
915
|
function runFailedError(summary, error, exitCode = 1) {
|
|
@@ -778,9 +918,9 @@ function runFailedError(summary, error, exitCode = 1) {
|
|
|
778
918
|
domain: "app",
|
|
779
919
|
summary,
|
|
780
920
|
why: error instanceof Error ? error.message : String(error),
|
|
781
|
-
fix: "Inspect the framework output above, fix the issue, and rerun prisma app run.",
|
|
921
|
+
fix: "Inspect the framework output above, fix the issue, and rerun prisma-cli app run.",
|
|
782
922
|
exitCode,
|
|
783
|
-
nextSteps: ["prisma app run"]
|
|
923
|
+
nextSteps: ["prisma-cli app run"]
|
|
784
924
|
});
|
|
785
925
|
}
|
|
786
926
|
function formatFrameworkName(framework) {
|
|
@@ -830,5 +970,21 @@ function sortApps(apps) {
|
|
|
830
970
|
function toOptionalEnvVars(envVars) {
|
|
831
971
|
return Object.keys(envVars).length > 0 ? envVars : void 0;
|
|
832
972
|
}
|
|
973
|
+
/**
|
|
974
|
+
* Emits a deprecation banner to stderr when the legacy single-shot
|
|
975
|
+
* env-var commands are invoked. The banner is suppressed in --json
|
|
976
|
+
* mode so machine consumers keep their JSON channel clean; --json
|
|
977
|
+
* users discover the deprecation via release notes and the new
|
|
978
|
+
* `prisma-cli project env` namespace's output anyway.
|
|
979
|
+
*
|
|
980
|
+
* Removal of these legacy commands is deliberately scoped out of the
|
|
981
|
+
* Public Beta — see the Compute Beta plan, sub-track 3B.1, where the
|
|
982
|
+
* Terminal team picks an explicit removal milestone.
|
|
983
|
+
*/
|
|
984
|
+
function emitLegacyEnvDeprecationWarning(context, legacyCommand, replacement) {
|
|
985
|
+
if (context.flags.json) return;
|
|
986
|
+
const message = `[deprecation] \`prisma-cli ${legacyCommand}\` is deprecated. Use \`prisma-cli ${replacement}\` instead.`;
|
|
987
|
+
context.runtime.stderr.write(`${message}\n`);
|
|
988
|
+
}
|
|
833
989
|
//#endregion
|
|
834
990
|
export { runAppBuild, runAppDeploy, runAppListDeploys, runAppListEnv, runAppLogs, runAppOpen, runAppPromote, runAppRemove, runAppRollback, runAppRun, runAppShow, runAppShowDeploy, runAppUpdateEnv };
|