From 66bc9fe578e303e8b1488814b3193b27d892a11d Mon Sep 17 00:00:00 2001 From: Aman Varshney Date: Wed, 2 Sep 2026 15:52:58 +0530 Subject: [PATCH 1/5] fix: reuse installed Prisma CLI after setup --- src/tasks/deploy-with-composer.ts | 13 +++++-------- src/tasks/setup-prisma.ts | 9 +++++++-- 2 files changed, 12 insertions(+), 10 deletions(-) diff --git a/src/tasks/deploy-with-composer.ts b/src/tasks/deploy-with-composer.ts index 8e8bcb3..76e08b4 100644 --- a/src/tasks/deploy-with-composer.ts +++ b/src/tasks/deploy-with-composer.ts @@ -3,7 +3,6 @@ import { execa } from "execa"; import { createInterface } from "node:readline"; import type { Writable } from "node:stream"; -import { PRISMA_PLATFORM_CLI_PACKAGE } from "../constants/dependencies"; import { ClassifiedCreateError, getCreateFailureReason, @@ -13,8 +12,8 @@ import { import type { PackageManager } from "../types"; import { getErrorMessage, redactSecrets } from "../utils/errors"; import { - getPackageExecutionArgs, - getPackageExecutionCommand, + getLocalPackageBinaryArgs, + getLocalPackageBinaryCommand, getRunScriptArgs, getRunScriptCommand, } from "../utils/package-manager"; @@ -149,7 +148,7 @@ export function parsePrismaCliEnvelope( } function getPrismaCliArgs(packageManager: PackageManager, args: string[]) { - return getPackageExecutionArgs(packageManager, [PRISMA_PLATFORM_CLI_PACKAGE, ...args]); + return getLocalPackageBinaryArgs(packageManager, "prisma", args); } async function runPrismaJsonCommand(options: { @@ -251,8 +250,7 @@ async function ensureAuthentication(options: { const authState = await whoami(); if (authState.authenticated) return authState; - const loginCommand = getPackageExecutionCommand(options.packageManager, [ - PRISMA_PLATFORM_CLI_PACKAGE, + const loginCommand = getLocalPackageBinaryCommand(options.packageManager, "prisma", [ "auth", "login", ]); @@ -517,8 +515,7 @@ export async function deployNewProjectWithComposer(options: { clearProgress(); failureStage = "composer_deploy"; failureReason = "composer_deploy_failed"; - const deployCommand = getPackageExecutionCommand(options.packageManager, [ - PRISMA_PLATFORM_CLI_PACKAGE, + const deployCommand = getLocalPackageBinaryCommand(options.packageManager, "prisma", [ "deploy", "module.ts", ]); diff --git a/src/tasks/setup-prisma.ts b/src/tasks/setup-prisma.ts index 4ace2e3..388f050 100644 --- a/src/tasks/setup-prisma.ts +++ b/src/tasks/setup-prisma.ts @@ -29,6 +29,7 @@ import { getErrorMessage } from "../utils/errors"; import { detectPackageManager, getInstallCommand, + getLocalPackageBinaryArgs, getPackageExecutionArgs, getRunScriptCommand, } from "../utils/package-manager"; @@ -235,6 +236,10 @@ function getPrismaCliInvocation(packageManager: PackageManager, args: string[]) return getPackageExecutionArgs(packageManager, [packageName, ...args]); } +function getInstalledPrismaCliInvocation(packageManager: PackageManager, args: string[]) { + return getLocalPackageBinaryArgs(packageManager, "prisma", args); +} + async function runPrismaInit(context: PrismaSetupContext, projectDir: string): Promise { const args = [ "orm", @@ -272,7 +277,7 @@ async function initializeAgentSkills( ): Promise { if (context.packageManager === "deno") return; - const invocation = getPrismaCliInvocation(context.packageManager, [ + const invocation = getInstalledPrismaCliInvocation(context.packageManager, [ "init", "--yes", "--no-interactive", @@ -342,7 +347,7 @@ async function runPrismaCli( projectDir: string, args: string[], ): Promise { - const invocation = getPrismaCliInvocation(context.packageManager, args); + const invocation = getInstalledPrismaCliInvocation(context.packageManager, args); if (context.verbose) { log.step([invocation.command, ...invocation.args].join(" "), { output: context.output }); } From d90d3c56358db01a3f0c5d3e68e699b08f4711d5 Mon Sep 17 00:00:00 2001 From: Aman Varshney Date: Wed, 2 Sep 2026 16:05:57 +0530 Subject: [PATCH 2/5] fix: require the installed Prisma CLI Signed-off-by: Aman Varshney --- src/utils/package-manager.ts | 7 +++++-- tests/install.test.ts | 12 ++++++++++++ 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/src/utils/package-manager.ts b/src/utils/package-manager.ts index 155467a..552bdc1 100644 --- a/src/utils/package-manager.ts +++ b/src/utils/package-manager.ts @@ -258,7 +258,7 @@ export function getLocalPackageBinaryArgs( case "deno": return { command: "deno", - args: ["run", "-A", DENO_ALLOW_FRESH_DEPENDENCIES, `npm:${binaryName}`, ...binaryArgs], + args: ["run", "-A", "--frozen", `npm:${binaryName}`, ...binaryArgs], }; case "pnpm": return { command: "pnpm", args: ["exec", binaryName, ...binaryArgs] }; @@ -268,7 +268,10 @@ export function getLocalPackageBinaryArgs( return { command: "bun", args: [binaryName, ...binaryArgs] }; case "npm": default: - return { command: "npm", args: ["exec", binaryName, "--", ...binaryArgs] }; + return { + command: "npm", + args: ["exec", "--offline", "--yes=false", "--", binaryName, ...binaryArgs], + }; } } diff --git a/tests/install.test.ts b/tests/install.test.ts index 171adfc..484f4f9 100644 --- a/tests/install.test.ts +++ b/tests/install.test.ts @@ -13,6 +13,7 @@ import { import { authoringStyles, createTemplates, databaseProviders, packageManagers } from "../src/types"; import { getInstallArgs, + getLocalPackageBinaryArgs, getPackageExecutionArgs, getRunScriptCommand, } from "../src/utils/package-manager"; @@ -134,6 +135,17 @@ describe("Composer package-manager commands", () => { args: ["run", "-A", "--minimum-dependency-age=0", "npm:prisma@8.0.0-rc.11", "orm", "init"], }); }); + + test("runs the installed Prisma CLI without registry fallback", () => { + expect(getLocalPackageBinaryArgs("npm", "prisma", ["contract", "emit"])).toEqual({ + command: "npm", + args: ["exec", "--offline", "--yes=false", "--", "prisma", "contract", "emit"], + }); + expect(getLocalPackageBinaryArgs("deno", "prisma", ["contract", "emit"])).toEqual({ + command: "deno", + args: ["run", "-A", "--frozen", "npm:prisma", "contract", "emit"], + }); + }); }); describe("generated templates", () => { From e3ec837a57ca15e88c826e085baf10fa7e8fbe25 Mon Sep 17 00:00:00 2001 From: Aman Varshney Date: Wed, 2 Sep 2026 16:10:59 +0530 Subject: [PATCH 3/5] fix: freeze Deno to the installed Prisma release Signed-off-by: Aman Varshney --- src/utils/package-manager.ts | 2 +- tests/install.test.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/utils/package-manager.ts b/src/utils/package-manager.ts index 552bdc1..9569143 100644 --- a/src/utils/package-manager.ts +++ b/src/utils/package-manager.ts @@ -258,7 +258,7 @@ export function getLocalPackageBinaryArgs( case "deno": return { command: "deno", - args: ["run", "-A", "--frozen", `npm:${binaryName}`, ...binaryArgs], + args: ["run", "-A", "--frozen", `npm:${binaryName}@latest`, ...binaryArgs], }; case "pnpm": return { command: "pnpm", args: ["exec", binaryName, ...binaryArgs] }; diff --git a/tests/install.test.ts b/tests/install.test.ts index 484f4f9..3c3ebbc 100644 --- a/tests/install.test.ts +++ b/tests/install.test.ts @@ -143,7 +143,7 @@ describe("Composer package-manager commands", () => { }); expect(getLocalPackageBinaryArgs("deno", "prisma", ["contract", "emit"])).toEqual({ command: "deno", - args: ["run", "-A", "--frozen", "npm:prisma", "contract", "emit"], + args: ["run", "-A", "--frozen", "npm:prisma@latest", "contract", "emit"], }); }); }); From 972350e1f6e2502c044364cb765b2c8e2b5028e2 Mon Sep 17 00:00:00 2001 From: Aman Varshney Date: Wed, 2 Sep 2026 16:16:18 +0530 Subject: [PATCH 4/5] fix: install Prisma before initialization Signed-off-by: Aman Varshney --- src/tasks/setup-prisma.ts | 49 +++++++++++++---------------- tests/e2e/create-prisma.e2e.test.ts | 10 +++--- 2 files changed, 27 insertions(+), 32 deletions(-) diff --git a/src/tasks/setup-prisma.ts b/src/tasks/setup-prisma.ts index 388f050..0e94b63 100644 --- a/src/tasks/setup-prisma.ts +++ b/src/tasks/setup-prisma.ts @@ -3,7 +3,6 @@ import fs from "fs-extra"; import path from "node:path"; import type { Writable } from "node:stream"; -import { PRISMA_DENO_CLI_PACKAGE, PRISMA_PLATFORM_CLI_PACKAGE } from "../constants/dependencies"; import { ClassifiedCreateError, CreateCancellationError, @@ -30,7 +29,6 @@ import { detectPackageManager, getInstallCommand, getLocalPackageBinaryArgs, - getPackageExecutionArgs, getRunScriptCommand, } from "../utils/package-manager"; import { runSetupCommand } from "../utils/run-command"; @@ -230,12 +228,6 @@ function getInitTarget(provider: DatabaseProvider): "postgres" | "mongodb" { return provider === "mongo" ? "mongodb" : "postgres"; } -function getPrismaCliInvocation(packageManager: PackageManager, args: string[]) { - const packageName = - packageManager === "deno" ? PRISMA_DENO_CLI_PACKAGE : PRISMA_PLATFORM_CLI_PACKAGE; - return getPackageExecutionArgs(packageManager, [packageName, ...args]); -} - function getInstalledPrismaCliInvocation(packageManager: PackageManager, args: string[]) { return getLocalPackageBinaryArgs(packageManager, "prisma", args); } @@ -254,7 +246,7 @@ async function runPrismaInit(context: PrismaSetupContext, projectDir: string): P getContractPath(context.authoring), "--skip-install", ]; - const invocation = getPrismaCliInvocation(context.packageManager, args); + const invocation = getInstalledPrismaCliInvocation(context.packageManager, args); if (context.verbose) { log.step(`Running ${[invocation.command, ...invocation.args].join(" ")}`, { output: context.output, @@ -459,12 +451,31 @@ export async function executePrismaSetupContext( : (options.progressSpinner ?? spinner({ output: context.output })); const ownsProgress = progress !== undefined && !options.progressSpinner; let gitInitialization: GitInitializationResult | undefined; - let setupStage: CreateFailureStage = "initialize_prisma"; - let setupReason: CreateFailureReason = "prisma_init_failed"; + let setupStage: CreateFailureStage = "configure_project"; + let setupReason: CreateFailureReason = "project_configuration_failed"; if (ownsProgress) progress.start("Creating Prisma 8 project..."); try { + await writePrismaDependencies( + context.databaseProvider, + context.packageManager, + context.authoring, + projectDir, + ); + + progress?.message( + `Installing dependencies with ${getInstallCommand(context.packageManager)}...`, + ); + setupStage = "install_dependencies"; + setupReason = "dependency_install_failed"; + await installProjectDependencies(context.packageManager, projectDir, { + verbose: context.verbose, + json: context.json, + }); + progress?.message("Preparing Prisma 8 project files..."); + setupStage = "initialize_prisma"; + setupReason = "prisma_init_failed"; await runPrismaInit(context, projectDir); setupStage = "configure_project"; @@ -477,12 +488,6 @@ export async function executePrismaSetupContext( authoring: context.authoring, packageManager: context.packageManager, }); - await writePrismaDependencies( - context.databaseProvider, - context.packageManager, - context.authoring, - projectDir, - ); await ensureComposerTypeScriptOptions(projectDir); if (context.databaseProvider === "mongo") await ensureMongoEnvironment(projectDir); if (context.packageManager !== "deno") { @@ -490,16 +495,6 @@ export async function executePrismaSetupContext( await ensureGitignoreEntry(projectDir, "/.prisma-composer"); } - progress?.message( - `Installing dependencies with ${getInstallCommand(context.packageManager)}...`, - ); - setupStage = "install_dependencies"; - setupReason = "dependency_install_failed"; - await installProjectDependencies(context.packageManager, projectDir, { - verbose: context.verbose, - json: context.json, - }); - progress?.message("Installing Prisma agent skills..."); setupStage = "initialize_agent_skills"; setupReason = "agent_skills_init_failed"; diff --git a/tests/e2e/create-prisma.e2e.test.ts b/tests/e2e/create-prisma.e2e.test.ts index 11c759d..e0bebf9 100644 --- a/tests/e2e/create-prisma.e2e.test.ts +++ b/tests/e2e/create-prisma.e2e.test.ts @@ -264,11 +264,11 @@ describe("create-prisma e2e", () => { ]); expect(exitCode).toBe(1); expect(stdout.trim().split(/\r?\n/)).toHaveLength(1); - expect(JSON.parse(stdout)).toMatchObject({ - schemaVersion: 1, - ok: false, - error: { stage: "initialize_prisma" }, - }); + expect(JSON.parse(stdout)).toMatchObject({ + schemaVersion: 1, + ok: false, + error: { stage: "install_dependencies" }, + }); expect(stderr).toBe(""); expect(await pathExists(path.join(rootDir, "failed-app", "package.json"))).toBe(true); }); From 1e16abbe7608b5233cdbdbd28db8cbe0e24c1b3e Mon Sep 17 00:00:00 2001 From: Aman Varshney Date: Wed, 2 Sep 2026 16:28:52 +0530 Subject: [PATCH 5/5] test: format setup failure assertion Signed-off-by: Aman Varshney --- tests/e2e/create-prisma.e2e.test.ts | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/tests/e2e/create-prisma.e2e.test.ts b/tests/e2e/create-prisma.e2e.test.ts index e0bebf9..7cf4048 100644 --- a/tests/e2e/create-prisma.e2e.test.ts +++ b/tests/e2e/create-prisma.e2e.test.ts @@ -264,11 +264,11 @@ describe("create-prisma e2e", () => { ]); expect(exitCode).toBe(1); expect(stdout.trim().split(/\r?\n/)).toHaveLength(1); - expect(JSON.parse(stdout)).toMatchObject({ - schemaVersion: 1, - ok: false, - error: { stage: "install_dependencies" }, - }); + expect(JSON.parse(stdout)).toMatchObject({ + schemaVersion: 1, + ok: false, + error: { stage: "install_dependencies" }, + }); expect(stderr).toBe(""); expect(await pathExists(path.join(rootDir, "failed-app", "package.json"))).toBe(true); });