@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.
@@ -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([...PREVIEW_BUILD_TYPES]).default("auto"));
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";
@@ -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 resolveConfiguredPreviewBuildSettings({
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 executePreviewBuild({
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 ${RESOLVED_PREVIEW_BUILD_TYPES.map(formatBuildTypeName).join(", ")}.`, "Pass a supported --build-type value, or pass --entry <path> for a Bun app.", getBuildTypeExamples("build"), "app");
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 resolveConfiguredPreviewBuildSettings({
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 resolveInferredPreviewBuildSettings({
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 = createPreviewDeployProgressState();
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: createPreviewDeployProgress(context.output.stderr, context.ui, !context.flags.json && !context.flags.quiet, progressState)
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: createPreviewPromoteProgress(context.output.stderr, !context.flags.json && !context.flags.quiet)
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: createPreviewPromoteProgress(context.output.stderr, !context.flags.json && !context.flags.quiet)
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 PreviewDomainApiError) {
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: PREVIEW_DEFAULT_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: PREVIEW_DEFAULT_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: PREVIEW_DEFAULT_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: PREVIEW_DEFAULT_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: createPreviewAppProvider(client, createPreviewLogAuthOptions(context.runtime.env, context.runtime.signal))
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 ${PREVIEW_BUILD_TYPES.join(", ")} are supported in the current preview.`, "Pass a supported --build-type value.", getBuildTypeExamples("build"), "app");
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 PREVIEW_BUILD_TYPES.includes(value);
2145
+ return APP_BUILD_TYPES.includes(value);
2146
2146
  }
2147
2147
  function getBuildTypeExamples(commandName) {
2148
- return RESOLVED_PREVIEW_BUILD_TYPES.map((buildType) => {
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 = createPreviewAppProvider(client);
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 = createPreviewAppProvider(client);
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;
@@ -0,0 +1,5 @@
1
+ import "../../shell/prompt.js";
2
+ //#region src/lib/app/app-interaction.ts
3
+ const DEFAULT_REGION = "eu-central-1";
4
+ //#endregion
5
+ export { DEFAULT_REGION };
@@ -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/preview-provider.ts
7
- var PreviewDomainApiError = class extends Error {
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 = "PreviewDomainApiError";
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 createPreviewAppProvider(client, options) {
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 PreviewBuildStrategy({
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 PreviewDomainApiError({
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 { PreviewDomainApiError, createPreviewAppProvider };
544
+ export { DomainApiError, createAppProvider };
@@ -1,4 +1,4 @@
1
- //#region src/lib/app/preview-branch-database.ts
1
+ //#region src/lib/app/branch-database-api.ts
2
2
  async function createBranchDatabase(client, options) {
3
3
  const result = await client.POST("/v1/databases", {
4
4
  body: {
@@ -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
- if (typeof packageJson?.main === "string") return packageJson.main;
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 or module.");
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/preview-progress.ts
3
- function createPreviewDeployProgressState() {
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 createPreviewDeployProgress(output, ui, enabled, state = createPreviewDeployProgressState()) {
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 createPreviewPromoteProgress(output, enabled) {
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 { createPreviewDeployProgress, createPreviewDeployProgressState, createPreviewPromoteProgress };
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.88.1",
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.23.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",