@prisma/cli 3.0.0-dev.88.1 → 3.0.0-dev.90.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.
- package/dist/commands/app/index.js +2 -2
- package/dist/controllers/app-env.js +1 -1
- package/dist/controllers/app.js +25 -24
- package/dist/controllers/project.js +3 -3
- package/dist/lib/app/app-interaction.js +5 -0
- package/dist/lib/app/{preview-provider.js → app-provider.js} +9 -9
- package/dist/lib/app/{preview-branch-database.js → branch-database-api.js} +1 -1
- package/dist/lib/app/build-settings.js +93 -0
- package/dist/lib/app/build.js +80 -0
- package/dist/lib/app/bun-project.js +2 -3
- package/dist/lib/app/{preview-progress.js → deploy-progress.js} +5 -5
- package/package.json +2 -2
- package/dist/lib/app/preview-build-settings.js +0 -376
- package/dist/lib/app/preview-build.js +0 -501
- package/dist/lib/app/preview-interaction.js +0 -5
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { usageError } from "../../shell/errors.js";
|
|
2
|
+
import { APP_BUILD_TYPES } from "../../lib/app/build.js";
|
|
2
3
|
import { attachCommandDescriptor } from "../../shell/command-meta.js";
|
|
3
4
|
import { addCompactGlobalFlags, addGlobalFlags } from "../../shell/global-flags.js";
|
|
4
5
|
import { configureRuntimeCommand } from "../../shell/runtime.js";
|
|
5
|
-
import { PREVIEW_BUILD_TYPES } from "../../lib/app/preview-build.js";
|
|
6
6
|
import { runAppBuild, runAppDeploy, runAppDomainAdd, runAppDomainRemove, runAppDomainRetry, runAppDomainShow, runAppDomainWait, runAppListDeploys, runAppLogs, runAppOpen, runAppPromote, runAppRemove, runAppRollback, runAppRun, runAppShow, runAppShowDeploy } from "../../controllers/app.js";
|
|
7
7
|
import { isAppDeployAllResult, renderAppBuild, renderAppDeploy, renderAppDeployAll, renderAppDomainAdd, renderAppDomainRemove, renderAppDomainRetry, renderAppDomainShow, renderAppListDeploys, renderAppOpen, renderAppPromote, renderAppRemove, renderAppRollback, renderAppRun, renderAppShow, renderAppShowDeploy, serializeAppBuild, serializeAppDeploy, serializeAppDeployAll, serializeAppDomainAdd, serializeAppDomainRemove, serializeAppDomainRetry, serializeAppDomainShow, serializeAppListDeploys, serializeAppOpen, serializeAppPromote, serializeAppRemove, serializeAppRollback, serializeAppRun, serializeAppShow, serializeAppShowDeploy } from "../../presenters/app.js";
|
|
8
8
|
import { runCommand, runStreamingCommand } from "../../shell/command-runner.js";
|
|
@@ -28,7 +28,7 @@ function createAppCommand(runtime) {
|
|
|
28
28
|
}
|
|
29
29
|
function createBuildCommand(runtime) {
|
|
30
30
|
const command = attachCommandDescriptor(configureRuntimeCommand(new Command("build"), runtime), "app.build");
|
|
31
|
-
command.argument("[app]", "App target from prisma.compute.ts when the config defines multiple apps").addOption(new Option("--entry <path>", "Entrypoint path for Bun or auto builds")).addOption(new Option("--build-type <type>", "Local build type").choices([...
|
|
31
|
+
command.argument("[app]", "App target from prisma.compute.ts when the config defines multiple apps").addOption(new Option("--entry <path>", "Entrypoint path for Bun or auto builds")).addOption(new Option("--build-type <type>", "Local build type").choices([...APP_BUILD_TYPES]).default("auto"));
|
|
32
32
|
addGlobalFlags(command);
|
|
33
33
|
command.action(async (configTarget, options) => {
|
|
34
34
|
const entry = options.entry;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { CliError, authRequiredError, usageError, workspaceRequiredError } from "../shell/errors.js";
|
|
2
|
-
import { projectResolutionErrorToCliError, resolveProjectTarget } from "../lib/project/resolution.js";
|
|
3
2
|
import { formatScopeLabel, parseKeyValuePositional, resolveEnvScope } from "../lib/app/env-config.js";
|
|
4
3
|
import { readEnvFileAssignments } from "../lib/app/env-file.js";
|
|
4
|
+
import { projectResolutionErrorToCliError, resolveProjectTarget } from "../lib/project/resolution.js";
|
|
5
5
|
import { requireComputeAuth } from "../lib/auth/guard.js";
|
|
6
6
|
import { readLocalGitBranch } from "../lib/git/local-branch.js";
|
|
7
7
|
import { requireAuthenticatedAuthState } from "./auth.js";
|
package/dist/controllers/app.js
CHANGED
|
@@ -2,6 +2,11 @@ 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 { DEFAULT_REGION } from "../lib/app/app-interaction.js";
|
|
6
|
+
import { PRISMA_APP_CONFIG_FILENAME, detectLegacyBuildSettings, resolveConfiguredAppBuildSettings, resolveInferredAppBuildSettings } from "../lib/app/build-settings.js";
|
|
7
|
+
import { APP_BUILD_TYPES, RESOLVED_APP_BUILD_TYPES, executeAppBuild } from "../lib/app/build.js";
|
|
8
|
+
import { envVarNames, parseEnvInputs } from "../lib/app/env-vars.js";
|
|
9
|
+
import { DomainApiError, createAppProvider } from "../lib/app/app-provider.js";
|
|
5
10
|
import { renderCommandHeader } from "../shell/ui.js";
|
|
6
11
|
import { canPrompt } from "../shell/runtime.js";
|
|
7
12
|
import { LOCAL_RESOLUTION_PIN_RELATIVE_PATH, readLocalResolutionPin } from "../lib/project/local-pin.js";
|
|
@@ -13,14 +18,9 @@ import { readBunPackageEntrypoint, readBunPackageJson } from "../lib/app/bun-pro
|
|
|
13
18
|
import { COMPUTE_CONFIG_FILENAME as COMPUTE_CONFIG_FILENAME$1, ComputeConfigTargetRequiredError, computeConfigErrorToCliError, computeFrameworkToBuildType, computeTargetAppDir, inferComputeTargetFromCwd, loadComputeConfig as loadComputeConfig$1, mergeComputeDeployInputs, mergeComputeLocalInputs, selectComputeDeployTarget } from "../lib/app/compute-config.js";
|
|
14
19
|
import { renderDeployOutputRows, renderDeploySettingsPreview } from "../lib/app/deploy-output.js";
|
|
15
20
|
import { describeDeployAllFailure, perAppInputsForDeployAll, planAppDeploy } from "../lib/app/deploy-plan.js";
|
|
21
|
+
import { createDeployProgress, createDeployProgressState, createPromoteProgress } from "../lib/app/deploy-progress.js";
|
|
16
22
|
import { formatDomainFailureFix } from "../lib/app/domain-guidance.js";
|
|
17
|
-
import { envVarNames, parseEnvInputs } from "../lib/app/env-vars.js";
|
|
18
23
|
import { DEFAULT_LOCAL_DEV_PORT, runLocalApp } from "../lib/app/local-dev.js";
|
|
19
|
-
import { PRISMA_APP_CONFIG_FILENAME, detectLegacyBuildSettings, resolveConfiguredPreviewBuildSettings, resolveInferredPreviewBuildSettings } from "../lib/app/preview-build-settings.js";
|
|
20
|
-
import { PREVIEW_BUILD_TYPES, RESOLVED_PREVIEW_BUILD_TYPES, executePreviewBuild } from "../lib/app/preview-build.js";
|
|
21
|
-
import { PREVIEW_DEFAULT_REGION } from "../lib/app/preview-interaction.js";
|
|
22
|
-
import { createPreviewDeployProgress, createPreviewDeployProgressState, createPreviewPromoteProgress } from "../lib/app/preview-progress.js";
|
|
23
|
-
import { PreviewDomainApiError, createPreviewAppProvider } from "../lib/app/preview-provider.js";
|
|
24
24
|
import { enforceProductionDeployGate } from "../lib/app/production-deploy-gate.js";
|
|
25
25
|
import { requireComputeAuth } from "../lib/auth/guard.js";
|
|
26
26
|
import { readAuthState } from "../lib/auth/auth-ops.js";
|
|
@@ -60,7 +60,7 @@ async function runAppBuild(context, options) {
|
|
|
60
60
|
}
|
|
61
61
|
assertSupportedEntrypoint(buildType, merged.entrypoint, "build");
|
|
62
62
|
if (compute.target?.build && buildType !== "auto") assertConfigBackedBuildSettings(buildType);
|
|
63
|
-
const buildSettings = compute.config && compute.target?.build && isConfigBackedBuildType(buildType) ? (await
|
|
63
|
+
const buildSettings = compute.config && compute.target?.build && isConfigBackedBuildType(buildType) ? (await resolveConfiguredAppBuildSettings({
|
|
64
64
|
appPath: appDir,
|
|
65
65
|
buildType,
|
|
66
66
|
configured: compute.target.build,
|
|
@@ -68,7 +68,7 @@ async function runAppBuild(context, options) {
|
|
|
68
68
|
signal: context.runtime.signal
|
|
69
69
|
})).settings : void 0;
|
|
70
70
|
try {
|
|
71
|
-
const { artifact, buildType: actualBuildType } = await
|
|
71
|
+
const { artifact, buildType: actualBuildType } = await executeAppBuild({
|
|
72
72
|
appPath: appDir,
|
|
73
73
|
entrypoint: merged.entrypoint,
|
|
74
74
|
buildType,
|
|
@@ -86,7 +86,7 @@ async function runAppBuild(context, options) {
|
|
|
86
86
|
nextSteps: ["prisma-cli app deploy"]
|
|
87
87
|
};
|
|
88
88
|
} catch (error) {
|
|
89
|
-
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 ${
|
|
89
|
+
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_APP_BUILD_TYPES.map(formatBuildTypeName).join(", ")}.`, "Pass a supported --build-type value, or pass --entry <path> for a Bun app.", getBuildTypeExamples("build"), "app");
|
|
90
90
|
throw buildFailedError("Local app build failed", error);
|
|
91
91
|
}
|
|
92
92
|
}
|
|
@@ -328,13 +328,13 @@ async function runSingleAppDeploy(context, appName, options, preloadedConfig) {
|
|
|
328
328
|
assertSupportedEntrypoint(buildType, merged.entrypoint?.value, "deploy");
|
|
329
329
|
const entrypoint = await resolveDeployEntrypoint(appDir, framework, merged.entrypoint?.value, context.runtime.signal);
|
|
330
330
|
if (computeConfig.target?.build) assertConfigBackedBuildSettings(buildType);
|
|
331
|
-
const buildSettingsResolution = computeConfig.config && computeConfig.target?.build && isConfigBackedBuildType(buildType) ? await
|
|
331
|
+
const buildSettingsResolution = computeConfig.config && computeConfig.target?.build && isConfigBackedBuildType(buildType) ? await resolveConfiguredAppBuildSettings({
|
|
332
332
|
appPath: appDir,
|
|
333
333
|
buildType,
|
|
334
334
|
configured: computeConfig.target.build,
|
|
335
335
|
configPath: computeConfig.config.configPath,
|
|
336
336
|
signal: context.runtime.signal
|
|
337
|
-
}) : await
|
|
337
|
+
}) : await resolveInferredAppBuildSettings({
|
|
338
338
|
appPath: appDir,
|
|
339
339
|
buildType,
|
|
340
340
|
signal: context.runtime.signal
|
|
@@ -348,7 +348,7 @@ async function runSingleAppDeploy(context, appName, options, preloadedConfig) {
|
|
|
348
348
|
firstProductionDeploy: productionDeployGate.firstProductionDeploy,
|
|
349
349
|
projectDir
|
|
350
350
|
});
|
|
351
|
-
const progressState =
|
|
351
|
+
const progressState = createDeployProgressState();
|
|
352
352
|
const deployStartedAt = Date.now();
|
|
353
353
|
const deployResult = await provider.deployApp({
|
|
354
354
|
cwd: appDir,
|
|
@@ -364,7 +364,7 @@ async function runSingleAppDeploy(context, appName, options, preloadedConfig) {
|
|
|
364
364
|
envVars,
|
|
365
365
|
interaction: void 0,
|
|
366
366
|
signal: context.runtime.signal,
|
|
367
|
-
progress:
|
|
367
|
+
progress: createDeployProgress(context.output.stderr, context.ui, !context.flags.json && !context.flags.quiet, progressState)
|
|
368
368
|
}).catch((error) => {
|
|
369
369
|
throw appDeployFailedError(error, progressState);
|
|
370
370
|
});
|
|
@@ -866,7 +866,7 @@ async function runAppPromote(context, deploymentId, appName, projectRef, configT
|
|
|
866
866
|
appId: selectedApp.id,
|
|
867
867
|
deploymentId: targetDeployment.id,
|
|
868
868
|
signal: context.runtime.signal,
|
|
869
|
-
progress:
|
|
869
|
+
progress: createPromoteProgress(context.output.stderr, !context.flags.json && !context.flags.quiet)
|
|
870
870
|
}).catch((error) => {
|
|
871
871
|
throw deployFailedError("Failed to promote deployment", error, ["prisma-cli app list-deploys"]);
|
|
872
872
|
});
|
|
@@ -914,7 +914,7 @@ async function runAppRollback(context, appName, deploymentId, projectRef, config
|
|
|
914
914
|
appId: selectedApp.id,
|
|
915
915
|
deploymentId: targetDeployment.id,
|
|
916
916
|
signal: context.runtime.signal,
|
|
917
|
-
progress:
|
|
917
|
+
progress: createPromoteProgress(context.output.stderr, !context.flags.json && !context.flags.quiet)
|
|
918
918
|
}).catch((error) => {
|
|
919
919
|
throw deployFailedError("Failed to roll back deployment", error, ["prisma-cli app list-deploys"]);
|
|
920
920
|
});
|
|
@@ -1106,7 +1106,7 @@ async function confirmDomainRemoval(context, target, hostname) {
|
|
|
1106
1106
|
})) throw usageError("Custom domain removal canceled", "The command was canceled before the domain was detached.", "Rerun the command and confirm removal, or pass --yes.", [`prisma-cli app domain remove ${hostname} --app ${target.app.name} --yes`], "app");
|
|
1107
1107
|
}
|
|
1108
1108
|
function domainCommandError(command, error, hostname) {
|
|
1109
|
-
if (error instanceof
|
|
1109
|
+
if (error instanceof DomainApiError) {
|
|
1110
1110
|
if (command === "add" && (error.status === 400 || error.status === 422) && isDomainDnsError(error)) return domainDnsNotConfiguredError(hostname, error);
|
|
1111
1111
|
if (command === "add" && error.status === 400) return new CliError({
|
|
1112
1112
|
code: "DOMAIN_HOSTNAME_INVALID",
|
|
@@ -1287,7 +1287,7 @@ async function resolveDeployAppSelection(context, projectId, apps, options) {
|
|
|
1287
1287
|
};
|
|
1288
1288
|
return {
|
|
1289
1289
|
appName: options.explicitAppName,
|
|
1290
|
-
region:
|
|
1290
|
+
region: DEFAULT_REGION,
|
|
1291
1291
|
displayName: options.explicitAppName,
|
|
1292
1292
|
annotation: "set by --app",
|
|
1293
1293
|
firstDeploy: options.firstDeploy
|
|
@@ -1316,7 +1316,7 @@ async function resolveDeployAppSelection(context, projectId, apps, options) {
|
|
|
1316
1316
|
};
|
|
1317
1317
|
return {
|
|
1318
1318
|
appName: configName.value,
|
|
1319
|
-
region:
|
|
1319
|
+
region: DEFAULT_REGION,
|
|
1320
1320
|
displayName: configName.value,
|
|
1321
1321
|
annotation: configName.annotation,
|
|
1322
1322
|
firstDeploy: options.firstDeploy
|
|
@@ -1334,7 +1334,7 @@ async function resolveDeployAppSelection(context, projectId, apps, options) {
|
|
|
1334
1334
|
};
|
|
1335
1335
|
return {
|
|
1336
1336
|
appName: inferredName.name,
|
|
1337
|
-
region:
|
|
1337
|
+
region: DEFAULT_REGION,
|
|
1338
1338
|
displayName: inferredName.name,
|
|
1339
1339
|
annotation: inferredName.source === "package-name" ? "created from package.json" : "created from directory name",
|
|
1340
1340
|
firstDeploy: options.firstDeploy
|
|
@@ -1366,7 +1366,7 @@ async function resolveAmbiguousDeployApp(context, matches, targetName, firstDepl
|
|
|
1366
1366
|
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");
|
|
1367
1367
|
if (selected === createNew) return {
|
|
1368
1368
|
appName: targetName,
|
|
1369
|
-
region:
|
|
1369
|
+
region: DEFAULT_REGION,
|
|
1370
1370
|
displayName: targetName,
|
|
1371
1371
|
annotation: "created from package.json",
|
|
1372
1372
|
firstDeploy
|
|
@@ -1531,7 +1531,7 @@ async function requirePreviewAppProviderWithClient(context) {
|
|
|
1531
1531
|
if (!client) throw authRequiredError(["prisma-cli auth login"]);
|
|
1532
1532
|
return {
|
|
1533
1533
|
client,
|
|
1534
|
-
provider:
|
|
1534
|
+
provider: createAppProvider(client, createPreviewLogAuthOptions(context.runtime.env, context.runtime.signal))
|
|
1535
1535
|
};
|
|
1536
1536
|
}
|
|
1537
1537
|
function createPreviewLogAuthOptions(env, signal) {
|
|
@@ -2139,13 +2139,13 @@ async function readCurrentWorkspaceId(context) {
|
|
|
2139
2139
|
function normalizeBuildType(requestedBuildType) {
|
|
2140
2140
|
if (!requestedBuildType) return "auto";
|
|
2141
2141
|
if (isPreviewBuildType(requestedBuildType)) return requestedBuildType;
|
|
2142
|
-
throw usageError(`Unsupported build type "${requestedBuildType}"`, `Only ${
|
|
2142
|
+
throw usageError(`Unsupported build type "${requestedBuildType}"`, `Only ${APP_BUILD_TYPES.join(", ")} are supported in the current preview.`, "Pass a supported --build-type value.", getBuildTypeExamples("build"), "app");
|
|
2143
2143
|
}
|
|
2144
2144
|
function isPreviewBuildType(value) {
|
|
2145
|
-
return
|
|
2145
|
+
return APP_BUILD_TYPES.includes(value);
|
|
2146
2146
|
}
|
|
2147
2147
|
function getBuildTypeExamples(commandName) {
|
|
2148
|
-
return
|
|
2148
|
+
return RESOLVED_APP_BUILD_TYPES.map((buildType) => {
|
|
2149
2149
|
return `prisma-cli app ${commandName} --build-type ${buildType}${buildType === "bun" ? " --entry server.ts" : ""}`;
|
|
2150
2150
|
});
|
|
2151
2151
|
}
|
|
@@ -2389,6 +2389,7 @@ function formatBuildTypeName(buildType) {
|
|
|
2389
2389
|
case "nextjs": return "Next.js";
|
|
2390
2390
|
case "nuxt": return "Nuxt";
|
|
2391
2391
|
case "astro": return "Astro";
|
|
2392
|
+
case "nestjs": return "NestJS";
|
|
2392
2393
|
case "tanstack-start": return "TanStack Start";
|
|
2393
2394
|
case "bun": return "Bun";
|
|
2394
2395
|
case "auto": return "Auto";
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { CliError, authRequiredError, featureUnavailableError, usageError, workspaceRequiredError } from "../shell/errors.js";
|
|
2
|
+
import { createAppProvider } from "../lib/app/app-provider.js";
|
|
2
3
|
import { renderSummaryLine } from "../shell/ui.js";
|
|
3
4
|
import { canPrompt } from "../shell/runtime.js";
|
|
4
5
|
import { readLocalResolutionPin } from "../lib/project/local-pin.js";
|
|
5
6
|
import { formatCommandArgument } from "../shell/command-arguments.js";
|
|
6
7
|
import { buildProjectSetupNextActions, inferTargetName, inspectProjectBinding, projectResolutionErrorToCliError, resolveProjectTarget, sortProjects } from "../lib/project/resolution.js";
|
|
7
8
|
import { bindProjectToDirectory, isValidProjectSetupName, projectCreateFailedError, projectDirectoryBindingErrorToCliError, projectSetupNameRequiredError, resolveProjectForSetup, toProjectSummary } from "../lib/project/setup.js";
|
|
8
|
-
import { createPreviewAppProvider } from "../lib/app/preview-provider.js";
|
|
9
9
|
import { requireComputeAuth } from "../lib/auth/guard.js";
|
|
10
10
|
import { promptForProjectSetupChoice } from "../lib/project/interactive-setup.js";
|
|
11
11
|
import { createCliUseCaseGateways } from "../use-cases/create-cli-gateways.js";
|
|
@@ -104,7 +104,7 @@ async function runProjectCreate(context, projectName) {
|
|
|
104
104
|
if (!isRealMode(context)) throw featureUnavailableError("Project create is not available in fixture mode", "Creating Projects requires live platform integration.", "Rerun without fixture mode enabled to create a Project.", ["prisma-cli auth login"], "project");
|
|
105
105
|
const client = await requireComputeAuth(context.runtime.env, context.runtime.signal);
|
|
106
106
|
if (!client) throw authRequiredError();
|
|
107
|
-
const provider =
|
|
107
|
+
const provider = createAppProvider(client);
|
|
108
108
|
const name = projectName.trim();
|
|
109
109
|
const created = await provider.createProject({
|
|
110
110
|
name,
|
|
@@ -136,7 +136,7 @@ async function runProjectLink(context, projectRef) {
|
|
|
136
136
|
if (isRealMode(context)) {
|
|
137
137
|
const client = await requireComputeAuth(context.runtime.env, context.runtime.signal);
|
|
138
138
|
if (!client) throw authRequiredError();
|
|
139
|
-
provider =
|
|
139
|
+
provider = createAppProvider(client);
|
|
140
140
|
projects = await listRealWorkspaceProjects(client, workspace, context.runtime.signal);
|
|
141
141
|
} else projects = listFixtureWorkspaceProjects(context, workspace);
|
|
142
142
|
let result;
|
|
@@ -1,22 +1,22 @@
|
|
|
1
|
+
import { createBranchDatabase, createEnvironmentVariable, deleteBranchDatabase, deleteEnvironmentVariable, listEnvironmentVariables, updateEnvironmentVariable } from "./branch-database-api.js";
|
|
2
|
+
import { AppBuildStrategy } from "./build.js";
|
|
1
3
|
import { envVarNames } from "./env-vars.js";
|
|
2
|
-
import { PreviewBuildStrategy } from "./preview-build.js";
|
|
3
|
-
import { createBranchDatabase, createEnvironmentVariable, deleteBranchDatabase, deleteEnvironmentVariable, listEnvironmentVariables, updateEnvironmentVariable } from "./preview-branch-database.js";
|
|
4
4
|
import path from "node:path";
|
|
5
5
|
import { ApiError, CancelledError, ComputeClient, streamLogs } from "@prisma/compute-sdk";
|
|
6
|
-
//#region src/lib/app/
|
|
7
|
-
var
|
|
6
|
+
//#region src/lib/app/app-provider.ts
|
|
7
|
+
var DomainApiError = class extends Error {
|
|
8
8
|
status;
|
|
9
9
|
code;
|
|
10
10
|
hint;
|
|
11
11
|
constructor(options) {
|
|
12
12
|
super(`${options.summary}: ${options.message}${options.hint ? ` ${options.hint}` : ""}`);
|
|
13
|
-
this.name = "
|
|
13
|
+
this.name = "DomainApiError";
|
|
14
14
|
this.status = options.status;
|
|
15
15
|
this.code = options.code ?? null;
|
|
16
16
|
this.hint = options.hint ?? null;
|
|
17
17
|
}
|
|
18
18
|
};
|
|
19
|
-
function
|
|
19
|
+
function createAppProvider(client, options) {
|
|
20
20
|
const sdk = new ComputeClient(client);
|
|
21
21
|
return {
|
|
22
22
|
async createProject(options) {
|
|
@@ -161,7 +161,7 @@ function createPreviewAppProvider(client, options) {
|
|
|
161
161
|
region: options.region
|
|
162
162
|
};
|
|
163
163
|
const deployResult = await sdk.deploy({
|
|
164
|
-
strategy: new
|
|
164
|
+
strategy: new AppBuildStrategy({
|
|
165
165
|
appPath: path.resolve(options.cwd),
|
|
166
166
|
entrypoint: options.entrypoint,
|
|
167
167
|
buildType: options.buildType,
|
|
@@ -491,7 +491,7 @@ function apiCallError(summary, response, error) {
|
|
|
491
491
|
return /* @__PURE__ */ new Error(`${summary}: ${message}${hint}`);
|
|
492
492
|
}
|
|
493
493
|
function domainApiCallError(summary, response, error) {
|
|
494
|
-
return new
|
|
494
|
+
return new DomainApiError({
|
|
495
495
|
summary,
|
|
496
496
|
status: response.status,
|
|
497
497
|
code: error.error?.code ?? null,
|
|
@@ -541,4 +541,4 @@ function toAbsoluteUrl(url) {
|
|
|
541
541
|
return url.startsWith("https://") || url.startsWith("http://") ? url : `https://${url}`;
|
|
542
542
|
}
|
|
543
543
|
//#endregion
|
|
544
|
-
export {
|
|
544
|
+
export { DomainApiError, createAppProvider };
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
import { readFile } from "node:fs/promises";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import { resolveBuildSettings, resolveConfiguredBuildSettings } from "@prisma/compute-sdk";
|
|
4
|
+
//#region src/lib/app/build-settings.ts
|
|
5
|
+
/** Legacy build-settings file: no longer read or written, only detected for migration. */
|
|
6
|
+
const PRISMA_APP_CONFIG_FILENAME = "prisma.app.json";
|
|
7
|
+
/**
|
|
8
|
+
* Detects a leftover `prisma.app.json`. The file is no longer used: one that
|
|
9
|
+
* matches the effective settings is reported for deletion, one with custom
|
|
10
|
+
* values must be migrated to the compute config so builds never silently
|
|
11
|
+
* change.
|
|
12
|
+
*/
|
|
13
|
+
async function detectLegacyBuildSettings(options) {
|
|
14
|
+
const configPath = path.join(options.appPath, PRISMA_APP_CONFIG_FILENAME);
|
|
15
|
+
let content;
|
|
16
|
+
try {
|
|
17
|
+
options.signal?.throwIfAborted();
|
|
18
|
+
content = await readFile(configPath, {
|
|
19
|
+
encoding: "utf8",
|
|
20
|
+
signal: options.signal
|
|
21
|
+
});
|
|
22
|
+
} catch (error) {
|
|
23
|
+
if (options.signal?.aborted) throw error;
|
|
24
|
+
return { kind: "absent" };
|
|
25
|
+
}
|
|
26
|
+
let legacy;
|
|
27
|
+
try {
|
|
28
|
+
const parsed = JSON.parse(content);
|
|
29
|
+
const buildCommand = parsed.buildCommand === null || typeof parsed.buildCommand === "string" ? typeof parsed.buildCommand === "string" ? parsed.buildCommand.trim() || null : null : void 0;
|
|
30
|
+
const outputDirectory = typeof parsed.outputDirectory === "string" ? normalizeRelativePath(parsed.outputDirectory) : void 0;
|
|
31
|
+
if (buildCommand === void 0 || !outputDirectory) return {
|
|
32
|
+
kind: "invalid",
|
|
33
|
+
configPath
|
|
34
|
+
};
|
|
35
|
+
legacy = {
|
|
36
|
+
buildCommand,
|
|
37
|
+
outputDirectory
|
|
38
|
+
};
|
|
39
|
+
} catch {
|
|
40
|
+
return {
|
|
41
|
+
kind: "invalid",
|
|
42
|
+
configPath
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
return legacy.buildCommand === options.effective.buildCommand && legacy.outputDirectory === options.effective.outputDirectory ? {
|
|
46
|
+
kind: "matching",
|
|
47
|
+
configPath
|
|
48
|
+
} : {
|
|
49
|
+
kind: "custom",
|
|
50
|
+
configPath,
|
|
51
|
+
...legacy
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
/** Resolves build settings purely from framework inference; nothing is read or written. */
|
|
55
|
+
async function resolveInferredAppBuildSettings(options) {
|
|
56
|
+
return {
|
|
57
|
+
status: "inferred",
|
|
58
|
+
configPath: null,
|
|
59
|
+
relativeConfigPath: null,
|
|
60
|
+
settings: await resolveBuildSettings(options)
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Resolves build settings when the compute config owns them: configured
|
|
65
|
+
* fields win, omitted fields fall back to framework defaults.
|
|
66
|
+
*/
|
|
67
|
+
async function resolveConfiguredAppBuildSettings(options) {
|
|
68
|
+
const configFilename = path.basename(options.configPath);
|
|
69
|
+
const settings = await resolveConfiguredBuildSettings({
|
|
70
|
+
appPath: options.appPath,
|
|
71
|
+
buildType: options.buildType,
|
|
72
|
+
configured: options.configured,
|
|
73
|
+
source: `set by ${configFilename}`,
|
|
74
|
+
signal: options.signal
|
|
75
|
+
});
|
|
76
|
+
return {
|
|
77
|
+
status: "config",
|
|
78
|
+
configPath: options.configPath,
|
|
79
|
+
relativeConfigPath: configFilename,
|
|
80
|
+
settings
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
function normalizeRelativePath(value) {
|
|
84
|
+
const raw = value.trim().replace(/\\/g, "/");
|
|
85
|
+
if (raw.length === 0 || raw.split("/").includes("..")) return;
|
|
86
|
+
if (/^[A-Za-z]:/.test(raw)) return;
|
|
87
|
+
const normalized = path.posix.normalize(raw);
|
|
88
|
+
const segments = normalized.split("/");
|
|
89
|
+
if (path.win32.isAbsolute(value) || path.posix.isAbsolute(normalized) || segments.includes("..")) return;
|
|
90
|
+
return normalized === "." ? "." : normalized;
|
|
91
|
+
}
|
|
92
|
+
//#endregion
|
|
93
|
+
export { PRISMA_APP_CONFIG_FILENAME, detectLegacyBuildSettings, resolveConfiguredAppBuildSettings, resolveInferredAppBuildSettings };
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import "./build-settings.js";
|
|
2
|
+
import "node:fs/promises";
|
|
3
|
+
import "node:path";
|
|
4
|
+
import { normalizeArtifactSymlinks, resolveBuildStrategy } from "@prisma/compute-sdk";
|
|
5
|
+
//#region src/lib/app/build.ts
|
|
6
|
+
const APP_BUILD_TYPES = [
|
|
7
|
+
"auto",
|
|
8
|
+
"bun",
|
|
9
|
+
"nextjs",
|
|
10
|
+
"nuxt",
|
|
11
|
+
"astro",
|
|
12
|
+
"nestjs",
|
|
13
|
+
"tanstack-start"
|
|
14
|
+
];
|
|
15
|
+
const RESOLVED_APP_BUILD_TYPES = APP_BUILD_TYPES.filter((buildType) => buildType !== "auto");
|
|
16
|
+
var AppBuildStrategy = class {
|
|
17
|
+
#appPath;
|
|
18
|
+
#entrypoint;
|
|
19
|
+
#buildType;
|
|
20
|
+
#signal;
|
|
21
|
+
#buildSettings;
|
|
22
|
+
constructor(options) {
|
|
23
|
+
this.#appPath = options.appPath;
|
|
24
|
+
this.#entrypoint = options.entrypoint;
|
|
25
|
+
this.#buildType = options.buildType ?? "auto";
|
|
26
|
+
this.#signal = options.signal;
|
|
27
|
+
this.#buildSettings = options.buildSettings;
|
|
28
|
+
}
|
|
29
|
+
async canBuild(signal = this.#signal) {
|
|
30
|
+
const { strategy } = await resolveAppBuildStrategy({
|
|
31
|
+
appPath: this.#appPath,
|
|
32
|
+
entrypoint: this.#entrypoint,
|
|
33
|
+
buildType: this.#buildType,
|
|
34
|
+
signal,
|
|
35
|
+
buildSettings: this.#buildSettings
|
|
36
|
+
});
|
|
37
|
+
return strategy.canBuild(signal);
|
|
38
|
+
}
|
|
39
|
+
async execute(signal = this.#signal) {
|
|
40
|
+
const { artifact } = await executeAppBuild({
|
|
41
|
+
appPath: this.#appPath,
|
|
42
|
+
entrypoint: this.#entrypoint,
|
|
43
|
+
buildType: this.#buildType,
|
|
44
|
+
signal,
|
|
45
|
+
buildSettings: this.#buildSettings
|
|
46
|
+
});
|
|
47
|
+
return artifact;
|
|
48
|
+
}
|
|
49
|
+
};
|
|
50
|
+
async function executeAppBuild(options) {
|
|
51
|
+
const { strategy, buildType } = await resolveAppBuildStrategy({
|
|
52
|
+
appPath: options.appPath,
|
|
53
|
+
entrypoint: options.entrypoint,
|
|
54
|
+
buildType: options.buildType ?? "auto",
|
|
55
|
+
signal: options.signal,
|
|
56
|
+
buildSettings: options.buildSettings
|
|
57
|
+
});
|
|
58
|
+
const artifact = await strategy.execute(options.signal);
|
|
59
|
+
try {
|
|
60
|
+
await normalizeArtifactSymlinks(artifact.directory, options.appPath, options.signal);
|
|
61
|
+
return {
|
|
62
|
+
artifact,
|
|
63
|
+
buildType
|
|
64
|
+
};
|
|
65
|
+
} catch (error) {
|
|
66
|
+
await artifact.cleanup?.().catch(() => void 0);
|
|
67
|
+
throw error;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
async function resolveAppBuildStrategy(options) {
|
|
71
|
+
return resolveBuildStrategy({
|
|
72
|
+
appPath: options.appPath,
|
|
73
|
+
buildType: options.buildType,
|
|
74
|
+
entrypoint: options.entrypoint,
|
|
75
|
+
buildSettings: options.buildSettings,
|
|
76
|
+
signal: options.signal
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
//#endregion
|
|
80
|
+
export { APP_BUILD_TYPES, AppBuildStrategy, RESOLVED_APP_BUILD_TYPES, executeAppBuild };
|
|
@@ -21,13 +21,12 @@ async function readBunPackageJson(appPath, signal) {
|
|
|
21
21
|
}
|
|
22
22
|
}
|
|
23
23
|
function readBunPackageEntrypoint(packageJson) {
|
|
24
|
-
|
|
25
|
-
if (typeof packageJson?.module === "string") return packageJson.module;
|
|
24
|
+
return typeof packageJson?.main === "string" ? packageJson.main : void 0;
|
|
26
25
|
}
|
|
27
26
|
async function resolveBunEntrypoint(appPath, explicitEntrypoint, signal) {
|
|
28
27
|
const packageJson = await readBunPackageJson(appPath, signal);
|
|
29
28
|
const candidate = explicitEntrypoint ?? readBunPackageEntrypoint(packageJson);
|
|
30
|
-
if (!candidate) throw new Error("Entrypoint is required. Pass --entry or define package.json main
|
|
29
|
+
if (!candidate) throw new Error("Entrypoint is required. Pass --entry or define package.json main.");
|
|
31
30
|
if (path.isAbsolute(candidate)) throw new Error("Entrypoint must be a relative path.");
|
|
32
31
|
const normalized = path.normalize(candidate);
|
|
33
32
|
if (normalized.startsWith("..") || path.isAbsolute(normalized) || normalized.includes(`${path.sep}..${path.sep}`)) throw new Error("Entrypoint must not escape the app directory.");
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { renderDeployOutputRows } from "./deploy-output.js";
|
|
2
|
-
//#region src/lib/app/
|
|
3
|
-
function
|
|
2
|
+
//#region src/lib/app/deploy-progress.ts
|
|
3
|
+
function createDeployProgressState() {
|
|
4
4
|
return {
|
|
5
5
|
buildStarted: false,
|
|
6
6
|
buildCompleted: false,
|
|
@@ -13,7 +13,7 @@ function createPreviewDeployProgressState() {
|
|
|
13
13
|
promotedUrl: null
|
|
14
14
|
};
|
|
15
15
|
}
|
|
16
|
-
function
|
|
16
|
+
function createDeployProgress(output, ui, enabled, state = createDeployProgressState()) {
|
|
17
17
|
const write = (line) => {
|
|
18
18
|
if (!enabled) return;
|
|
19
19
|
output.write(`${line}\n`);
|
|
@@ -63,7 +63,7 @@ function createPreviewDeployProgress(output, ui, enabled, state = createPreviewD
|
|
|
63
63
|
function formatArtifactSize(byteLength) {
|
|
64
64
|
return `${(byteLength / 1024 / 1024).toFixed(1)} MB`;
|
|
65
65
|
}
|
|
66
|
-
function
|
|
66
|
+
function createPromoteProgress(output, enabled) {
|
|
67
67
|
if (!enabled) return;
|
|
68
68
|
const write = (line) => {
|
|
69
69
|
output.write(`${line}\n`);
|
|
@@ -97,4 +97,4 @@ function createPreviewPromoteProgress(output, enabled) {
|
|
|
97
97
|
};
|
|
98
98
|
}
|
|
99
99
|
//#endregion
|
|
100
|
-
export {
|
|
100
|
+
export { createDeployProgress, createDeployProgressState, createPromoteProgress };
|
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.90.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.28.0",
|
|
48
48
|
"@prisma/credentials-store": "^7.8.0",
|
|
49
49
|
"@prisma/management-api-sdk": "^1.37.0",
|
|
50
50
|
"better-result": "^2.9.2",
|