@prisma/cli 3.0.0-beta.10 → 3.0.0-beta.12
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/adapters/token-storage.js +2 -2
- package/dist/cli.js +7 -7
- package/dist/cli2.js +3 -3
- package/dist/commands/app/index.js +65 -52
- package/dist/controllers/app-env.js +6 -5
- package/dist/controllers/app.js +505 -184
- package/dist/controllers/branch.js +1 -1
- package/dist/controllers/database.js +1 -1
- package/dist/controllers/project.js +6 -6
- package/dist/lib/app/app-interaction.js +5 -0
- package/dist/lib/app/{preview-provider.js → app-provider.js} +32 -28
- package/dist/lib/app/{preview-branch-database.js → branch-database-api.js} +1 -1
- package/dist/lib/app/branch-database-deploy.js +12 -60
- package/dist/lib/app/branch-database.js +1 -102
- package/dist/lib/app/build-settings.js +93 -0
- package/dist/lib/app/build.js +80 -0
- package/dist/lib/app/bun-project.js +2 -3
- package/dist/lib/app/compute-config.js +147 -0
- package/dist/lib/app/deploy-plan.js +58 -0
- package/dist/lib/app/{preview-progress.js → deploy-progress.js} +5 -5
- package/dist/lib/app/local-dev.js +3 -60
- package/dist/lib/app/production-deploy-gate.js +3 -3
- package/dist/lib/app/read-branch.js +30 -0
- package/dist/lib/auth/login.js +31 -24
- package/dist/lib/diagnostics.js +1 -1
- package/dist/lib/fs/home-path.js +24 -0
- package/dist/lib/git/local-branch.js +15 -3
- package/dist/lib/project/resolution.js +2 -2
- package/dist/lib/project/setup.js +10 -7
- package/dist/output/patterns.js +1 -1
- package/dist/presenters/app.js +44 -39
- package/dist/presenters/branch.js +1 -1
- package/dist/presenters/database.js +2 -2
- package/dist/presenters/project.js +3 -9
- package/dist/shell/command-runner.js +37 -27
- package/dist/shell/diagnostics-output.js +2 -8
- package/dist/shell/help.js +30 -20
- package/dist/shell/runtime.js +8 -4
- package/dist/shell/ui.js +19 -2
- package/package.json +17 -3
- package/dist/lib/app/preview-build-settings.js +0 -385
- package/dist/lib/app/preview-build.js +0 -475
- package/dist/lib/app/preview-interaction.js +0 -5
package/dist/presenters/app.js
CHANGED
|
@@ -28,7 +28,8 @@ function renderAppBuild(context, descriptor, result) {
|
|
|
28
28
|
function serializeAppBuild(result) {
|
|
29
29
|
return result;
|
|
30
30
|
}
|
|
31
|
-
function renderAppDeploy(context, descriptor, result) {
|
|
31
|
+
function renderAppDeploy(context, descriptor, result, options) {
|
|
32
|
+
const logsCommand = options?.logsTarget ? `prisma-cli app logs ${options.logsTarget}` : "prisma-cli app logs";
|
|
32
33
|
return [
|
|
33
34
|
`Live in ${formatDuration(result.durationMs)}`,
|
|
34
35
|
...result.deployment.url ? [context.ui.link(result.deployment.url)] : [],
|
|
@@ -36,12 +37,37 @@ function renderAppDeploy(context, descriptor, result) {
|
|
|
36
37
|
"",
|
|
37
38
|
...renderDeployOutputRows(context.ui, [{
|
|
38
39
|
label: "Logs",
|
|
39
|
-
value:
|
|
40
|
+
value: logsCommand
|
|
40
41
|
}]),
|
|
41
42
|
...renderDeployResolvedContextBlock(context, result),
|
|
42
43
|
...renderDeploySettingsBlock(context, result)
|
|
43
44
|
];
|
|
44
45
|
}
|
|
46
|
+
function isAppDeployAllResult(result) {
|
|
47
|
+
return "deployments" in result;
|
|
48
|
+
}
|
|
49
|
+
function renderAppDeployAll(context, descriptor, result) {
|
|
50
|
+
const lines = [];
|
|
51
|
+
for (const deployment of result.deployments) {
|
|
52
|
+
lines.push(deployment.target);
|
|
53
|
+
lines.push(...renderAppDeploy(context, descriptor, deployment.result, { logsTarget: deployment.target }).map((line) => line ? ` ${line}` : line));
|
|
54
|
+
lines.push("");
|
|
55
|
+
}
|
|
56
|
+
lines.push(...renderDeployOutputRows(context.ui, result.deployments.map((deployment) => ({
|
|
57
|
+
label: deployment.target,
|
|
58
|
+
value: deployment.result.deployment.url ?? deployment.result.deployment.id
|
|
59
|
+
}))));
|
|
60
|
+
return lines;
|
|
61
|
+
}
|
|
62
|
+
function serializeAppDeployAll(result) {
|
|
63
|
+
return {
|
|
64
|
+
count: result.deployments.length,
|
|
65
|
+
deployments: result.deployments.map((deployment) => ({
|
|
66
|
+
target: deployment.target,
|
|
67
|
+
...serializeAppDeploy(deployment.result)
|
|
68
|
+
}))
|
|
69
|
+
};
|
|
70
|
+
}
|
|
45
71
|
function serializeAppDeploy(result) {
|
|
46
72
|
const { deploySettings, localPin: _localPin, ...serialized } = result;
|
|
47
73
|
const { id: _branchId, ...branch } = serialized.branch;
|
|
@@ -57,27 +83,13 @@ function serializeAppDeploy(result) {
|
|
|
57
83
|
}
|
|
58
84
|
function renderBranchDatabaseDeploySummary(context, result) {
|
|
59
85
|
if (!result.branchDatabase || result.branchDatabase.status !== "created") return [];
|
|
60
|
-
return ["", ...renderDeployOutputRows(context.ui, [
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
value: result.branchDatabase.envVars.join(", ")
|
|
68
|
-
},
|
|
69
|
-
...result.branchDatabase.schema ? [{
|
|
70
|
-
label: "Schema",
|
|
71
|
-
value: formatBranchDatabaseSchemaCommand(result.branchDatabase.schema.command)
|
|
72
|
-
}] : []
|
|
73
|
-
])];
|
|
74
|
-
}
|
|
75
|
-
function formatBranchDatabaseSchemaCommand(command) {
|
|
76
|
-
switch (command) {
|
|
77
|
-
case "migrate-deploy": return "prisma migrate deploy";
|
|
78
|
-
case "db-push": return "prisma db push";
|
|
79
|
-
case "prisma-next-db-init": return "prisma-next db init";
|
|
80
|
-
}
|
|
86
|
+
return ["", ...renderDeployOutputRows(context.ui, [{
|
|
87
|
+
label: "Database",
|
|
88
|
+
value: result.branchDatabase.database?.name ?? "created"
|
|
89
|
+
}, {
|
|
90
|
+
label: "Env",
|
|
91
|
+
value: result.branchDatabase.envVars.join(", ")
|
|
92
|
+
}])];
|
|
81
93
|
}
|
|
82
94
|
function formatDuration(durationMs) {
|
|
83
95
|
if (durationMs < 1e3) return `${durationMs}ms`;
|
|
@@ -163,21 +175,14 @@ function branchDatabaseRows(branchDatabase) {
|
|
|
163
175
|
value: "not configured",
|
|
164
176
|
tone: "dim"
|
|
165
177
|
}];
|
|
166
|
-
return [
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
value: branchDatabase.envVars.join(", ")
|
|
175
|
-
}] : [],
|
|
176
|
-
...branchDatabase.schema ? [{
|
|
177
|
-
key: "branch db schema",
|
|
178
|
-
value: `${formatBranchDatabaseSchemaCommand(branchDatabase.schema.command)} (${branchDatabase.schema.source}, ${branchDatabase.schema.path})`
|
|
179
|
-
}] : []
|
|
180
|
-
];
|
|
178
|
+
return [{
|
|
179
|
+
key: "branch db",
|
|
180
|
+
value: branchDatabase.status === "created" ? `created${branchDatabase.database ? ` (${branchDatabase.database.name})` : ""}` : `skipped${branchDatabase.reason ? ` (${branchDatabase.reason})` : ""}`,
|
|
181
|
+
tone: branchDatabase.status === "created" ? "success" : "dim"
|
|
182
|
+
}, ...branchDatabase.envVars.length > 0 ? [{
|
|
183
|
+
key: "branch db env",
|
|
184
|
+
value: branchDatabase.envVars.join(", ")
|
|
185
|
+
}] : []];
|
|
181
186
|
}
|
|
182
187
|
function formatEnvVarNames(envVars) {
|
|
183
188
|
return envVars.length > 0 ? envVars.join(", ") : "none";
|
|
@@ -638,4 +643,4 @@ function formatRecentDeployments(deployments) {
|
|
|
638
643
|
return deployments.map((deployment) => `${deployment.id}${deployment.live ? " (live)" : ""}`).join(", ");
|
|
639
644
|
}
|
|
640
645
|
//#endregion
|
|
641
|
-
export { renderAppBuild, renderAppDeploy, renderAppDomainAdd, renderAppDomainRemove, renderAppDomainRetry, renderAppDomainShow, renderAppListDeploys, renderAppOpen, renderAppPromote, renderAppRemove, renderAppRollback, renderAppRun, renderAppShow, renderAppShowDeploy, serializeAppBuild, serializeAppDeploy, serializeAppDomainAdd, serializeAppDomainRemove, serializeAppDomainRetry, serializeAppDomainShow, serializeAppListDeploys, serializeAppOpen, serializeAppPromote, serializeAppRemove, serializeAppRollback, serializeAppRun, serializeAppShow, serializeAppShowDeploy };
|
|
646
|
+
export { isAppDeployAllResult, renderAppBuild, renderAppDeploy, renderAppDeployAll, renderAppDomainAdd, renderAppDomainRemove, renderAppDomainRetry, renderAppDomainShow, renderAppListDeploys, renderAppOpen, renderAppPromote, renderAppRemove, renderAppRollback, renderAppRun, renderAppShow, renderAppShowDeploy, serializeAppBuild, serializeAppDeploy, serializeAppDeployAll, serializeAppDomainAdd, serializeAppDomainRemove, serializeAppDomainRetry, serializeAppDomainShow, serializeAppListDeploys, serializeAppOpen, serializeAppPromote, serializeAppRemove, serializeAppRollback, serializeAppRun, serializeAppShow, serializeAppShowDeploy };
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { formatColumns } from "../shell/ui.js";
|
|
2
1
|
import { formatDescriptorLabel } from "../shell/command-meta.js";
|
|
2
|
+
import { formatColumns } from "../shell/ui.js";
|
|
3
3
|
import { renderResolvedProjectContextBlock } from "./verbose-context.js";
|
|
4
4
|
//#region src/presenters/branch.ts
|
|
5
5
|
function renderBranchList(context, descriptor, result) {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { formatColumns, renderSummaryLine } from "../shell/ui.js";
|
|
2
1
|
import { formatDescriptorLabel } from "../shell/command-meta.js";
|
|
2
|
+
import { formatColumns, renderSummaryLine } from "../shell/ui.js";
|
|
3
3
|
import { renderMutate, renderShow, serializeList } from "../output/patterns.js";
|
|
4
4
|
import { renderResolvedProjectContextBlock, stripVerboseContext } from "./verbose-context.js";
|
|
5
5
|
//#region src/presenters/database.ts
|
|
@@ -234,7 +234,7 @@ function renderDatabaseConnectionRemove(context, descriptor, result) {
|
|
|
234
234
|
}, context.ui);
|
|
235
235
|
}
|
|
236
236
|
function serializeDatabaseConnectionRemove(result) {
|
|
237
|
-
return result;
|
|
237
|
+
return { connection: result.connection };
|
|
238
238
|
}
|
|
239
239
|
function formatStatus(database) {
|
|
240
240
|
return database.status ?? (database.isDefault ? "default" : "unknown");
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { padDisplay, renderNextSteps, renderSummaryLine, renderVerboseBlock } from "../shell/ui.js";
|
|
2
1
|
import { formatDescriptorLabel } from "../shell/command-meta.js";
|
|
2
|
+
import { padDisplay, renderNextSteps, renderSummaryLine, renderVerboseBlock } from "../shell/ui.js";
|
|
3
|
+
import { shortenHomePath } from "../lib/fs/home-path.js";
|
|
3
4
|
import { formatCommandArgument } from "../shell/command-arguments.js";
|
|
4
5
|
import { renderMutate, renderShow, serializeList } from "../output/patterns.js";
|
|
5
6
|
import { renderResolvedProjectContextBlock } from "./verbose-context.js";
|
|
6
|
-
import path from "node:path";
|
|
7
7
|
import stringWidth from "string-width";
|
|
8
8
|
//#region src/presenters/project.ts
|
|
9
9
|
function renderProjectList(context, descriptor, result) {
|
|
@@ -160,13 +160,7 @@ function renderBoundProjectShow(context, descriptor, result) {
|
|
|
160
160
|
return lines;
|
|
161
161
|
}
|
|
162
162
|
function formatLocalRepoPath(cwd, env) {
|
|
163
|
-
|
|
164
|
-
const home = env.HOME ? path.resolve(env.HOME) : null;
|
|
165
|
-
if (home && (resolved === home || resolved.startsWith(`${home}${path.sep}`))) {
|
|
166
|
-
const relative = path.relative(home, resolved);
|
|
167
|
-
return relative ? `~/${relative}` : "~";
|
|
168
|
-
}
|
|
169
|
-
return resolved;
|
|
163
|
+
return shortenHomePath(cwd, env);
|
|
170
164
|
}
|
|
171
165
|
function formatGitConnectionDetail(status) {
|
|
172
166
|
switch (status) {
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { CliError, authRequiredError, commandCanceledError } from "./errors.js";
|
|
2
|
-
import { cliErrorToJson, writeHumanError, writeHumanLines, writeJsonError, writeJsonEvent, writeJsonSuccess } from "./output.js";
|
|
3
2
|
import { getCommandDescriptor } from "./command-meta.js";
|
|
4
3
|
import { resolveGlobalFlags } from "./global-flags.js";
|
|
5
4
|
import { createCommandContext } from "./runtime.js";
|
|
5
|
+
import { cliErrorToJson, writeHumanError, writeHumanLines, writeJsonError, writeJsonEvent, writeJsonSuccess } from "./output.js";
|
|
6
6
|
import { collectCommandDiagnostics } from "../lib/diagnostics.js";
|
|
7
7
|
import { renderCommandDiagnostics } from "./diagnostics-output.js";
|
|
8
8
|
import { AuthError } from "@prisma/management-api-sdk";
|
|
@@ -18,44 +18,54 @@ function isCancellationError(error) {
|
|
|
18
18
|
return error.name === "AbortError" || error.name === "CancelledError";
|
|
19
19
|
}
|
|
20
20
|
async function runCommand(runtime, commandName, options, handler, presenter) {
|
|
21
|
-
const
|
|
22
|
-
const context = await createCommandContext(runtime, flags);
|
|
21
|
+
const context = await createCommandContext(runtime, resolveGlobalFlags(runtime.argv, options));
|
|
23
22
|
const descriptor = getCommandDescriptor(commandName);
|
|
24
23
|
const startedAt = Date.now();
|
|
25
24
|
try {
|
|
26
|
-
|
|
27
|
-
if (flags.json) {
|
|
28
|
-
writeJsonSuccess(context.output, {
|
|
29
|
-
...success,
|
|
30
|
-
result: presenter.renderJson ? presenter.renderJson(success.result) : success.result
|
|
31
|
-
});
|
|
32
|
-
return;
|
|
33
|
-
}
|
|
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`);
|
|
25
|
+
await writeCommandSuccess(context, descriptor, await handler(context), presenter, Date.now() - startedAt);
|
|
48
26
|
} catch (error) {
|
|
49
27
|
const cliError = toCliError(error, runtime);
|
|
50
28
|
if (cliError) {
|
|
51
|
-
|
|
52
|
-
else writeHumanError(context.output, context.ui, cliError, { trace: flags.trace });
|
|
29
|
+
writeCommandError(context, commandName, cliError);
|
|
53
30
|
process.exitCode = cliError.exitCode;
|
|
54
31
|
return;
|
|
55
32
|
}
|
|
56
33
|
throw error;
|
|
57
34
|
}
|
|
58
35
|
}
|
|
36
|
+
async function writeCommandSuccess(context, descriptor, success, presenter, durationMs) {
|
|
37
|
+
if (context.flags.json) {
|
|
38
|
+
writeJsonSuccess(context.output, {
|
|
39
|
+
...success,
|
|
40
|
+
result: presenter.renderJson ? presenter.renderJson(success.result) : success.result
|
|
41
|
+
});
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
44
|
+
const stdout = presenter.renderStdout?.(context, descriptor, success.result) ?? [];
|
|
45
|
+
if (context.flags.quiet) {
|
|
46
|
+
writeStdoutLines(context, stdout);
|
|
47
|
+
return;
|
|
48
|
+
}
|
|
49
|
+
const rendered = presenter.renderHuman(context, descriptor, success.result);
|
|
50
|
+
const diagnostics = await renderBestEffortCommandDiagnostics(context, {
|
|
51
|
+
enabled: context.flags.verbose && rendered.length > 0,
|
|
52
|
+
durationMs
|
|
53
|
+
});
|
|
54
|
+
const humanLines = [...rendered, ...diagnostics];
|
|
55
|
+
if (stdout.length > 0 && humanLines.length > 0) humanLines.push("");
|
|
56
|
+
writeHumanLines(context.output, humanLines);
|
|
57
|
+
writeStdoutLines(context, stdout);
|
|
58
|
+
}
|
|
59
|
+
function writeCommandError(context, commandName, cliError) {
|
|
60
|
+
if (context.flags.json) {
|
|
61
|
+
writeJsonError(context.output, commandName, cliError);
|
|
62
|
+
return;
|
|
63
|
+
}
|
|
64
|
+
writeHumanError(context.output, context.ui, cliError, { trace: context.flags.trace });
|
|
65
|
+
}
|
|
66
|
+
function writeStdoutLines(context, lines) {
|
|
67
|
+
if (lines.length > 0) context.output.stdout.write(`${lines.join("\n")}\n`);
|
|
68
|
+
}
|
|
59
69
|
async function renderBestEffortCommandDiagnostics(context, options) {
|
|
60
70
|
if (!options.enabled) return [];
|
|
61
71
|
try {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { renderVerboseBlock } from "./ui.js";
|
|
2
|
-
import
|
|
2
|
+
import { shortenHomePath } from "../lib/fs/home-path.js";
|
|
3
3
|
//#region src/shell/diagnostics-output.ts
|
|
4
4
|
function renderCommandDiagnostics(context, diagnostics, rows = [], options = {}) {
|
|
5
5
|
if (!diagnostics) return [];
|
|
@@ -43,13 +43,7 @@ function renderCommandDiagnostics(context, diagnostics, rows = [], options = {})
|
|
|
43
43
|
], { title: options.title ?? "Local context" });
|
|
44
44
|
}
|
|
45
45
|
function formatLocalPath(value, env) {
|
|
46
|
-
|
|
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;
|
|
46
|
+
return shortenHomePath(value, env);
|
|
53
47
|
}
|
|
54
48
|
function formatDirtyState(dirty) {
|
|
55
49
|
if (dirty === null) return "unknown";
|
package/dist/shell/help.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { createShellUi, padDisplay, wrapText } from "./ui.js";
|
|
2
1
|
import { formatDescriptorLabel, getDescriptorForCommand } from "./command-meta.js";
|
|
3
2
|
import { COMPACT_GLOBAL_OPTION_FLAGS, resolveGlobalFlags } from "./global-flags.js";
|
|
3
|
+
import { createShellUi, padDisplay, wrapText } from "./ui.js";
|
|
4
4
|
//#region src/shell/help.ts
|
|
5
5
|
function renderHelp(command, runtime) {
|
|
6
6
|
const descriptor = getDescriptorForCommand(command);
|
|
@@ -10,28 +10,38 @@ function renderHelp(command, runtime) {
|
|
|
10
10
|
const visibleCommands = command.commands.filter((candidate) => candidate.name() !== "help" && !candidate.hidden);
|
|
11
11
|
const visibleOptions = command.options.filter((candidate) => !candidate.hidden);
|
|
12
12
|
if (visibleCommands.length > 0) lines.push(...renderCommandRows(rail, ui, visibleCommands));
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
}
|
|
18
|
-
if (visibleOptions.length > 0) {
|
|
19
|
-
if (visibleCommands.length > 0) lines.push(`${rail}`);
|
|
20
|
-
if (visibleCommands.length > 0 && visibleOptions.every((option) => COMPACT_GLOBAL_OPTION_FLAGS.includes(option.flags))) lines.push(`${rail} Global options:`);
|
|
21
|
-
lines.push(...renderOptionRows(rail, ui, visibleOptions));
|
|
22
|
-
}
|
|
23
|
-
if (descriptor.examples && descriptor.examples.length > 0) {
|
|
24
|
-
lines.push(`${rail}`);
|
|
25
|
-
lines.push(`${rail} Examples:`);
|
|
26
|
-
for (const example of descriptor.examples) lines.push(`${rail} $ ${example}`);
|
|
27
|
-
}
|
|
28
|
-
if (descriptor.docsPath) {
|
|
29
|
-
lines.push(`${rail}`);
|
|
30
|
-
lines.push(`${rail} ${ui.accent(padDisplay("Read more", 16))} ${ui.link(descriptor.docsPath)}`);
|
|
31
|
-
}
|
|
13
|
+
lines.push(...renderLongDescription(rail, ui, descriptor.longDescription));
|
|
14
|
+
lines.push(...renderVisibleOptions(rail, ui, visibleCommands, visibleOptions));
|
|
15
|
+
lines.push(...renderExamples(rail, descriptor.examples));
|
|
16
|
+
lines.push(...renderDocsPath(rail, ui, descriptor.docsPath));
|
|
32
17
|
lines.push("");
|
|
33
18
|
return `${lines.join("\n")}`;
|
|
34
19
|
}
|
|
20
|
+
function renderLongDescription(rail, ui, longDescription) {
|
|
21
|
+
if (!longDescription) return [];
|
|
22
|
+
return [`${rail}`, ...wrapText(longDescription, Math.max(ui.width - 3, 40)).map((line) => `${rail} ${line}`)];
|
|
23
|
+
}
|
|
24
|
+
function renderVisibleOptions(rail, ui, visibleCommands, visibleOptions) {
|
|
25
|
+
if (visibleOptions.length === 0) return [];
|
|
26
|
+
const lines = visibleCommands.length > 0 ? [`${rail}`] : [];
|
|
27
|
+
if (shouldLabelGlobalOptions(visibleCommands, visibleOptions)) lines.push(`${rail} Global options:`);
|
|
28
|
+
return [...lines, ...renderOptionRows(rail, ui, visibleOptions)];
|
|
29
|
+
}
|
|
30
|
+
function shouldLabelGlobalOptions(visibleCommands, visibleOptions) {
|
|
31
|
+
return visibleCommands.length > 0 && visibleOptions.every((option) => COMPACT_GLOBAL_OPTION_FLAGS.includes(option.flags));
|
|
32
|
+
}
|
|
33
|
+
function renderExamples(rail, examples) {
|
|
34
|
+
if (!examples || examples.length === 0) return [];
|
|
35
|
+
return [
|
|
36
|
+
`${rail}`,
|
|
37
|
+
`${rail} Examples:`,
|
|
38
|
+
...examples.map((example) => `${rail} $ ${example}`)
|
|
39
|
+
];
|
|
40
|
+
}
|
|
41
|
+
function renderDocsPath(rail, ui, docsPath) {
|
|
42
|
+
if (!docsPath) return [];
|
|
43
|
+
return [`${rail}`, `${rail} ${ui.accent(padDisplay("Read more", 16))} ${ui.link(docsPath)}`];
|
|
44
|
+
}
|
|
35
45
|
function renderCommandRows(rail, ui, commands) {
|
|
36
46
|
return renderAlignedRows(rail, ui, commands.map((command) => {
|
|
37
47
|
const descriptor = getDescriptorForCommand(command);
|
package/dist/shell/runtime.js
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
import { createShellUi } from "./ui.js";
|
|
2
1
|
import { LocalStateStore } from "../adapters/local-state.js";
|
|
3
2
|
import { MockApi } from "../adapters/mock-api.js";
|
|
3
|
+
import { createShellUi } from "./ui.js";
|
|
4
4
|
import { renderHelp } from "./help.js";
|
|
5
|
+
import { findComputeConfigDir } from "@prisma/compute-sdk/config";
|
|
5
6
|
import path from "node:path";
|
|
6
7
|
//#region src/shell/runtime.ts
|
|
7
8
|
const DEFAULT_STATE_DIR_NAME = path.join(".prisma", "cli");
|
|
@@ -20,7 +21,7 @@ function configureRuntimeCommand(command, runtime) {
|
|
|
20
21
|
}
|
|
21
22
|
async function createCommandContext(runtime, flags) {
|
|
22
23
|
const fixturePath = runtime.fixturePath ?? runtime.env.PRISMA_CLI_MOCK_FIXTURE_PATH;
|
|
23
|
-
const stateDir = resolveStateDir(runtime);
|
|
24
|
+
const stateDir = await resolveStateDir(runtime);
|
|
24
25
|
let loadedApi;
|
|
25
26
|
if (fixturePath) loadedApi = await MockApi.load(fixturePath, runtime.signal);
|
|
26
27
|
return {
|
|
@@ -38,8 +39,11 @@ async function createCommandContext(runtime, flags) {
|
|
|
38
39
|
ui: createShellUi(runtime, flags)
|
|
39
40
|
};
|
|
40
41
|
}
|
|
41
|
-
function resolveStateDir(runtime) {
|
|
42
|
-
|
|
42
|
+
async function resolveStateDir(runtime) {
|
|
43
|
+
const explicitStateDir = runtime.stateDir ?? runtime.env.PRISMA_CLI_STATE_DIR;
|
|
44
|
+
if (explicitStateDir) return explicitStateDir;
|
|
45
|
+
const projectDir = await findComputeConfigDir(runtime.cwd, runtime.signal);
|
|
46
|
+
return path.join(projectDir ?? runtime.cwd, DEFAULT_STATE_DIR_NAME);
|
|
43
47
|
}
|
|
44
48
|
function canPrompt(context) {
|
|
45
49
|
if (context.flags.json) return false;
|
package/dist/shell/ui.js
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
|
+
import { createColors } from "colorette";
|
|
1
2
|
import stringWidth from "string-width";
|
|
2
3
|
import stripAnsi from "strip-ansi";
|
|
3
4
|
import wrapAnsi from "wrap-ansi";
|
|
4
|
-
import { createColors } from "colorette";
|
|
5
5
|
//#region src/shell/ui.ts
|
|
6
|
+
const URL_CREDENTIALS_PATTERN = /:\/\/[^:@/\s]+:[^@/\s]+@/g;
|
|
6
7
|
const DEFAULT_WIDTH = 80;
|
|
7
8
|
function createShellUi(runtime, flags) {
|
|
8
9
|
const isTTY = Boolean(runtime.stderr.isTTY);
|
|
@@ -73,7 +74,23 @@ function padDisplay(text, width) {
|
|
|
73
74
|
return `${text}${" ".repeat(padding)}`;
|
|
74
75
|
}
|
|
75
76
|
function maskValue(value) {
|
|
76
|
-
return value
|
|
77
|
+
return maskEmailLocalParts(value).replace(URL_CREDENTIALS_PATTERN, "://****:****@");
|
|
78
|
+
}
|
|
79
|
+
function maskEmailLocalParts(value) {
|
|
80
|
+
let masked = "";
|
|
81
|
+
let segmentStart = 0;
|
|
82
|
+
for (let index = 0; index < value.length; index += 1) {
|
|
83
|
+
if (value[index] !== "@") continue;
|
|
84
|
+
let localStart = index;
|
|
85
|
+
while (localStart > segmentStart && isEmailLocalPartChar(value[localStart - 1])) localStart -= 1;
|
|
86
|
+
if (localStart === index) continue;
|
|
87
|
+
masked += `${value.slice(segmentStart, localStart)}****@`;
|
|
88
|
+
segmentStart = index + 1;
|
|
89
|
+
}
|
|
90
|
+
return masked + value.slice(segmentStart);
|
|
91
|
+
}
|
|
92
|
+
function isEmailLocalPartChar(char) {
|
|
93
|
+
return char >= "A" && char <= "Z" || char >= "a" && char <= "z" || char >= "0" && char <= "9" || char === "!" || char === "#" || char === "$" || char === "." || char === "&" || char === "'" || char === "*" || char === "%" || char === "+" || char === "-" || char === "/" || char === "=" || char === "?" || char === "^" || char === "_" || char === "`" || char === "{" || char === "|" || char === "}" || char === "~";
|
|
77
94
|
}
|
|
78
95
|
function resolveColorEnabled(runtime, flags, isTTY) {
|
|
79
96
|
if (flags.color === true) return true;
|
package/package.json
CHANGED
|
@@ -1,11 +1,14 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@prisma/cli",
|
|
3
|
-
"version": "3.0.0-beta.
|
|
3
|
+
"version": "3.0.0-beta.12",
|
|
4
4
|
"description": "Command-line interface for the Prisma Developer Platform.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
7
7
|
"prisma-cli": "./dist/cli.js"
|
|
8
8
|
},
|
|
9
|
+
"exports": {
|
|
10
|
+
"./package.json": "./package.json"
|
|
11
|
+
},
|
|
9
12
|
"files": [
|
|
10
13
|
"dist",
|
|
11
14
|
"README.md",
|
|
@@ -34,13 +37,17 @@
|
|
|
34
37
|
"url": "https://github.com/prisma/prisma-cli/issues"
|
|
35
38
|
},
|
|
36
39
|
"license": "Apache-2.0",
|
|
40
|
+
"scripts": {
|
|
41
|
+
"build": "tsdown",
|
|
42
|
+
"prepack": "pnpm run build",
|
|
43
|
+
"test": "vitest run"
|
|
44
|
+
},
|
|
37
45
|
"dependencies": {
|
|
38
46
|
"@clack/prompts": "^1.5.0",
|
|
39
|
-
"@prisma/compute-sdk": "^0.
|
|
47
|
+
"@prisma/compute-sdk": "^0.28.0",
|
|
40
48
|
"@prisma/credentials-store": "^7.8.0",
|
|
41
49
|
"@prisma/management-api-sdk": "^1.37.0",
|
|
42
50
|
"better-result": "^2.9.2",
|
|
43
|
-
"c12": "4.0.0-beta.5",
|
|
44
51
|
"colorette": "^2.0.20",
|
|
45
52
|
"commander": "^14.0.3",
|
|
46
53
|
"dotenv": "^17.4.2",
|
|
@@ -49,5 +56,12 @@
|
|
|
49
56
|
"string-width": "^8.2.1",
|
|
50
57
|
"strip-ansi": "^7.2.0",
|
|
51
58
|
"wrap-ansi": "^10.0.0"
|
|
59
|
+
},
|
|
60
|
+
"devDependencies": {
|
|
61
|
+
"@types/node": "^22.19.19",
|
|
62
|
+
"tsdown": "^0.21.10",
|
|
63
|
+
"tsx": "^4.22.4",
|
|
64
|
+
"typescript": "^6.0.3",
|
|
65
|
+
"vitest": "^4.1.8"
|
|
52
66
|
}
|
|
53
67
|
}
|