@prisma/cli 3.0.0-dev.105.1 → 3.0.0-dev.108.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/cli2.js +2 -0
- package/dist/commands/build/index.js +29 -0
- package/dist/controllers/app.js +1 -1
- package/dist/controllers/build.js +88 -0
- package/dist/lib/app/app-provider.js +3 -3
- package/dist/shell/command-meta.js +16 -0
- package/dist/shell/command-runner.js +2 -2
- package/package.json +2 -2
package/dist/cli2.js
CHANGED
|
@@ -9,6 +9,7 @@ import "./shell/prompt.js";
|
|
|
9
9
|
import { createAppCommand } from "./commands/app/index.js";
|
|
10
10
|
import { createAuthCommand } from "./commands/auth/index.js";
|
|
11
11
|
import { createBranchCommand } from "./commands/branch/index.js";
|
|
12
|
+
import { createBuildCommand } from "./commands/build/index.js";
|
|
12
13
|
import { createDatabaseCommand } from "./commands/database/index.js";
|
|
13
14
|
import { createGitCommand } from "./commands/git/index.js";
|
|
14
15
|
import { createProjectCommand } from "./commands/project/index.js";
|
|
@@ -52,6 +53,7 @@ function createProgram(runtime) {
|
|
|
52
53
|
program.addCommand(createProjectCommand(runtime));
|
|
53
54
|
program.addCommand(createGitCommand(runtime));
|
|
54
55
|
program.addCommand(createBranchCommand(runtime));
|
|
56
|
+
program.addCommand(createBuildCommand(runtime));
|
|
55
57
|
program.addCommand(createDatabaseCommand(runtime));
|
|
56
58
|
program.addCommand(createAppCommand(runtime));
|
|
57
59
|
return program;
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { attachCommandDescriptor } from "../../shell/command-meta.js";
|
|
2
|
+
import { addCompactGlobalFlags, addGlobalFlags } from "../../shell/global-flags.js";
|
|
3
|
+
import { configureRuntimeCommand } from "../../shell/runtime.js";
|
|
4
|
+
import { runStreamingCommand } from "../../shell/command-runner.js";
|
|
5
|
+
import { runBuildLogs } from "../../controllers/build.js";
|
|
6
|
+
import { Command, Option } from "commander";
|
|
7
|
+
//#region src/commands/build/index.ts
|
|
8
|
+
function createBuildCommand(runtime) {
|
|
9
|
+
const build = attachCommandDescriptor(configureRuntimeCommand(new Command("build"), runtime), "build");
|
|
10
|
+
addCompactGlobalFlags(build);
|
|
11
|
+
build.addCommand(createLogsCommand(runtime));
|
|
12
|
+
return build;
|
|
13
|
+
}
|
|
14
|
+
function createLogsCommand(runtime) {
|
|
15
|
+
const command = attachCommandDescriptor(configureRuntimeCommand(new Command("logs"), runtime), "build.logs");
|
|
16
|
+
command.argument("<buildId>", "Build id from a git-push or Console deploy").addOption(new Option("--follow", "Keep the connection open and stream new logs as the build runs")).addOption(new Option("--cursor <cursor>", "Resume from a prior terminal cursor"));
|
|
17
|
+
addGlobalFlags(command);
|
|
18
|
+
command.action(async (buildId, options) => {
|
|
19
|
+
const follow = options.follow;
|
|
20
|
+
const cursor = options.cursor;
|
|
21
|
+
await runStreamingCommand(runtime, "build.logs", options, (context) => runBuildLogs(context, buildId, {
|
|
22
|
+
follow,
|
|
23
|
+
cursor
|
|
24
|
+
}), { emitJsonSuccessEvent: false });
|
|
25
|
+
});
|
|
26
|
+
return command;
|
|
27
|
+
}
|
|
28
|
+
//#endregion
|
|
29
|
+
export { createBuildCommand };
|
package/dist/controllers/app.js
CHANGED
|
@@ -1088,7 +1088,7 @@ function toAppDomainSummary(domain) {
|
|
|
1088
1088
|
type: domain.type,
|
|
1089
1089
|
url: domain.url,
|
|
1090
1090
|
hostname: domain.hostname,
|
|
1091
|
-
|
|
1091
|
+
appId: domain.appId,
|
|
1092
1092
|
status: domain.status,
|
|
1093
1093
|
foundryStatus: domain.foundryStatus,
|
|
1094
1094
|
failureReason: domain.failureReason,
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import { CliError, authRequiredError } from "../shell/errors.js";
|
|
2
|
+
import { writeJsonEvent } from "../shell/output.js";
|
|
3
|
+
import { requireComputeAuth } from "../lib/auth/guard.js";
|
|
4
|
+
//#region src/controllers/build.ts
|
|
5
|
+
async function runBuildLogs(context, buildId, options = {}) {
|
|
6
|
+
const client = await requireComputeAuth(context.runtime.env, context.runtime.signal);
|
|
7
|
+
if (!client) throw authRequiredError(["prisma-cli auth login"]);
|
|
8
|
+
if (!context.flags.json && !context.flags.quiet) context.output.stderr.write(`build logs → Streaming logs for build ${buildId}\n\n`);
|
|
9
|
+
const { data, response } = await client.GET("/v1/builds/{buildId}/logs", {
|
|
10
|
+
params: {
|
|
11
|
+
path: { buildId },
|
|
12
|
+
query: {
|
|
13
|
+
...options.follow ? { follow: "true" } : {},
|
|
14
|
+
...options.cursor ? { cursor: options.cursor } : {}
|
|
15
|
+
}
|
|
16
|
+
},
|
|
17
|
+
parseAs: "stream",
|
|
18
|
+
signal: context.runtime.signal
|
|
19
|
+
});
|
|
20
|
+
const body = data;
|
|
21
|
+
if (!response.ok || !body) throw buildLogsRequestError(buildId, response.status);
|
|
22
|
+
let sawError = false;
|
|
23
|
+
await forEachNdjsonRecord(body, (record) => {
|
|
24
|
+
if (record.type === "terminal" && record.kind === "error") sawError = true;
|
|
25
|
+
writeBuildLogRecord(context, record);
|
|
26
|
+
});
|
|
27
|
+
if (sawError) process.exitCode = 1;
|
|
28
|
+
}
|
|
29
|
+
function writeBuildLogRecord(context, record) {
|
|
30
|
+
if (context.flags.json) {
|
|
31
|
+
writeJsonEvent(context.output, {
|
|
32
|
+
type: record.type,
|
|
33
|
+
command: "build.logs",
|
|
34
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
35
|
+
data: record
|
|
36
|
+
});
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
if (record.type === "log") {
|
|
40
|
+
const stream = record.source === "stderr" || record.level === "error" ? context.output.stderr : context.output.stdout;
|
|
41
|
+
stream.write(record.text);
|
|
42
|
+
if (!record.text.endsWith("\n")) stream.write("\n");
|
|
43
|
+
return;
|
|
44
|
+
}
|
|
45
|
+
if (record.code !== "end") context.output.stderr.write(`${record.message}\n`);
|
|
46
|
+
}
|
|
47
|
+
/** Reads a newline-delimited JSON body line by line, parsing each into a record. */
|
|
48
|
+
async function forEachNdjsonRecord(body, onRecord) {
|
|
49
|
+
const reader = body.getReader();
|
|
50
|
+
const decoder = new TextDecoder();
|
|
51
|
+
let buffer = "";
|
|
52
|
+
for (;;) {
|
|
53
|
+
const { done, value } = await reader.read();
|
|
54
|
+
if (value) buffer += decoder.decode(value, { stream: true });
|
|
55
|
+
let newlineIndex = buffer.indexOf("\n");
|
|
56
|
+
while (newlineIndex !== -1) {
|
|
57
|
+
const line = buffer.slice(0, newlineIndex).trim();
|
|
58
|
+
buffer = buffer.slice(newlineIndex + 1);
|
|
59
|
+
if (line) onRecord(JSON.parse(line));
|
|
60
|
+
newlineIndex = buffer.indexOf("\n");
|
|
61
|
+
}
|
|
62
|
+
if (done) {
|
|
63
|
+
const tail = buffer.trim();
|
|
64
|
+
if (tail) onRecord(JSON.parse(tail));
|
|
65
|
+
return;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
function buildLogsRequestError(buildId, status) {
|
|
70
|
+
if (status === 404) return new CliError({
|
|
71
|
+
code: "BUILD_NOT_FOUND",
|
|
72
|
+
domain: "app",
|
|
73
|
+
summary: `Build ${buildId} was not found`,
|
|
74
|
+
why: "The build does not exist, or your workspace does not have access to it.",
|
|
75
|
+
fix: "Check the build id, or run prisma-cli auth login to switch to the workspace that owns it.",
|
|
76
|
+
exitCode: 1
|
|
77
|
+
});
|
|
78
|
+
return new CliError({
|
|
79
|
+
code: "BUILD_LOGS_FAILED",
|
|
80
|
+
domain: "app",
|
|
81
|
+
summary: `Failed to read logs for build ${buildId}`,
|
|
82
|
+
why: `The Management API returned HTTP ${status}.`,
|
|
83
|
+
fix: "Retry the command, or rerun with --trace for more detail.",
|
|
84
|
+
exitCode: 1
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
//#endregion
|
|
88
|
+
export { runBuildLogs };
|
|
@@ -404,9 +404,9 @@ async function listComputeServices(client, options) {
|
|
|
404
404
|
liveUrl: toAbsoluteUrl(service.appEndpointDomain ?? null)
|
|
405
405
|
}));
|
|
406
406
|
}
|
|
407
|
-
async function listComputeServiceDomains(client,
|
|
407
|
+
async function listComputeServiceDomains(client, appId, signal) {
|
|
408
408
|
const result = await client.GET("/v1/apps/{appId}/domains", {
|
|
409
|
-
params: { path: { appId
|
|
409
|
+
params: { path: { appId } },
|
|
410
410
|
signal
|
|
411
411
|
});
|
|
412
412
|
if (result.error || !result.data) throw domainApiCallError("Failed to list custom domains", result.response, result.error);
|
|
@@ -418,7 +418,7 @@ function normalizeDomainRecord(domain) {
|
|
|
418
418
|
type: domain.type,
|
|
419
419
|
url: domain.url,
|
|
420
420
|
hostname: domain.hostname,
|
|
421
|
-
|
|
421
|
+
appId: domain.appId,
|
|
422
422
|
status: domain.status,
|
|
423
423
|
foundryStatus: domain.foundryStatus,
|
|
424
424
|
failureReason: domain.failureReason,
|
|
@@ -195,6 +195,22 @@ const DESCRIPTORS = [
|
|
|
195
195
|
description: "View your Platform branches",
|
|
196
196
|
examples: ["prisma-cli branch list"]
|
|
197
197
|
},
|
|
198
|
+
{
|
|
199
|
+
id: "build",
|
|
200
|
+
path: ["prisma", "build"],
|
|
201
|
+
description: "Inspect builds",
|
|
202
|
+
examples: ["prisma-cli build logs <build_id>"]
|
|
203
|
+
},
|
|
204
|
+
{
|
|
205
|
+
id: "build.logs",
|
|
206
|
+
path: [
|
|
207
|
+
"prisma",
|
|
208
|
+
"build",
|
|
209
|
+
"logs"
|
|
210
|
+
],
|
|
211
|
+
description: "Stream the logs for a build",
|
|
212
|
+
examples: ["prisma-cli build logs <build_id>", "prisma-cli build logs <build_id> --follow"]
|
|
213
|
+
},
|
|
198
214
|
{
|
|
199
215
|
id: "database",
|
|
200
216
|
path: ["prisma", "database"],
|
|
@@ -75,12 +75,12 @@ async function renderBestEffortCommandDiagnostics(context, options) {
|
|
|
75
75
|
return [];
|
|
76
76
|
}
|
|
77
77
|
}
|
|
78
|
-
async function runStreamingCommand(runtime, commandName, options, handler) {
|
|
78
|
+
async function runStreamingCommand(runtime, commandName, options, handler, streamOptions) {
|
|
79
79
|
const flags = resolveGlobalFlags(runtime.argv, options);
|
|
80
80
|
const context = await createCommandContext(runtime, flags);
|
|
81
81
|
try {
|
|
82
82
|
await handler(context);
|
|
83
|
-
if (flags.json) writeJsonEvent(context.output, {
|
|
83
|
+
if (flags.json && (streamOptions?.emitJsonSuccessEvent ?? true)) writeJsonEvent(context.output, {
|
|
84
84
|
type: "success",
|
|
85
85
|
command: commandName,
|
|
86
86
|
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@prisma/cli",
|
|
3
|
-
"version": "3.0.0-dev.
|
|
3
|
+
"version": "3.0.0-dev.108.1",
|
|
4
4
|
"description": "Command-line interface for the Prisma Developer Platform.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -46,7 +46,7 @@
|
|
|
46
46
|
"@clack/prompts": "^1.5.0",
|
|
47
47
|
"@prisma/compute-sdk": "0.31.0",
|
|
48
48
|
"@prisma/credentials-store": "^7.8.0",
|
|
49
|
-
"@prisma/management-api-sdk": "^1.
|
|
49
|
+
"@prisma/management-api-sdk": "^1.46.0",
|
|
50
50
|
"better-result": "^2.9.2",
|
|
51
51
|
"colorette": "^2.0.20",
|
|
52
52
|
"commander": "^14.0.3",
|