@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 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 };
@@ -1088,7 +1088,7 @@ function toAppDomainSummary(domain) {
1088
1088
  type: domain.type,
1089
1089
  url: domain.url,
1090
1090
  hostname: domain.hostname,
1091
- computeServiceId: domain.computeServiceId,
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, computeServiceId, signal) {
407
+ async function listComputeServiceDomains(client, appId, signal) {
408
408
  const result = await client.GET("/v1/apps/{appId}/domains", {
409
- params: { path: { appId: computeServiceId } },
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
- computeServiceId: domain.computeServiceId,
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.105.1",
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.44.0",
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",