@prisma/cli 3.0.0-dev.62.1 → 3.0.0-dev.63.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.
- package/dist/lib/project/resolution.js +49 -4
- package/dist/presenters/project.js +15 -16
- package/package.json +1 -1
|
@@ -5,8 +5,12 @@ import { readFile } from "node:fs/promises";
|
|
|
5
5
|
import path from "node:path";
|
|
6
6
|
//#region src/lib/project/resolution.ts
|
|
7
7
|
async function resolveProjectTarget(options) {
|
|
8
|
+
const localPin = await readImplicitLocalPin(options, { allowEnvProjectId: true });
|
|
8
9
|
const projects = await options.listProjects();
|
|
9
|
-
const target = await resolveBoundProjectTarget(options, projects, {
|
|
10
|
+
const target = await resolveBoundProjectTarget(options, projects, {
|
|
11
|
+
allowEnvProjectId: true,
|
|
12
|
+
localPin
|
|
13
|
+
});
|
|
10
14
|
if (target) return target;
|
|
11
15
|
throw await projectSetupRequiredError({
|
|
12
16
|
cwd: options.context.runtime.cwd,
|
|
@@ -16,8 +20,12 @@ async function resolveProjectTarget(options) {
|
|
|
16
20
|
});
|
|
17
21
|
}
|
|
18
22
|
async function inspectProjectBinding(options) {
|
|
23
|
+
const localPin = await readImplicitLocalPin(options, { allowEnvProjectId: false });
|
|
19
24
|
const projects = await options.listProjects();
|
|
20
|
-
const target = await resolveBoundProjectTarget(options, projects, {
|
|
25
|
+
const target = await resolveBoundProjectTarget(options, projects, {
|
|
26
|
+
allowEnvProjectId: false,
|
|
27
|
+
localPin
|
|
28
|
+
});
|
|
21
29
|
if (target) return target;
|
|
22
30
|
return {
|
|
23
31
|
workspace: options.workspace,
|
|
@@ -73,6 +81,28 @@ function localStateStaleError() {
|
|
|
73
81
|
nextSteps: ["prisma-cli project list", "prisma-cli project link <id-or-name>"]
|
|
74
82
|
});
|
|
75
83
|
}
|
|
84
|
+
function localProjectWorkspaceMismatchError(options) {
|
|
85
|
+
return new CliError({
|
|
86
|
+
code: "LOCAL_PROJECT_WORKSPACE_MISMATCH",
|
|
87
|
+
domain: "project",
|
|
88
|
+
summary: "Project link uses another workspace",
|
|
89
|
+
why: `${LOCAL_RESOLUTION_PIN_RELATIVE_PATH} links this directory to project ${options.pinnedProjectId} in workspace ${options.pinnedWorkspaceId}, but your current CLI session is workspace "${options.activeWorkspace.name}" (${options.activeWorkspace.id}).`,
|
|
90
|
+
fix: "Sign in to the linked workspace, or relink this directory to a project in the current workspace.",
|
|
91
|
+
meta: {
|
|
92
|
+
pinPath: LOCAL_RESOLUTION_PIN_RELATIVE_PATH,
|
|
93
|
+
pinnedWorkspaceId: options.pinnedWorkspaceId,
|
|
94
|
+
pinnedProjectId: options.pinnedProjectId,
|
|
95
|
+
activeWorkspaceId: options.activeWorkspace.id,
|
|
96
|
+
activeWorkspaceName: options.activeWorkspace.name
|
|
97
|
+
},
|
|
98
|
+
exitCode: 1,
|
|
99
|
+
nextSteps: [
|
|
100
|
+
"prisma-cli auth login",
|
|
101
|
+
"prisma-cli project list",
|
|
102
|
+
"prisma-cli project link <id-or-name>"
|
|
103
|
+
]
|
|
104
|
+
});
|
|
105
|
+
}
|
|
76
106
|
async function buildProjectSetupSuggestion(options) {
|
|
77
107
|
const suggestedName = await inferTargetName(options.cwd, options.signal);
|
|
78
108
|
const candidates = sortProjects(options.projects.filter((project) => projectMatchesSuggestedName(project, suggestedName.name))).map(toProjectSummary);
|
|
@@ -192,10 +222,15 @@ async function resolveBoundProjectTarget(options, projects, settings) {
|
|
|
192
222
|
targetNameSource: "env"
|
|
193
223
|
});
|
|
194
224
|
}
|
|
195
|
-
const localPin =
|
|
225
|
+
const localPin = settings.localPin;
|
|
226
|
+
if (!localPin) return null;
|
|
196
227
|
if (localPin.kind === "invalid") throw localStateStaleError();
|
|
197
228
|
if (localPin.kind === "present") {
|
|
198
|
-
if (localPin.pin.workspaceId !== options.workspace.id) throw
|
|
229
|
+
if (localPin.pin.workspaceId !== options.workspace.id) throw localProjectWorkspaceMismatchError({
|
|
230
|
+
pinnedWorkspaceId: localPin.pin.workspaceId,
|
|
231
|
+
pinnedProjectId: localPin.pin.projectId,
|
|
232
|
+
activeWorkspace: options.workspace
|
|
233
|
+
});
|
|
199
234
|
const project = projects.find((candidate) => candidate.id === localPin.pin.projectId);
|
|
200
235
|
if (!project) throw localStateStaleError();
|
|
201
236
|
return resolvedTarget(options.workspace, project, "local-pin", {
|
|
@@ -210,6 +245,16 @@ async function resolveBoundProjectTarget(options, projects, settings) {
|
|
|
210
245
|
});
|
|
211
246
|
return null;
|
|
212
247
|
}
|
|
248
|
+
async function readImplicitLocalPin(options, settings) {
|
|
249
|
+
if (options.explicitProject || settings.allowEnvProjectId && options.envProjectId) return null;
|
|
250
|
+
const localPin = await readLocalResolutionPin(options.context.runtime.cwd, options.context.runtime.signal);
|
|
251
|
+
if (localPin.kind === "present" && localPin.pin.workspaceId !== options.workspace.id) throw localProjectWorkspaceMismatchError({
|
|
252
|
+
pinnedWorkspaceId: localPin.pin.workspaceId,
|
|
253
|
+
pinnedProjectId: localPin.pin.projectId,
|
|
254
|
+
activeWorkspace: options.workspace
|
|
255
|
+
});
|
|
256
|
+
return localPin;
|
|
257
|
+
}
|
|
213
258
|
function resolvedTarget(workspace, project, projectSource, resolutionDetails) {
|
|
214
259
|
return {
|
|
215
260
|
workspace,
|
|
@@ -1,25 +1,24 @@
|
|
|
1
1
|
import { padDisplay, renderNextSteps, renderSummaryLine } from "../shell/ui.js";
|
|
2
2
|
import { formatDescriptorLabel } from "../shell/command-meta.js";
|
|
3
3
|
import { formatCommandArgument } from "../shell/command-arguments.js";
|
|
4
|
-
import {
|
|
4
|
+
import { renderMutate, renderShow, serializeList } from "../output/patterns.js";
|
|
5
5
|
import path from "node:path";
|
|
6
|
+
import stringWidth from "string-width";
|
|
6
7
|
//#region src/presenters/project.ts
|
|
7
8
|
function renderProjectList(context, descriptor, result) {
|
|
8
|
-
const
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
emptyMessage: "No projects found."
|
|
22
|
-
}, context.ui);
|
|
9
|
+
const ui = context.ui;
|
|
10
|
+
const rail = ui.dim("│");
|
|
11
|
+
const lines = [`${ui.strong(formatDescriptorLabel(descriptor))} ${ui.dim("→")} ${ui.dim("Listing projects for the authenticated workspace.")}`, ""];
|
|
12
|
+
lines.push(`${rail} ${ui.accent("workspace:")} ${result.workspace.name}`);
|
|
13
|
+
if (result.projects.length === 0) {
|
|
14
|
+
lines.push(`${rail} ${ui.dim("No projects found.")}`);
|
|
15
|
+
if (result.localBinding?.status === "not-linked" || result.localBinding?.status === "invalid") lines.push(...renderNextSteps(["Link an existing Project you choose: prisma-cli project link <id-or-name>", "Create a new Project: prisma-cli project create <name>"]));
|
|
16
|
+
return lines;
|
|
17
|
+
}
|
|
18
|
+
const nameWidth = Math.max(4, ...result.projects.map((project) => stringWidth(project.name)));
|
|
19
|
+
lines.push(rail);
|
|
20
|
+
lines.push(`${rail} ${ui.accent(padDisplay("name", nameWidth))} ${ui.accent("id")}`);
|
|
21
|
+
for (const project of result.projects) lines.push(`${rail} ${padDisplay(project.name, nameWidth)} ${project.id}`);
|
|
23
22
|
if (result.localBinding?.status === "not-linked" || result.localBinding?.status === "invalid") lines.push(...renderNextSteps(["Link an existing Project you choose: prisma-cli project link <id-or-name>", "Create a new Project: prisma-cli project create <name>"]));
|
|
24
23
|
return lines;
|
|
25
24
|
}
|