@prisma/cli 8.0.0-rc.1 → 8.0.0-rc.2-dev.49

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.
Files changed (110) hide show
  1. package/dist/cli.js +15410 -16
  2. package/dist/deploy-framework-C7bQM00A.js +23 -0
  3. package/dist/{v8/sender.js → sender.js} +2 -2
  4. package/package.json +11 -15
  5. package/dist/adapters/git.js +0 -54
  6. package/dist/adapters/local-state.js +0 -155
  7. package/dist/auth/client.js +0 -30
  8. package/dist/auth/errors.js +0 -50
  9. package/dist/auth/guard.js +0 -39
  10. package/dist/auth/login.js +0 -471
  11. package/dist/auth/operations.js +0 -208
  12. package/dist/auth/recipient.js +0 -42
  13. package/dist/auth/token-storage.js +0 -439
  14. package/dist/auth/workspaces.js +0 -171
  15. package/dist/cli-command.js +0 -14
  16. package/dist/cli-name.js +0 -12
  17. package/dist/cli2.js +0 -136
  18. package/dist/command-arguments.js +0 -12
  19. package/dist/commands/agent/index.js +0 -60
  20. package/dist/commands/app/index.js +0 -350
  21. package/dist/commands/auth/index.js +0 -95
  22. package/dist/commands/branch/index.js +0 -27
  23. package/dist/commands/bucket/index.js +0 -123
  24. package/dist/commands/build/index.js +0 -29
  25. package/dist/commands/database/index.js +0 -249
  26. package/dist/commands/env.js +0 -99
  27. package/dist/commands/feedback/index.js +0 -20
  28. package/dist/commands/git/index.js +0 -36
  29. package/dist/commands/init/index.js +0 -33
  30. package/dist/commands/project/index.js +0 -118
  31. package/dist/commands/version/index.js +0 -18
  32. package/dist/controllers/agent-setup.js +0 -52
  33. package/dist/controllers/agent.js +0 -228
  34. package/dist/controllers/app-env-api.js +0 -55
  35. package/dist/controllers/app-env-file.js +0 -181
  36. package/dist/controllers/app-env.js +0 -502
  37. package/dist/controllers/app.js +0 -2508
  38. package/dist/controllers/auth.js +0 -124
  39. package/dist/controllers/branch.js +0 -92
  40. package/dist/controllers/bucket.js +0 -184
  41. package/dist/controllers/build.js +0 -88
  42. package/dist/controllers/database.js +0 -463
  43. package/dist/controllers/feedback.js +0 -90
  44. package/dist/controllers/init.js +0 -814
  45. package/dist/controllers/project.js +0 -892
  46. package/dist/controllers/select-prompt-port.js +0 -13
  47. package/dist/controllers/version.js +0 -12
  48. package/dist/errors.js +0 -102
  49. package/dist/lib/agent/cli-command.js +0 -20
  50. package/dist/lib/agent/constants.js +0 -12
  51. package/dist/lib/agent/package-manager.js +0 -99
  52. package/dist/lib/agent/setup-status.js +0 -83
  53. package/dist/lib/app/app-provider.js +0 -617
  54. package/dist/lib/app/branch-database-api.js +0 -102
  55. package/dist/lib/app/branch-database-deploy.js +0 -353
  56. package/dist/lib/app/branch-database.js +0 -234
  57. package/dist/lib/app/build-settings.js +0 -98
  58. package/dist/lib/app/build.js +0 -82
  59. package/dist/lib/app/bun-project.js +0 -45
  60. package/dist/lib/app/compute-config.js +0 -145
  61. package/dist/lib/app/deploy-output.js +0 -24
  62. package/dist/lib/app/deploy-plan.js +0 -59
  63. package/dist/lib/app/deploy-progress.js +0 -100
  64. package/dist/lib/app/domain-guidance.js +0 -14
  65. package/dist/lib/app/env-config.js +0 -67
  66. package/dist/lib/app/env-file.js +0 -82
  67. package/dist/lib/app/env-vars.js +0 -50
  68. package/dist/lib/app/local-dev.js +0 -109
  69. package/dist/lib/app/production-deploy-gate.js +0 -162
  70. package/dist/lib/app/read-branch.js +0 -30
  71. package/dist/lib/bucket/provider.js +0 -139
  72. package/dist/lib/database/provider.js +0 -385
  73. package/dist/lib/diagnostics.js +0 -16
  74. package/dist/lib/feedback.js +0 -15
  75. package/dist/lib/fs/home-path.js +0 -24
  76. package/dist/lib/git/local-branch.js +0 -53
  77. package/dist/lib/git/local-status.js +0 -57
  78. package/dist/lib/project/interactive-setup.js +0 -57
  79. package/dist/lib/project/local-pin.js +0 -200
  80. package/dist/lib/project/provider.js +0 -93
  81. package/dist/lib/project/resolution.js +0 -389
  82. package/dist/lib/project/setup.js +0 -138
  83. package/dist/lib/version.js +0 -56
  84. package/dist/lib/workspace-id.js +0 -18
  85. package/dist/output/patterns.js +0 -90
  86. package/dist/presenters/agent.js +0 -74
  87. package/dist/presenters/app-env.js +0 -265
  88. package/dist/presenters/app.js +0 -672
  89. package/dist/presenters/auth.js +0 -184
  90. package/dist/presenters/branch.js +0 -46
  91. package/dist/presenters/bucket.js +0 -174
  92. package/dist/presenters/database.js +0 -462
  93. package/dist/presenters/feedback.js +0 -26
  94. package/dist/presenters/init.js +0 -30
  95. package/dist/presenters/project.js +0 -268
  96. package/dist/presenters/verbose-context.js +0 -64
  97. package/dist/presenters/version.js +0 -29
  98. package/dist/shell/cli-command.js +0 -2
  99. package/dist/shell/command-meta.js +0 -923
  100. package/dist/shell/command-runner.js +0 -119
  101. package/dist/shell/diagnostics-output.js +0 -57
  102. package/dist/shell/global-flags.js +0 -37
  103. package/dist/shell/help.js +0 -90
  104. package/dist/shell/output.js +0 -144
  105. package/dist/shell/prompt.js +0 -48
  106. package/dist/shell/runtime.js +0 -38
  107. package/dist/shell/ui.js +0 -116
  108. package/dist/state-dir.js +0 -12
  109. package/dist/update-check.js +0 -248
  110. package/dist/v8/cli.js +0 -14699
@@ -1,124 +0,0 @@
1
- import { resolvePrismaCliPackageCommand } from "../lib/agent/cli-command.js";
2
- import { PRISMA_AGENT_INSTALL_ARGS } from "../lib/agent/constants.js";
3
- import { isLikelyProjectDirectory, readPrismaAgentSetupStatus, resolvePrismaAgentSetupCwd, shouldOfferPrismaAgentSetup } from "../lib/agent/setup-status.js";
4
- import { authRequiredError, usageError } from "../errors.js";
5
- import { performLogin, performLogout, readAuthState, storeLegacyCredential } from "../auth/operations.js";
6
- import { canPrompt } from "../shell/runtime.js";
7
- import { workspaceSwitchUnavailableError } from "../auth/errors.js";
8
- import { listAuthWorkspaces, logoutAuthWorkspace, switchAuthWorkspace } from "../auth/workspaces.js";
9
- import { createSelectPromptPort } from "./select-prompt-port.js";
10
- import { SERVICE_TOKEN_ENV_VAR } from "@prisma/cli-engine";
11
- //#region src/controllers/auth.ts
12
- function workspaceOperationContext(context) {
13
- return {
14
- env: context.runtime.env,
15
- signal: context.runtime.signal
16
- };
17
- }
18
- async function runAuthLogin(context) {
19
- const credential = await performLogin(context.runtime.env, context.runtime.signal);
20
- await storeLegacyCredential(context.runtime.env, credential, context.runtime.signal);
21
- let result = await readAuthState(context.runtime.env, context.runtime.signal);
22
- const agentSetupTipCommand = await resolveAgentSetupTipCommand(context);
23
- if (agentSetupTipCommand) result = {
24
- ...result,
25
- agentSetupTip: { command: agentSetupTipCommand }
26
- };
27
- return createAuthSuccess("auth.login", result, [
28
- "prisma-cli auth whoami",
29
- "prisma-cli project list",
30
- ...result.agentSetupTip ? [result.agentSetupTip.command] : []
31
- ]);
32
- }
33
- async function runAuthLogout(context) {
34
- await performLogout(context.runtime.env, context.runtime.signal);
35
- return createAuthSuccess("auth.logout", await readAuthState(context.runtime.env, context.runtime.signal), ["prisma-cli auth login"]);
36
- }
37
- async function runAuthWhoAmI(context) {
38
- const result = await readAuthState(context.runtime.env, context.runtime.signal);
39
- return createAuthSuccess("auth.whoami", result, result.authenticated ? [] : ["prisma-cli auth login"]);
40
- }
41
- async function runAuthWorkspaceList(context) {
42
- const result = await listAuthWorkspaces(workspaceOperationContext(context));
43
- return {
44
- command: "auth.workspace.list",
45
- result,
46
- warnings: [],
47
- nextSteps: result.workspaces.length === 0 ? ["prisma-cli auth login"] : []
48
- };
49
- }
50
- async function runAuthWorkspaceUse(context, workspaceRef) {
51
- const trimmedWorkspaceRef = workspaceRef?.trim();
52
- const selectedWorkspaceRef = trimmedWorkspaceRef ? trimmedWorkspaceRef : await selectWorkspaceSession(context);
53
- return {
54
- command: "auth.workspace.use",
55
- result: await switchAuthWorkspace(workspaceOperationContext(context), selectedWorkspaceRef),
56
- warnings: [],
57
- nextSteps: ["prisma-cli auth whoami", "prisma-cli project list"]
58
- };
59
- }
60
- async function runAuthWorkspaceLogout(context, workspaceRef) {
61
- if (!workspaceRef?.trim()) throw usageError("Workspace required", "auth workspace logout needs a workspace id or cached workspace name.", "Pass a workspace from prisma-cli auth workspace list.", ["prisma-cli auth workspace list"], "auth");
62
- const result = await logoutAuthWorkspace(workspaceOperationContext(context), workspaceRef);
63
- return {
64
- command: "auth.workspace.logout",
65
- result,
66
- warnings: [],
67
- nextSteps: result.activeWorkspace ? ["prisma-cli auth workspace list"] : ["prisma-cli auth workspace list", "prisma-cli auth workspace use <id>"]
68
- };
69
- }
70
- async function requireAuthenticatedAuthState(context) {
71
- const current = await readAuthState(context.runtime.env, context.runtime.signal);
72
- if (current.authenticated) return current;
73
- if (!canPrompt(context)) throw authRequiredError();
74
- const credential = await performLogin(context.runtime.env, context.runtime.signal);
75
- await storeLegacyCredential(context.runtime.env, credential, context.runtime.signal);
76
- return readAuthState(context.runtime.env, context.runtime.signal);
77
- }
78
- async function selectWorkspaceSession(context) {
79
- if (context.runtime.env[SERVICE_TOKEN_ENV_VAR] !== void 0) throw workspaceSwitchUnavailableError();
80
- const workspaces = (await listAuthWorkspaces(workspaceOperationContext(context))).workspaces.filter((workspace) => workspace.switchable);
81
- if (workspaces.length === 0) throw usageError("No authenticated workspaces", "There are no local OAuth workspace sessions to select.", "Run prisma-cli auth login and authorize a workspace.", ["prisma-cli auth login"], "auth");
82
- if (workspaces.length === 1) return workspaces[0].id;
83
- if (!canPrompt(context)) throw usageError("Interactive workspace selection unavailable", "auth workspace use needs an interactive terminal when no workspace is provided and more than one workspace is available.", "Run prisma-cli auth workspace use <id-or-name> with a workspace from prisma-cli auth workspace list.", ["prisma-cli auth workspace list"], "auth");
84
- return (await createSelectPromptPort(context).select({
85
- message: "Select a workspace",
86
- choices: workspaces.map((workspace) => ({
87
- label: `${workspace.name} (${workspace.id})${workspace.active ? " active" : ""}`,
88
- value: workspace
89
- }))
90
- })).id;
91
- }
92
- function createAuthSuccess(command, result, nextSteps) {
93
- return {
94
- command,
95
- result,
96
- warnings: [],
97
- nextSteps
98
- };
99
- }
100
- async function resolveAgentSetupTipCommand(context) {
101
- if (context.flags.json || context.flags.quiet) return null;
102
- if (context.runtime.env.CI && context.flags.interactive !== true) return null;
103
- if (!context.runtime.stderr.isTTY && context.flags.interactive !== true) return null;
104
- const setupCwd = await resolvePrismaAgentSetupCwd({
105
- cwd: context.runtime.cwd,
106
- signal: context.runtime.signal
107
- });
108
- if (!await isLikelyProjectDirectory({
109
- cwd: setupCwd,
110
- signal: context.runtime.signal
111
- })) return null;
112
- if (!shouldOfferPrismaAgentSetup(await readPrismaAgentSetupStatus({
113
- cwd: setupCwd,
114
- stateStore: context.stateStore,
115
- signal: context.runtime.signal
116
- }))) return null;
117
- return await resolvePrismaCliPackageCommand({
118
- cwd: setupCwd,
119
- signal: context.runtime.signal,
120
- args: PRISMA_AGENT_INSTALL_ARGS
121
- });
122
- }
123
- //#endregion
124
- export { requireAuthenticatedAuthState, runAuthLogin, runAuthLogout, runAuthWhoAmI, runAuthWorkspaceList, runAuthWorkspaceLogout, runAuthWorkspaceUse };
@@ -1,92 +0,0 @@
1
- import { CliError, authRequiredError, workspaceRequiredError } from "../errors.js";
2
- import { authenticatedManagementApiClient } from "../auth/guard.js";
3
- import { projectResolutionErrorToCliError, resolveProjectTarget } from "../lib/project/resolution.js";
4
- import { requireAuthenticatedAuthState } from "./auth.js";
5
- import { listRealWorkspaceProjects } from "./project.js";
6
- //#region src/controllers/branch.ts
7
- async function runBranchList(context) {
8
- return {
9
- command: "branch.list",
10
- result: await listRealBranches(context),
11
- warnings: [],
12
- nextSteps: []
13
- };
14
- }
15
- async function listRealBranches(context) {
16
- const authState = await requireAuthenticatedAuthState(context);
17
- const client = await authenticatedManagementApiClient(context.runtime.env, context.runtime.signal);
18
- if (!client) throw authRequiredError(["prisma-cli auth login"]);
19
- const workspace = authState.workspace;
20
- if (!workspace) throw workspaceRequiredError();
21
- const targetResult = await resolveProjectTarget({
22
- context,
23
- workspace,
24
- listProjects: () => listRealWorkspaceProjects(client, context.runtime.signal)
25
- });
26
- if (targetResult.isErr()) throw projectResolutionErrorToCliError(targetResult.error);
27
- const target = targetResult.value;
28
- const branches = await listBranches(client, target.project.id, context.runtime.signal);
29
- return {
30
- projectId: target.project.id,
31
- projectName: target.project.name,
32
- verboseContext: {
33
- workspace,
34
- project: target.project,
35
- resolution: target.resolution
36
- },
37
- branches: sortBranches(branches.map(toBranchSummary))
38
- };
39
- }
40
- function sortBranches(branches) {
41
- return branches.slice().sort((left, right) => {
42
- const leftRank = branchOrder(left);
43
- const rightRank = branchOrder(right);
44
- if (leftRank !== rightRank) return leftRank - rightRank;
45
- return left.name.localeCompare(right.name);
46
- });
47
- }
48
- function branchOrder(branch) {
49
- return branch.role === "production" ? 0 : 1;
50
- }
51
- async function listBranches(client, projectId, signal) {
52
- const collected = [];
53
- let cursor;
54
- while (true) {
55
- const query = {};
56
- if (cursor !== void 0) query.cursor = cursor;
57
- const { data, error, response } = await client.GET("/v1/projects/{projectId}/branches", {
58
- params: {
59
- path: { projectId },
60
- query
61
- },
62
- signal
63
- });
64
- if (error || !data) throw branchApiError("Failed to list branches", response, error);
65
- collected.push(...data.data);
66
- if (!data.pagination.hasMore || !data.pagination.nextCursor) break;
67
- cursor = data.pagination.nextCursor;
68
- }
69
- return collected;
70
- }
71
- function toBranchSummary(branch) {
72
- return {
73
- id: branch.id,
74
- name: branch.gitName,
75
- role: branch.role,
76
- envMap: branch.role
77
- };
78
- }
79
- function branchApiError(summary, response, error) {
80
- const status = response?.status ?? 0;
81
- return new CliError({
82
- code: error?.error?.code ?? "BRANCH_API_ERROR",
83
- domain: "branch",
84
- summary,
85
- why: error?.error?.message ?? `The Management API returned status ${status || "unknown"}.`,
86
- fix: error?.error?.hint ?? "Re-run with --trace for the underlying API response details.",
87
- exitCode: 1,
88
- nextSteps: []
89
- });
90
- }
91
- //#endregion
92
- export { runBranchList };
@@ -1,184 +0,0 @@
1
- import { CliError, authRequiredError, workspaceRequiredError } from "../errors.js";
2
- import { authenticatedManagementApiClient } from "../auth/guard.js";
3
- import { projectResolutionErrorToCliError, resolveProjectTarget } from "../lib/project/resolution.js";
4
- import { requireAuthenticatedAuthState } from "./auth.js";
5
- import { listRealWorkspaceProjects } from "./project.js";
6
- import { createManagementBucketProvider } from "../lib/bucket/provider.js";
7
- //#region src/controllers/bucket.ts
8
- async function runBucketList(context, flags) {
9
- const { provider, target } = await requireBucketContext(context, flags, "bucket list");
10
- const buckets = await provider.listBuckets({
11
- projectId: target.project.id,
12
- branchName: flags.branchName,
13
- signal: context.runtime.signal
14
- });
15
- return {
16
- command: "bucket.list",
17
- result: {
18
- projectId: target.project.id,
19
- projectName: target.project.name,
20
- branchName: flags.branchName ?? null,
21
- verboseContext: target,
22
- buckets
23
- },
24
- warnings: [],
25
- nextSteps: []
26
- };
27
- }
28
- async function runBucketCreate(context, flags) {
29
- const { provider, target } = await requireBucketContext(context, flags, "bucket create");
30
- const bucket = await provider.createBucket({
31
- projectId: target.project.id,
32
- name: flags.name?.trim() || void 0,
33
- branchGitName: flags.branchName,
34
- signal: context.runtime.signal
35
- });
36
- return {
37
- command: "bucket.create",
38
- result: {
39
- projectId: target.project.id,
40
- projectName: target.project.name,
41
- verboseContext: target,
42
- bucket
43
- },
44
- warnings: [],
45
- nextSteps: []
46
- };
47
- }
48
- async function runBucketDelete(context, bucketId, flags) {
49
- const id = bucketId.trim();
50
- if (!id) throw new CliError({
51
- code: "USAGE_ERROR",
52
- domain: "bucket",
53
- summary: "Bucket id required",
54
- why: "Bucket deletion needs a bucket id.",
55
- fix: "Pass the bucket id to delete.",
56
- exitCode: 2,
57
- nextSteps: ["prisma-cli bucket list"]
58
- });
59
- if (flags.confirm !== id) throw new CliError({
60
- code: "CONFIRMATION_REQUIRED",
61
- domain: "bucket",
62
- summary: "Confirm bucket deletion",
63
- why: "Deleting this bucket permanently removes all objects and access keys.",
64
- fix: `Rerun with --confirm ${id}.`,
65
- exitCode: 2,
66
- nextSteps: [`prisma-cli bucket delete ${id} --confirm ${id}`],
67
- meta: {
68
- expectedConfirm: id,
69
- receivedConfirm: flags.confirm ?? null
70
- }
71
- });
72
- await (await requireBucketProviderOnly(context)).deleteBucket(id, { signal: context.runtime.signal });
73
- return {
74
- command: "bucket.delete",
75
- result: { bucket: { id } },
76
- warnings: [],
77
- nextSteps: []
78
- };
79
- }
80
- async function runBucketKeyList(context, bucketId) {
81
- const id = bucketId.trim();
82
- if (!id) throw new CliError({
83
- code: "USAGE_ERROR",
84
- domain: "bucket",
85
- summary: "Bucket id required",
86
- why: "Bucket key listing needs a bucket id.",
87
- fix: "Pass the bucket id.",
88
- exitCode: 2,
89
- nextSteps: ["prisma-cli bucket list"]
90
- });
91
- return {
92
- command: "bucket.key.list",
93
- result: {
94
- bucketId: id,
95
- keys: await (await requireBucketProviderOnly(context)).listKeys(id, { signal: context.runtime.signal })
96
- },
97
- warnings: [],
98
- nextSteps: []
99
- };
100
- }
101
- async function runBucketKeyCreate(context, bucketId, flags) {
102
- const id = bucketId.trim();
103
- if (!id) throw new CliError({
104
- code: "USAGE_ERROR",
105
- domain: "bucket",
106
- summary: "Bucket id required",
107
- why: "Bucket key creation needs a bucket id.",
108
- fix: "Pass the bucket id.",
109
- exitCode: 2,
110
- nextSteps: ["prisma-cli bucket list"]
111
- });
112
- const role = resolveKeyRole(flags.role);
113
- const created = await (await requireBucketProviderOnly(context)).createKey({
114
- bucketId: id,
115
- name: flags.name?.trim() || void 0,
116
- role,
117
- signal: context.runtime.signal
118
- });
119
- return {
120
- command: "bucket.key.create",
121
- result: {
122
- bucketId: id,
123
- key: created.key,
124
- secretAccessKey: created.secretAccessKey,
125
- accessKeyId: created.accessKeyId,
126
- endpoint: created.endpoint,
127
- bucketName: created.bucketName
128
- },
129
- warnings: [],
130
- nextSteps: []
131
- };
132
- }
133
- async function runBucketKeyDelete(context, bucketId, keyId) {
134
- const bktId = bucketId.trim();
135
- const kId = keyId.trim();
136
- if (!bktId || !kId) throw new CliError({
137
- code: "USAGE_ERROR",
138
- domain: "bucket",
139
- summary: "Bucket id and key id required",
140
- why: "Bucket key deletion needs both a bucket id and a key id.",
141
- fix: "Pass the bucket id and key id.",
142
- exitCode: 2,
143
- nextSteps: ["prisma-cli bucket key list <bucketId>"]
144
- });
145
- await (await requireBucketProviderOnly(context)).deleteKey(bktId, kId, { signal: context.runtime.signal });
146
- return {
147
- command: "bucket.key.delete",
148
- result: { key: { id: kId } },
149
- warnings: [],
150
- nextSteps: []
151
- };
152
- }
153
- async function resolveBucketProvider(context) {
154
- const client = await authenticatedManagementApiClient(context.runtime.env, context.runtime.signal);
155
- if (!client) throw authRequiredError();
156
- return createManagementBucketProvider(client);
157
- }
158
- async function requireBucketContext(context, flags, commandName) {
159
- const workspace = (await requireAuthenticatedAuthState(context)).workspace;
160
- if (!workspace) throw workspaceRequiredError();
161
- const client = await authenticatedManagementApiClient(context.runtime.env, context.runtime.signal);
162
- if (!client) throw authRequiredError();
163
- const targetResult = await resolveProjectTarget({
164
- context,
165
- workspace,
166
- explicitProject: flags.projectRef,
167
- listProjects: () => listRealWorkspaceProjects(client, context.runtime.signal),
168
- commandName
169
- });
170
- if (targetResult.isErr()) throw projectResolutionErrorToCliError(targetResult.error);
171
- return {
172
- provider: createManagementBucketProvider(client),
173
- target: targetResult.value
174
- };
175
- }
176
- async function requireBucketProviderOnly(context) {
177
- await requireAuthenticatedAuthState(context);
178
- return resolveBucketProvider(context);
179
- }
180
- function resolveKeyRole(role) {
181
- return role === "read" ? "read" : "read_write";
182
- }
183
- //#endregion
184
- export { runBucketCreate, runBucketDelete, runBucketKeyCreate, runBucketKeyDelete, runBucketKeyList, runBucketList };
@@ -1,88 +0,0 @@
1
- import { CliError, authRequiredError } from "../errors.js";
2
- import { authenticatedManagementApiClient } from "../auth/guard.js";
3
- import { writeJsonEvent } from "../shell/output.js";
4
- //#region src/controllers/build.ts
5
- async function runBuildLogs(context, buildId, options = {}) {
6
- const client = await authenticatedManagementApiClient(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 };