@prisma/cli 3.0.0-dev.71.1 → 3.0.0-dev.73.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.
@@ -31,6 +31,7 @@ import { listRealWorkspaceProjects } from "./project.js";
31
31
  import { access, readFile } from "node:fs/promises";
32
32
  import path from "node:path";
33
33
  import open from "open";
34
+ import { Result, matchError } from "better-result";
34
35
  //#region src/controllers/app.ts
35
36
  const DEPLOY_FRAMEWORKS = [
36
37
  "nextjs",
@@ -112,9 +113,9 @@ async function runAppDeploy(context, appName, options) {
112
113
  createProjectName: options?.createProjectName,
113
114
  envProjectId
114
115
  });
115
- const skipLocalPin = Boolean(envProjectId || options?.projectRef || options?.createProjectName);
116
- const localPin = skipLocalPin ? { kind: "missing" } : await readLocalResolutionPin(context.runtime.cwd, context.runtime.signal);
117
- if (!skipLocalPin && localPin.kind === "invalid") throw localResolutionPinStaleError();
116
+ const localPinReadResult = Boolean(envProjectId || options?.projectRef || options?.createProjectName) ? Result.ok({ kind: "missing" }) : await readLocalResolutionPin(context.runtime.cwd, context.runtime.signal);
117
+ if (localPinReadResult.isErr()) throw localPinReadErrorToDeployError(localPinReadResult.error);
118
+ const localPin = localPinReadResult.value;
118
119
  const branch = await resolveDeployBranch(context, options?.branchName);
119
120
  if (options?.httpPort) parseDeployHttpPort(options.httpPort);
120
121
  assertSupportedEntrypointForRequestedDeployShape({
@@ -1976,6 +1977,18 @@ function localResolutionPinStaleError() {
1976
1977
  ]
1977
1978
  });
1978
1979
  }
1980
+ function localPinReadErrorToDeployError(error) {
1981
+ return matchError(error, {
1982
+ LocalResolutionPinInvalidJsonError: () => localResolutionPinStaleError(),
1983
+ LocalResolutionPinInvalidShapeError: () => localResolutionPinStaleError(),
1984
+ LocalResolutionPinReadAbortedError: (error) => {
1985
+ throw error;
1986
+ },
1987
+ UnhandledException: (error) => {
1988
+ throw error;
1989
+ }
1990
+ });
1991
+ }
1979
1992
  function readDeployEnvOverride(context, name) {
1980
1993
  const value = context.runtime.env[name]?.trim();
1981
1994
  return value ? value : void 0;
@@ -13,6 +13,7 @@ import { requireAuthenticatedAuthState } from "./auth.js";
13
13
  import { parseGitHubRepositoryUrl, readGitOriginRemote } from "../adapters/git.js";
14
14
  import { createProjectUseCases } from "../use-cases/project.js";
15
15
  import open from "open";
16
+ import { matchError } from "better-result";
16
17
  //#region src/controllers/project.ts
17
18
  const GITHUB_INSTALL_POLL_INTERVAL_MS = 2e3;
18
19
  const GITHUB_INSTALL_POLL_TIMEOUT_MS = 12e4;
@@ -20,11 +21,24 @@ function isRealMode(context) {
20
21
  return !context.runtime.fixturePath && !context.runtime.env.PRISMA_CLI_MOCK_FIXTURE_PATH;
21
22
  }
22
23
  async function readProjectListLocalBinding(cwd, workspace, projects, signal) {
23
- const pin = await readLocalResolutionPin(cwd, signal);
24
+ const pinResult = await readLocalResolutionPin(cwd, signal);
25
+ if (pinResult.isErr()) return localPinReadErrorToInvalidLocalBinding(pinResult.error);
26
+ const pin = pinResult.value;
24
27
  if (pin.kind === "present") return pin.pin.workspaceId === workspace.id && projects.some((project) => project.id === pin.pin.projectId) ? { status: "linked" } : { status: "invalid" };
25
- if (pin.kind === "invalid") return { status: "invalid" };
26
28
  return { status: "not-linked" };
27
29
  }
30
+ function localPinReadErrorToInvalidLocalBinding(error) {
31
+ return matchError(error, {
32
+ LocalResolutionPinInvalidJsonError: () => ({ status: "invalid" }),
33
+ LocalResolutionPinInvalidShapeError: () => ({ status: "invalid" }),
34
+ LocalResolutionPinReadAbortedError: (error) => {
35
+ throw error;
36
+ },
37
+ UnhandledException: (error) => {
38
+ throw error;
39
+ }
40
+ });
41
+ }
28
42
  async function runProjectList(context) {
29
43
  const authState = await requireAuthenticatedAuthState(context);
30
44
  const workspace = authState.workspace;
@@ -3,6 +3,7 @@ import { renderSummaryLine } from "../../shell/ui.js";
3
3
  import { canPrompt } from "../../shell/runtime.js";
4
4
  import { confirmPrompt } from "../../shell/prompt.js";
5
5
  import { formatCommandArgument } from "../../shell/command-arguments.js";
6
+ import "../project/setup.js";
6
7
  import { hasBranchDatabaseSignal, inspectBranchDatabaseSignal, runBranchDatabaseSchemaSetup } from "./branch-database.js";
7
8
  import path from "node:path";
8
9
  //#region src/lib/app/branch-database-deploy.ts
@@ -1,25 +1,75 @@
1
1
  import { mkdir, readFile, rename, writeFile } from "node:fs/promises";
2
2
  import path from "node:path";
3
+ import { Result, TaggedError, UnhandledException } from "better-result";
3
4
  //#region src/lib/project/local-pin.ts
4
5
  const LOCAL_RESOLUTION_PIN_RELATIVE_PATH = ".prisma/local.json";
5
- async function readLocalResolutionPin(cwd, signal) {
6
- signal?.throwIfAborted();
7
- try {
8
- const raw = await readFile(path.join(cwd, LOCAL_RESOLUTION_PIN_RELATIVE_PATH), {
9
- encoding: "utf8",
10
- signal
6
+ var LocalResolutionPinInvalidJsonError = class extends TaggedError("LocalResolutionPinInvalidJsonError")() {
7
+ constructor(cause) {
8
+ super({
9
+ message: `${LOCAL_RESOLUTION_PIN_RELATIVE_PATH} contains invalid JSON.`,
10
+ cause,
11
+ pinPath: LOCAL_RESOLUTION_PIN_RELATIVE_PATH
12
+ });
13
+ }
14
+ };
15
+ var LocalResolutionPinInvalidShapeError = class extends TaggedError("LocalResolutionPinInvalidShapeError")() {
16
+ constructor() {
17
+ super({
18
+ message: `${LOCAL_RESOLUTION_PIN_RELATIVE_PATH} must contain workspaceId and projectId string fields only.`,
19
+ pinPath: LOCAL_RESOLUTION_PIN_RELATIVE_PATH
20
+ });
21
+ }
22
+ };
23
+ var LocalResolutionPinReadAbortedError = class extends TaggedError("LocalResolutionPinReadAbortedError")() {
24
+ constructor(cause) {
25
+ super({
26
+ message: `Reading ${LOCAL_RESOLUTION_PIN_RELATIVE_PATH} was aborted.`,
27
+ cause,
28
+ pinPath: LOCAL_RESOLUTION_PIN_RELATIVE_PATH
11
29
  });
12
- const parsed = JSON.parse(raw);
13
- if (!isLocalResolutionPin(parsed)) return { kind: "invalid" };
14
- return {
30
+ }
31
+ };
32
+ async function readLocalResolutionPin(cwd, signal) {
33
+ return Result.gen(async function* () {
34
+ yield* ensureLocalResolutionPinReadNotAborted(signal);
35
+ const file = yield* Result.await(readLocalResolutionPinFile(cwd, signal));
36
+ if (file.kind === "missing") return Result.ok({ kind: "missing" });
37
+ const parsed = yield* parseLocalResolutionPin(file.raw);
38
+ if (!isLocalResolutionPin(parsed)) return Result.err(new LocalResolutionPinInvalidShapeError());
39
+ return Result.ok({
15
40
  kind: "present",
16
41
  pin: parsed
17
- };
18
- } catch (error) {
19
- if (error.code === "ENOENT") return { kind: "missing" };
20
- if (error instanceof SyntaxError) return { kind: "invalid" };
21
- throw error;
42
+ });
43
+ });
44
+ }
45
+ function ensureLocalResolutionPinReadNotAborted(signal) {
46
+ return Result.try({
47
+ try: () => signal?.throwIfAborted(),
48
+ catch: (cause) => new LocalResolutionPinReadAbortedError(cause)
49
+ });
50
+ }
51
+ async function readLocalResolutionPinFile(cwd, signal) {
52
+ const readResult = await Result.tryPromise({
53
+ try: () => readFile(path.join(cwd, LOCAL_RESOLUTION_PIN_RELATIVE_PATH), {
54
+ encoding: "utf8",
55
+ signal
56
+ }),
57
+ catch: (cause) => signal?.aborted ? new LocalResolutionPinReadAbortedError(cause) : new UnhandledException({ cause })
58
+ });
59
+ if (readResult.isErr()) {
60
+ if (readResult.error instanceof UnhandledException && readResult.error.cause.code === "ENOENT") return Result.ok({ kind: "missing" });
61
+ return Result.err(readResult.error);
22
62
  }
63
+ return Result.ok({
64
+ kind: "present",
65
+ raw: readResult.value
66
+ });
67
+ }
68
+ function parseLocalResolutionPin(raw) {
69
+ return Result.try({
70
+ try: () => JSON.parse(raw),
71
+ catch: (cause) => cause instanceof SyntaxError ? new LocalResolutionPinInvalidJsonError(cause) : new UnhandledException({ cause })
72
+ });
23
73
  }
24
74
  async function writeLocalResolutionPin(cwd, pin, signal) {
25
75
  const prismaDir = path.join(cwd, ".prisma");
@@ -3,6 +3,7 @@ import { formatCommandArgument } from "../../shell/command-arguments.js";
3
3
  import { LOCAL_RESOLUTION_PIN_RELATIVE_PATH, readLocalResolutionPin } from "./local-pin.js";
4
4
  import { readFile } from "node:fs/promises";
5
5
  import path from "node:path";
6
+ import { matchError } from "better-result";
6
7
  //#region src/lib/project/resolution.ts
7
8
  async function resolveProjectTarget(options) {
8
9
  const localPin = await readImplicitLocalPin(options, { allowEnvProjectId: true });
@@ -224,7 +225,6 @@ async function resolveBoundProjectTarget(options, projects, settings) {
224
225
  }
225
226
  const localPin = settings.localPin;
226
227
  if (!localPin) return null;
227
- if (localPin.kind === "invalid") throw localStateStaleError();
228
228
  if (localPin.kind === "present") {
229
229
  if (localPin.pin.workspaceId !== options.workspace.id) throw localProjectWorkspaceMismatchError({
230
230
  pinnedWorkspaceId: localPin.pin.workspaceId,
@@ -247,7 +247,9 @@ async function resolveBoundProjectTarget(options, projects, settings) {
247
247
  }
248
248
  async function readImplicitLocalPin(options, settings) {
249
249
  if (options.explicitProject || settings.allowEnvProjectId && options.envProjectId) return null;
250
- const localPin = await readLocalResolutionPin(options.context.runtime.cwd, options.context.runtime.signal);
250
+ const localPinResult = await readLocalResolutionPin(options.context.runtime.cwd, options.context.runtime.signal);
251
+ if (localPinResult.isErr()) throw localPinReadErrorToProjectError(localPinResult.error);
252
+ const localPin = localPinResult.value;
251
253
  if (localPin.kind === "present" && localPin.pin.workspaceId !== options.workspace.id) throw localProjectWorkspaceMismatchError({
252
254
  pinnedWorkspaceId: localPin.pin.workspaceId,
253
255
  pinnedProjectId: localPin.pin.projectId,
@@ -255,6 +257,18 @@ async function readImplicitLocalPin(options, settings) {
255
257
  });
256
258
  return localPin;
257
259
  }
260
+ function localPinReadErrorToProjectError(error) {
261
+ return matchError(error, {
262
+ LocalResolutionPinInvalidJsonError: () => localStateStaleError(),
263
+ LocalResolutionPinInvalidShapeError: () => localStateStaleError(),
264
+ LocalResolutionPinReadAbortedError: (error) => {
265
+ throw error;
266
+ },
267
+ UnhandledException: (error) => {
268
+ throw error;
269
+ }
270
+ });
271
+ }
258
272
  function resolvedTarget(workspace, project, projectSource, resolutionDetails) {
259
273
  return {
260
274
  workspace,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@prisma/cli",
3
- "version": "3.0.0-dev.71.1",
3
+ "version": "3.0.0-dev.73.1",
4
4
  "description": "Command-line interface for the Prisma Developer Platform.",
5
5
  "type": "module",
6
6
  "bin": {
@@ -39,6 +39,7 @@
39
39
  "@prisma/compute-sdk": "^0.22.0",
40
40
  "@prisma/credentials-store": "^7.8.0",
41
41
  "@prisma/management-api-sdk": "^1.37.0",
42
+ "better-result": "^2.9.2",
42
43
  "c12": "4.0.0-beta.5",
43
44
  "colorette": "^2.0.20",
44
45
  "commander": "^14.0.3",