Skip to content

fix: codegen prisma#117

Open
olliethedev wants to merge 4 commits intomainfrom
fix/cogegen-cli-prisma
Open

fix: codegen prisma#117
olliethedev wants to merge 4 commits intomainfrom
fix/cogegen-cli-prisma

Conversation

@olliethedev
Copy link
Copy Markdown
Collaborator

@olliethedev olliethedev commented Apr 15, 2026

Summary

  • fix codegen cli issues for prisma adapter

Type of change

  • Bug fix
  • New plugin
  • Feature / enhancement to an existing plugin
  • Documentation
  • Chore / refactor / tooling

Checklist

  • pnpm build passes
  • pnpm typecheck passes
  • pnpm lint passes
  • Tests added or updated (unit and/or E2E)
  • Docs updated (docs/content/docs/) if consumer-facing types or behavior changed
  • All three codegen-projects create successfully and pass E2E tests
  • New plugin: submission checklist in CONTRIBUTING.md completed

Screenshots


Note

Medium Risk
Touches init scaffolding, dependency installation, and generate passthrough args; mistakes could break new project setup or produce codegen output in the wrong location, especially for Prisma.

Overview
Fixes Prisma adapter initialization so generated projects can run codegen successfully and resolve the Prisma client consistently.

init now passes an explicit --output to generate (via new getOutputForAdapter) and updates the generate hint accordingly. The Prisma adapter metadata now installs required extra dependencies (@prisma/adapter-pg, pg), and the scaffolded Prisma stack config switches to a PrismaPg-backed PrismaClient imported from the scaffolded generated/prisma output.

When Prisma is selected, scaffolding also writes a prisma/schema.prisma with an explicit client output directory plus a prisma.config.ts to point Prisma at the schema and DATABASE_URL.

Reviewed by Cursor Bugbot for commit 1a6c772. Bugbot is set up for automated code reviews on this repo. Configure here.

@vercel
Copy link
Copy Markdown

vercel bot commented Apr 15, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
better-stack-docs Ready Ready Preview, Comment Apr 15, 2026 9:21pm
better-stack-playground Ready Ready Preview, Comment Apr 15, 2026 9:21pm

Request Review

Copy link
Copy Markdown

@cursor cursor bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Security Review — No High-Confidence Vulnerabilities Found

The diff introduces two focused changes: a hardcoded --output path for Prisma codegen and updated Prisma scaffold templates. After reviewing each change against the threat checklist, no exploitable security vulnerabilities were identified.

Analysis

Injection risks (CLI argument building)
getOutputForAdapter returns one of three hardcoded literal strings ("prisma/schema.prisma", "src/db/schema.ts", "migrations/schema.sql"). The adapter and orm values are resolved through a constant allowlist (ADAPTERS), so no user-controlled data flows into the constructed argument array. runCliPassthrough calls execa in array mode (not a shell string), which fully eliminates shell-injection risk regardless of argument content.

Path traversal
The new --output argument value is derived from a hardcoded lookup, not from user or filesystem input. No traversal vector exists.

Secrets / credential handling
The scaffolded stack.ts uses process.env.DATABASE_URL! and the prisma.config.ts uses process.env.DATABASE_URL ?? ''. Both are standard environment-variable references in generated template code. Neither logs nor leaks credentials.

Supply-chain
The only new dependency introduced in generated code is @prisma/adapter-pg, a first-party Prisma package. No novel or unknown third-party packages are added.

Functional notes (not security findings)

  • The generated prisma/schema.prisma omits a url field in datasource db; Prisma will refuse to run without it. This is a misconfiguration bug, not a vulnerability.
  • DATABASE_URL ?? '' in prisma.config.ts silently passes an empty string when the env var is unset, causing a confusing runtime failure rather than an early error. Consider failing loudly instead.
  • The non-null assertion process.env.DATABASE_URL! in stack.ts passes undefined at runtime if the variable is missing; a guard or explicit error would be safer ergonomically, though not exploitable.
Open in Web View Automation 

Sent by Cursor Automation: Find vulnerabilities

Comment thread packages/cli/src/utils/scaffold-plan.ts Outdated
…k file depth

Co-authored-by: Ollie <olliethedev@users.noreply.github.com>
Comment thread packages/cli/src/utils/scaffold-plan.ts
Co-authored-by: Ollie <olliethedev@users.noreply.github.com>
Copy link
Copy Markdown

@cursor cursor bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Fix All in Cursor

Bugbot Autofix prepared a fix for the issue found in the latest run.

  • ✅ Fixed: Missing pg dependency in Prisma adapter extra packages
    • Added "pg" to the extraPackages array for the prisma adapter in constants.ts so it gets installed alongside @prisma/adapter-pg.
Preview (1a6c772ba3)
diff --git a/packages/cli/src/commands/init.ts b/packages/cli/src/commands/init.ts
--- a/packages/cli/src/commands/init.ts
+++ b/packages/cli/src/commands/init.ts
@@ -321,8 +321,13 @@
 						const orm = ADAPTERS.find(
 							(item) => item.key === adapter,
 						)?.ormForGenerate;
+						const outputPath = getOutputForAdapter(adapter);
 						const args = orm
-							? [`--orm=${orm}`, `--config=${stackPath}`]
+							? [
+									`--orm=${orm}`,
+									`--config=${stackPath}`,
+									...(outputPath ? [`--output=${outputPath}`] : []),
+								]
 							: [`--config=${stackPath}`];
 						const exitCode = await runCliPassthrough({
 							cwd,

diff --git a/packages/cli/src/utils/constants.ts b/packages/cli/src/utils/constants.ts
--- a/packages/cli/src/utils/constants.ts
+++ b/packages/cli/src/utils/constants.ts
@@ -5,6 +5,8 @@
 	label: string;
 	packageName: string;
 	ormForGenerate?: "prisma" | "drizzle" | "kysely";
+	/** Additional npm packages that must be installed when this adapter is selected. */
+	extraPackages?: string[];
 }
 
 export interface PluginMeta {
@@ -33,6 +35,7 @@
 		label: "Prisma",
 		packageName: "@btst/adapter-prisma",
 		ormForGenerate: "prisma",
+		extraPackages: ["@prisma/adapter-pg", "pg"],
 	},
 	{
 		key: "drizzle",

diff --git a/packages/cli/src/utils/package-installer.ts b/packages/cli/src/utils/package-installer.ts
--- a/packages/cli/src/utils/package-installer.ts
+++ b/packages/cli/src/utils/package-installer.ts
@@ -39,6 +39,7 @@
 		"@btst/yar",
 		"@tanstack/react-query",
 		adapterMeta.packageName,
+		...(adapterMeta.extraPackages ?? []),
 		...pluginExtraPackages,
 	];
 	const { command, args } = getInstallCommand(input.packageManager, packages);

diff --git a/packages/cli/src/utils/passthrough.ts b/packages/cli/src/utils/passthrough.ts
--- a/packages/cli/src/utils/passthrough.ts
+++ b/packages/cli/src/utils/passthrough.ts
@@ -7,6 +7,15 @@
 	return Boolean(ADAPTERS.find((item) => item.key === adapter)?.ormForGenerate);
 }
 
+export function getOutputForAdapter(adapter: Adapter): string | null {
+	const meta = ADAPTERS.find((item) => item.key === adapter);
+	if (!meta?.ormForGenerate) return null;
+
+	if (meta.ormForGenerate === "prisma") return "prisma/schema.prisma";
+	if (meta.ormForGenerate === "drizzle") return "src/db/schema.ts";
+	return "migrations/schema.sql";
+}
+
 export function getGenerateHintForAdapter(
 	adapter: Adapter,
 	configPath: string,
@@ -14,12 +23,8 @@
 	const meta = ADAPTERS.find((item) => item.key === adapter);
 	if (!meta?.ormForGenerate) return null;
 
-	const output =
-		meta.ormForGenerate === "prisma"
-			? "schema.prisma"
-			: meta.ormForGenerate === "drizzle"
-				? "src/db/schema.ts"
-				: "migrations/schema.sql";
+	const output = getOutputForAdapter(adapter);
+	if (!output) return null;
 
 	return `npx @btst/codegen generate --orm=${meta.ormForGenerate} --config=${configPath} --output=${output}`;
 }

diff --git a/packages/cli/src/utils/scaffold-plan.ts b/packages/cli/src/utils/scaffold-plan.ts
--- a/packages/cli/src/utils/scaffold-plan.ts
+++ b/packages/cli/src/utils/scaffold-plan.ts
@@ -322,7 +322,7 @@
 	};
 }
 
-function buildAdapterTemplateContext(adapter: Adapter) {
+function buildAdapterTemplateContext(adapter: Adapter, stackPath: string) {
 	const meta = ADAPTERS.find((item) => item.key === adapter);
 	if (!meta) {
 		throw new Error(`Unsupported adapter: ${adapter}`);
@@ -337,15 +337,19 @@
 	}
 
 	if (adapter === "prisma") {
+		const depth = stackPath.split("/").length - 1;
+		const prismaClientPath = `${"../".repeat(depth)}generated/prisma/client`;
 		return {
 			adapterImport: `import { createPrismaAdapter } from "${meta.packageName}"
-import { PrismaClient } from "@prisma/client"`,
-			adapterSetup: `const prisma = new PrismaClient()
+import { PrismaClient } from "${prismaClientPath}"
+import { PrismaPg } from "@prisma/adapter-pg"`,
+			adapterSetup: `const pgAdapter = new PrismaPg({ connectionString: process.env.DATABASE_URL! })
+const prisma = new PrismaClient({ adapter: pgAdapter })
 
-const provider = process.env.BTST_PRISMA_PROVIDER ?? "postgresql"
+const provider = (process.env.BTST_PRISMA_PROVIDER ?? "postgresql") as "postgresql" | "sqlite" | "cockroachdb" | "mysql" | "sqlserver" | "mongodb"
 `,
 			adapterStackLine:
-				"adapter: (db) => createPrismaAdapter(prisma, db, { provider }),",
+				"adapter: (db) => createPrismaAdapter(prisma, db, { provider })({}),",
 		};
 	}
 
@@ -385,7 +389,10 @@
 		input.plugins,
 		input.framework,
 	);
-	const adapterContext = buildAdapterTemplateContext(input.adapter);
+	const adapterContext = buildAdapterTemplateContext(
+		input.adapter,
+		frameworkPaths.stackPath,
+	);
 
 	const sharedContext = {
 		alias: input.alias,
@@ -402,6 +409,20 @@
 			content: await renderTemplate("shared/lib/stack.ts.hbs", sharedContext),
 			description: "BTST backend stack configuration",
 		},
+		...(input.adapter === "prisma"
+			? [
+					{
+						path: "prisma/schema.prisma",
+						content: `generator client {\n  provider = "prisma-client"\n  output   = "../generated/prisma"\n}\n\ndatasource db {\n  provider = "postgresql"\n}\n`,
+						description: "Prisma schema with explicit client output path",
+					},
+					{
+						path: "prisma.config.ts",
+						content: `import { defineConfig } from 'prisma/config'\n\nexport default defineConfig({\n  schema: 'prisma/schema.prisma',\n  datasource: {\n    url: process.env.DATABASE_URL ?? '',\n  },\n})\n`,
+						description: "Prisma configuration file",
+					},
+				]
+			: []),
 		{
 			path: frameworkPaths.stackClientPath,
 			content: await renderTemplate(

You can send follow-ups to the cloud agent here.

Reviewed by Cursor Bugbot for commit c112ecd. Configure here.

Comment thread packages/cli/src/utils/constants.ts Outdated
Co-authored-by: Ollie <olliethedev@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants