@prisma/cli 3.0.0-dev.99.1 → 8.0.0-rc.10-dev.80

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 (86) hide show
  1. package/README.md +26 -28
  2. package/dist/cli.js +14551 -16
  3. package/dist/payload-B88Qvzxk-CrtTXSOe.js +34 -0
  4. package/dist/sender.js +192 -0
  5. package/package.json +26 -19
  6. package/dist/adapters/git.js +0 -54
  7. package/dist/adapters/local-state.js +0 -144
  8. package/dist/adapters/mock-api.js +0 -136
  9. package/dist/adapters/token-storage.js +0 -418
  10. package/dist/cli2.js +0 -119
  11. package/dist/commands/app/index.js +0 -345
  12. package/dist/commands/auth/index.js +0 -96
  13. package/dist/commands/branch/index.js +0 -27
  14. package/dist/commands/database/index.js +0 -159
  15. package/dist/commands/env.js +0 -99
  16. package/dist/commands/git/index.js +0 -36
  17. package/dist/commands/project/index.js +0 -69
  18. package/dist/commands/version/index.js +0 -18
  19. package/dist/controllers/app-env-api.js +0 -54
  20. package/dist/controllers/app-env-file.js +0 -181
  21. package/dist/controllers/app-env.js +0 -502
  22. package/dist/controllers/app.js +0 -2443
  23. package/dist/controllers/auth.js +0 -316
  24. package/dist/controllers/branch.js +0 -103
  25. package/dist/controllers/database.js +0 -318
  26. package/dist/controllers/project.js +0 -731
  27. package/dist/controllers/select-prompt-port.js +0 -12
  28. package/dist/controllers/version.js +0 -12
  29. package/dist/lib/app/app-interaction.js +0 -5
  30. package/dist/lib/app/app-provider.js +0 -544
  31. package/dist/lib/app/branch-database-api.js +0 -102
  32. package/dist/lib/app/branch-database-deploy.js +0 -325
  33. package/dist/lib/app/branch-database.js +0 -215
  34. package/dist/lib/app/build-settings.js +0 -93
  35. package/dist/lib/app/build.js +0 -80
  36. package/dist/lib/app/bun-project.js +0 -45
  37. package/dist/lib/app/compute-config.js +0 -147
  38. package/dist/lib/app/deploy-output.js +0 -24
  39. package/dist/lib/app/deploy-plan.js +0 -58
  40. package/dist/lib/app/deploy-progress.js +0 -100
  41. package/dist/lib/app/domain-guidance.js +0 -14
  42. package/dist/lib/app/env-config.js +0 -67
  43. package/dist/lib/app/env-file.js +0 -82
  44. package/dist/lib/app/env-vars.js +0 -50
  45. package/dist/lib/app/local-dev.js +0 -109
  46. package/dist/lib/app/production-deploy-gate.js +0 -161
  47. package/dist/lib/app/read-branch.js +0 -30
  48. package/dist/lib/auth/auth-ops.js +0 -158
  49. package/dist/lib/auth/client.js +0 -22
  50. package/dist/lib/auth/guard.js +0 -38
  51. package/dist/lib/auth/login.js +0 -330
  52. package/dist/lib/database/provider.js +0 -167
  53. package/dist/lib/diagnostics.js +0 -15
  54. package/dist/lib/fs/home-path.js +0 -24
  55. package/dist/lib/git/local-branch.js +0 -53
  56. package/dist/lib/git/local-status.js +0 -57
  57. package/dist/lib/project/interactive-setup.js +0 -56
  58. package/dist/lib/project/local-pin.js +0 -200
  59. package/dist/lib/project/resolution.js +0 -386
  60. package/dist/lib/project/setup.js +0 -135
  61. package/dist/lib/version.js +0 -55
  62. package/dist/output/patterns.js +0 -90
  63. package/dist/presenters/app-env.js +0 -265
  64. package/dist/presenters/app.js +0 -646
  65. package/dist/presenters/auth.js +0 -183
  66. package/dist/presenters/branch.js +0 -46
  67. package/dist/presenters/database.js +0 -274
  68. package/dist/presenters/project.js +0 -174
  69. package/dist/presenters/verbose-context.js +0 -64
  70. package/dist/presenters/version.js +0 -29
  71. package/dist/shell/command-arguments.js +0 -6
  72. package/dist/shell/command-meta.js +0 -622
  73. package/dist/shell/command-runner.js +0 -112
  74. package/dist/shell/diagnostics-output.js +0 -57
  75. package/dist/shell/errors.js +0 -134
  76. package/dist/shell/global-flags.js +0 -37
  77. package/dist/shell/help.js +0 -89
  78. package/dist/shell/output.js +0 -82
  79. package/dist/shell/prompt.js +0 -41
  80. package/dist/shell/runtime.js +0 -55
  81. package/dist/shell/ui.js +0 -116
  82. package/dist/shell/update-check.js +0 -247
  83. package/dist/use-cases/auth.js +0 -145
  84. package/dist/use-cases/branch.js +0 -47
  85. package/dist/use-cases/create-cli-gateways.js +0 -68
  86. package/dist/use-cases/project.js +0 -30
@@ -1,316 +0,0 @@
1
- import { CLIENT_ID, SERVICE_TOKEN_ENV_VAR, getApiBaseUrl } from "../lib/auth/client.js";
2
- import { FileTokenStorage, WorkspaceSelectionError } from "../adapters/token-storage.js";
3
- import { authRequiredError, usageError, workspaceAmbiguousError, workspaceNotAuthenticatedError, workspaceSwitchUnavailableError } from "../shell/errors.js";
4
- import { canPrompt } from "../shell/runtime.js";
5
- import { performLogin, performLogout, readAuthState } from "../lib/auth/auth-ops.js";
6
- import { createAuthUseCases } from "../use-cases/auth.js";
7
- import { createCliUseCaseGateways } from "../use-cases/create-cli-gateways.js";
8
- import { createSelectPromptPort } from "./select-prompt-port.js";
9
- import { createManagementApiSdk } from "@prisma/management-api-sdk";
10
- //#region src/controllers/auth.ts
11
- function isRealMode(context) {
12
- return !context.runtime.fixturePath && !context.runtime.env.PRISMA_CLI_MOCK_FIXTURE_PATH;
13
- }
14
- async function runAuthLogin(context, options) {
15
- let result;
16
- if (isRealMode(context)) {
17
- await performLogin(context.runtime.env, context.runtime.signal);
18
- result = await readAuthState(context.runtime.env, context.runtime.signal);
19
- } else result = await loginWithSelectionFlow(context, createAuthUseCases(createCliUseCaseGateways(context)), options);
20
- return createAuthSuccess("auth.login", result, ["prisma-cli auth whoami", "prisma-cli project list"]);
21
- }
22
- async function runAuthLogout(context) {
23
- let result;
24
- if (isRealMode(context)) {
25
- await performLogout(context.runtime.env, context.runtime.signal);
26
- result = await readAuthState(context.runtime.env, context.runtime.signal);
27
- } else result = await createAuthUseCases(createCliUseCaseGateways(context)).logout();
28
- return createAuthSuccess("auth.logout", result, ["prisma-cli auth login"]);
29
- }
30
- async function runAuthWhoAmI(context) {
31
- let result;
32
- if (isRealMode(context)) result = await readAuthState(context.runtime.env, context.runtime.signal);
33
- else result = await createAuthUseCases(createCliUseCaseGateways(context)).whoami();
34
- return createAuthSuccess("auth.whoami", result, result.authenticated ? [] : ["prisma-cli auth login"]);
35
- }
36
- async function runAuthWorkspaceList(context) {
37
- const result = isRealMode(context) ? await listRealAuthWorkspaces(context) : await createAuthUseCases(createCliUseCaseGateways(context)).listWorkspaces();
38
- return {
39
- command: "auth.workspace.list",
40
- result,
41
- warnings: [],
42
- nextSteps: result.workspaces.length === 0 ? ["prisma-cli auth login"] : []
43
- };
44
- }
45
- async function runAuthWorkspaceUse(context, workspaceRef) {
46
- const trimmedWorkspaceRef = workspaceRef?.trim();
47
- const selectedWorkspaceRef = trimmedWorkspaceRef ? trimmedWorkspaceRef : await selectWorkspaceSession(context);
48
- return {
49
- command: "auth.workspace.use",
50
- result: isRealMode(context) ? await useRealAuthWorkspace(context, selectedWorkspaceRef) : await createAuthUseCases(createCliUseCaseGateways(context)).useWorkspace(selectedWorkspaceRef),
51
- warnings: [],
52
- nextSteps: ["prisma-cli auth whoami", "prisma-cli project list"]
53
- };
54
- }
55
- async function runAuthWorkspaceLogout(context, workspaceRef) {
56
- 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");
57
- const result = isRealMode(context) ? await logoutRealAuthWorkspace(context, workspaceRef) : await createAuthUseCases(createCliUseCaseGateways(context)).logoutWorkspace(workspaceRef);
58
- return {
59
- command: "auth.workspace.logout",
60
- result,
61
- warnings: [],
62
- nextSteps: result.activeWorkspace ? ["prisma-cli auth workspace list"] : ["prisma-cli auth workspace list", "prisma-cli auth workspace use <id>"]
63
- };
64
- }
65
- async function requireAuthenticatedAuthState(context) {
66
- if (isRealMode(context)) {
67
- const current = await readAuthState(context.runtime.env, context.runtime.signal);
68
- if (current.authenticated) return current;
69
- if (!canPrompt(context)) throw authRequiredError();
70
- await performLogin(context.runtime.env, context.runtime.signal);
71
- return readAuthState(context.runtime.env, context.runtime.signal);
72
- }
73
- const useCases = createAuthUseCases(createCliUseCaseGateways(context));
74
- const current = await useCases.whoami();
75
- if (current.authenticated) return current;
76
- if (!canPrompt(context)) throw authRequiredError();
77
- return loginWithSelectionFlow(context, useCases, {});
78
- }
79
- async function listRealAuthWorkspaces(context) {
80
- const rawServiceToken = context.runtime.env[SERVICE_TOKEN_ENV_VAR];
81
- const storage = new FileTokenStorage(context.runtime.env, context.runtime.signal);
82
- const localWorkspaces = await hydrateLocalAuthWorkspaces(context, storage, await storage.listWorkspaces());
83
- if (rawServiceToken !== void 0) {
84
- const authState = await readAuthState(context.runtime.env, context.runtime.signal);
85
- return {
86
- authSource: authState.authenticated ? "service_token" : "none",
87
- activeWorkspace: authState.workspace,
88
- workspaces: [...authState.workspace ? [{
89
- ...authState.workspace,
90
- credentialWorkspaceId: null,
91
- active: true,
92
- source: "service_token",
93
- switchable: false,
94
- lastSeenAt: null
95
- }] : [], ...localWorkspaces.map((workspace) => ({
96
- ...toAuthWorkspace(workspace),
97
- credentialWorkspaceId: workspace.credentialWorkspaceId,
98
- active: false,
99
- source: "oauth",
100
- switchable: false,
101
- lastSeenAt: workspace.lastSeenAt
102
- }))]
103
- };
104
- }
105
- const active = localWorkspaces.find((workspace) => workspace.active) ?? null;
106
- return {
107
- authSource: localWorkspaces.length > 0 ? "oauth" : "none",
108
- activeWorkspace: active ? toAuthWorkspace(active) : null,
109
- workspaces: localWorkspaces.map((workspace) => ({
110
- ...toAuthWorkspace(workspace),
111
- credentialWorkspaceId: workspace.credentialWorkspaceId,
112
- active: workspace.active,
113
- source: "oauth",
114
- switchable: true,
115
- lastSeenAt: workspace.lastSeenAt
116
- }))
117
- };
118
- }
119
- async function useRealAuthWorkspace(context, workspaceRef) {
120
- if (context.runtime.env["PRISMA_SERVICE_TOKEN"] !== void 0) throw workspaceSwitchUnavailableError();
121
- const storage = new FileTokenStorage(context.runtime.env, context.runtime.signal);
122
- await hydrateLocalAuthWorkspaces(context, storage, await storage.listWorkspaces());
123
- try {
124
- const result = await storage.useWorkspace(workspaceRef);
125
- return {
126
- previousWorkspace: result.previous ? toAuthWorkspace(result.previous) : null,
127
- workspace: toAuthWorkspace(result.selected)
128
- };
129
- } catch (error) {
130
- if (error instanceof WorkspaceSelectionError) {
131
- if (error.reason === "ambiguous") throw workspaceAmbiguousError(error.workspaceRef ?? workspaceRef, error.matches.map((match) => ({
132
- id: match.id,
133
- name: match.name,
134
- credentialWorkspaceId: match.credentialWorkspaceId
135
- })));
136
- throw workspaceNotAuthenticatedError(error.workspaceRef ?? workspaceRef);
137
- }
138
- throw error;
139
- }
140
- }
141
- async function logoutRealAuthWorkspace(context, workspaceRef) {
142
- const storage = new FileTokenStorage(context.runtime.env, context.runtime.signal);
143
- await hydrateLocalAuthWorkspaces(context, storage, await storage.listWorkspaces());
144
- try {
145
- const result = await storage.logoutWorkspace(workspaceRef);
146
- return {
147
- workspace: toAuthWorkspace(result.workspace),
148
- wasActive: result.wasActive,
149
- activeWorkspace: result.activeWorkspace ? toAuthWorkspace(result.activeWorkspace) : null
150
- };
151
- } catch (error) {
152
- if (error instanceof WorkspaceSelectionError) {
153
- if (error.reason === "ambiguous") throw workspaceAmbiguousError(error.workspaceRef ?? workspaceRef, error.matches.map((match) => ({
154
- id: match.id,
155
- name: match.name,
156
- credentialWorkspaceId: match.credentialWorkspaceId
157
- })));
158
- throw workspaceNotAuthenticatedError(error.workspaceRef ?? workspaceRef);
159
- }
160
- throw error;
161
- }
162
- }
163
- async function selectWorkspaceSession(context) {
164
- const realMode = isRealMode(context);
165
- if (realMode && context.runtime.env["PRISMA_SERVICE_TOKEN"] !== void 0) throw workspaceSwitchUnavailableError();
166
- const workspaces = (realMode ? await listRealAuthWorkspaces(context) : await createAuthUseCases(createCliUseCaseGateways(context)).listWorkspaces()).workspaces.filter((workspace) => workspace.switchable);
167
- 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");
168
- if (workspaces.length === 1) return workspaces[0].id;
169
- 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");
170
- return (await createSelectPromptPort(context).select({
171
- message: "Select a workspace",
172
- choices: workspaces.map((workspace) => ({
173
- label: `${workspace.name} (${workspace.id})${workspace.active ? " active" : ""}`,
174
- value: workspace
175
- }))
176
- })).id;
177
- }
178
- async function hydrateLocalAuthWorkspaces(context, storage, workspaces) {
179
- const candidates = workspaces.filter(needsWorkspaceMetadataHydration);
180
- if (candidates.length === 0) return workspaces;
181
- const tokensByCredentialWorkspaceId = new Map((await storage.listWorkspaceTokens()).map((tokens) => [tokens.workspaceId, tokens]));
182
- let nextWorkspaces = workspaces;
183
- for (const workspace of candidates) {
184
- const tokens = tokensByCredentialWorkspaceId.get(workspace.credentialWorkspaceId);
185
- if (!tokens) continue;
186
- const resolved = await resolveOAuthWorkspaceMetadata(context, tokens);
187
- if (!resolved) continue;
188
- await rememberResolvedWorkspaceMetadata(context, storage, tokens, resolved);
189
- nextWorkspaces = nextWorkspaces.map((candidate) => candidate.credentialWorkspaceId === workspace.credentialWorkspaceId ? {
190
- ...candidate,
191
- id: resolved.id,
192
- name: resolved.name,
193
- lastSeenAt: (/* @__PURE__ */ new Date()).toISOString()
194
- } : candidate);
195
- }
196
- return nextWorkspaces;
197
- }
198
- async function rememberResolvedWorkspaceMetadata(context, storage, tokens, resolved) {
199
- try {
200
- await storage.rememberWorkspace(tokens.workspaceId, resolved);
201
- } catch {
202
- context.runtime.signal?.throwIfAborted();
203
- }
204
- }
205
- function needsWorkspaceMetadataHydration(workspace) {
206
- return workspace.id === workspace.credentialWorkspaceId || workspace.name === "Unknown workspace" || workspace.name === workspace.credentialWorkspaceId;
207
- }
208
- async function resolveOAuthWorkspaceMetadata(context, tokens) {
209
- const sdk = createManagementApiSdk({
210
- clientId: CLIENT_ID,
211
- redirectUri: "http://localhost:0/auth/callback",
212
- tokenStorage: createSingleWorkspaceTokenStorage(new FileTokenStorage(context.runtime.env, context.runtime.signal, { activateOnSetTokens: false }), tokens),
213
- apiBaseUrl: getApiBaseUrl(context.runtime.env)
214
- });
215
- try {
216
- const { data } = await sdk.client.GET("/v1/workspaces/{id}", {
217
- params: { path: { id: tokens.workspaceId } },
218
- signal: context.runtime.signal
219
- });
220
- const id = stringOrNull(data?.data?.id) ?? tokens.workspaceId;
221
- const name = stringOrNull(data?.data?.name) ?? id;
222
- if (id === tokens.workspaceId && name === tokens.workspaceId) return null;
223
- return {
224
- id,
225
- name
226
- };
227
- } catch {
228
- context.runtime.signal?.throwIfAborted();
229
- return null;
230
- }
231
- }
232
- function createSingleWorkspaceTokenStorage(storage, initialTokens) {
233
- let currentTokens = initialTokens;
234
- return {
235
- getTokens: async () => currentTokens,
236
- setTokens: async (tokens) => {
237
- currentTokens = tokens;
238
- await storage.setTokens(tokens);
239
- },
240
- clearTokens: async () => {
241
- const tokens = currentTokens;
242
- currentTokens = null;
243
- if (tokens) await storage.clearTokensIfCurrent(tokens);
244
- }
245
- };
246
- }
247
- function stringOrNull(value) {
248
- return typeof value === "string" && value.trim().length > 0 ? value.trim() : null;
249
- }
250
- function toAuthWorkspace(workspace) {
251
- return {
252
- id: workspace.id,
253
- name: workspace.name
254
- };
255
- }
256
- async function loginWithSelectionFlow(context, useCases, options) {
257
- const selection = await resolveLoginSelection(useCases, canPrompt(context) ? createSelectPromptPort(context) : null, options);
258
- return useCases.login(selection);
259
- }
260
- async function resolveLoginSelection(useCases, prompt, options) {
261
- const provider = options.provider ? (await useCases.resolveProvider(options.provider)).id : (await selectProvider(useCases, prompt)).id;
262
- const user = options.user ? await useCases.resolveUserForProvider(provider, options.user) : await selectUser(useCases, prompt, provider);
263
- const workspace = options.workspace ? await useCases.resolveWorkspaceForUser(user.id, options.workspace) : await selectWorkspace(useCases, prompt, user.id);
264
- return {
265
- provider,
266
- userId: user.id,
267
- workspaceId: workspace.id
268
- };
269
- }
270
- async function selectProvider(useCases, prompt) {
271
- if (!prompt) throw nonInteractiveLoginError("Re-run prisma-cli auth login in a TTY, or provide --provider and --user, and --workspace when required.");
272
- const providers = await useCases.listProviders();
273
- return prompt.select({
274
- message: "Select a provider",
275
- choices: providers.map((provider) => ({
276
- label: provider.name,
277
- value: provider
278
- }))
279
- });
280
- }
281
- async function selectUser(useCases, prompt, provider) {
282
- const users = await useCases.listUsersForProvider(provider);
283
- if (!prompt) throw nonInteractiveLoginError("Re-run prisma-cli auth login in a TTY, or provide --provider and --user, and --workspace when required.");
284
- return prompt.select({
285
- message: "Select a user",
286
- choices: users.map((user) => ({
287
- label: `${user.name} <${user.email}>`,
288
- value: user
289
- }))
290
- });
291
- }
292
- async function selectWorkspace(useCases, prompt, userId) {
293
- const workspaces = await useCases.listWorkspacesForUser(userId);
294
- if (workspaces.length === 1) return workspaces[0];
295
- if (!prompt) throw usageError("Login requires explicit selectors in non-interactive mode", "The selected mock user belongs to more than one workspace and the shell cannot prompt in the current mode.", "Re-run prisma-cli auth login in a TTY, or provide --workspace.", ["prisma-cli auth login"], "auth");
296
- return prompt.select({
297
- message: "Select a workspace",
298
- choices: workspaces.map((workspace) => ({
299
- label: `${workspace.name} (${workspace.id})`,
300
- value: workspace
301
- }))
302
- });
303
- }
304
- function nonInteractiveLoginError(fix) {
305
- return usageError("Login requires explicit selectors in non-interactive mode", "The fixture mode cannot prompt in the current mode.", fix, ["prisma-cli auth login"], "auth");
306
- }
307
- function createAuthSuccess(command, result, nextSteps) {
308
- return {
309
- command,
310
- result,
311
- warnings: [],
312
- nextSteps
313
- };
314
- }
315
- //#endregion
316
- export { requireAuthenticatedAuthState, runAuthLogin, runAuthLogout, runAuthWhoAmI, runAuthWorkspaceList, runAuthWorkspaceLogout, runAuthWorkspaceUse };
@@ -1,103 +0,0 @@
1
- import { CliError, authRequiredError, workspaceRequiredError } from "../shell/errors.js";
2
- import { projectResolutionErrorToCliError, resolveProjectTarget } from "../lib/project/resolution.js";
3
- import { requireComputeAuth } from "../lib/auth/guard.js";
4
- import { createCliUseCaseGateways } from "../use-cases/create-cli-gateways.js";
5
- import { requireAuthenticatedAuthState } from "./auth.js";
6
- import { listRealWorkspaceProjects } from "./project.js";
7
- import { createBranchUseCases } from "../use-cases/branch.js";
8
- //#region src/controllers/branch.ts
9
- function isRealMode(context) {
10
- return !context.runtime.fixturePath && !context.runtime.env.PRISMA_CLI_MOCK_FIXTURE_PATH;
11
- }
12
- async function runBranchList(context) {
13
- if (isRealMode(context)) return {
14
- command: "branch.list",
15
- result: await listRealBranches(context),
16
- warnings: [],
17
- nextSteps: []
18
- };
19
- return {
20
- command: "branch.list",
21
- result: await createBranchUseCases(createCliUseCaseGateways(context)).list(),
22
- warnings: [],
23
- nextSteps: []
24
- };
25
- }
26
- async function listRealBranches(context) {
27
- const authState = await requireAuthenticatedAuthState(context);
28
- const client = await requireComputeAuth(context.runtime.env, context.runtime.signal);
29
- if (!client) throw authRequiredError(["prisma-cli auth login"]);
30
- const workspace = authState.workspace;
31
- if (!workspace) throw workspaceRequiredError();
32
- const targetResult = await resolveProjectTarget({
33
- context,
34
- workspace,
35
- listProjects: () => listRealWorkspaceProjects(client, workspace, context.runtime.signal)
36
- });
37
- if (targetResult.isErr()) throw projectResolutionErrorToCliError(targetResult.error);
38
- const target = targetResult.value;
39
- const branches = await listBranches(client, target.project.id, context.runtime.signal);
40
- return {
41
- projectId: target.project.id,
42
- projectName: target.project.name,
43
- verboseContext: {
44
- workspace,
45
- project: target.project,
46
- resolution: target.resolution
47
- },
48
- branches: sortBranches(branches.map(toBranchSummary))
49
- };
50
- }
51
- function sortBranches(branches) {
52
- return branches.slice().sort((left, right) => {
53
- const leftRank = branchOrder(left);
54
- const rightRank = branchOrder(right);
55
- if (leftRank !== rightRank) return leftRank - rightRank;
56
- return left.name.localeCompare(right.name);
57
- });
58
- }
59
- function branchOrder(branch) {
60
- return branch.role === "production" ? 0 : 1;
61
- }
62
- async function listBranches(client, projectId, signal) {
63
- const collected = [];
64
- let cursor;
65
- while (true) {
66
- const query = {};
67
- if (cursor !== void 0) query.cursor = cursor;
68
- const { data, error, response } = await client.GET("/v1/projects/{projectId}/branches", {
69
- params: {
70
- path: { projectId },
71
- query
72
- },
73
- signal
74
- });
75
- if (error || !data) throw branchApiError("Failed to list branches", response, error);
76
- collected.push(...data.data);
77
- if (!data.pagination.hasMore || !data.pagination.nextCursor) break;
78
- cursor = data.pagination.nextCursor;
79
- }
80
- return collected;
81
- }
82
- function toBranchSummary(branch) {
83
- return {
84
- id: branch.id,
85
- name: branch.gitName,
86
- role: branch.role,
87
- envMap: branch.role
88
- };
89
- }
90
- function branchApiError(summary, response, error) {
91
- const status = response?.status ?? 0;
92
- return new CliError({
93
- code: error?.error?.code ?? "BRANCH_API_ERROR",
94
- domain: "branch",
95
- summary,
96
- why: error?.error?.message ?? `The Management API returned status ${status || "unknown"}.`,
97
- fix: error?.error?.hint ?? "Re-run with --trace for the underlying API response details.",
98
- exitCode: 1,
99
- nextSteps: []
100
- });
101
- }
102
- //#endregion
103
- export { runBranchList };