@prisma/cli 3.0.0-dev.102.1 → 3.0.0-dev.104.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -66,7 +66,7 @@ function createRunCommand(runtime) {
|
|
|
66
66
|
}
|
|
67
67
|
function createDeployCommand(runtime) {
|
|
68
68
|
const command = attachCommandDescriptor(configureRuntimeCommand(new Command("deploy"), runtime), "app.deploy");
|
|
69
|
-
command.argument("[app]", "App target from prisma.compute.ts when the config defines multiple apps").addOption(new Option("--app <name>", "App name")).addOption(new Option("--project <id-or-name>", "Project id or name")).addOption(new Option("--create-project <name>", "Create and link a new Project before deploying")).addOption(new Option("--branch <name>", "Branch name")).addOption(new Option("--framework <name>", "Framework to deploy").choices([...FRAMEWORK_KEYS])).addOption(new Option("--entry <path>", "Entrypoint path for Bun deploys")).addOption(new Option("--http-port <port>", "HTTP port override for the deployed app")).addOption(new Option("--env <name=value|file>", "Environment variable assignment or dotenv file").argParser(collectRepeatableValues)).addOption(new Option("--db", "Create and wire a Prisma Postgres database for this deploy target")).addOption(new Option("--no-db", "Skip database setup")).addOption(new Option("--prod", "Confirm intent to deploy to production"));
|
|
69
|
+
command.argument("[app]", "App target from prisma.compute.ts when the config defines multiple apps").addOption(new Option("--app <name>", "App name")).addOption(new Option("--project <id-or-name>", "Project id or name")).addOption(new Option("--create-project <name>", "Create and link a new Project before deploying")).addOption(new Option("--branch <name>", "Branch name")).addOption(new Option("--framework <name>", "Framework to deploy").choices([...FRAMEWORK_KEYS])).addOption(new Option("--entry <path>", "Entrypoint path for Bun deploys")).addOption(new Option("--http-port <port>", "HTTP port override for the deployed app")).addOption(new Option("--region <region>", "Region for a newly created app; existing apps keep their region")).addOption(new Option("--env <name=value|file>", "Environment variable assignment or dotenv file").argParser(collectRepeatableValues)).addOption(new Option("--db", "Create and wire a Prisma Postgres database for this deploy target")).addOption(new Option("--no-db", "Skip database setup")).addOption(new Option("--prod", "Confirm intent to deploy to production"));
|
|
70
70
|
addGlobalFlags(command);
|
|
71
71
|
command.action(async (configTarget, options) => {
|
|
72
72
|
const appName = options.app;
|
|
@@ -74,6 +74,7 @@ function createDeployCommand(runtime) {
|
|
|
74
74
|
const branchName = options.branch;
|
|
75
75
|
const framework = options.framework;
|
|
76
76
|
const httpPort = options.httpPort;
|
|
77
|
+
const region = options.region;
|
|
77
78
|
const envAssignments = options.env;
|
|
78
79
|
const projectRef = options.project;
|
|
79
80
|
const createProjectName = options.createProject;
|
|
@@ -89,6 +90,7 @@ function createDeployCommand(runtime) {
|
|
|
89
90
|
entrypoint: entry,
|
|
90
91
|
framework,
|
|
91
92
|
httpPort,
|
|
93
|
+
region,
|
|
92
94
|
envAssignments,
|
|
93
95
|
prod: prod === true,
|
|
94
96
|
db,
|
package/dist/controllers/app.js
CHANGED
|
@@ -2,7 +2,7 @@ import { SERVICE_TOKEN_ENV_VAR, getApiBaseUrl } from "../lib/auth/client.js";
|
|
|
2
2
|
import { FileTokenStorage } from "../adapters/token-storage.js";
|
|
3
3
|
import { CliError, authRequiredError, featureUnavailableError, usageError, workspaceRequiredError } from "../shell/errors.js";
|
|
4
4
|
import { confirmPrompt, selectPrompt, textPrompt } from "../shell/prompt.js";
|
|
5
|
-
import
|
|
5
|
+
import "../lib/app/app-interaction.js";
|
|
6
6
|
import { PRISMA_APP_CONFIG_FILENAME, detectLegacyBuildSettings, resolveConfiguredAppBuildSettings, resolveInferredAppBuildSettings } from "../lib/app/build-settings.js";
|
|
7
7
|
import { APP_BUILD_TYPES, APP_BUILD_TYPE_LABELS, RESOLVED_APP_BUILD_TYPES, executeAppBuild } from "../lib/app/build.js";
|
|
8
8
|
import { envVarNames, parseEnvInputs } from "../lib/app/env-vars.js";
|
|
@@ -31,7 +31,7 @@ import { writeJsonEvent } from "../shell/output.js";
|
|
|
31
31
|
import { createSelectPromptPort } from "./select-prompt-port.js";
|
|
32
32
|
import { requireAuthenticatedAuthState } from "./auth.js";
|
|
33
33
|
import { listRealWorkspaceProjects } from "./project.js";
|
|
34
|
-
import { ENTRYPOINT_BUILD_TYPES, FRAMEWORKS, LOCAL_DEV_BUILD_TYPES, frameworkByKey, frameworkFromAlias, isConfigBackedBuildType } from "@prisma/compute-sdk/config";
|
|
34
|
+
import { COMPUTE_REGIONS, ENTRYPOINT_BUILD_TYPES, FRAMEWORKS, LOCAL_DEV_BUILD_TYPES, frameworkByKey, frameworkFromAlias, isConfigBackedBuildType } from "@prisma/compute-sdk/config";
|
|
35
35
|
import { access, readFile } from "node:fs/promises";
|
|
36
36
|
import path from "node:path";
|
|
37
37
|
import { Result, matchError } from "better-result";
|
|
@@ -40,6 +40,7 @@ import open from "open";
|
|
|
40
40
|
const FRAMEWORK_DEFAULT_HTTP_PORT = 3e3;
|
|
41
41
|
const PRISMA_PROJECT_ID_ENV_VAR = "PRISMA_PROJECT_ID";
|
|
42
42
|
const PRISMA_APP_ID_ENV_VAR = "PRISMA_APP_ID";
|
|
43
|
+
const COMPUTE_REGION_IDS = new Set(COMPUTE_REGIONS);
|
|
43
44
|
function isRealMode(context) {
|
|
44
45
|
return !context.runtime.fixturePath && !context.runtime.env.PRISMA_CLI_MOCK_FIXTURE_PATH;
|
|
45
46
|
}
|
|
@@ -154,7 +155,7 @@ async function runAppDeploy(context, appName, options) {
|
|
|
154
155
|
return runSingleAppDeploy(context, appName, options, config);
|
|
155
156
|
}
|
|
156
157
|
async function runAppDeployAll(context, config, plannedTargets, appName, options) {
|
|
157
|
-
assertNoPerAppInputsForDeployAll(context,
|
|
158
|
+
assertNoPerAppInputsForDeployAll(context, plannedTargets, appName, options);
|
|
158
159
|
const deployments = [];
|
|
159
160
|
const warnings = [];
|
|
160
161
|
for (const planned of plannedTargets) {
|
|
@@ -172,7 +173,7 @@ async function runAppDeployAll(context, config, plannedTargets, appName, options
|
|
|
172
173
|
});
|
|
173
174
|
warnings.push(...single.warnings);
|
|
174
175
|
} catch (error) {
|
|
175
|
-
throw deployAllFailedError(error,
|
|
176
|
+
throw deployAllFailedError(error, plannedTargets, planned.index, deployments);
|
|
176
177
|
}
|
|
177
178
|
}
|
|
178
179
|
return {
|
|
@@ -182,12 +183,13 @@ async function runAppDeployAll(context, config, plannedTargets, appName, options
|
|
|
182
183
|
nextSteps: ["prisma-cli app list-deploys <app>"]
|
|
183
184
|
};
|
|
184
185
|
}
|
|
185
|
-
function assertNoPerAppInputsForDeployAll(context,
|
|
186
|
+
function assertNoPerAppInputsForDeployAll(context, plannedTargets, appName, options) {
|
|
186
187
|
const used = perAppInputsForDeployAll({
|
|
187
188
|
appName,
|
|
188
189
|
framework: options?.framework,
|
|
189
190
|
entrypoint: options?.entrypoint,
|
|
190
191
|
httpPort: options?.httpPort,
|
|
192
|
+
region: options?.region,
|
|
191
193
|
envAssignments: options?.envAssignments,
|
|
192
194
|
appIdEnvVar: {
|
|
193
195
|
name: PRISMA_APP_ID_ENV_VAR,
|
|
@@ -195,17 +197,17 @@ function assertNoPerAppInputsForDeployAll(context, config, appName, options) {
|
|
|
195
197
|
}
|
|
196
198
|
});
|
|
197
199
|
if (used.length === 0) return;
|
|
198
|
-
const
|
|
199
|
-
throw usageError(`Deploying all apps does not accept ${used.join(", ")}`, `Without a target, app deploy deploys every configured app (${
|
|
200
|
+
const targetKeys = plannedTargets.map((target) => target.targetKey);
|
|
201
|
+
throw usageError(`Deploying all apps does not accept ${used.join(", ")}`, `Without a target, app deploy deploys every configured app (${targetKeys.join(", ")}), so per-app inputs are ambiguous.`, "Pass the app target to apply per-app inputs to one app, or remove them to deploy all apps.", targetKeys.map((target) => `prisma-cli app deploy ${target}`), "app");
|
|
200
202
|
}
|
|
201
203
|
function maybeRenderDeployAllTargetHeader(context, planned) {
|
|
202
204
|
if (context.flags.json || context.flags.quiet) return;
|
|
203
205
|
context.output.stderr.write(`${planned.index > 0 ? "\n" : ""}── ${planned.targetKey} (${planned.index + 1}/${planned.total}) ──\n\n`);
|
|
204
206
|
}
|
|
205
|
-
function deployAllFailedError(error,
|
|
207
|
+
function deployAllFailedError(error, plannedTargets, failedIndex, deployments) {
|
|
206
208
|
if (!(error instanceof CliError)) return error;
|
|
207
209
|
const failure = describeDeployAllFailure({
|
|
208
|
-
targetKeys:
|
|
210
|
+
targetKeys: plannedTargets.map((target) => target.targetKey),
|
|
209
211
|
failedIndex,
|
|
210
212
|
completed: deployments.map(({ target, result }) => ({
|
|
211
213
|
target,
|
|
@@ -255,6 +257,7 @@ async function runSingleAppDeploy(context, appName, options, preloadedConfig) {
|
|
|
255
257
|
framework: options?.framework,
|
|
256
258
|
entrypoint: options?.entrypoint,
|
|
257
259
|
httpPort: options?.httpPort,
|
|
260
|
+
region: options?.region,
|
|
258
261
|
envInputs: options?.envAssignments
|
|
259
262
|
},
|
|
260
263
|
target: computeConfig.target,
|
|
@@ -267,6 +270,7 @@ async function runSingleAppDeploy(context, appName, options, preloadedConfig) {
|
|
|
267
270
|
const localPin = localPinReadResult.value;
|
|
268
271
|
const branch = await resolveDeployBranch(context, options?.branchName);
|
|
269
272
|
if (merged.httpPort) parseDeployHttpPort(merged.httpPort.value);
|
|
273
|
+
const deployRegion = normalizeDeployRegionInput(merged.region);
|
|
270
274
|
assertSupportedEntrypointForRequestedDeployShape({
|
|
271
275
|
requestedFramework: merged.framework?.value,
|
|
272
276
|
entrypoint: merged.entrypoint?.value
|
|
@@ -299,6 +303,7 @@ async function runSingleAppDeploy(context, appName, options, preloadedConfig) {
|
|
|
299
303
|
explicitAppName: appName,
|
|
300
304
|
explicitAppId: envAppId,
|
|
301
305
|
configAppName: merged.configAppName,
|
|
306
|
+
configRegion: deployRegion,
|
|
302
307
|
firstDeploy: Boolean(target.localPinAction),
|
|
303
308
|
inferName: () => inferTargetName(appDir, context.runtime.signal)
|
|
304
309
|
});
|
|
@@ -328,15 +333,9 @@ async function runSingleAppDeploy(context, appName, options, preloadedConfig) {
|
|
|
328
333
|
const buildType = framework.buildType;
|
|
329
334
|
assertSupportedEntrypoint(buildType, merged.entrypoint?.value, "deploy");
|
|
330
335
|
const entrypoint = await resolveDeployEntrypoint(appDir, framework, merged.entrypoint?.value, context.runtime.signal);
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
buildType,
|
|
335
|
-
configured: computeConfig.target.build,
|
|
336
|
-
configPath: computeConfig.config.configPath,
|
|
337
|
-
signal: context.runtime.signal
|
|
338
|
-
}) : await resolveInferredAppBuildSettings({
|
|
339
|
-
appPath: appDir,
|
|
336
|
+
const buildSettingsResolution = await resolveDeployBuildSettings({
|
|
337
|
+
computeConfig,
|
|
338
|
+
appDir,
|
|
340
339
|
buildType,
|
|
341
340
|
signal: context.runtime.signal
|
|
342
341
|
});
|
|
@@ -409,7 +408,7 @@ async function runSingleAppDeploy(context, appName, options, preloadedConfig) {
|
|
|
409
408
|
},
|
|
410
409
|
entrypoint: entrypoint ?? buildSettingsResolution.settings.entrypoint ?? null,
|
|
411
410
|
httpPort: runtime.port,
|
|
412
|
-
region: selectedApp.region ?? null,
|
|
411
|
+
region: deployResult.app.region ?? selectedApp.region ?? null,
|
|
413
412
|
envVars: envVarNames(envVars)
|
|
414
413
|
},
|
|
415
414
|
durationMs: deployDurationMs,
|
|
@@ -419,6 +418,22 @@ async function runSingleAppDeploy(context, appName, options, preloadedConfig) {
|
|
|
419
418
|
nextSteps: ["prisma-cli app list-deploys", `prisma-cli app show-deploy ${deployResult.deployment.id}`]
|
|
420
419
|
};
|
|
421
420
|
}
|
|
421
|
+
async function resolveDeployBuildSettings(options) {
|
|
422
|
+
const { computeConfig, appDir, buildType, signal } = options;
|
|
423
|
+
if (computeConfig.target?.build) assertConfigBackedBuildSettings(buildType);
|
|
424
|
+
if (computeConfig.config && computeConfig.target?.build && isConfigBackedBuildType(buildType)) return resolveConfiguredAppBuildSettings({
|
|
425
|
+
appPath: appDir,
|
|
426
|
+
buildType,
|
|
427
|
+
configured: computeConfig.target.build,
|
|
428
|
+
configPath: computeConfig.config.configPath,
|
|
429
|
+
signal
|
|
430
|
+
});
|
|
431
|
+
return resolveInferredAppBuildSettings({
|
|
432
|
+
appPath: appDir,
|
|
433
|
+
buildType,
|
|
434
|
+
signal
|
|
435
|
+
});
|
|
436
|
+
}
|
|
422
437
|
async function runAppListDeploys(context, appName, projectRef, configTarget) {
|
|
423
438
|
ensurePreviewAppMode(context);
|
|
424
439
|
const compute = await resolveComputeManagementContext(context, configTarget, "list-deploys");
|
|
@@ -1276,27 +1291,19 @@ async function sleep(milliseconds, signal) {
|
|
|
1276
1291
|
});
|
|
1277
1292
|
}
|
|
1278
1293
|
async function resolveDeployAppSelection(context, projectId, apps, options) {
|
|
1279
|
-
|
|
1280
|
-
|
|
1281
|
-
|
|
1282
|
-
|
|
1283
|
-
|
|
1284
|
-
|
|
1285
|
-
|
|
1286
|
-
|
|
1287
|
-
|
|
1288
|
-
};
|
|
1289
|
-
return {
|
|
1290
|
-
appName: options.explicitAppName,
|
|
1291
|
-
region: DEFAULT_REGION,
|
|
1292
|
-
displayName: options.explicitAppName,
|
|
1293
|
-
annotation: "set by --app",
|
|
1294
|
-
firstDeploy: options.firstDeploy
|
|
1295
|
-
};
|
|
1296
|
-
}
|
|
1294
|
+
const newAppRegion = deployNewAppRegion(options.configRegion);
|
|
1295
|
+
if (options.explicitAppName) return resolveDeployAppByName(context, apps, {
|
|
1296
|
+
name: options.explicitAppName,
|
|
1297
|
+
matchedAnnotation: "set by --app",
|
|
1298
|
+
newAnnotation: "set by --app",
|
|
1299
|
+
requestedRegion: options.configRegion,
|
|
1300
|
+
newAppRegion,
|
|
1301
|
+
firstDeploy: options.firstDeploy
|
|
1302
|
+
});
|
|
1297
1303
|
if (options.explicitAppId) {
|
|
1298
1304
|
const matched = apps.find((app) => app.id === options.explicitAppId);
|
|
1299
1305
|
if (!matched) throw usageError("Selected app does not exist in the resolved project", `The app "${options.explicitAppId}" from ${PRISMA_APP_ID_ENV_VAR} could not be found in resolved project "${projectId}".`, `Unset ${PRISMA_APP_ID_ENV_VAR}, pass --app <name>, or choose an app from prisma-cli app list-deploys.`, ["prisma-cli app list-deploys"], "app");
|
|
1306
|
+
assertDeployRegionMatchesExistingApp(matched, options.configRegion);
|
|
1300
1307
|
return {
|
|
1301
1308
|
appId: matched.id,
|
|
1302
1309
|
displayName: matched.name,
|
|
@@ -1306,42 +1313,52 @@ async function resolveDeployAppSelection(context, projectId, apps, options) {
|
|
|
1306
1313
|
}
|
|
1307
1314
|
if (options.configAppName) {
|
|
1308
1315
|
const configName = options.configAppName;
|
|
1309
|
-
|
|
1310
|
-
|
|
1311
|
-
|
|
1312
|
-
|
|
1313
|
-
|
|
1314
|
-
|
|
1315
|
-
annotation: configName.annotation,
|
|
1316
|
+
return resolveDeployAppByName(context, apps, {
|
|
1317
|
+
name: configName.value,
|
|
1318
|
+
matchedAnnotation: configName.annotation,
|
|
1319
|
+
newAnnotation: configName.annotation,
|
|
1320
|
+
requestedRegion: options.configRegion,
|
|
1321
|
+
newAppRegion,
|
|
1316
1322
|
firstDeploy: options.firstDeploy
|
|
1317
|
-
};
|
|
1323
|
+
});
|
|
1324
|
+
}
|
|
1325
|
+
const inferredName = await options.inferName();
|
|
1326
|
+
const newAnnotation = inferredName.source === "package-name" ? "created from package.json" : "created from directory name";
|
|
1327
|
+
return resolveDeployAppByName(context, apps, {
|
|
1328
|
+
name: inferredName.name,
|
|
1329
|
+
matchedAnnotation: "existing app on this branch",
|
|
1330
|
+
newAnnotation,
|
|
1331
|
+
requestedRegion: options.configRegion,
|
|
1332
|
+
newAppRegion,
|
|
1333
|
+
firstDeploy: options.firstDeploy
|
|
1334
|
+
});
|
|
1335
|
+
}
|
|
1336
|
+
async function resolveDeployAppByName(context, apps, options) {
|
|
1337
|
+
const matches = findAppsByName(apps, options.name);
|
|
1338
|
+
if (matches.length > 1) return resolveAmbiguousDeployApp(context, matches, options.name, options.requestedRegion, options.newAppRegion, options.firstDeploy);
|
|
1339
|
+
const matched = matches[0];
|
|
1340
|
+
if (matched) {
|
|
1341
|
+
assertDeployRegionMatchesExistingApp(matched, options.requestedRegion);
|
|
1318
1342
|
return {
|
|
1319
|
-
|
|
1320
|
-
|
|
1321
|
-
|
|
1322
|
-
annotation: configName.annotation,
|
|
1343
|
+
appId: matched.id,
|
|
1344
|
+
displayName: matched.name,
|
|
1345
|
+
annotation: options.matchedAnnotation,
|
|
1323
1346
|
firstDeploy: options.firstDeploy
|
|
1324
1347
|
};
|
|
1325
1348
|
}
|
|
1326
|
-
const inferredName = await options.inferName();
|
|
1327
|
-
const matches = findAppsByName(apps, inferredName.name);
|
|
1328
|
-
if (matches.length > 1) return resolveAmbiguousDeployApp(context, matches, inferredName.name, options.firstDeploy);
|
|
1329
|
-
const matched = matches[0];
|
|
1330
|
-
if (matched) return {
|
|
1331
|
-
appId: matched.id,
|
|
1332
|
-
displayName: matched.name,
|
|
1333
|
-
annotation: "existing app on this branch",
|
|
1334
|
-
firstDeploy: options.firstDeploy
|
|
1335
|
-
};
|
|
1336
1349
|
return {
|
|
1337
|
-
appName:
|
|
1338
|
-
region:
|
|
1339
|
-
displayName:
|
|
1340
|
-
annotation:
|
|
1350
|
+
appName: options.name,
|
|
1351
|
+
region: options.newAppRegion,
|
|
1352
|
+
displayName: options.name,
|
|
1353
|
+
annotation: options.newAnnotation,
|
|
1341
1354
|
firstDeploy: options.firstDeploy
|
|
1342
1355
|
};
|
|
1343
1356
|
}
|
|
1344
|
-
|
|
1357
|
+
function assertDeployRegionMatchesExistingApp(app, requestedRegion) {
|
|
1358
|
+
if (requestedRegion?.annotation !== "set by --region" || !app.region || app.region === requestedRegion.value) return;
|
|
1359
|
+
throw usageError("App already exists in another region", `The selected app "${app.name}" is in region "${app.region}", but --region requested "${requestedRegion.value}".`, "Remove --region to deploy the existing app, or pass --app <new-name> to create a new app in that region.", [`prisma-cli app deploy --app ${formatCommandArgument(app.name)}`, `prisma-cli app deploy --app <new-name> --region ${formatCommandArgument(requestedRegion.value)}`], "app");
|
|
1360
|
+
}
|
|
1361
|
+
async function resolveAmbiguousDeployApp(context, matches, targetName, requestedRegion, newAppRegion, firstDeploy) {
|
|
1345
1362
|
if (canPrompt(context)) {
|
|
1346
1363
|
const createNew = "__create_new_app__";
|
|
1347
1364
|
const cancel = "__cancel__";
|
|
@@ -1367,11 +1384,12 @@ async function resolveAmbiguousDeployApp(context, matches, targetName, firstDepl
|
|
|
1367
1384
|
if (selected === cancel) throw usageError("App selection canceled", "The command was canceled before an app was selected.", "Re-run the command and choose an app, or pass --app <name>.", ["prisma-cli app deploy --app <name>"], "app");
|
|
1368
1385
|
if (selected === createNew) return {
|
|
1369
1386
|
appName: targetName,
|
|
1370
|
-
region:
|
|
1387
|
+
region: newAppRegion,
|
|
1371
1388
|
displayName: targetName,
|
|
1372
1389
|
annotation: "created from package.json",
|
|
1373
1390
|
firstDeploy
|
|
1374
1391
|
};
|
|
1392
|
+
assertDeployRegionMatchesExistingApp(selected, requestedRegion);
|
|
1375
1393
|
return {
|
|
1376
1394
|
appId: selected.id,
|
|
1377
1395
|
displayName: selected.name,
|
|
@@ -1393,6 +1411,9 @@ async function resolveAmbiguousDeployApp(context, matches, targetName, firstDepl
|
|
|
1393
1411
|
nextSteps: ["prisma-cli app deploy --app <name>"]
|
|
1394
1412
|
});
|
|
1395
1413
|
}
|
|
1414
|
+
function deployNewAppRegion(configRegion) {
|
|
1415
|
+
return configRegion?.value ?? "eu-central-1";
|
|
1416
|
+
}
|
|
1396
1417
|
async function resolveExistingAppSelection(context, projectId, apps, explicitAppName) {
|
|
1397
1418
|
if (explicitAppName) {
|
|
1398
1419
|
const matched = findAppByName(apps, explicitAppName);
|
|
@@ -2198,6 +2219,19 @@ function parseDeployHttpPort(requestedPort) {
|
|
|
2198
2219
|
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");
|
|
2199
2220
|
return port;
|
|
2200
2221
|
}
|
|
2222
|
+
function parseDeployRegion(requestedRegion, source) {
|
|
2223
|
+
const region = requestedRegion.trim();
|
|
2224
|
+
if (region.length === 0) throw usageError("Invalid app region", `The app region ${source} must be a non-empty region id.`, "Pass a Prisma Compute region id.", ["prisma-cli app deploy --region eu-central-1"], "app");
|
|
2225
|
+
if (!COMPUTE_REGION_IDS.has(region)) throw usageError("Invalid app region", `The app region ${source} must be one of: ${COMPUTE_REGIONS.join(", ")}.`, "Pass a supported Prisma Compute region id.", ["prisma-cli app deploy --region eu-central-1"], "app");
|
|
2226
|
+
return region;
|
|
2227
|
+
}
|
|
2228
|
+
function normalizeDeployRegionInput(region) {
|
|
2229
|
+
if (!region) return;
|
|
2230
|
+
return {
|
|
2231
|
+
...region,
|
|
2232
|
+
value: parseDeployRegion(region.value, region.annotation)
|
|
2233
|
+
};
|
|
2234
|
+
}
|
|
2201
2235
|
function ensurePreviewAppMode(context) {
|
|
2202
2236
|
if (isRealMode(context)) return;
|
|
2203
2237
|
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 show"], "app");
|
|
@@ -18,47 +18,45 @@ function computeFrameworkToBuildType(framework) {
|
|
|
18
18
|
function mergeComputeDeployInputs(options) {
|
|
19
19
|
const { cli, target, configFilename } = options;
|
|
20
20
|
const configAnnotation = `set by ${configFilename}`;
|
|
21
|
-
const framework = cli.framework
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
value: target.framework,
|
|
26
|
-
annotation: configAnnotation
|
|
27
|
-
} : void 0;
|
|
28
|
-
const entrypoint = cli.entrypoint ? {
|
|
29
|
-
value: cli.entrypoint,
|
|
30
|
-
annotation: "set by --entry"
|
|
31
|
-
} : target?.entry ? {
|
|
32
|
-
value: target.entry,
|
|
33
|
-
annotation: configAnnotation
|
|
34
|
-
} : void 0;
|
|
35
|
-
const httpPort = cli.httpPort ? {
|
|
36
|
-
value: cli.httpPort,
|
|
37
|
-
annotation: "set by --http-port"
|
|
38
|
-
} : target?.httpPort ? {
|
|
39
|
-
value: String(target.httpPort),
|
|
40
|
-
annotation: configAnnotation
|
|
41
|
-
} : void 0;
|
|
21
|
+
const framework = mergeStringInput(cli.framework, "set by --framework", target?.framework ?? void 0, configAnnotation);
|
|
22
|
+
const entrypoint = mergeStringInput(cli.entrypoint, "set by --entry", target?.entry ?? void 0, configAnnotation);
|
|
23
|
+
const httpPort = mergeStringInput(cli.httpPort, "set by --http-port", target?.httpPort ? String(target.httpPort) : void 0, configAnnotation);
|
|
24
|
+
const region = mergeStringInput(cli.region, "set by --region", target?.region ?? void 0, configAnnotation);
|
|
42
25
|
const cliEnvInputs = cli.envInputs && cli.envInputs.length > 0 ? cli.envInputs : void 0;
|
|
43
26
|
const configEnvInputs = target && target.envInputs.length > 0 ? target.envInputs : void 0;
|
|
44
27
|
const envInputs = cliEnvInputs ?? configEnvInputs;
|
|
45
|
-
const configAppName = target
|
|
46
|
-
value: target.name,
|
|
47
|
-
annotation: configAnnotation
|
|
48
|
-
} : target?.key ? {
|
|
49
|
-
value: target.key,
|
|
50
|
-
annotation: configAnnotation
|
|
51
|
-
} : void 0;
|
|
28
|
+
const configAppName = readConfigAppName(target, configAnnotation);
|
|
52
29
|
return {
|
|
53
30
|
framework,
|
|
54
31
|
entrypoint,
|
|
55
32
|
httpPort,
|
|
33
|
+
region,
|
|
56
34
|
envInputs,
|
|
57
35
|
envInputsFromConfig: !cliEnvInputs && configEnvInputs !== void 0,
|
|
58
36
|
configAppName,
|
|
59
37
|
appRoot: target?.root ?? void 0
|
|
60
38
|
};
|
|
61
39
|
}
|
|
40
|
+
function mergeStringInput(cliValue, cliAnnotation, configValue, configAnnotation) {
|
|
41
|
+
if (cliValue !== void 0) return {
|
|
42
|
+
value: cliValue,
|
|
43
|
+
annotation: cliAnnotation
|
|
44
|
+
};
|
|
45
|
+
if (configValue) return {
|
|
46
|
+
value: configValue,
|
|
47
|
+
annotation: configAnnotation
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
function readConfigAppName(target, configAnnotation) {
|
|
51
|
+
if (target?.name) return {
|
|
52
|
+
value: target.name,
|
|
53
|
+
annotation: configAnnotation
|
|
54
|
+
};
|
|
55
|
+
if (target?.key) return {
|
|
56
|
+
value: target.key,
|
|
57
|
+
annotation: configAnnotation
|
|
58
|
+
};
|
|
59
|
+
}
|
|
62
60
|
/**
|
|
63
61
|
* Merges CLI inputs for the local `app build` and `app run` commands with a
|
|
64
62
|
* selected config target. Explicit flags win; `--build-type auto` is the
|
|
@@ -30,6 +30,7 @@ function perAppInputsForDeployAll(inputs) {
|
|
|
30
30
|
["--framework", inputs.framework],
|
|
31
31
|
["--entry", inputs.entrypoint],
|
|
32
32
|
["--http-port", inputs.httpPort],
|
|
33
|
+
["--region", inputs.region],
|
|
33
34
|
["--env", inputs.envAssignments?.length ? inputs.envAssignments : void 0],
|
|
34
35
|
[inputs.appIdEnvVar.name, inputs.appIdEnvVar.value]
|
|
35
36
|
].filter(([, value]) => value !== void 0).map(([flag]) => flag);
|
|
@@ -350,6 +350,7 @@ const DESCRIPTORS = [
|
|
|
350
350
|
"prisma-cli app deploy --db",
|
|
351
351
|
"prisma-cli app deploy --db --yes",
|
|
352
352
|
"prisma-cli app deploy --app my-app --framework nextjs --http-port 3000",
|
|
353
|
+
"prisma-cli app deploy --app my-app --region us-west-1",
|
|
353
354
|
"prisma-cli app deploy --branch feat-login --framework hono",
|
|
354
355
|
"prisma-cli app deploy --prod --yes",
|
|
355
356
|
"prisma-cli app deploy --framework bun --entry src/server.ts"
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@prisma/cli",
|
|
3
|
-
"version": "3.0.0-dev.
|
|
3
|
+
"version": "3.0.0-dev.104.1",
|
|
4
4
|
"description": "Command-line interface for the Prisma Developer Platform.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -44,7 +44,7 @@
|
|
|
44
44
|
},
|
|
45
45
|
"dependencies": {
|
|
46
46
|
"@clack/prompts": "^1.5.0",
|
|
47
|
-
"@prisma/compute-sdk": "0.
|
|
47
|
+
"@prisma/compute-sdk": "0.31.0",
|
|
48
48
|
"@prisma/credentials-store": "^7.8.0",
|
|
49
49
|
"@prisma/management-api-sdk": "^1.44.0",
|
|
50
50
|
"better-result": "^2.9.2",
|