@prisma/cli 3.0.0-dev.77.1 → 3.0.0-dev.78.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.
|
@@ -2,7 +2,7 @@ import { CliError, authRequiredError, usageError, workspaceRequiredError } from
|
|
|
2
2
|
import { requireComputeAuth } from "../lib/auth/guard.js";
|
|
3
3
|
import { formatScopeLabel, parseKeyValuePositional, resolveEnvScope } from "../lib/app/env-config.js";
|
|
4
4
|
import { readEnvFileAssignments } from "../lib/app/env-file.js";
|
|
5
|
-
import { resolveProjectTarget } from "../lib/project/resolution.js";
|
|
5
|
+
import { projectResolutionErrorToCliError, resolveProjectTarget } from "../lib/project/resolution.js";
|
|
6
6
|
import { readLocalGitBranch } from "../lib/git/local-branch.js";
|
|
7
7
|
import { requireAuthenticatedAuthState } from "./auth.js";
|
|
8
8
|
import { listRealWorkspaceProjects } from "./project.js";
|
|
@@ -205,13 +205,15 @@ async function requireClientAndProject(context, explicitProject, commandName) {
|
|
|
205
205
|
const client = await requireComputeAuth(context.runtime.env, context.runtime.signal);
|
|
206
206
|
if (!client) throw authRequiredError(["prisma-cli auth login"]);
|
|
207
207
|
if (!authState.workspace) throw workspaceRequiredError();
|
|
208
|
-
const
|
|
208
|
+
const targetResult = await resolveProjectTarget({
|
|
209
209
|
context,
|
|
210
210
|
workspace: authState.workspace,
|
|
211
211
|
explicitProject,
|
|
212
212
|
listProjects: () => listRealWorkspaceProjects(client, authState.workspace, context.runtime.signal),
|
|
213
213
|
commandName
|
|
214
214
|
});
|
|
215
|
+
if (targetResult.isErr()) throw projectResolutionErrorToCliError(targetResult.error);
|
|
216
|
+
const target = targetResult.value;
|
|
215
217
|
return {
|
|
216
218
|
client,
|
|
217
219
|
projectId: target.project.id,
|
package/dist/controllers/app.js
CHANGED
|
@@ -13,7 +13,7 @@ import { readBunPackageEntrypoint, readBunPackageJson } from "../lib/app/bun-pro
|
|
|
13
13
|
import { DEFAULT_LOCAL_DEV_PORT, resolveLocalBuildType, runLocalApp } from "../lib/app/local-dev.js";
|
|
14
14
|
import { formatCommandArgument } from "../shell/command-arguments.js";
|
|
15
15
|
import { LOCAL_RESOLUTION_PIN_RELATIVE_PATH, readLocalResolutionPin } from "../lib/project/local-pin.js";
|
|
16
|
-
import { buildProjectSetupNextActions, inferTargetName, projectNotFoundError, resolveDurablePlatformMapping, resolveProjectTarget, sortProjects } from "../lib/project/resolution.js";
|
|
16
|
+
import { buildProjectSetupNextActions, inferTargetName, projectNotFoundError, projectResolutionErrorToCliError, resolveDurablePlatformMapping, resolveProjectTarget, sortProjects } from "../lib/project/resolution.js";
|
|
17
17
|
import { bindProjectToDirectory, projectCreateFailedError, projectDirectoryBindingErrorToCliError, projectSetupNameRequiredError, resolveProjectForSetup, toProjectSummary } from "../lib/project/setup.js";
|
|
18
18
|
import { promptForProjectSetupChoice } from "../lib/project/interactive-setup.js";
|
|
19
19
|
import { readLocalGitBranch } from "../lib/git/local-branch.js";
|
|
@@ -1358,7 +1358,7 @@ async function requireProviderAndDeployProjectContext(context, explicitProject,
|
|
|
1358
1358
|
async function resolveProjectContext(context, client, explicitProject, options) {
|
|
1359
1359
|
const authState = await requireAuthenticatedAuthState(context);
|
|
1360
1360
|
if (!authState.workspace) throw workspaceRequiredError();
|
|
1361
|
-
const
|
|
1361
|
+
const resolvedResult = await resolveProjectTarget({
|
|
1362
1362
|
context,
|
|
1363
1363
|
workspace: authState.workspace,
|
|
1364
1364
|
explicitProject,
|
|
@@ -1366,6 +1366,8 @@ async function resolveProjectContext(context, client, explicitProject, options)
|
|
|
1366
1366
|
listProjects: () => listRealWorkspaceProjects(client, authState.workspace, context.runtime.signal),
|
|
1367
1367
|
commandName: options?.commandName
|
|
1368
1368
|
});
|
|
1369
|
+
if (resolvedResult.isErr()) throw projectResolutionErrorToCliError(resolvedResult.error);
|
|
1370
|
+
const resolved = resolvedResult.value;
|
|
1369
1371
|
const branch = options?.branch ?? await resolveDeployBranch(context, void 0);
|
|
1370
1372
|
return {
|
|
1371
1373
|
...resolved,
|
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
import { CliError, authRequiredError, workspaceRequiredError } from "../shell/errors.js";
|
|
2
2
|
import { requireComputeAuth } from "../lib/auth/guard.js";
|
|
3
|
-
import { resolveProjectTarget } from "../lib/project/resolution.js";
|
|
3
|
+
import { projectResolutionErrorToCliError, resolveProjectTarget } from "../lib/project/resolution.js";
|
|
4
4
|
import { createCliUseCaseGateways } from "../use-cases/create-cli-gateways.js";
|
|
5
|
-
import { createSelectPromptPort } from "./select-prompt-port.js";
|
|
6
5
|
import { requireAuthenticatedAuthState } from "./auth.js";
|
|
7
6
|
import { listRealWorkspaceProjects } from "./project.js";
|
|
8
7
|
import { createBranchUseCases } from "../use-cases/branch.js";
|
|
@@ -30,13 +29,13 @@ async function listRealBranches(context) {
|
|
|
30
29
|
if (!client) throw authRequiredError(["prisma-cli auth login"]);
|
|
31
30
|
const workspace = authState.workspace;
|
|
32
31
|
if (!workspace) throw workspaceRequiredError();
|
|
33
|
-
const
|
|
32
|
+
const targetResult = await resolveProjectTarget({
|
|
34
33
|
context,
|
|
35
34
|
workspace,
|
|
36
|
-
listProjects: () => listRealWorkspaceProjects(client, workspace, context.runtime.signal)
|
|
37
|
-
prompt: createSelectPromptPort(context),
|
|
38
|
-
remember: true
|
|
35
|
+
listProjects: () => listRealWorkspaceProjects(client, workspace, context.runtime.signal)
|
|
39
36
|
});
|
|
37
|
+
if (targetResult.isErr()) throw projectResolutionErrorToCliError(targetResult.error);
|
|
38
|
+
const target = targetResult.value;
|
|
40
39
|
const branches = await listBranches(client, target.project.id, context.runtime.signal);
|
|
41
40
|
return {
|
|
42
41
|
projectId: target.project.id,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { CliError, authRequiredError, usageError, workspaceRequiredError } from "../shell/errors.js";
|
|
2
2
|
import { requireComputeAuth } from "../lib/auth/guard.js";
|
|
3
|
-
import { resolveProjectTarget } from "../lib/project/resolution.js";
|
|
3
|
+
import { projectResolutionErrorToCliError, resolveProjectTarget } from "../lib/project/resolution.js";
|
|
4
4
|
import { requireAuthenticatedAuthState } from "./auth.js";
|
|
5
5
|
import { listFixtureWorkspaceProjects, listRealWorkspaceProjects } from "./project.js";
|
|
6
6
|
import { createManagementDatabaseProvider, normalizeConnection, normalizeDatabase } from "../lib/database/provider.js";
|
|
@@ -155,28 +155,30 @@ async function requireDatabaseContext(context, flags, commandName) {
|
|
|
155
155
|
if (isRealMode(context)) {
|
|
156
156
|
const client = await requireComputeAuth(context.runtime.env, context.runtime.signal);
|
|
157
157
|
if (!client) throw authRequiredError();
|
|
158
|
-
const
|
|
158
|
+
const targetResult = await resolveProjectTarget({
|
|
159
159
|
context,
|
|
160
160
|
workspace,
|
|
161
161
|
explicitProject: flags.projectRef,
|
|
162
162
|
listProjects: () => listRealWorkspaceProjects(client, workspace, context.runtime.signal),
|
|
163
163
|
commandName
|
|
164
164
|
});
|
|
165
|
+
if (targetResult.isErr()) throw projectResolutionErrorToCliError(targetResult.error);
|
|
165
166
|
return {
|
|
166
167
|
provider: createManagementDatabaseProvider(client),
|
|
167
|
-
target
|
|
168
|
+
target: targetResult.value
|
|
168
169
|
};
|
|
169
170
|
}
|
|
170
|
-
const
|
|
171
|
+
const targetResult = await resolveProjectTarget({
|
|
171
172
|
context,
|
|
172
173
|
workspace,
|
|
173
174
|
explicitProject: flags.projectRef,
|
|
174
175
|
listProjects: async () => listFixtureWorkspaceProjects(context, workspace),
|
|
175
176
|
commandName
|
|
176
177
|
});
|
|
178
|
+
if (targetResult.isErr()) throw projectResolutionErrorToCliError(targetResult.error);
|
|
177
179
|
return {
|
|
178
180
|
provider: createFixtureDatabaseProvider(context),
|
|
179
|
-
target
|
|
181
|
+
target: targetResult.value
|
|
180
182
|
};
|
|
181
183
|
}
|
|
182
184
|
async function requireDatabaseProviderOnly(context) {
|
|
@@ -4,7 +4,7 @@ import { canPrompt } from "../shell/runtime.js";
|
|
|
4
4
|
import { requireComputeAuth } from "../lib/auth/guard.js";
|
|
5
5
|
import { formatCommandArgument } from "../shell/command-arguments.js";
|
|
6
6
|
import { readLocalResolutionPin } from "../lib/project/local-pin.js";
|
|
7
|
-
import { buildProjectSetupNextActions, inferTargetName, inspectProjectBinding, resolveProjectTarget, sortProjects } from "../lib/project/resolution.js";
|
|
7
|
+
import { buildProjectSetupNextActions, inferTargetName, inspectProjectBinding, projectResolutionErrorToCliError, resolveProjectTarget, sortProjects } from "../lib/project/resolution.js";
|
|
8
8
|
import { bindProjectToDirectory, isValidProjectSetupName, projectCreateFailedError, projectDirectoryBindingErrorToCliError, projectSetupNameRequiredError, resolveProjectForSetup, toProjectSummary } from "../lib/project/setup.js";
|
|
9
9
|
import { promptForProjectSetupChoice } from "../lib/project/interactive-setup.js";
|
|
10
10
|
import { createPreviewAppProvider } from "../lib/app/preview-provider.js";
|
|
@@ -330,42 +330,50 @@ async function runGitDisconnect(context, options = {}) {
|
|
|
330
330
|
async function resolveProjectShowInRealMode(context, workspace, explicitProject) {
|
|
331
331
|
const client = await requireComputeAuth(context.runtime.env, context.runtime.signal);
|
|
332
332
|
if (!client) throw authRequiredError();
|
|
333
|
-
|
|
333
|
+
const result = await inspectProjectBinding({
|
|
334
334
|
context,
|
|
335
335
|
workspace,
|
|
336
336
|
explicitProject,
|
|
337
337
|
listProjects: () => listRealWorkspaceProjects(client, workspace, context.runtime.signal),
|
|
338
338
|
commandName: "project show"
|
|
339
339
|
});
|
|
340
|
+
if (result.isErr()) throw projectResolutionErrorToCliError(result.error);
|
|
341
|
+
return result.value;
|
|
340
342
|
}
|
|
341
343
|
async function resolveRequiredProjectInRealMode(context, workspace, explicitProject, commandName) {
|
|
342
344
|
const client = await requireComputeAuth(context.runtime.env, context.runtime.signal);
|
|
343
345
|
if (!client) throw authRequiredError();
|
|
344
|
-
|
|
346
|
+
const result = await resolveProjectTarget({
|
|
345
347
|
context,
|
|
346
348
|
workspace,
|
|
347
349
|
explicitProject,
|
|
348
350
|
listProjects: () => listRealWorkspaceProjects(client, workspace, context.runtime.signal),
|
|
349
351
|
commandName
|
|
350
352
|
});
|
|
353
|
+
if (result.isErr()) throw projectResolutionErrorToCliError(result.error);
|
|
354
|
+
return result.value;
|
|
351
355
|
}
|
|
352
356
|
async function resolveProjectShowInFixtureMode(context, workspace, explicitProject) {
|
|
353
|
-
|
|
357
|
+
const result = await inspectProjectBinding({
|
|
354
358
|
context,
|
|
355
359
|
workspace,
|
|
356
360
|
explicitProject,
|
|
357
361
|
listProjects: async () => listFixtureWorkspaceProjects(context, workspace),
|
|
358
362
|
commandName: "project show"
|
|
359
363
|
});
|
|
364
|
+
if (result.isErr()) throw projectResolutionErrorToCliError(result.error);
|
|
365
|
+
return result.value;
|
|
360
366
|
}
|
|
361
367
|
async function resolveRequiredProjectInFixtureMode(context, workspace, explicitProject, commandName) {
|
|
362
|
-
|
|
368
|
+
const result = await resolveProjectTarget({
|
|
363
369
|
context,
|
|
364
370
|
workspace,
|
|
365
371
|
explicitProject,
|
|
366
372
|
listProjects: async () => listFixtureWorkspaceProjects(context, workspace),
|
|
367
373
|
commandName
|
|
368
374
|
});
|
|
375
|
+
if (result.isErr()) throw projectResolutionErrorToCliError(result.error);
|
|
376
|
+
return result.value;
|
|
369
377
|
}
|
|
370
378
|
async function listRealWorkspaceProjects(client, workspace, signal) {
|
|
371
379
|
const { data } = await client.GET("/v1/projects", { signal });
|
|
@@ -3,45 +3,98 @@ 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
|
+
import { Result, TaggedError, matchError } from "better-result";
|
|
7
7
|
//#region src/lib/project/resolution.ts
|
|
8
|
+
var ProjectNotFoundError = class extends TaggedError("ProjectNotFoundError")() {
|
|
9
|
+
constructor(projectRef, workspace) {
|
|
10
|
+
super({
|
|
11
|
+
message: `Project "${projectRef}" was not found in workspace "${workspace.name}".`,
|
|
12
|
+
projectRef,
|
|
13
|
+
workspace
|
|
14
|
+
});
|
|
15
|
+
}
|
|
16
|
+
};
|
|
17
|
+
var ProjectAmbiguousError = class extends TaggedError("ProjectAmbiguousError")() {
|
|
18
|
+
constructor(projectRef, matches) {
|
|
19
|
+
super({
|
|
20
|
+
message: projectRef ? `Multiple projects matched "${projectRef}".` : "Multiple projects matched the current directory context.",
|
|
21
|
+
projectRef,
|
|
22
|
+
matches
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
};
|
|
26
|
+
var LocalStateStaleError = class extends TaggedError("LocalStateStaleError")() {
|
|
27
|
+
constructor() {
|
|
28
|
+
super({
|
|
29
|
+
message: `The target recorded in ${LOCAL_RESOLUTION_PIN_RELATIVE_PATH} is no longer available in the selected workspace.`,
|
|
30
|
+
pinPath: LOCAL_RESOLUTION_PIN_RELATIVE_PATH
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
};
|
|
34
|
+
var LocalProjectWorkspaceMismatchError = class extends TaggedError("LocalProjectWorkspaceMismatchError")() {
|
|
35
|
+
constructor(options) {
|
|
36
|
+
super({
|
|
37
|
+
message: `${LOCAL_RESOLUTION_PIN_RELATIVE_PATH} links this directory to project ${options.pinnedProjectId} in workspace ${options.pinnedWorkspaceId}, but the active workspace is "${options.activeWorkspace.name}" (${options.activeWorkspace.id}).`,
|
|
38
|
+
pinnedWorkspaceId: options.pinnedWorkspaceId,
|
|
39
|
+
pinnedProjectId: options.pinnedProjectId,
|
|
40
|
+
activeWorkspace: options.activeWorkspace
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
};
|
|
44
|
+
var ProjectSetupRequiredError = class extends TaggedError("ProjectSetupRequiredError")() {
|
|
45
|
+
constructor(options) {
|
|
46
|
+
const commandLabel = options.commandName ? `prisma-cli ${options.commandName}` : "this command";
|
|
47
|
+
super({
|
|
48
|
+
message: `This directory is not linked to a Prisma Project, and ${commandLabel} will not choose one from package or directory names.`,
|
|
49
|
+
commandName: options.commandName,
|
|
50
|
+
suggestion: options.suggestion
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
};
|
|
8
54
|
async function resolveProjectTarget(options) {
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
55
|
+
return Result.gen(async function* () {
|
|
56
|
+
const localPin = yield* Result.await(readImplicitLocalPin(options, { allowEnvProjectId: true }));
|
|
57
|
+
const projects = await options.listProjects();
|
|
58
|
+
const target = yield* Result.await(resolveBoundProjectTarget(options, projects, {
|
|
59
|
+
allowEnvProjectId: true,
|
|
60
|
+
localPin
|
|
61
|
+
}));
|
|
62
|
+
if (target) return Result.ok(target);
|
|
63
|
+
return Result.err(await projectSetupRequiredError({
|
|
64
|
+
cwd: options.context.runtime.cwd,
|
|
65
|
+
projects,
|
|
66
|
+
commandName: options.commandName,
|
|
67
|
+
signal: options.context.runtime.signal
|
|
68
|
+
}));
|
|
21
69
|
});
|
|
22
70
|
}
|
|
23
71
|
async function inspectProjectBinding(options) {
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
72
|
+
return Result.gen(async function* () {
|
|
73
|
+
const localPin = yield* Result.await(readImplicitLocalPin(options, { allowEnvProjectId: false }));
|
|
74
|
+
const projects = await options.listProjects();
|
|
75
|
+
const target = yield* Result.await(resolveBoundProjectTarget(options, projects, {
|
|
76
|
+
allowEnvProjectId: false,
|
|
77
|
+
localPin
|
|
78
|
+
}));
|
|
79
|
+
if (target) return Result.ok(target);
|
|
80
|
+
return Result.ok({
|
|
81
|
+
workspace: options.workspace,
|
|
82
|
+
project: null,
|
|
83
|
+
localBinding: { status: "not-linked" },
|
|
84
|
+
resolution: { projectSource: "unbound" },
|
|
85
|
+
...await buildProjectSetupSuggestion({
|
|
86
|
+
cwd: options.context.runtime.cwd,
|
|
87
|
+
projects,
|
|
88
|
+
commandName: options.commandName ?? "project show",
|
|
89
|
+
signal: options.context.runtime.signal
|
|
90
|
+
})
|
|
91
|
+
});
|
|
29
92
|
});
|
|
30
|
-
if (target) return target;
|
|
31
|
-
return {
|
|
32
|
-
workspace: options.workspace,
|
|
33
|
-
project: null,
|
|
34
|
-
localBinding: { status: "not-linked" },
|
|
35
|
-
resolution: { projectSource: "unbound" },
|
|
36
|
-
...await buildProjectSetupSuggestion({
|
|
37
|
-
cwd: options.context.runtime.cwd,
|
|
38
|
-
projects,
|
|
39
|
-
commandName: options.commandName ?? "project show",
|
|
40
|
-
signal: options.context.runtime.signal
|
|
41
|
-
})
|
|
42
|
-
};
|
|
43
93
|
}
|
|
44
94
|
function projectNotFoundError(projectRef, workspace) {
|
|
95
|
+
return projectResolutionErrorToCliError(new ProjectNotFoundError(projectRef, workspace));
|
|
96
|
+
}
|
|
97
|
+
function projectNotFoundCliError(projectRef, workspace) {
|
|
45
98
|
return new CliError({
|
|
46
99
|
code: "PROJECT_NOT_FOUND",
|
|
47
100
|
domain: "project",
|
|
@@ -53,6 +106,9 @@ function projectNotFoundError(projectRef, workspace) {
|
|
|
53
106
|
});
|
|
54
107
|
}
|
|
55
108
|
function projectAmbiguousError(projectRef, matches) {
|
|
109
|
+
return projectResolutionErrorToCliError(new ProjectAmbiguousError(projectRef, matches));
|
|
110
|
+
}
|
|
111
|
+
function projectAmbiguousCliError(projectRef, matches) {
|
|
56
112
|
const firstMatch = matches[0];
|
|
57
113
|
const nextSteps = ["prisma-cli project list"];
|
|
58
114
|
if (firstMatch) nextSteps.push(`prisma-cli app deploy --project ${firstMatch.id}`);
|
|
@@ -70,7 +126,7 @@ function projectAmbiguousError(projectRef, matches) {
|
|
|
70
126
|
nextSteps
|
|
71
127
|
});
|
|
72
128
|
}
|
|
73
|
-
function
|
|
129
|
+
function localStateStaleCliError() {
|
|
74
130
|
return new CliError({
|
|
75
131
|
code: "LOCAL_STATE_STALE",
|
|
76
132
|
domain: "project",
|
|
@@ -82,7 +138,7 @@ function localStateStaleError() {
|
|
|
82
138
|
nextSteps: ["prisma-cli project list", "prisma-cli project link <id-or-name>"]
|
|
83
139
|
});
|
|
84
140
|
}
|
|
85
|
-
function
|
|
141
|
+
function localProjectWorkspaceMismatchCliError(options) {
|
|
86
142
|
return new CliError({
|
|
87
143
|
code: "LOCAL_PROJECT_WORKSPACE_MISMATCH",
|
|
88
144
|
domain: "project",
|
|
@@ -104,6 +160,31 @@ function localProjectWorkspaceMismatchError(options) {
|
|
|
104
160
|
]
|
|
105
161
|
});
|
|
106
162
|
}
|
|
163
|
+
/**
|
|
164
|
+
* Converts expected project-resolution variants to command-boundary CliErrors.
|
|
165
|
+
* `LocalResolutionPinReadAbortedError` and `UnhandledException` intentionally
|
|
166
|
+
* propagate as exceptions; callers such as `resolveProjectShowInRealMode`
|
|
167
|
+
* throw this helper's result, so passthrough variants should keep bubbling.
|
|
168
|
+
*/
|
|
169
|
+
function projectResolutionErrorToCliError(error) {
|
|
170
|
+
return matchError(error, {
|
|
171
|
+
ProjectNotFoundError: (error) => projectNotFoundCliError(error.projectRef, error.workspace),
|
|
172
|
+
ProjectAmbiguousError: (error) => projectAmbiguousCliError(error.projectRef, error.matches),
|
|
173
|
+
ProjectSetupRequiredError: (error) => projectSetupRequiredCliError(error),
|
|
174
|
+
LocalStateStaleError: () => localStateStaleCliError(),
|
|
175
|
+
LocalProjectWorkspaceMismatchError: (error) => localProjectWorkspaceMismatchCliError({
|
|
176
|
+
pinnedWorkspaceId: error.pinnedWorkspaceId,
|
|
177
|
+
pinnedProjectId: error.pinnedProjectId,
|
|
178
|
+
activeWorkspace: error.activeWorkspace
|
|
179
|
+
}),
|
|
180
|
+
LocalResolutionPinReadAbortedError: (error) => {
|
|
181
|
+
throw error;
|
|
182
|
+
},
|
|
183
|
+
UnhandledException: (error) => {
|
|
184
|
+
throw error;
|
|
185
|
+
}
|
|
186
|
+
});
|
|
187
|
+
}
|
|
107
188
|
async function buildProjectSetupSuggestion(options) {
|
|
108
189
|
const suggestedName = await inferTargetName(options.cwd, options.signal);
|
|
109
190
|
const candidates = sortProjects(options.projects.filter((project) => projectMatchesSuggestedName(project, suggestedName.name))).map(toProjectSummary);
|
|
@@ -116,17 +197,24 @@ async function buildProjectSetupSuggestion(options) {
|
|
|
116
197
|
}
|
|
117
198
|
async function projectSetupRequiredError(options) {
|
|
118
199
|
const suggestion = await buildProjectSetupSuggestion(options);
|
|
200
|
+
return new ProjectSetupRequiredError({
|
|
201
|
+
commandName: options.commandName,
|
|
202
|
+
suggestion
|
|
203
|
+
});
|
|
204
|
+
}
|
|
205
|
+
function projectSetupRequiredCliError(error) {
|
|
206
|
+
const suggestion = error.suggestion;
|
|
119
207
|
return new CliError({
|
|
120
208
|
code: "PROJECT_SETUP_REQUIRED",
|
|
121
209
|
domain: "project",
|
|
122
210
|
summary: "Choose a Project before running this command",
|
|
123
|
-
why:
|
|
211
|
+
why: error.message,
|
|
124
212
|
fix: "Link the directory to an existing Project, or pass --project <id-or-name> for this command.",
|
|
125
213
|
meta: { ...suggestion },
|
|
126
214
|
exitCode: 1,
|
|
127
215
|
nextSteps: ["prisma-cli project list", ...suggestion.recoveryCommands],
|
|
128
216
|
nextActions: buildProjectSetupNextActions({
|
|
129
|
-
commandName:
|
|
217
|
+
commandName: error.commandName,
|
|
130
218
|
suggestedProjectName: suggestion.suggestedProjectName
|
|
131
219
|
})
|
|
132
220
|
});
|
|
@@ -200,9 +288,9 @@ function sortProjects(projects) {
|
|
|
200
288
|
}
|
|
201
289
|
function resolveExplicitProject(projectRef, projects, workspace) {
|
|
202
290
|
const matches = projects.filter((project) => project.id === projectRef || project.name === projectRef);
|
|
203
|
-
if (matches.length === 1) return matches[0];
|
|
204
|
-
if (matches.length > 1)
|
|
205
|
-
|
|
291
|
+
if (matches.length === 1) return Result.ok(matches[0]);
|
|
292
|
+
if (matches.length > 1) return Result.err(new ProjectAmbiguousError(projectRef, matches));
|
|
293
|
+
return Result.err(new ProjectNotFoundError(projectRef, workspace));
|
|
206
294
|
}
|
|
207
295
|
function projectMatchesSuggestedName(project, suggestedName) {
|
|
208
296
|
return project.id === suggestedName || project.name === suggestedName || project.slug === suggestedName;
|
|
@@ -211,62 +299,62 @@ async function resolveDurablePlatformMapping() {
|
|
|
211
299
|
return null;
|
|
212
300
|
}
|
|
213
301
|
async function resolveBoundProjectTarget(options, projects, settings) {
|
|
214
|
-
if (options.explicitProject)
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
302
|
+
if (options.explicitProject) {
|
|
303
|
+
const projectResult = resolveExplicitProject(options.explicitProject, projects, options.workspace);
|
|
304
|
+
if (projectResult.isErr()) return Result.err(projectResult.error);
|
|
305
|
+
return Result.ok(resolvedTarget(options.workspace, projectResult.value, "explicit", {
|
|
306
|
+
targetName: options.explicitProject,
|
|
307
|
+
targetNameSource: "explicit"
|
|
308
|
+
}));
|
|
309
|
+
}
|
|
218
310
|
if (settings.allowEnvProjectId && options.envProjectId) {
|
|
219
311
|
const project = projects.find((candidate) => candidate.id === options.envProjectId);
|
|
220
|
-
if (!project)
|
|
221
|
-
return resolvedTarget(options.workspace, project, "env", {
|
|
312
|
+
if (!project) return Result.err(new ProjectNotFoundError(options.envProjectId, options.workspace));
|
|
313
|
+
return Result.ok(resolvedTarget(options.workspace, project, "env", {
|
|
222
314
|
targetName: options.envProjectId,
|
|
223
315
|
targetNameSource: "env"
|
|
224
|
-
});
|
|
316
|
+
}));
|
|
225
317
|
}
|
|
226
318
|
const localPin = settings.localPin;
|
|
227
|
-
if (!localPin) return null;
|
|
319
|
+
if (!localPin) return Result.ok(null);
|
|
228
320
|
if (localPin.kind === "present") {
|
|
229
|
-
if (localPin.pin.workspaceId !== options.workspace.id)
|
|
321
|
+
if (localPin.pin.workspaceId !== options.workspace.id) return Result.err(new LocalProjectWorkspaceMismatchError({
|
|
230
322
|
pinnedWorkspaceId: localPin.pin.workspaceId,
|
|
231
323
|
pinnedProjectId: localPin.pin.projectId,
|
|
232
324
|
activeWorkspace: options.workspace
|
|
233
|
-
});
|
|
325
|
+
}));
|
|
234
326
|
const project = projects.find((candidate) => candidate.id === localPin.pin.projectId);
|
|
235
|
-
if (!project)
|
|
236
|
-
return resolvedTarget(options.workspace, project, "local-pin", {
|
|
327
|
+
if (!project) return Result.err(new LocalStateStaleError());
|
|
328
|
+
return Result.ok(resolvedTarget(options.workspace, project, "local-pin", {
|
|
237
329
|
targetName: project.name,
|
|
238
330
|
targetNameSource: "local-pin"
|
|
239
|
-
});
|
|
331
|
+
}));
|
|
240
332
|
}
|
|
241
333
|
const platformMapping = await resolveDurablePlatformMapping();
|
|
242
|
-
if (platformMapping && platformMapping.workspace.id === options.workspace.id) return resolvedTarget(options.workspace, platformMapping, "platform-mapping", {
|
|
334
|
+
if (platformMapping && platformMapping.workspace.id === options.workspace.id) return Result.ok(resolvedTarget(options.workspace, platformMapping, "platform-mapping", {
|
|
243
335
|
targetName: platformMapping.name,
|
|
244
336
|
targetNameSource: "platform-mapping"
|
|
245
|
-
});
|
|
246
|
-
return null;
|
|
337
|
+
}));
|
|
338
|
+
return Result.ok(null);
|
|
247
339
|
}
|
|
248
340
|
async function readImplicitLocalPin(options, settings) {
|
|
249
|
-
if (options.explicitProject || settings.allowEnvProjectId && options.envProjectId) return null;
|
|
341
|
+
if (options.explicitProject || settings.allowEnvProjectId && options.envProjectId) return Result.ok(null);
|
|
250
342
|
const localPinResult = await readLocalResolutionPin(options.context.runtime.cwd, options.context.runtime.signal);
|
|
251
|
-
if (localPinResult.isErr())
|
|
343
|
+
if (localPinResult.isErr()) return Result.err(localPinReadErrorToProjectError(localPinResult.error));
|
|
252
344
|
const localPin = localPinResult.value;
|
|
253
|
-
if (localPin.kind === "present" && localPin.pin.workspaceId !== options.workspace.id)
|
|
345
|
+
if (localPin.kind === "present" && localPin.pin.workspaceId !== options.workspace.id) return Result.err(new LocalProjectWorkspaceMismatchError({
|
|
254
346
|
pinnedWorkspaceId: localPin.pin.workspaceId,
|
|
255
347
|
pinnedProjectId: localPin.pin.projectId,
|
|
256
348
|
activeWorkspace: options.workspace
|
|
257
|
-
});
|
|
258
|
-
return localPin;
|
|
349
|
+
}));
|
|
350
|
+
return Result.ok(localPin);
|
|
259
351
|
}
|
|
260
352
|
function localPinReadErrorToProjectError(error) {
|
|
261
353
|
return matchError(error, {
|
|
262
|
-
LocalResolutionPinInvalidJsonError: () =>
|
|
263
|
-
LocalResolutionPinInvalidShapeError: () =>
|
|
264
|
-
LocalResolutionPinReadAbortedError: (error) =>
|
|
265
|
-
|
|
266
|
-
},
|
|
267
|
-
UnhandledException: (error) => {
|
|
268
|
-
throw error;
|
|
269
|
-
}
|
|
354
|
+
LocalResolutionPinInvalidJsonError: () => new LocalStateStaleError(),
|
|
355
|
+
LocalResolutionPinInvalidShapeError: () => new LocalStateStaleError(),
|
|
356
|
+
LocalResolutionPinReadAbortedError: (error) => error,
|
|
357
|
+
UnhandledException: (error) => error
|
|
270
358
|
});
|
|
271
359
|
}
|
|
272
360
|
function resolvedTarget(workspace, project, projectSource, resolutionDetails) {
|
|
@@ -292,4 +380,4 @@ function toProjectSummary(project) {
|
|
|
292
380
|
};
|
|
293
381
|
}
|
|
294
382
|
//#endregion
|
|
295
|
-
export { buildProjectSetupNextActions, inferTargetName, inspectProjectBinding, projectAmbiguousError, projectNotFoundError, resolveDurablePlatformMapping, resolveProjectTarget, sortProjects };
|
|
383
|
+
export { buildProjectSetupNextActions, inferTargetName, inspectProjectBinding, projectAmbiguousError, projectNotFoundError, projectResolutionErrorToCliError, resolveDurablePlatformMapping, resolveProjectTarget, sortProjects };
|