@prisma/cli 3.0.0-dev.80.1 → 3.0.0-dev.82.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.
@@ -69,7 +69,8 @@ function hasBranchDatabaseSignal(signal) {
69
69
  }
70
70
  async function runBranchDatabaseSchemaSetup(options) {
71
71
  const schemaPath = path.relative(options.context.runtime.cwd, options.schema.path) || defaultSchemaSourcePath(options.schema);
72
- const commands = buildSchemaSetupCommands(options.schema, schemaPath, options.databaseUrl);
72
+ const prisma = await resolvePrismaInvocation(options.context.runtime.cwd);
73
+ const commands = buildSchemaSetupCommands(options.schema, schemaPath, options.databaseUrl, prisma);
73
74
  for (const command of commands) await runPrismaCommand({
74
75
  context: options.context,
75
76
  ...command,
@@ -229,28 +230,73 @@ async function readTextFileIfSmall(filePath, signal) {
229
230
  signal
230
231
  });
231
232
  }
232
- function buildSchemaSetupCommands(schema, schemaPath, databaseUrl) {
233
+ const FALLBACK_PRISMA_CLI_VERSION = "6.19.3";
234
+ /**
235
+ * Picks how `prisma` CLI commands are invoked for schema setup. Projects
236
+ * with the CLI installed run their own binary (version-exact). Projects
237
+ * without it fall back to a versioned `npx prisma@<x>` pinned to the
238
+ * installed `@prisma/client` — never bare `npx prisma`, which resolves to
239
+ * latest and can be a major version ahead of the project's schema.
240
+ */
241
+ async function resolvePrismaInvocation(cwd) {
242
+ if (await localPrismaBinExists(cwd)) return {
243
+ argsPrefix: ["--no-install", "prisma"],
244
+ displayPrefix: "npx --no-install prisma"
245
+ };
246
+ const pinned = await readInstalledPrismaClientVersion(cwd) ?? FALLBACK_PRISMA_CLI_VERSION;
247
+ return {
248
+ argsPrefix: ["--yes", `prisma@${pinned}`],
249
+ displayPrefix: `npx prisma@${pinned}`
250
+ };
251
+ }
252
+ /** npm/pnpm name the local CLI shim `prisma` on POSIX and `prisma.cmd`/`prisma.ps1` on Windows. */
253
+ async function localPrismaBinExists(cwd) {
254
+ const binDir = path.join(cwd, "node_modules", ".bin");
255
+ return (await Promise.all([
256
+ "prisma",
257
+ "prisma.cmd",
258
+ "prisma.ps1"
259
+ ].map((name) => fileExists(path.join(binDir, name))))).some(Boolean);
260
+ }
261
+ async function fileExists(filePath) {
262
+ try {
263
+ await access(filePath);
264
+ return true;
265
+ } catch {
266
+ return false;
267
+ }
268
+ }
269
+ async function readInstalledPrismaClientVersion(cwd) {
270
+ try {
271
+ const raw = await readFile(path.join(cwd, "node_modules", "@prisma", "client", "package.json"), { encoding: "utf8" });
272
+ const parsed = JSON.parse(raw);
273
+ if (typeof parsed !== "object" || parsed === null) return null;
274
+ const version = parsed.version;
275
+ return typeof version === "string" && version.length > 0 ? version : null;
276
+ } catch {
277
+ return null;
278
+ }
279
+ }
280
+ function buildSchemaSetupCommands(schema, schemaPath, databaseUrl, prisma) {
233
281
  if (schema.command === "migrate-deploy") return [{
234
282
  args: [
235
- "--no-install",
236
- "prisma",
283
+ ...prisma.argsPrefix,
237
284
  "migrate",
238
285
  "deploy",
239
286
  "--schema",
240
287
  schemaPath
241
288
  ],
242
- displayCommand: "npx --no-install prisma migrate deploy"
289
+ displayCommand: `${prisma.displayPrefix} migrate deploy`
243
290
  }];
244
291
  if (schema.command === "db-push") return [{
245
292
  args: [
246
- "--no-install",
247
- "prisma",
293
+ ...prisma.argsPrefix,
248
294
  "db",
249
295
  "push",
250
296
  "--schema",
251
297
  schemaPath
252
298
  ],
253
- displayCommand: "npx --no-install prisma db push"
299
+ displayCommand: `${prisma.displayPrefix} db push`
254
300
  }];
255
301
  return [{
256
302
  args: [
@@ -1,6 +1,6 @@
1
1
  import { readBunPackageJson, resolveBunEntrypoint } from "./bun-project.js";
2
2
  import { PRISMA_APP_CONFIG_FILENAME, hasAnyPackageDependency, hasPackageDependency, hasRootFile, joinPosix, nextOutputRootFromStandaloneDirectory, resolvePreviewBuildSettings, runResolvedBuildCommand } from "./preview-build-settings.js";
3
- import { chmod, copyFile, cp, lstat, mkdir, mkdtemp, readFile, readdir, readlink, rm, stat } from "node:fs/promises";
3
+ import { chmod, copyFile, cp, lstat, mkdir, mkdtemp, readFile, readdir, readlink, rm, stat, writeFile } from "node:fs/promises";
4
4
  import path from "node:path";
5
5
  import os from "node:os";
6
6
  import { AstroBuild, BunBuild, NuxtBuild } from "@prisma/compute-sdk";
@@ -151,7 +151,7 @@ var PreviewNextjsBuild = class {
151
151
  });
152
152
  await runResolvedBuildCommand(this.#appPath, settings, "Next.js", signal);
153
153
  const standaloneDir = path.join(this.#appPath, settings.outputDirectory);
154
- if (!await directoryExists(standaloneDir, signal)) throw new Error(`Next.js build did not produce standalone output at ${settings.outputDirectory}. Add output: "standalone" to your next.config file, or update ${PRISMA_APP_CONFIG_FILENAME}.`);
154
+ if (!await directoryExists(standaloneDir, signal)) return stageNextjsFullTreeFallbackArtifact(this.#appPath, signal);
155
155
  const outDir = await unsupportedFilesystemBoundary(signal, () => mkdtemp(path.join(os.tmpdir(), "compute-build-")));
156
156
  try {
157
157
  const artifactDir = path.join(outDir, "app");
@@ -187,6 +187,45 @@ var PreviewNextjsBuild = class {
187
187
  }
188
188
  }
189
189
  };
190
+ const FULL_TREE_NEXT_START_ENTRYPOINT = "prisma-next-start.cjs";
191
+ const FULL_TREE_NEXT_START_SOURCE = [
192
+ "process.chdir(__dirname);",
193
+ "process.env.NODE_ENV = \"production\";",
194
+ "process.argv.push(\"start\", \"-p\", process.env.PORT ?? \"3000\");",
195
+ "require(\"next/dist/bin/next\");",
196
+ ""
197
+ ].join("\n");
198
+ async function stageNextjsFullTreeFallbackArtifact(appPath, signal) {
199
+ const outDir = await unsupportedFilesystemBoundary(signal, () => mkdtemp(path.join(os.tmpdir(), "compute-build-")));
200
+ try {
201
+ const artifactDir = path.join(outDir, "app");
202
+ await unsupportedFilesystemBoundary(signal, () => cp(appPath, artifactDir, {
203
+ recursive: true,
204
+ verbatimSymlinks: true,
205
+ filter: (source) => !isExcludedFromFullTreeArtifact(path.basename(source))
206
+ }));
207
+ await unsupportedFilesystemBoundary(signal, () => writeFile(path.join(artifactDir, FULL_TREE_NEXT_START_ENTRYPOINT), FULL_TREE_NEXT_START_SOURCE));
208
+ return {
209
+ directory: artifactDir,
210
+ entrypoint: FULL_TREE_NEXT_START_ENTRYPOINT,
211
+ defaultPortMapping: { http: 3e3 },
212
+ cleanup: () => rm(outDir, {
213
+ recursive: true,
214
+ force: true
215
+ })
216
+ };
217
+ } catch (error) {
218
+ await rm(outDir, {
219
+ recursive: true,
220
+ force: true
221
+ });
222
+ throw error;
223
+ }
224
+ }
225
+ /** Excludes VCS internals and dotenv files (local secrets, superseded by the deploy env). */
226
+ function isExcludedFromFullTreeArtifact(basename) {
227
+ return basename === ".git" || basename === ".env" || basename.startsWith(".env.");
228
+ }
190
229
  var PreviewTanstackStartBuild = class {
191
230
  #appPath;
192
231
  #buildSettings;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@prisma/cli",
3
- "version": "3.0.0-dev.80.1",
3
+ "version": "3.0.0-dev.82.1",
4
4
  "description": "Command-line interface for the Prisma Developer Platform.",
5
5
  "type": "module",
6
6
  "bin": {