Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 19 additions & 5 deletions docs/product/command-spec.md
Original file line number Diff line number Diff line change
Expand Up @@ -879,7 +879,7 @@ Examples:
prisma-cli database connection remove conn_123 --confirm conn_123
```

## `prisma-cli app build [app] --entry <path> --build-type <auto|bun|nextjs|nuxt|astro|tanstack-start>`
## `prisma-cli app build [app] --entry <path> --build-type <auto|bun|nextjs|nuxt|astro|nestjs|tanstack-start|custom>`

Purpose:

Expand All @@ -889,7 +889,7 @@ Behavior:

- resolves the optional `[app]` target, app root, framework, and entrypoint from `prisma.compute.ts` exactly like `app deploy`; explicit `--entry` and a non-`auto` `--build-type` override the config
- detects supported project shapes when `--build-type auto` is used and no config framework applies
- supports Bun, Next.js, Nuxt, Astro, and TanStack Start app builds in the beta package
- supports Bun, Next.js, Nuxt, Astro, NestJS, TanStack Start, and custom artifact app builds in the beta package
- fails with `USAGE_ERROR` when framework detection is ambiguous

Examples:
Expand All @@ -898,9 +898,11 @@ Examples:
prisma-cli app build --build-type nextjs
prisma-cli app build --build-type nuxt
prisma-cli app build --build-type astro
prisma-cli app build --build-type nestjs
prisma-cli app build --build-type tanstack-start
prisma-cli app build --build-type bun --entry server.ts
prisma-cli app build api
prisma-cli app build frontend
```

## `prisma-cli app run [app] --entry <path> --build-type <auto|bun|nextjs> --port <port>`
Expand All @@ -925,7 +927,7 @@ prisma-cli app run --build-type bun --entry server.ts --port 3000
prisma-cli app run api
```

## `prisma-cli app deploy [app] --project <id-or-name> --create-project <name> --app <name> --branch <name> --framework <nextjs|nuxt|astro|hono|tanstack-start|bun> --entry <path> --http-port <port> --env <name=value|file> --db --no-db --prod`
## `prisma-cli app deploy [app] --project <id-or-name> --create-project <name> --app <name> --branch <name> --framework <nextjs|nuxt|astro|hono|nestjs|tanstack-start|custom|bun> --entry <path> --http-port <port> --env <name=value|file> --db --no-db --prod`

Purpose:

Expand All @@ -943,8 +945,9 @@ Compute config file (`prisma.compute.ts`):
- `apps` — a multi-app or monorepo repository, keyed by deploy target name
- each app accepts `name`, `root`, `framework`, `entry`, `httpPort`, `env`, and `build`:
- `env` is a dotenv file path, or `{ file, vars }` with file path(s) and inline assignments
- `build` is `{ command, outputDirectory }`; both fields are optional and `command: null` skips the build step
- `build` applies to frameworks whose preview build consumes committed settings (`nextjs`, `hono`, `tanstack-start`, `bun`); `nuxt` and `astro` builds run their framework CLI automatically, so a `build` block with those frameworks is a validation error (`BUILD_SETTINGS_UNSUPPORTED` when only detected at deploy time)
- `build` is `{ command, outputDirectory, entrypoint }`; all fields are optional except where a framework requires enough information to stage a runnable artifact, and `command: null` skips the build step
- `build.entrypoint` is the built artifact entrypoint when `outputDirectory` is set, and is the source entrypoint for Bun/Hono configs that do not set an output directory
- `framework: "custom"` deploys a prebuilt or custom-built artifact and requires `build.outputDirectory` and `build.entrypoint`
- when `build` is present, the compute config owns build settings for that app: fields it sets override framework defaults, fields it omits are inferred; without a `build` block, settings are inferred entirely, with their sources shown
- the compute config does not declare databases in the current beta; database setup stays on the `--db`/`--no-db` flags (a future project-level `database` field is the reserved growth path, since databases are branch resources shared by every app on the branch)

Expand Down Expand Up @@ -991,6 +994,15 @@ export default defineComputeConfig({
apps: {
web: { root: "apps/web", framework: "nextjs" },
worker: { root: "apps/worker", framework: "bun", entry: "src/index.ts" },
frontend: {
root: "apps/frontend",
framework: "custom",
build: {
command: "npm run build",
outputDirectory: "build",
entrypoint: "handler.js",
},
},
},
});
```
Expand Down Expand Up @@ -1030,6 +1042,7 @@ Behavior:
- build commands run with every `node_modules/.bin` between the app and the repository or workspace root on `PATH`, so hoisted workspace binaries resolve
- otherwise `Build Command` falls back to the framework default, such as `next build`
- `Output Directory` is a literal framework output path, such as `.next/standalone`, `.output`, or `.`
- `Entrypoint` is shown when the config or framework settings provide a concrete built artifact entrypoint
- `prisma.app.json` is legacy and never read or written; a leftover file that matches the resolved settings produces a deletion warning, an unparsable one is ignored with a warning, and one with custom values fails with `BUILD_SETTINGS_MIGRATION_REQUIRED` including the exact `build` block to move into `prisma.compute.ts`
- after setup, deploy prints `Deploying to <Project> / <Branch> / <App>`; later deploys print a compact target header such as `Deploying ./j1 to j1 / main / j1`
- deploy progress uses short stage copy (`Building locally...`, `Built <size>`, `Uploading...`, `Uploaded`, `Deploying...`, `Deployed`) and never prints `Status: running` or `Deployment is running at ...`
Expand All @@ -1052,6 +1065,7 @@ Behavior:
- `--env DATABASE_URL=...`, `--env DIRECT_URL=...`, or the same keys loaded from an env file suppress automatic database prompting; combining those database env vars with `--db` is rejected
- maps user-facing framework names to deploy build strategies
- does not accept `--build-command` or `--output-directory`; custom build settings live in the `build` block of `prisma.compute.ts`
- deploys arbitrary framework output with `framework: "custom"` when the config provides a built output directory and entrypoint; `build.command` is optional for prebuilt artifacts
- uses `src/index.ts` as the Hono deploy entrypoint when the app has no `package.json#main` or `package.json#module` and that file exists
- supports vanilla Bun apps with `--framework bun` using `package.json#main` or `package.json#module`, or with `--entry <path>`
- treats `--entry <path>` without `--framework` as a Bun app deploy
Expand Down
2 changes: 1 addition & 1 deletion docs/product/error-conventions.md
Original file line number Diff line number Diff line change
Expand Up @@ -239,7 +239,7 @@ Recommended meanings:
- `COMPUTE_CONFIG_TARGET_REQUIRED`: a multi-app compute config needs an `[app]` target and none was given or inferred
- `COMPUTE_CONFIG_TARGET_UNKNOWN`: the `[app]` target matches no configured app
- `BUILD_SETTINGS_MIGRATION_REQUIRED`: a legacy `prisma.app.json` contains custom build settings that must move into the `build` block of `prisma.compute.ts`
- `BUILD_SETTINGS_UNSUPPORTED`: a compute config `build` block targets a framework whose strategy owns its build (nuxt, astro)
- `BUILD_SETTINGS_UNSUPPORTED`: a compute config `build` block targets a framework whose SDK strategy does not consume committed build settings
- `FRAMEWORK_NOT_DETECTED`: app deploy could not detect a supported Beta framework and no explicit framework/build type was provided
- `DEPLOYMENT_NOT_FOUND`: requested deployment id does not exist
- `NO_DEPLOYMENTS`: command resolved a branch or app but found no deployments
Expand Down
2 changes: 1 addition & 1 deletion docs/product/resource-model.md
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ Rules:
- the runtime app service is scoped by branch in the platform model
- the app may be selected or created as part of app deployment workflows
- app selection is local CLI state when needed for the beta package
- app build settings live in the `build` block of `prisma.compute.ts` (`command`, `outputDirectory`); `prisma.app.json` is legacy and no longer read
- app build settings live in the `build` block of `prisma.compute.ts` (`command`, `outputDirectory`, `entrypoint`); `prisma.app.json` is legacy and no longer read

### Deployment

Expand Down
2 changes: 1 addition & 1 deletion packages/cli/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@
},
"dependencies": {
"@clack/prompts": "^1.5.0",
"@prisma/compute-sdk": "^0.28.0",
"@prisma/compute-sdk": "^0.29.0",
"@prisma/credentials-store": "^7.8.0",
"@prisma/management-api-sdk": "^1.37.0",
"better-result": "^2.9.2",
Expand Down
46 changes: 24 additions & 22 deletions packages/cli/src/controllers/app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
maybeSetupBranchDatabase,
} from "../lib/app/branch-database-deploy";
import {
APP_BUILD_TYPE_LABELS,
APP_BUILD_TYPES,
type AppBuildSettings,
type AppBuildSettingsResolution,
Expand Down Expand Up @@ -443,12 +444,12 @@
: undefined,
};
try {
const single = await runSingleAppDeploy(
context,
undefined,
targetOptions,
config,
);

Check notice on line 452 in packages/cli/src/controllers/app.ts

View workflow job for this annotation

GitHub Actions / Lint

lint/performance/noAwaitInLoops

Avoid using await inside loops.
deployments.push({ target: planned.targetKey, result: single.result });
warnings.push(...single.warnings);
} catch (error) {
Expand Down Expand Up @@ -487,7 +488,7 @@
return;
}

const targets = config.targets.map((target) => target.key!).join(", ");

Check warning on line 491 in packages/cli/src/controllers/app.ts

View workflow job for this annotation

GitHub Actions / Lint

lint/style/noNonNullAssertion

Forbidden non-null assertion.
throw usageError(
`Deploying all apps does not accept ${used.join(", ")}`,
`Without a target, app deploy deploys every configured app (${targets}), so per-app inputs are ambiguous.`,
Expand Down Expand Up @@ -521,7 +522,7 @@
}

const failure = describeDeployAllFailure({
targetKeys: config.targets.map((target) => target.key!),

Check warning on line 525 in packages/cli/src/controllers/app.ts

View workflow job for this annotation

GitHub Actions / Lint

lint/style/noNonNullAssertion

Forbidden non-null assertion.
failedIndex,
completed: deployments.map(({ target, result }) => ({
target,
Expand Down Expand Up @@ -562,7 +563,7 @@
});
}

async function runSingleAppDeploy(

Check notice on line 566 in packages/cli/src/controllers/app.ts

View workflow job for this annotation

GitHub Actions / Lint

lint/complexity/noExcessiveCognitiveComplexity

Excessive complexity of 16 detected (max: 15).
context: CommandContext,
appName: string | undefined,
options: AppDeployOptions | undefined,
Expand Down Expand Up @@ -845,7 +846,8 @@
name: framework.displayName,
source: framework.annotation,
},
entrypoint: entrypoint ?? null,
entrypoint:
entrypoint ?? buildSettingsResolution.settings.entrypoint ?? null,
Comment thread
AmanVarshney01 marked this conversation as resolved.
httpPort: runtime.port,
region: selectedApp.region ?? null,
envVars: envVarNames(envVars),
Expand Down Expand Up @@ -1102,9 +1104,9 @@
...deployment.deployment,
live: providerLiveDeploymentId
? deployment.deployment.id === providerLiveDeploymentId
: knownLiveDeploymentId
? deployment.deployment.id === knownLiveDeploymentId
: deployment.deployment.live,

Check notice on line 1109 in packages/cli/src/controllers/app.ts

View workflow job for this annotation

GitHub Actions / Lint

lint/style/noNestedTernary

Do not nest ternary expressions.
},
},
warnings: [],
Expand Down Expand Up @@ -1483,10 +1485,10 @@
});
}

await sleep(
Math.min(pollIntervalMs, Math.max(deadline - Date.now(), 0)),
context.runtime.signal,
);

Check notice on line 1491 in packages/cli/src/controllers/app.ts

View workflow job for this annotation

GitHub Actions / Lint

lint/performance/noAwaitInLoops

Avoid using await inside loops.
current = await target.provider
.showDomain(current.id, { signal: context.runtime.signal })
.catch((error) => {
Expand Down Expand Up @@ -2048,7 +2050,7 @@
const compute = await resolveComputeManagementContext(
context,
options?.configTarget,
commandName.replace(/^app /, ""),

Check warning on line 2053 in packages/cli/src/controllers/app.ts

View workflow job for this annotation

GitHub Actions / Lint

lint/performance/useTopLevelRegex

This regex literal is not defined in the top level scope. This can lead to performance issues if this function is called frequently.
);
const branch = resolveDomainBranch(options?.branchName);
if (toBranchKind(branch.name) !== "production") {
Expand Down Expand Up @@ -2216,14 +2218,14 @@
}

return labels.every((label) =>
/^[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?$/.test(label),

Check warning on line 2221 in packages/cli/src/controllers/app.ts

View workflow job for this annotation

GitHub Actions / Lint

lint/performance/useTopLevelRegex

This regex literal is not defined in the top level scope. This can lead to performance issues if this function is called frequently.
);
}

function sameDomainHostname(left: string, right: string): boolean {
return (
left.trim().replace(/\.$/, "").toLowerCase() ===

Check warning on line 2227 in packages/cli/src/controllers/app.ts

View workflow job for this annotation

GitHub Actions / Lint

lint/performance/useTopLevelRegex

This regex literal is not defined in the top level scope. This can lead to performance issues if this function is called frequently.
right.trim().replace(/\.$/, "").toLowerCase()

Check warning on line 2228 in packages/cli/src/controllers/app.ts

View workflow job for this annotation

GitHub Actions / Lint

lint/performance/useTopLevelRegex

This regex literal is not defined in the top level scope. This can lead to performance issues if this function is called frequently.
);
}

Expand Down Expand Up @@ -2310,7 +2312,7 @@
}
}

function domainCommandError(

Check notice on line 2315 in packages/cli/src/controllers/app.ts

View workflow job for this annotation

GitHub Actions / Lint

lint/complexity/noExcessiveCognitiveComplexity

Excessive complexity of 26 detected (max: 15).
command: AppDomainCommand,
error: unknown,
hostname: string,
Expand Down Expand Up @@ -2447,7 +2449,7 @@
text.includes("no cname") ||
text.includes("cname record") ||
text.includes("no a/aaaa") ||
/\bcname(?:s)?\s+to\b/.test(text)

Check warning on line 2452 in packages/cli/src/controllers/app.ts

View workflow job for this annotation

GitHub Actions / Lint

lint/performance/useTopLevelRegex

This regex literal is not defined in the top level scope. This can lead to performance issues if this function is called frequently.
);
}

Expand Down Expand Up @@ -2476,7 +2478,7 @@

function extractDomainDnsTarget(error: DomainApiError): string | null {
const text = `${error.hint ?? ""} ${error.message}`;
const match = /\b((?:[a-z0-9-]+\.)+prisma\.build)\b/i.exec(text);

Check warning on line 2481 in packages/cli/src/controllers/app.ts

View workflow job for this annotation

GitHub Actions / Lint

lint/performance/useTopLevelRegex

This regex literal is not defined in the top level scope. This can lead to performance issues if this function is called frequently.
return match?.[1]?.toLowerCase() ?? null;
}

Expand Down Expand Up @@ -2512,7 +2514,7 @@
return 0;
}

const match = /^(\d+)(ms|s|m|h)$/.exec(trimmed);

Check warning on line 2517 in packages/cli/src/controllers/app.ts

View workflow job for this annotation

GitHub Actions / Lint

lint/performance/useTopLevelRegex

This regex literal is not defined in the top level scope. This can lead to performance issues if this function is called frequently.
if (!match) {
throw usageError(
`Invalid timeout "${value}"`,
Expand All @@ -2528,11 +2530,11 @@
const multiplier =
unit === "h"
? 60 * 60 * 1000
: unit === "m"
? 60 * 1000
: unit === "s"
? 1000
: 1;

Check notice on line 2537 in packages/cli/src/controllers/app.ts

View workflow job for this annotation

GitHub Actions / Lint

lint/style/noNestedTernary

Do not nest ternary expressions.

Check notice on line 2537 in packages/cli/src/controllers/app.ts

View workflow job for this annotation

GitHub Actions / Lint

lint/style/noNestedTernary

Do not nest ternary expressions.
return amount * multiplier;
}

Expand Down Expand Up @@ -2613,7 +2615,7 @@
});
}

async function resolveDeployAppSelection(

Check notice on line 2618 in packages/cli/src/controllers/app.ts

View workflow job for this annotation

GitHub Actions / Lint

lint/complexity/noExcessiveCognitiveComplexity

Excessive complexity of 16 detected (max: 15).
context: CommandContext,
projectId: string,
apps: AppRecord[],
Expand Down Expand Up @@ -3272,7 +3274,7 @@
listProjects: () =>
listRealWorkspaceProjects(
client,
authState.workspace!,

Check warning on line 3277 in packages/cli/src/controllers/app.ts

View workflow job for this annotation

GitHub Actions / Lint

lint/style/noNonNullAssertion

Forbidden non-null assertion.
context.runtime.signal,
),
commandName: options?.commandName,
Expand Down Expand Up @@ -3306,7 +3308,7 @@
};
}

async function resolveDeployProjectContext(

Check notice on line 3311 in packages/cli/src/controllers/app.ts

View workflow job for this annotation

GitHub Actions / Lint

lint/complexity/noExcessiveCognitiveComplexity

Excessive complexity of 18 detected (max: 15).
context: CommandContext,
client: ManagementApiClient,
provider: ReturnType<typeof createAppProvider>,
Expand Down Expand Up @@ -3981,7 +3983,7 @@
continue;
}

const configFile = await detectFrameworkConfigFile(cwd, framework, signal);

Check notice on line 3986 in packages/cli/src/controllers/app.ts

View workflow job for this annotation

GitHub Actions / Lint

lint/performance/noAwaitInLoops

Avoid using await inside loops.
if (
!configFile.exists &&
!hasAnyPackageDependency(packageJson, framework.detectPackages)
Expand Down Expand Up @@ -4079,11 +4081,6 @@
};
}

/**
* The nuxt and astro strategies build with their framework CLI and stage
* fixed output, so a compute config `build` block has nothing to apply to.
* Erroring beats silently ignoring committed settings.
*/
function assertConfigBackedBuildSettings(
buildType: FrameworkBuildType,
): asserts buildType is ConfigBackedBuildType {
Expand Down Expand Up @@ -4185,6 +4182,15 @@
value: settings.outputDirectory,
origin: settings.outputDirectorySource ?? undefined,
},
...(settings.entrypoint
? [
{
label: "Entrypoint",
value: settings.entrypoint,
origin: settings.entrypointSource ?? undefined,
},
]
: []),
]).join("\n")}\n\n`,
);
}
Expand Down Expand Up @@ -4394,7 +4400,7 @@

throw usageError(
`Unsupported build type "${requestedBuildType}"`,
`Only ${APP_BUILD_TYPES.join(", ")} are supported in the current preview.`,
`Only ${APP_BUILD_TYPE_LABELS} are supported in the current preview.`,
"Pass a supported --build-type value.",
getBuildTypeExamples("build"),
"app",
Expand Down Expand Up @@ -4844,22 +4850,18 @@
}

function formatBuildTypeName(buildType: AppBuildType): string {
switch (buildType) {
case "nextjs":
return "Next.js";
case "nuxt":
return "Nuxt";
case "astro":
return "Astro";
case "nestjs":
return "NestJS";
case "tanstack-start":
return "TanStack Start";
case "bun":
return "Bun";
case "auto":
return "Auto";
if (buildType === "auto") {
return "Auto";
}

for (let index = FRAMEWORKS.length - 1; index >= 0; index -= 1) {
const framework = FRAMEWORKS[index];
if (framework?.buildType === buildType) {
return framework.displayName;
}
}

return buildType;
}

function removeFailedError(
Expand Down
1 change: 1 addition & 0 deletions packages/cli/src/lib/app/build-settings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,7 @@ export async function resolveConfiguredAppBuildSettings(options: {
configured: {
command: string | null | undefined;
outputDirectory: string | undefined;
entrypoint?: string | undefined;
};
/** Absolute path of the compute config file owning these settings. */
configPath: string;
Expand Down
43 changes: 28 additions & 15 deletions packages/cli/src/lib/app/build.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,15 @@ import path from "node:path";
import {
type BuildArtifact,
type BuildStrategy,
type BuildType,
normalizeArtifactSymlinks,
resolveBuildStrategy,
stageStandaloneArtifact,
} from "@prisma/compute-sdk";
import {
FRAMEWORKS,
type FrameworkBuildType,
} from "@prisma/compute-sdk/config";

import type { AppBuildSettings } from "./build-settings";

Expand All @@ -25,22 +30,30 @@ export {
resolveInferredAppBuildSettings,
} from "./build-settings";

export const APP_BUILD_TYPES = [
export type AppBuildType = BuildType;
export type ResolvedAppBuildType = FrameworkBuildType;

export const RESOLVED_APP_BUILD_TYPES: readonly ResolvedAppBuildType[] = [
...frameworkBuildTypesByLastOccurrence(),
];

export const APP_BUILD_TYPES: readonly AppBuildType[] = [
"auto",
"bun",
"nextjs",
"nuxt",
"astro",
"nestjs",
"tanstack-start",
] as const;

export type AppBuildType = (typeof APP_BUILD_TYPES)[number];
export type ResolvedAppBuildType = Exclude<AppBuildType, "auto">;

export const RESOLVED_APP_BUILD_TYPES = APP_BUILD_TYPES.filter(
(buildType): buildType is ResolvedAppBuildType => buildType !== "auto",
);
...RESOLVED_APP_BUILD_TYPES,
];

export const APP_BUILD_TYPE_LABELS = APP_BUILD_TYPES.join(", ");

function frameworkBuildTypesByLastOccurrence(): Set<FrameworkBuildType> {
const buildTypes = new Set<FrameworkBuildType>();
for (const framework of FRAMEWORKS) {
if (buildTypes.has(framework.buildType)) {
buildTypes.delete(framework.buildType);
}
buildTypes.add(framework.buildType);
}
return buildTypes;
}

export class AppBuildStrategy implements BuildStrategy {
readonly #appPath: string;
Expand Down
9 changes: 8 additions & 1 deletion packages/cli/src/types/app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,14 @@ export interface AppShowResult {
export interface AppBuildResult {
directory: string;
entrypoint: string | null;
buildType: "bun" | "nextjs" | "nuxt" | "astro" | "nestjs" | "tanstack-start";
buildType:
| "bun"
| "nextjs"
| "nuxt"
| "astro"
| "nestjs"
| "tanstack-start"
| "custom";
}

export interface AppShowDeployResult {
Expand Down
96 changes: 96 additions & 0 deletions packages/cli/tests/app-controller.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1682,6 +1682,102 @@ describe("app controller", () => {
);
});

it("uses and renders configured build entrypoints for custom deploys", async () => {
const requireComputeAuth = vi.fn().mockResolvedValue(createProjectClient());
const listApps = vi.fn().mockResolvedValue([]);
const deployApp = vi.fn().mockResolvedValue({
projectId: "proj_123",
app: {
id: "app_new",
name: "frontend",
region: "eu-central-1",
liveDeploymentId: "dep_123",
},
deployment: {
id: "dep_123",
status: "running",
url: "https://frontend.prisma.app",
},
});

vi.doMock("../src/lib/auth/guard", () => ({
requireComputeAuth,
}));
vi.doMock("../src/lib/app/app-provider", () => ({
createAppProvider: vi.fn(() =>
withBranchDatabaseProviderDefaults({
resolveBranch: createResolveBranch(),
listApps,
deployApp,
listDeployments: vi.fn(),
showDeployment: vi.fn(),
}),
),
}));

const { createTempCwd, createTestCommandContext } = await import(
"./helpers"
);
const { runAppDeploy } = await import("../src/controllers/app");
const cwd = await createTempCwd();
await writeFile(
path.join(cwd, "prisma.compute.ts"),
[
"export default {",
" app: {",
' name: "frontend",',
' framework: "custom",',
" build: {",
' outputDirectory: "dist",',
' entrypoint: "server.js",',
" },",
" },",
"};",
"",
].join("\n"),
"utf8",
);
const { context, stderr } = await createTestCommandContext({
cwd,
stateDir: path.join(cwd, ".state"),
isTTY: false,
env: {
...process.env,
PRISMA_CLI_MOCK_FIXTURE_PATH: undefined,
},
});

const result = await runAppDeploy(context, undefined, {
projectRef: "proj_123",
});

expect(deployApp).toHaveBeenCalledWith(
expect.objectContaining({
appName: "frontend",
buildType: "custom",
entrypoint: undefined,
buildSettings: {
buildCommand: null,
buildCommandSource: null,
outputDirectory: "dist",
outputDirectorySource: "set by prisma.compute.ts",
entrypoint: "server.js",
entrypointSource: "set by prisma.compute.ts",
},
}),
);
expect(asSingleDeployResult(result).result.deploySettings).toMatchObject({
config: {
path: "prisma.compute.ts",
status: "config",
},
entrypoint: "server.js",
});
expect(stderr.buffer).toContain("Using prisma.compute.ts");
expect(stderr.buffer).toContain("Entrypoint");
expect(stderr.buffer).toContain("server.js");
});

it("returns LOCAL_STATE_WRITE_FAILED when deploy cannot store the local binding", async () => {
const requireComputeAuth = vi
.fn()
Expand Down
Loading
Loading