@prisma/cli 3.0.0-beta.0 → 3.0.0-beta.10
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/README.md +18 -3
- package/dist/adapters/git.js +8 -3
- package/dist/adapters/local-state.js +12 -4
- package/dist/adapters/mock-api.js +81 -2
- package/dist/adapters/token-storage.js +63 -22
- package/dist/cli.js +17 -2
- package/dist/cli2.js +7 -3
- package/dist/commands/app/index.js +26 -13
- package/dist/commands/branch/index.js +2 -27
- package/dist/commands/database/index.js +159 -0
- package/dist/commands/env.js +8 -4
- package/dist/commands/project/index.js +28 -2
- package/dist/controllers/app-env-api.js +54 -0
- package/dist/controllers/app-env-file.js +181 -0
- package/dist/controllers/app-env.js +284 -132
- package/dist/controllers/app.js +493 -344
- package/dist/controllers/auth.js +8 -8
- package/dist/controllers/branch.js +78 -48
- package/dist/controllers/database.js +318 -0
- package/dist/controllers/project.js +302 -75
- package/dist/lib/app/branch-database-deploy.js +373 -0
- package/dist/lib/app/branch-database.js +316 -0
- package/dist/lib/app/bun-project.js +12 -5
- package/dist/lib/app/deploy-output.js +10 -1
- package/dist/lib/app/env-config.js +1 -1
- package/dist/lib/app/env-file.js +82 -0
- package/dist/lib/app/env-vars.js +28 -2
- package/dist/lib/app/local-dev.js +34 -18
- package/dist/lib/app/preview-branch-database.js +102 -0
- package/dist/lib/app/preview-build-settings.js +385 -0
- package/dist/lib/app/preview-build.js +272 -81
- package/dist/lib/app/preview-provider.js +163 -54
- package/dist/lib/app/production-deploy-gate.js +161 -0
- package/dist/lib/auth/auth-ops.js +69 -19
- package/dist/lib/auth/guard.js +3 -2
- package/dist/lib/auth/login.js +109 -14
- package/dist/lib/database/provider.js +167 -0
- package/dist/lib/diagnostics.js +15 -0
- package/dist/lib/git/local-branch.js +41 -0
- package/dist/lib/git/local-status.js +57 -0
- package/dist/lib/project/interactive-setup.js +56 -0
- package/dist/lib/project/local-pin.js +182 -33
- package/dist/lib/project/resolution.js +287 -105
- package/dist/lib/project/setup.js +132 -0
- package/dist/presenters/app-env.js +149 -14
- package/dist/presenters/app.js +170 -20
- package/dist/presenters/auth.js +19 -6
- package/dist/presenters/branch.js +37 -102
- package/dist/presenters/database.js +274 -0
- package/dist/presenters/project.js +100 -47
- package/dist/presenters/verbose-context.js +64 -0
- package/dist/shell/command-arguments.js +6 -0
- package/dist/shell/command-meta.js +139 -16
- package/dist/shell/command-runner.js +38 -8
- package/dist/shell/diagnostics-output.js +63 -0
- package/dist/shell/errors.js +14 -1
- package/dist/shell/output.js +13 -2
- package/dist/shell/runtime.js +3 -3
- package/dist/shell/ui.js +23 -1
- package/dist/shell/update-check.js +247 -0
- package/dist/use-cases/auth.js +15 -4
- package/dist/use-cases/branch.js +20 -68
- package/dist/use-cases/create-cli-gateways.js +2 -17
- package/dist/use-cases/project.js +2 -1
- package/package.json +12 -10
|
@@ -54,7 +54,11 @@ const DESCRIPTORS = [
|
|
|
54
54
|
id: "project",
|
|
55
55
|
path: ["prisma", "project"],
|
|
56
56
|
description: "Manage and inspect your Prisma projects",
|
|
57
|
-
examples: [
|
|
57
|
+
examples: [
|
|
58
|
+
"prisma-cli project list",
|
|
59
|
+
"prisma-cli project link proj_123",
|
|
60
|
+
"prisma-cli project create my-app"
|
|
61
|
+
]
|
|
58
62
|
},
|
|
59
63
|
{
|
|
60
64
|
id: "app",
|
|
@@ -65,8 +69,18 @@ const DESCRIPTORS = [
|
|
|
65
69
|
{
|
|
66
70
|
id: "branch",
|
|
67
71
|
path: ["prisma", "branch"],
|
|
68
|
-
description: "View your
|
|
69
|
-
examples: ["prisma-cli branch list"
|
|
72
|
+
description: "View your Platform branches",
|
|
73
|
+
examples: ["prisma-cli branch list"]
|
|
74
|
+
},
|
|
75
|
+
{
|
|
76
|
+
id: "database",
|
|
77
|
+
path: ["prisma", "database"],
|
|
78
|
+
description: "Manage Prisma Postgres databases for a project",
|
|
79
|
+
examples: [
|
|
80
|
+
"prisma-cli database list",
|
|
81
|
+
"prisma-cli database create my-db",
|
|
82
|
+
"prisma-cli database connection create db_123"
|
|
83
|
+
]
|
|
70
84
|
},
|
|
71
85
|
{
|
|
72
86
|
id: "git",
|
|
@@ -91,9 +105,33 @@ const DESCRIPTORS = [
|
|
|
91
105
|
"project",
|
|
92
106
|
"show"
|
|
93
107
|
],
|
|
94
|
-
description: "Show
|
|
108
|
+
description: "Show this directory's Project binding",
|
|
95
109
|
examples: ["prisma-cli project show", "prisma-cli project show --project proj_123 --json"]
|
|
96
110
|
},
|
|
111
|
+
{
|
|
112
|
+
id: "project.create",
|
|
113
|
+
path: [
|
|
114
|
+
"prisma",
|
|
115
|
+
"project",
|
|
116
|
+
"create"
|
|
117
|
+
],
|
|
118
|
+
description: "Create a Project and link this directory",
|
|
119
|
+
examples: ["prisma-cli project create my-app", "prisma-cli project create my-app --json"]
|
|
120
|
+
},
|
|
121
|
+
{
|
|
122
|
+
id: "project.link",
|
|
123
|
+
path: [
|
|
124
|
+
"prisma",
|
|
125
|
+
"project",
|
|
126
|
+
"link"
|
|
127
|
+
],
|
|
128
|
+
description: "Link this directory to a Project",
|
|
129
|
+
examples: [
|
|
130
|
+
"prisma-cli project link",
|
|
131
|
+
"prisma-cli project link proj_123",
|
|
132
|
+
"prisma-cli project link \"Acme Dashboard\" --json"
|
|
133
|
+
]
|
|
134
|
+
},
|
|
97
135
|
{
|
|
98
136
|
id: "git.connect",
|
|
99
137
|
path: [
|
|
@@ -125,28 +163,99 @@ const DESCRIPTORS = [
|
|
|
125
163
|
"branch",
|
|
126
164
|
"list"
|
|
127
165
|
],
|
|
128
|
-
description: "List
|
|
166
|
+
description: "List Platform branches for the resolved project",
|
|
129
167
|
examples: ["prisma-cli branch list", "prisma-cli branch list --json"]
|
|
130
168
|
},
|
|
131
169
|
{
|
|
132
|
-
id: "
|
|
170
|
+
id: "database.list",
|
|
133
171
|
path: [
|
|
134
172
|
"prisma",
|
|
135
|
-
"
|
|
173
|
+
"database",
|
|
174
|
+
"list"
|
|
175
|
+
],
|
|
176
|
+
description: "List Prisma Postgres databases for the resolved project",
|
|
177
|
+
examples: [
|
|
178
|
+
"prisma-cli database list",
|
|
179
|
+
"prisma-cli database list --branch feature/foo",
|
|
180
|
+
"prisma-cli database list --json"
|
|
181
|
+
]
|
|
182
|
+
},
|
|
183
|
+
{
|
|
184
|
+
id: "database.show",
|
|
185
|
+
path: [
|
|
186
|
+
"prisma",
|
|
187
|
+
"database",
|
|
136
188
|
"show"
|
|
137
189
|
],
|
|
138
|
-
description: "Show
|
|
139
|
-
examples: ["prisma-cli
|
|
190
|
+
description: "Show database metadata without secret values",
|
|
191
|
+
examples: ["prisma-cli database show db_123", "prisma-cli database show acme-preview --branch preview --json"]
|
|
140
192
|
},
|
|
141
193
|
{
|
|
142
|
-
id: "
|
|
194
|
+
id: "database.create",
|
|
143
195
|
path: [
|
|
144
196
|
"prisma",
|
|
145
|
-
"
|
|
146
|
-
"
|
|
197
|
+
"database",
|
|
198
|
+
"create"
|
|
147
199
|
],
|
|
148
|
-
description: "
|
|
149
|
-
examples: ["prisma-cli
|
|
200
|
+
description: "Create a Prisma Postgres database and print its one-time connection URL",
|
|
201
|
+
examples: ["prisma-cli database create my-db", "prisma-cli database create my-db --branch feature/foo --region eu-central-1"]
|
|
202
|
+
},
|
|
203
|
+
{
|
|
204
|
+
id: "database.remove",
|
|
205
|
+
path: [
|
|
206
|
+
"prisma",
|
|
207
|
+
"database",
|
|
208
|
+
"remove"
|
|
209
|
+
],
|
|
210
|
+
description: "Remove a database after exact id confirmation",
|
|
211
|
+
examples: ["prisma-cli database remove db_123 --confirm db_123"]
|
|
212
|
+
},
|
|
213
|
+
{
|
|
214
|
+
id: "database.connection",
|
|
215
|
+
path: [
|
|
216
|
+
"prisma",
|
|
217
|
+
"database",
|
|
218
|
+
"connection"
|
|
219
|
+
],
|
|
220
|
+
description: "Manage one-time-view database connection strings",
|
|
221
|
+
examples: [
|
|
222
|
+
"prisma-cli database connection list db_123",
|
|
223
|
+
"prisma-cli database connection create db_123",
|
|
224
|
+
"prisma-cli database connection remove conn_123 --confirm conn_123"
|
|
225
|
+
]
|
|
226
|
+
},
|
|
227
|
+
{
|
|
228
|
+
id: "database.connection.list",
|
|
229
|
+
path: [
|
|
230
|
+
"prisma",
|
|
231
|
+
"database",
|
|
232
|
+
"connection",
|
|
233
|
+
"list"
|
|
234
|
+
],
|
|
235
|
+
description: "List database connection metadata without secret values",
|
|
236
|
+
examples: ["prisma-cli database connection list db_123", "prisma-cli database connection list acme-preview --branch preview --json"]
|
|
237
|
+
},
|
|
238
|
+
{
|
|
239
|
+
id: "database.connection.create",
|
|
240
|
+
path: [
|
|
241
|
+
"prisma",
|
|
242
|
+
"database",
|
|
243
|
+
"connection",
|
|
244
|
+
"create"
|
|
245
|
+
],
|
|
246
|
+
description: "Create a database connection and print its one-time connection URL",
|
|
247
|
+
examples: ["prisma-cli database connection create db_123", "prisma-cli database connection create db_123 --name readonly"]
|
|
248
|
+
},
|
|
249
|
+
{
|
|
250
|
+
id: "database.connection.remove",
|
|
251
|
+
path: [
|
|
252
|
+
"prisma",
|
|
253
|
+
"database",
|
|
254
|
+
"connection",
|
|
255
|
+
"remove"
|
|
256
|
+
],
|
|
257
|
+
description: "Remove a database connection after exact id confirmation",
|
|
258
|
+
examples: ["prisma-cli database connection remove conn_123 --confirm conn_123"]
|
|
150
259
|
},
|
|
151
260
|
{
|
|
152
261
|
id: "app.build",
|
|
@@ -180,11 +289,20 @@ const DESCRIPTORS = [
|
|
|
180
289
|
"deploy"
|
|
181
290
|
],
|
|
182
291
|
description: "Creates a new deployment for the app",
|
|
292
|
+
longDescription: "Agent skills for guided Next.js deploys are available from the Prisma CLI skill cluster.",
|
|
183
293
|
examples: [
|
|
184
294
|
"prisma-cli app deploy",
|
|
295
|
+
"prisma-cli app deploy --project proj_123",
|
|
296
|
+
"prisma-cli app deploy --create-project my-app --yes",
|
|
185
297
|
"prisma-cli app deploy --app my-app --env DATABASE_URL=postgresql://example",
|
|
298
|
+
"prisma-cli app deploy --env .env",
|
|
299
|
+
"prisma-cli app deploy --db",
|
|
300
|
+
"prisma-cli app deploy --db --yes",
|
|
186
301
|
"prisma-cli app deploy --app my-app --framework nextjs --http-port 3000",
|
|
187
|
-
"prisma-cli app deploy --branch feat-login --framework hono"
|
|
302
|
+
"prisma-cli app deploy --branch feat-login --framework hono",
|
|
303
|
+
"prisma-cli app deploy --prod --yes",
|
|
304
|
+
"pnpm dlx skills@latest add prisma/prisma-cli/skills#cli-v<cli-version> --all",
|
|
305
|
+
"prisma-cli app deploy --framework bun --entry src/server.ts"
|
|
188
306
|
]
|
|
189
307
|
},
|
|
190
308
|
{
|
|
@@ -345,8 +463,9 @@ const DESCRIPTORS = [
|
|
|
345
463
|
],
|
|
346
464
|
description: "Manage environment variables for the active project",
|
|
347
465
|
examples: [
|
|
348
|
-
"prisma-cli project env list
|
|
466
|
+
"prisma-cli project env list",
|
|
349
467
|
"prisma-cli project env add STRIPE_KEY=sk_test_xxx --role production",
|
|
468
|
+
"prisma-cli project env add --file .env --role preview",
|
|
350
469
|
"prisma-cli project env add DATABASE_URL=postgresql://branch --branch feature/foo",
|
|
351
470
|
"prisma-cli project env remove STRIPE_KEY --role preview"
|
|
352
471
|
]
|
|
@@ -363,7 +482,9 @@ const DESCRIPTORS = [
|
|
|
363
482
|
examples: [
|
|
364
483
|
"prisma-cli project env add STRIPE_KEY=sk_test_xxx --role production",
|
|
365
484
|
"prisma-cli project env add STRIPE_KEY=sk_test_xxx --role preview",
|
|
485
|
+
"prisma-cli project env add --file .env --role preview",
|
|
366
486
|
"prisma-cli project env add DATABASE_URL=postgresql://branch --branch feature/foo",
|
|
487
|
+
"prisma-cli project env add --file .env.local --branch feature/foo",
|
|
367
488
|
"API_URL=https://api.example prisma-cli project env add API_URL --project proj_123 --role preview"
|
|
368
489
|
]
|
|
369
490
|
},
|
|
@@ -379,6 +500,7 @@ const DESCRIPTORS = [
|
|
|
379
500
|
examples: [
|
|
380
501
|
"prisma-cli project env update STRIPE_KEY=sk_new_xxx --role production",
|
|
381
502
|
"prisma-cli project env update STRIPE_KEY=sk_new_xxx --role preview",
|
|
503
|
+
"prisma-cli project env update --file .env --role production",
|
|
382
504
|
"prisma-cli project env update DATABASE_URL=postgresql://branch --branch feature/foo"
|
|
383
505
|
]
|
|
384
506
|
},
|
|
@@ -392,6 +514,7 @@ const DESCRIPTORS = [
|
|
|
392
514
|
],
|
|
393
515
|
description: "List environment variable metadata for a scope (no values).",
|
|
394
516
|
examples: [
|
|
517
|
+
"prisma-cli project env list",
|
|
395
518
|
"prisma-cli project env list --role production",
|
|
396
519
|
"prisma-cli project env list --role preview",
|
|
397
520
|
"prisma-cli project env list --branch feature/foo"
|
|
@@ -1,19 +1,27 @@
|
|
|
1
|
-
import { CliError, authRequiredError } from "./errors.js";
|
|
1
|
+
import { CliError, authRequiredError, commandCanceledError } from "./errors.js";
|
|
2
2
|
import { cliErrorToJson, writeHumanError, writeHumanLines, writeJsonError, writeJsonEvent, writeJsonSuccess } from "./output.js";
|
|
3
3
|
import { getCommandDescriptor } from "./command-meta.js";
|
|
4
4
|
import { resolveGlobalFlags } from "./global-flags.js";
|
|
5
5
|
import { createCommandContext } from "./runtime.js";
|
|
6
|
+
import { collectCommandDiagnostics } from "../lib/diagnostics.js";
|
|
7
|
+
import { renderCommandDiagnostics } from "./diagnostics-output.js";
|
|
6
8
|
import { AuthError } from "@prisma/management-api-sdk";
|
|
7
9
|
//#region src/shell/command-runner.ts
|
|
8
|
-
function toCliError(error) {
|
|
10
|
+
function toCliError(error, runtime) {
|
|
11
|
+
if (isCancellationError(error) || runtime.signal.aborted) return commandCanceledError();
|
|
9
12
|
if (error instanceof CliError) return error;
|
|
10
13
|
if (error instanceof AuthError) return authRequiredError(["prisma-cli auth login"], { debug: error.message });
|
|
11
14
|
return null;
|
|
12
15
|
}
|
|
16
|
+
function isCancellationError(error) {
|
|
17
|
+
if (!(error instanceof Error)) return false;
|
|
18
|
+
return error.name === "AbortError" || error.name === "CancelledError";
|
|
19
|
+
}
|
|
13
20
|
async function runCommand(runtime, commandName, options, handler, presenter) {
|
|
14
21
|
const flags = resolveGlobalFlags(runtime.argv, options);
|
|
15
22
|
const context = await createCommandContext(runtime, flags);
|
|
16
23
|
const descriptor = getCommandDescriptor(commandName);
|
|
24
|
+
const startedAt = Date.now();
|
|
17
25
|
try {
|
|
18
26
|
const success = await handler(context);
|
|
19
27
|
if (flags.json) {
|
|
@@ -23,10 +31,22 @@ async function runCommand(runtime, commandName, options, handler, presenter) {
|
|
|
23
31
|
});
|
|
24
32
|
return;
|
|
25
33
|
}
|
|
26
|
-
|
|
27
|
-
|
|
34
|
+
const stdout = presenter.renderStdout?.(context, descriptor, success.result) ?? [];
|
|
35
|
+
if (flags.quiet) {
|
|
36
|
+
if (stdout.length > 0) context.output.stdout.write(`${stdout.join("\n")}\n`);
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
const rendered = presenter.renderHuman(context, descriptor, success.result);
|
|
40
|
+
const diagnostics = await renderBestEffortCommandDiagnostics(context, {
|
|
41
|
+
enabled: flags.verbose && rendered.length > 0,
|
|
42
|
+
durationMs: Date.now() - startedAt
|
|
43
|
+
});
|
|
44
|
+
const humanLines = [...rendered, ...diagnostics];
|
|
45
|
+
if (stdout.length > 0 && humanLines.length > 0) humanLines.push("");
|
|
46
|
+
writeHumanLines(context.output, humanLines);
|
|
47
|
+
if (stdout.length > 0) context.output.stdout.write(`${stdout.join("\n")}\n`);
|
|
28
48
|
} catch (error) {
|
|
29
|
-
const cliError = toCliError(error);
|
|
49
|
+
const cliError = toCliError(error, runtime);
|
|
30
50
|
if (cliError) {
|
|
31
51
|
if (flags.json) writeJsonError(context.output, commandName, cliError);
|
|
32
52
|
else writeHumanError(context.output, context.ui, cliError, { trace: flags.trace });
|
|
@@ -36,6 +56,14 @@ async function runCommand(runtime, commandName, options, handler, presenter) {
|
|
|
36
56
|
throw error;
|
|
37
57
|
}
|
|
38
58
|
}
|
|
59
|
+
async function renderBestEffortCommandDiagnostics(context, options) {
|
|
60
|
+
if (!options.enabled) return [];
|
|
61
|
+
try {
|
|
62
|
+
return renderCommandDiagnostics(context, await collectCommandDiagnostics(context, { durationMs: options.durationMs }));
|
|
63
|
+
} catch {
|
|
64
|
+
return [];
|
|
65
|
+
}
|
|
66
|
+
}
|
|
39
67
|
async function runStreamingCommand(runtime, commandName, options, handler) {
|
|
40
68
|
const flags = resolveGlobalFlags(runtime.argv, options);
|
|
41
69
|
const context = await createCommandContext(runtime, flags);
|
|
@@ -47,10 +75,11 @@ async function runStreamingCommand(runtime, commandName, options, handler) {
|
|
|
47
75
|
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
48
76
|
result: null,
|
|
49
77
|
warnings: [],
|
|
50
|
-
nextSteps: []
|
|
78
|
+
nextSteps: [],
|
|
79
|
+
nextActions: []
|
|
51
80
|
});
|
|
52
81
|
} catch (error) {
|
|
53
|
-
const cliError = toCliError(error);
|
|
82
|
+
const cliError = toCliError(error, runtime);
|
|
54
83
|
if (cliError) {
|
|
55
84
|
if (flags.json) writeJsonEvent(context.output, {
|
|
56
85
|
type: "error",
|
|
@@ -58,7 +87,8 @@ async function runStreamingCommand(runtime, commandName, options, handler) {
|
|
|
58
87
|
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
59
88
|
error: cliErrorToJson(cliError),
|
|
60
89
|
warnings: [],
|
|
61
|
-
nextSteps: cliError.nextSteps
|
|
90
|
+
nextSteps: cliError.nextSteps,
|
|
91
|
+
nextActions: cliError.nextActions
|
|
62
92
|
});
|
|
63
93
|
else writeHumanError(context.output, context.ui, cliError, { trace: flags.trace });
|
|
64
94
|
process.exitCode = cliError.exitCode;
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { renderVerboseBlock } from "./ui.js";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
//#region src/shell/diagnostics-output.ts
|
|
4
|
+
function renderCommandDiagnostics(context, diagnostics, rows = [], options = {}) {
|
|
5
|
+
if (!diagnostics) return [];
|
|
6
|
+
const { env } = context.runtime;
|
|
7
|
+
const git = diagnostics.git;
|
|
8
|
+
return renderVerboseBlock(context.ui, [
|
|
9
|
+
...rows,
|
|
10
|
+
...diagnostics.durationMs === void 0 ? [] : [{
|
|
11
|
+
key: "duration",
|
|
12
|
+
value: formatDuration(diagnostics.durationMs)
|
|
13
|
+
}],
|
|
14
|
+
{
|
|
15
|
+
key: "cwd",
|
|
16
|
+
value: formatLocalPath(diagnostics.cwd, env)
|
|
17
|
+
},
|
|
18
|
+
{
|
|
19
|
+
key: "state file",
|
|
20
|
+
value: formatLocalPath(diagnostics.stateFilePath, env)
|
|
21
|
+
},
|
|
22
|
+
...git ? [
|
|
23
|
+
{
|
|
24
|
+
key: "git ref",
|
|
25
|
+
value: git.ref ?? "detached",
|
|
26
|
+
tone: git.ref ? "default" : "dim"
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
key: "git sha",
|
|
30
|
+
value: git.sha ?? "unknown",
|
|
31
|
+
tone: git.sha ? "default" : "dim"
|
|
32
|
+
},
|
|
33
|
+
{
|
|
34
|
+
key: "git dirty",
|
|
35
|
+
value: formatDirtyState(git.dirty),
|
|
36
|
+
tone: git.dirty ? "warning" : "dim"
|
|
37
|
+
}
|
|
38
|
+
] : [{
|
|
39
|
+
key: "git",
|
|
40
|
+
value: "not detected",
|
|
41
|
+
tone: "dim"
|
|
42
|
+
}]
|
|
43
|
+
], { title: options.title ?? "Local context" });
|
|
44
|
+
}
|
|
45
|
+
function formatLocalPath(value, env) {
|
|
46
|
+
const resolved = path.resolve(value);
|
|
47
|
+
const home = env.HOME ? path.resolve(env.HOME) : null;
|
|
48
|
+
if (home && (resolved === home || resolved.startsWith(`${home}${path.sep}`))) {
|
|
49
|
+
const relative = path.relative(home, resolved);
|
|
50
|
+
return relative ? `~/${relative}` : "~";
|
|
51
|
+
}
|
|
52
|
+
return resolved;
|
|
53
|
+
}
|
|
54
|
+
function formatDirtyState(dirty) {
|
|
55
|
+
if (dirty === null) return "unknown";
|
|
56
|
+
return dirty ? "yes" : "no";
|
|
57
|
+
}
|
|
58
|
+
function formatDuration(durationMs) {
|
|
59
|
+
if (durationMs < 1e3) return `${durationMs}ms`;
|
|
60
|
+
return `${(durationMs / 1e3).toFixed(1)}s`;
|
|
61
|
+
}
|
|
62
|
+
//#endregion
|
|
63
|
+
export { renderCommandDiagnostics };
|
package/dist/shell/errors.js
CHANGED
|
@@ -12,6 +12,7 @@ var CliError = class extends Error {
|
|
|
12
12
|
docsUrl;
|
|
13
13
|
exitCode;
|
|
14
14
|
nextSteps;
|
|
15
|
+
nextActions;
|
|
15
16
|
humanLines;
|
|
16
17
|
constructor(options) {
|
|
17
18
|
super(options.summary);
|
|
@@ -28,6 +29,7 @@ var CliError = class extends Error {
|
|
|
28
29
|
this.docsUrl = options.docsUrl ?? null;
|
|
29
30
|
this.exitCode = options.exitCode ?? 1;
|
|
30
31
|
this.nextSteps = options.nextSteps ?? [];
|
|
32
|
+
this.nextActions = options.nextActions ?? [];
|
|
31
33
|
this.humanLines = options.humanLines && options.humanLines.length > 0 ? [...options.humanLines] : null;
|
|
32
34
|
}
|
|
33
35
|
};
|
|
@@ -54,6 +56,17 @@ function authRequiredError(nextSteps = ["prisma-cli auth login"], options = {})
|
|
|
54
56
|
nextSteps
|
|
55
57
|
});
|
|
56
58
|
}
|
|
59
|
+
function commandCanceledError() {
|
|
60
|
+
return new CliError({
|
|
61
|
+
code: "COMMAND_CANCELED",
|
|
62
|
+
domain: "cli",
|
|
63
|
+
summary: "Command canceled",
|
|
64
|
+
why: null,
|
|
65
|
+
fix: null,
|
|
66
|
+
exitCode: 130,
|
|
67
|
+
humanLines: ["Command canceled [COMMAND_CANCELED]"]
|
|
68
|
+
});
|
|
69
|
+
}
|
|
57
70
|
function workspaceRequiredError() {
|
|
58
71
|
return usageError("Workspace required", "This command needs an active workspace, but the authenticated session does not have one.", "Run prisma-cli auth login and choose a workspace.", ["prisma-cli auth login"], "auth");
|
|
59
72
|
}
|
|
@@ -69,4 +82,4 @@ function featureUnavailableError(summary, why, fix, nextSteps = [], domain = "cl
|
|
|
69
82
|
});
|
|
70
83
|
}
|
|
71
84
|
//#endregion
|
|
72
|
-
export { CliError, authRequiredError, featureUnavailableError, usageError, workspaceRequiredError };
|
|
85
|
+
export { CliError, authRequiredError, commandCanceledError, featureUnavailableError, usageError, workspaceRequiredError };
|
package/dist/shell/output.js
CHANGED
|
@@ -3,6 +3,7 @@ import { renderNextSteps, renderSummaryLine } from "./ui.js";
|
|
|
3
3
|
function writeJsonSuccess(output, success) {
|
|
4
4
|
output.stdout.write(`${JSON.stringify({
|
|
5
5
|
ok: true,
|
|
6
|
+
nextActions: [],
|
|
6
7
|
...success
|
|
7
8
|
}, null, 2)}\n`);
|
|
8
9
|
}
|
|
@@ -22,13 +23,23 @@ function cliErrorToJson(error) {
|
|
|
22
23
|
docsUrl: error.docsUrl
|
|
23
24
|
};
|
|
24
25
|
}
|
|
26
|
+
function formatUnexpectedError(error, trace) {
|
|
27
|
+
const debug = error instanceof Error ? error.stack ?? error.message : String(error);
|
|
28
|
+
if (trace) return `${debug}\n`;
|
|
29
|
+
return [
|
|
30
|
+
`Unexpected CLI error: ${error instanceof Error && error.message ? error.message : String(error)}`,
|
|
31
|
+
"More: Re-run with --trace for deeper diagnostics",
|
|
32
|
+
""
|
|
33
|
+
].join("\n");
|
|
34
|
+
}
|
|
25
35
|
function writeJsonError(output, command, error) {
|
|
26
36
|
output.stdout.write(`${JSON.stringify({
|
|
27
37
|
ok: false,
|
|
28
38
|
command,
|
|
29
39
|
error: cliErrorToJson(error),
|
|
30
40
|
warnings: [],
|
|
31
|
-
nextSteps: error.nextSteps
|
|
41
|
+
nextSteps: error.nextSteps,
|
|
42
|
+
nextActions: error.nextActions
|
|
32
43
|
}, null, 2)}\n`);
|
|
33
44
|
}
|
|
34
45
|
function writeHumanLines(output, lines) {
|
|
@@ -68,4 +79,4 @@ function writeHumanError(output, ui, error, options) {
|
|
|
68
79
|
writeHumanLines(output, lines);
|
|
69
80
|
}
|
|
70
81
|
//#endregion
|
|
71
|
-
export { cliErrorToJson, writeHumanError, writeHumanLines, writeJsonError, writeJsonEvent, writeJsonSuccess };
|
|
82
|
+
export { cliErrorToJson, formatUnexpectedError, writeHumanError, writeHumanLines, writeJsonError, writeJsonEvent, writeJsonSuccess };
|
package/dist/shell/runtime.js
CHANGED
|
@@ -22,13 +22,13 @@ async function createCommandContext(runtime, flags) {
|
|
|
22
22
|
const fixturePath = runtime.fixturePath ?? runtime.env.PRISMA_CLI_MOCK_FIXTURE_PATH;
|
|
23
23
|
const stateDir = resolveStateDir(runtime);
|
|
24
24
|
let loadedApi;
|
|
25
|
-
if (fixturePath) loadedApi = await MockApi.load(fixturePath);
|
|
25
|
+
if (fixturePath) loadedApi = await MockApi.load(fixturePath, runtime.signal);
|
|
26
26
|
return {
|
|
27
27
|
get api() {
|
|
28
28
|
if (!loadedApi) throw new Error("context.api accessed in real mode. Set runtime.fixturePath or PRISMA_CLI_MOCK_FIXTURE_PATH to use fixture mode.");
|
|
29
29
|
return loadedApi;
|
|
30
30
|
},
|
|
31
|
-
stateStore: new LocalStateStore(stateDir),
|
|
31
|
+
stateStore: new LocalStateStore(stateDir, runtime.signal),
|
|
32
32
|
output: {
|
|
33
33
|
stdout: runtime.stdout,
|
|
34
34
|
stderr: runtime.stderr
|
|
@@ -48,4 +48,4 @@ function canPrompt(context) {
|
|
|
48
48
|
return Boolean(context.runtime.stdin.isTTY && context.runtime.stderr.isTTY);
|
|
49
49
|
}
|
|
50
50
|
//#endregion
|
|
51
|
-
export { canPrompt, configureRuntimeCommand, createCommandContext };
|
|
51
|
+
export { canPrompt, configureRuntimeCommand, createCommandContext, resolveStateDir };
|
package/dist/shell/ui.js
CHANGED
|
@@ -48,6 +48,20 @@ function renderNextSteps(steps) {
|
|
|
48
48
|
...steps.map((step) => `- ${step}`)
|
|
49
49
|
];
|
|
50
50
|
}
|
|
51
|
+
function renderVerboseBlock(ui, rows, options = {}) {
|
|
52
|
+
if (!ui.verbose || rows.length === 0) return [];
|
|
53
|
+
const title = options.title ?? "Details";
|
|
54
|
+
const keyWidth = Math.max(...rows.map((row) => stringWidth(`${row.key}:`)));
|
|
55
|
+
const rail = ui.dim("│");
|
|
56
|
+
return [
|
|
57
|
+
"",
|
|
58
|
+
`${ui.dim(title)}:`,
|
|
59
|
+
...rows.map((row) => `${rail} ${ui.accent(padDisplay(`${row.key}:`, keyWidth))} ${formatVerboseValue(ui, row)}`)
|
|
60
|
+
];
|
|
61
|
+
}
|
|
62
|
+
function formatColumns(columns, widths) {
|
|
63
|
+
return columns.map((value, index) => padDisplay(value, widths[index])).join(" ").trimEnd();
|
|
64
|
+
}
|
|
51
65
|
function wrapText(text, width, indent = "") {
|
|
52
66
|
return wrapAnsi(text, width, {
|
|
53
67
|
hard: false,
|
|
@@ -73,5 +87,13 @@ function formatHeaderValue(ui, row) {
|
|
|
73
87
|
if (row.tone === "link") return ui.link(value);
|
|
74
88
|
return value;
|
|
75
89
|
}
|
|
90
|
+
function formatVerboseValue(ui, row) {
|
|
91
|
+
const value = row.sensitive ? maskValue(row.value) : row.value;
|
|
92
|
+
if (row.tone === "dim") return ui.dim(value);
|
|
93
|
+
if (row.tone === "success") return ui.success(value);
|
|
94
|
+
if (row.tone === "warning") return ui.warning(value);
|
|
95
|
+
if (row.tone === "link") return ui.link(value);
|
|
96
|
+
return value;
|
|
97
|
+
}
|
|
76
98
|
//#endregion
|
|
77
|
-
export { createShellUi, maskValue, padDisplay, renderCommandHeader, renderNextSteps, renderSummaryLine, wrapText };
|
|
99
|
+
export { createShellUi, formatColumns, maskValue, padDisplay, renderCommandHeader, renderNextSteps, renderSummaryLine, renderVerboseBlock, wrapText };
|