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

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 (87) hide show
  1. package/README.md +3 -1
  2. package/dist/cli.js +15115 -16
  3. package/dist/deploy-framework-C7bQM00A.js +23 -0
  4. package/dist/payload-B88Qvzxk-CrtTXSOe.js +34 -0
  5. package/dist/sender.js +192 -0
  6. package/package.json +22 -18
  7. package/dist/adapters/git.js +0 -54
  8. package/dist/adapters/local-state.js +0 -144
  9. package/dist/adapters/mock-api.js +0 -136
  10. package/dist/adapters/token-storage.js +0 -418
  11. package/dist/cli2.js +0 -119
  12. package/dist/commands/app/index.js +0 -345
  13. package/dist/commands/auth/index.js +0 -96
  14. package/dist/commands/branch/index.js +0 -27
  15. package/dist/commands/database/index.js +0 -159
  16. package/dist/commands/env.js +0 -99
  17. package/dist/commands/git/index.js +0 -36
  18. package/dist/commands/project/index.js +0 -69
  19. package/dist/commands/version/index.js +0 -18
  20. package/dist/controllers/app-env-api.js +0 -54
  21. package/dist/controllers/app-env-file.js +0 -181
  22. package/dist/controllers/app-env.js +0 -502
  23. package/dist/controllers/app.js +0 -2443
  24. package/dist/controllers/auth.js +0 -316
  25. package/dist/controllers/branch.js +0 -103
  26. package/dist/controllers/database.js +0 -318
  27. package/dist/controllers/project.js +0 -731
  28. package/dist/controllers/select-prompt-port.js +0 -12
  29. package/dist/controllers/version.js +0 -12
  30. package/dist/lib/app/app-interaction.js +0 -5
  31. package/dist/lib/app/app-provider.js +0 -544
  32. package/dist/lib/app/branch-database-api.js +0 -102
  33. package/dist/lib/app/branch-database-deploy.js +0 -325
  34. package/dist/lib/app/branch-database.js +0 -215
  35. package/dist/lib/app/build-settings.js +0 -93
  36. package/dist/lib/app/build.js +0 -80
  37. package/dist/lib/app/bun-project.js +0 -45
  38. package/dist/lib/app/compute-config.js +0 -147
  39. package/dist/lib/app/deploy-output.js +0 -24
  40. package/dist/lib/app/deploy-plan.js +0 -58
  41. package/dist/lib/app/deploy-progress.js +0 -100
  42. package/dist/lib/app/domain-guidance.js +0 -14
  43. package/dist/lib/app/env-config.js +0 -67
  44. package/dist/lib/app/env-file.js +0 -82
  45. package/dist/lib/app/env-vars.js +0 -50
  46. package/dist/lib/app/local-dev.js +0 -109
  47. package/dist/lib/app/production-deploy-gate.js +0 -161
  48. package/dist/lib/app/read-branch.js +0 -30
  49. package/dist/lib/auth/auth-ops.js +0 -158
  50. package/dist/lib/auth/client.js +0 -22
  51. package/dist/lib/auth/guard.js +0 -38
  52. package/dist/lib/auth/login.js +0 -330
  53. package/dist/lib/database/provider.js +0 -167
  54. package/dist/lib/diagnostics.js +0 -15
  55. package/dist/lib/fs/home-path.js +0 -24
  56. package/dist/lib/git/local-branch.js +0 -53
  57. package/dist/lib/git/local-status.js +0 -57
  58. package/dist/lib/project/interactive-setup.js +0 -56
  59. package/dist/lib/project/local-pin.js +0 -200
  60. package/dist/lib/project/resolution.js +0 -386
  61. package/dist/lib/project/setup.js +0 -135
  62. package/dist/lib/version.js +0 -55
  63. package/dist/output/patterns.js +0 -90
  64. package/dist/presenters/app-env.js +0 -265
  65. package/dist/presenters/app.js +0 -646
  66. package/dist/presenters/auth.js +0 -183
  67. package/dist/presenters/branch.js +0 -46
  68. package/dist/presenters/database.js +0 -274
  69. package/dist/presenters/project.js +0 -174
  70. package/dist/presenters/verbose-context.js +0 -64
  71. package/dist/presenters/version.js +0 -29
  72. package/dist/shell/command-arguments.js +0 -6
  73. package/dist/shell/command-meta.js +0 -622
  74. package/dist/shell/command-runner.js +0 -112
  75. package/dist/shell/diagnostics-output.js +0 -57
  76. package/dist/shell/errors.js +0 -134
  77. package/dist/shell/global-flags.js +0 -37
  78. package/dist/shell/help.js +0 -89
  79. package/dist/shell/output.js +0 -82
  80. package/dist/shell/prompt.js +0 -41
  81. package/dist/shell/runtime.js +0 -55
  82. package/dist/shell/ui.js +0 -116
  83. package/dist/shell/update-check.js +0 -247
  84. package/dist/use-cases/auth.js +0 -145
  85. package/dist/use-cases/branch.js +0 -47
  86. package/dist/use-cases/create-cli-gateways.js +0 -68
  87. package/dist/use-cases/project.js +0 -30
@@ -1,502 +0,0 @@
1
- import { CliError, authRequiredError, usageError, workspaceRequiredError } from "../shell/errors.js";
2
- import { formatScopeLabel, parseKeyValuePositional, resolveEnvScope } from "../lib/app/env-config.js";
3
- import { readEnvFileAssignments } from "../lib/app/env-file.js";
4
- import { projectResolutionErrorToCliError, resolveProjectTarget } from "../lib/project/resolution.js";
5
- import { requireComputeAuth } from "../lib/auth/guard.js";
6
- import { readLocalGitBranch } from "../lib/git/local-branch.js";
7
- import { requireAuthenticatedAuthState } from "./auth.js";
8
- import { listRealWorkspaceProjects } from "./project.js";
9
- import { apiCallError, findVariableByNaturalKey, toMetadata } from "./app-env-api.js";
10
- import { runEnvAddFile, runEnvUpdateFile } from "./app-env-file.js";
11
- //#region src/controllers/app-env.ts
12
- async function runEnvAdd(context, rawAssignment, flags) {
13
- const source = resolveEnvWriteSource(rawAssignment, flags.filePath, "add");
14
- const scope = resolveEnvScope(flags, {
15
- requireExplicit: true,
16
- command: "add"
17
- });
18
- if (!scope) throw usageError(`prisma-cli project env add requires --role or --branch`, "Writing without an explicit scope is rejected.", "Pass --role production, --role preview, or --branch <git-name>.", ["prisma-cli project env add KEY=value --role production"], "app");
19
- const input = await resolveEnvWriteInput(context, source, "add");
20
- const { client, projectId, verboseContext } = await requireClientAndProject(context, flags.projectRef, "project env add");
21
- const resolved = await resolveScopeToApi(client, projectId, scope, {
22
- createBranchIfMissing: true,
23
- signal: context.runtime.signal
24
- });
25
- if (input.kind === "file") return runEnvAddFile(context, client, projectId, resolved, input.filePath, input.assignments, verboseContext);
26
- if (await findVariableByNaturalKey(client, projectId, input.key, resolved, context.runtime.signal)) throw new CliError({
27
- code: "ENV_VARIABLE_ALREADY_EXISTS",
28
- domain: "app",
29
- summary: `Variable "${input.key}" already exists in ${formatScopeLabel(scope)}`,
30
- why: "A variable with this key already exists in the targeted scope.",
31
- fix: "Use `prisma-cli project env update` to change an existing variable's value.",
32
- exitCode: 1,
33
- nextSteps: [`prisma-cli project env update ${input.key}=<new-value> ${formatScopeFlag(scope)}`]
34
- });
35
- const warnings = scope.kind === "branch" && !await findVariableByNaturalKey(client, projectId, input.key, {
36
- descriptor: {
37
- kind: "role",
38
- role: "preview"
39
- },
40
- apiTarget: {
41
- class: "preview",
42
- branchId: null
43
- }
44
- }, context.runtime.signal) ? [`Variable "${input.key}" does not exist in preview. It will only exist on ${formatScopeLabel(scope)}.`] : [];
45
- const { data, error, response } = await client.POST("/v1/environment-variables", {
46
- body: {
47
- projectId,
48
- class: resolved.apiTarget.class,
49
- ...resolved.apiTarget.branchId !== null ? { branchId: resolved.apiTarget.branchId } : {},
50
- key: input.key,
51
- value: input.value
52
- },
53
- signal: context.runtime.signal
54
- });
55
- if (error || !data) throw apiCallError(`Failed to add ${input.key}`, response, error);
56
- return {
57
- command: "project.env.add",
58
- result: {
59
- projectId,
60
- verboseContext,
61
- scope: resolved.descriptor,
62
- variable: toMetadata(data.data, resolved.descriptor)
63
- },
64
- warnings,
65
- nextSteps: []
66
- };
67
- }
68
- async function runEnvUpdate(context, rawAssignment, flags) {
69
- const source = resolveEnvWriteSource(rawAssignment, flags.filePath, "update");
70
- const scope = resolveEnvScope(flags, {
71
- requireExplicit: true,
72
- command: "update"
73
- });
74
- if (!scope) throw usageError(`prisma-cli project env update requires --role or --branch`, "Writing without an explicit scope is rejected.", "Pass --role production, --role preview, or --branch <git-name>.", ["prisma-cli project env update KEY=value --role production"], "app");
75
- const input = await resolveEnvWriteInput(context, source, "update");
76
- const { client, projectId, verboseContext } = await requireClientAndProject(context, flags.projectRef, "project env update");
77
- const resolved = await resolveScopeToApi(client, projectId, scope, {
78
- createBranchIfMissing: false,
79
- signal: context.runtime.signal
80
- });
81
- if (input.kind === "file") return runEnvUpdateFile(context, client, projectId, resolved, input.filePath, input.assignments, verboseContext);
82
- const existing = await findVariableByNaturalKey(client, projectId, input.key, resolved, context.runtime.signal);
83
- if (!existing) throw new CliError({
84
- code: "ENV_VARIABLE_NOT_FOUND",
85
- domain: "app",
86
- summary: `Variable "${input.key}" not found in ${formatScopeLabel(scope)}`,
87
- why: "No variable with this key exists in the targeted scope.",
88
- fix: "Use `prisma-cli project env add` to create a new variable.",
89
- exitCode: 1,
90
- nextSteps: [`prisma-cli project env add ${input.key}=<value> ${formatScopeFlag(scope)}`]
91
- });
92
- const { data, error, response } = await client.PATCH("/v1/environment-variables/{envVarId}", {
93
- params: { path: { envVarId: existing.id } },
94
- body: { value: input.value },
95
- signal: context.runtime.signal
96
- });
97
- if (error || !data) throw apiCallError(`Failed to update value for ${input.key}`, response, error);
98
- return {
99
- command: "project.env.update",
100
- result: {
101
- projectId,
102
- verboseContext,
103
- scope: resolved.descriptor,
104
- variable: toMetadata(data.data, resolved.descriptor)
105
- },
106
- warnings: [],
107
- nextSteps: []
108
- };
109
- }
110
- function resolveEnvWriteSource(rawAssignment, filePath, command) {
111
- if (filePath !== void 0 && rawAssignment !== void 0) throw usageError(`prisma-cli project env ${command} accepts either KEY=VALUE or --file`, "The command received both a positional assignment and a dotenv file path.", "Pass one input source.", [`prisma-cli project env ${command} KEY=value --role preview`, `prisma-cli project env ${command} --file .env --role preview`], "app");
112
- if (filePath !== void 0) {
113
- if (filePath.length === 0) throw usageError(`prisma-cli project env ${command} --file requires a path`, "The --file flag was passed without a file path.", "Pass a readable dotenv file path.", [`prisma-cli project env ${command} --file .env --role preview`], "app");
114
- return {
115
- kind: "file",
116
- filePath
117
- };
118
- }
119
- if (rawAssignment === void 0) throw usageError(`prisma-cli project env ${command} requires KEY=VALUE or --file`, "No environment variable input was supplied.", "Pass a single KEY=VALUE assignment or a dotenv file path.", [`prisma-cli project env ${command} KEY=value --role preview`, `prisma-cli project env ${command} --file .env --role preview`], "app");
120
- return {
121
- kind: "single",
122
- rawAssignment
123
- };
124
- }
125
- async function resolveEnvWriteInput(context, source, command) {
126
- if (source.kind === "file") return {
127
- kind: "file",
128
- filePath: source.filePath,
129
- assignments: await readEnvFileAssignments(context.runtime.cwd, source.filePath, command)
130
- };
131
- return {
132
- kind: "single",
133
- ...parseKeyValuePositional(source.rawAssignment, command, context.runtime.env)
134
- };
135
- }
136
- async function runEnvList(context, flags) {
137
- const explicit = resolveEnvScope(flags, {
138
- requireExplicit: false,
139
- command: "list"
140
- });
141
- const { client, projectId, verboseContext } = await requireClientAndProject(context, flags.projectRef, "project env list");
142
- const resolved = await resolveListScopeToApi(client, projectId, explicit ?? void 0, {
143
- cwd: context.runtime.cwd,
144
- signal: context.runtime.signal
145
- });
146
- const variables = resolved.kind === "scoped" ? await listVariables(client, projectId, {
147
- scope: resolved.addScope,
148
- descriptor: resolved.descriptor,
149
- apiTarget: resolved.apiTarget
150
- }, context.runtime.signal) : await listOverviewVariables(client, projectId, context.runtime.signal);
151
- return {
152
- command: "project.env.list",
153
- result: {
154
- projectId,
155
- verboseContext,
156
- scope: resolved.descriptor,
157
- target: resolved.target,
158
- variables: variables.map((row) => toMetadata(row, resolved.descriptor))
159
- },
160
- warnings: [],
161
- nextSteps: variables.length === 0 ? [`prisma-cli project env add KEY=value ${formatScopeFlag(resolved.addScope)}`] : []
162
- };
163
- }
164
- async function runEnvRemove(context, key, flags) {
165
- if (!key) throw usageError("prisma-cli project env remove requires KEY", "No KEY positional argument was supplied.", "Pass the variable name to remove, e.g. STRIPE_KEY.", ["prisma-cli project env remove STRIPE_KEY --role production"], "app");
166
- const scope = resolveEnvScope(flags, {
167
- requireExplicit: true,
168
- command: "remove"
169
- });
170
- if (!scope) throw usageError("prisma-cli project env remove requires --role or --branch", "Writing without an explicit scope is rejected.", "Pass --role production, --role preview, or --branch <git-name>.", [`prisma-cli project env remove ${key} --role production`], "app");
171
- const { client, projectId, verboseContext } = await requireClientAndProject(context, flags.projectRef, "project env remove");
172
- const resolved = await resolveScopeToApi(client, projectId, scope, {
173
- createBranchIfMissing: false,
174
- signal: context.runtime.signal
175
- });
176
- const existing = await findVariableByNaturalKey(client, projectId, key, resolved, context.runtime.signal);
177
- if (!existing) throw new CliError({
178
- code: "ENV_VARIABLE_NOT_FOUND",
179
- domain: "app",
180
- summary: `Variable "${key}" not found in ${formatScopeLabel(scope)}`,
181
- why: "No variable with this key exists in the targeted scope, so there is nothing to remove.",
182
- fix: "Run prisma-cli project env list with the same scope to see the available variables.",
183
- exitCode: 1,
184
- nextSteps: [`prisma-cli project env list ${formatScopeFlag(scope)}`]
185
- });
186
- const { error, response } = await client.DELETE("/v1/environment-variables/{envVarId}", {
187
- params: { path: { envVarId: existing.id } },
188
- signal: context.runtime.signal
189
- });
190
- if (error) throw apiCallError(`Failed to remove ${key}`, response, error);
191
- return {
192
- command: "project.env.remove",
193
- result: {
194
- projectId,
195
- verboseContext,
196
- scope: resolved.descriptor,
197
- key
198
- },
199
- warnings: [],
200
- nextSteps: []
201
- };
202
- }
203
- async function requireClientAndProject(context, explicitProject, commandName) {
204
- const authState = await requireAuthenticatedAuthState(context);
205
- const client = await requireComputeAuth(context.runtime.env, context.runtime.signal);
206
- if (!client) throw authRequiredError(["prisma-cli auth login"]);
207
- const workspace = authState.workspace;
208
- if (!workspace) throw workspaceRequiredError();
209
- const targetResult = await resolveProjectTarget({
210
- context,
211
- workspace,
212
- explicitProject,
213
- listProjects: () => listRealWorkspaceProjects(client, workspace, context.runtime.signal),
214
- commandName
215
- });
216
- if (targetResult.isErr()) throw projectResolutionErrorToCliError(targetResult.error);
217
- const target = targetResult.value;
218
- return {
219
- client,
220
- projectId: target.project.id,
221
- verboseContext: {
222
- workspace,
223
- project: target.project,
224
- resolution: target.resolution
225
- }
226
- };
227
- }
228
- async function resolveScopeToApi(client, projectId, scope, options) {
229
- if (scope.kind === "role") return {
230
- scope,
231
- descriptor: {
232
- kind: "role",
233
- role: scope.role
234
- },
235
- apiTarget: {
236
- class: scope.role,
237
- branchId: null
238
- }
239
- };
240
- const branch = options.createBranchIfMissing ? await resolveOrCreateBranch(client, projectId, scope.branchName, options.signal) : await resolveExistingBranch(client, projectId, scope.branchName, options.signal);
241
- if (branch.role === "production") throw new CliError({
242
- code: "ENV_BRANCH_SCOPE_IS_PRODUCTION",
243
- domain: "app",
244
- summary: `Branch "${scope.branchName}" is the production branch`,
245
- why: "Production variables are project-level only; branch overrides apply to preview branches.",
246
- fix: "Use --role production for the production branch.",
247
- exitCode: 1,
248
- nextSteps: ["prisma-cli project env list --role production"]
249
- });
250
- return {
251
- scope,
252
- descriptor: {
253
- kind: "branch",
254
- branchName: branch.gitName,
255
- branchId: branch.id
256
- },
257
- apiTarget: {
258
- class: "preview",
259
- branchId: branch.id
260
- }
261
- };
262
- }
263
- async function resolveListScopeToApi(client, projectId, explicit, options) {
264
- if (explicit) {
265
- const resolved = await resolveScopeToApi(client, projectId, explicit, {
266
- createBranchIfMissing: false,
267
- signal: options.signal
268
- });
269
- return {
270
- kind: "scoped",
271
- descriptor: resolved.descriptor,
272
- target: targetFromExplicitScope(resolved.descriptor),
273
- apiTarget: resolved.apiTarget,
274
- addScope: resolved.scope
275
- };
276
- }
277
- const gitBranch = await readLocalGitBranch(options.cwd, options.signal);
278
- if (gitBranch) {
279
- const branch = (await listBranchesByName(client, projectId, gitBranch, options.signal))[0];
280
- if (!branch) return {
281
- kind: "scoped",
282
- descriptor: {
283
- kind: "role",
284
- role: "preview"
285
- },
286
- target: {
287
- source: "local-git",
288
- branchName: gitBranch,
289
- branchExists: false,
290
- envMap: "preview"
291
- },
292
- apiTarget: {
293
- class: "preview",
294
- branchId: null
295
- },
296
- addScope: {
297
- kind: "branch",
298
- branchName: gitBranch
299
- }
300
- };
301
- if (branch.role === "production") return {
302
- kind: "scoped",
303
- descriptor: {
304
- kind: "role",
305
- role: "production"
306
- },
307
- target: {
308
- source: "local-git",
309
- branchName: branch.gitName,
310
- branchId: branch.id,
311
- branchRole: branch.role,
312
- branchExists: true,
313
- envMap: "production"
314
- },
315
- apiTarget: {
316
- class: "production",
317
- branchId: null
318
- },
319
- addScope: {
320
- kind: "role",
321
- role: "production"
322
- }
323
- };
324
- return {
325
- kind: "scoped",
326
- descriptor: {
327
- kind: "branch",
328
- branchName: branch.gitName,
329
- branchId: branch.id
330
- },
331
- target: {
332
- source: "local-git",
333
- branchName: branch.gitName,
334
- branchId: branch.id,
335
- branchRole: branch.role,
336
- branchExists: true,
337
- envMap: "preview"
338
- },
339
- apiTarget: {
340
- class: "preview",
341
- branchId: branch.id
342
- },
343
- addScope: {
344
- kind: "branch",
345
- branchName: branch.gitName
346
- }
347
- };
348
- }
349
- return {
350
- kind: "overview",
351
- descriptor: { kind: "overview" },
352
- target: {
353
- source: "overview",
354
- envMap: "overview"
355
- },
356
- addScope: {
357
- kind: "role",
358
- role: "preview"
359
- }
360
- };
361
- }
362
- function targetFromExplicitScope(scope) {
363
- if (scope.kind === "branch") return {
364
- source: "explicit",
365
- branchName: scope.branchName,
366
- branchId: scope.branchId,
367
- branchRole: "preview",
368
- branchExists: true,
369
- envMap: "preview"
370
- };
371
- if (scope.kind === "role") return {
372
- source: "explicit",
373
- envMap: scope.role
374
- };
375
- return {
376
- source: "overview",
377
- envMap: "overview"
378
- };
379
- }
380
- function formatScopeFlag(scope) {
381
- if (scope.kind === "role") return `--role ${scope.role}`;
382
- return `--branch ${scope.branchName}`;
383
- }
384
- async function listBranchesByName(client, projectId, branchName, signal) {
385
- const { data, error, response } = await client.GET("/v1/projects/{projectId}/branches", {
386
- params: {
387
- path: { projectId },
388
- query: { gitName: branchName }
389
- },
390
- signal
391
- });
392
- if (error || !data) throw apiCallError(`Failed to resolve branch "${branchName}"`, response, error);
393
- return data.data;
394
- }
395
- async function resolveExistingBranch(client, projectId, branchName, signal) {
396
- const branch = (await listBranchesByName(client, projectId, branchName, signal))[0];
397
- if (!branch) throw new CliError({
398
- code: "ENV_BRANCH_NOT_FOUND",
399
- domain: "app",
400
- summary: `Branch "${branchName}" not found`,
401
- why: "Branch update, list, and remove commands only target existing preview branches.",
402
- fix: "Create the branch by deploying it, or use `project env add --branch` to create its first override.",
403
- exitCode: 1,
404
- nextSteps: [`prisma-cli project env add KEY=value --branch ${branchName}`]
405
- });
406
- return branch;
407
- }
408
- async function resolveOrCreateBranch(client, projectId, branchName, signal) {
409
- const existing = (await listBranchesByName(client, projectId, branchName, signal))[0];
410
- if (existing) return existing;
411
- if (!await projectHasDefaultBranch(client, projectId, signal)) throw new CliError({
412
- code: "ENV_BRANCH_CREATE_REQUIRES_DEFAULT_BRANCH",
413
- domain: "app",
414
- summary: `Cannot create branch "${branchName}" from project env`,
415
- why: "Creating the first branch would make it the project default, but branch overrides are preview-only.",
416
- fix: "Create or deploy the default branch first, then add the branch override.",
417
- exitCode: 1,
418
- nextSteps: ["prisma-cli app deploy --branch main"]
419
- });
420
- const { data, error, response } = await client.POST("/v1/projects/{projectId}/branches", {
421
- params: { path: { projectId } },
422
- body: {
423
- gitName: branchName,
424
- isDefault: false
425
- },
426
- signal
427
- });
428
- if (error || !data) {
429
- if (response?.status === 409) {
430
- const raced = (await listBranchesByName(client, projectId, branchName, signal))[0];
431
- if (raced) return raced;
432
- }
433
- throw apiCallError(`Failed to create branch "${branchName}"`, response, error);
434
- }
435
- return data.data;
436
- }
437
- async function projectHasDefaultBranch(client, projectId, signal) {
438
- let cursor;
439
- while (true) {
440
- const query = {};
441
- if (cursor !== void 0) query.cursor = cursor;
442
- const result = await client.GET("/v1/projects/{projectId}/branches", {
443
- params: {
444
- path: { projectId },
445
- query
446
- },
447
- signal
448
- });
449
- if (result.error || !result.data) throw apiCallError("Failed to check project default branch", result.response, result.error);
450
- if (result.data.data.some((branch) => branch.isDefault)) return true;
451
- if (!result.data.pagination.hasMore || !result.data.pagination.nextCursor) return false;
452
- cursor = result.data.pagination.nextCursor;
453
- }
454
- }
455
- async function listVariables(client, projectId, resolved, signal) {
456
- return materializeEffectiveRows(await collectEnvironmentVariables(client, projectId, signal, {
457
- className: resolved.apiTarget.class,
458
- filter: (row) => rowMatchesScope(row, resolved)
459
- }), resolved);
460
- }
461
- async function listOverviewVariables(client, projectId, signal) {
462
- return (await collectEnvironmentVariables(client, projectId, signal, { filter: (row) => row.branchId === null && (row.class === "production" || row.class === "preview") })).sort((left, right) => {
463
- const roleOrder = roleSortOrder(left.class) - roleSortOrder(right.class);
464
- return roleOrder !== 0 ? roleOrder : left.key.localeCompare(right.key);
465
- });
466
- }
467
- async function collectEnvironmentVariables(client, projectId, signal, options) {
468
- const collected = [];
469
- let cursor;
470
- while (true) {
471
- const query = { projectId };
472
- if (options.className !== void 0) query.class = options.className;
473
- if (cursor !== void 0) query.cursor = cursor;
474
- const result = await client.GET("/v1/environment-variables", {
475
- params: { query },
476
- signal
477
- });
478
- if (result.error || !result.data) throw apiCallError(`Failed to list environment variables`, result.response, result.error);
479
- const page = result.data.data.filter(options.filter);
480
- collected.push(...page);
481
- if (!result.data.pagination.hasMore || !result.data.pagination.nextCursor) break;
482
- cursor = result.data.pagination.nextCursor;
483
- }
484
- return collected;
485
- }
486
- function roleSortOrder(role) {
487
- return role === "production" ? 0 : 1;
488
- }
489
- function rowMatchesScope(row, resolved) {
490
- if (row.class !== resolved.apiTarget.class) return false;
491
- if (resolved.apiTarget.branchId === null) return row.branchId === null;
492
- return row.branchId === null || row.branchId === resolved.apiTarget.branchId;
493
- }
494
- function materializeEffectiveRows(rows, resolved) {
495
- if (resolved.apiTarget.branchId === null) return rows;
496
- const byKey = /* @__PURE__ */ new Map();
497
- for (const row of rows) if (row.branchId === null && !byKey.has(row.key)) byKey.set(row.key, row);
498
- for (const row of rows) if (row.branchId === resolved.apiTarget.branchId) byKey.set(row.key, row);
499
- return [...byKey.values()].sort((left, right) => left.key.localeCompare(right.key));
500
- }
501
- //#endregion
502
- export { runEnvAdd, runEnvList, runEnvRemove, runEnvUpdate };