vercel 51.5.0 → 51.6.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.
Files changed (66) hide show
  1. package/dist/chunks/{add-RNQLGEYS.js → add-JALB3DKU.js} +6 -6
  2. package/dist/chunks/{chunk-DKFFXOHJ.js → chunk-34IM6J7A.js} +5 -2
  3. package/dist/chunks/{chunk-D2D4FJ6S.js → chunk-3N3AYMMW.js} +33 -18
  4. package/dist/chunks/{chunk-SG4QOQTF.js → chunk-4X7GBE5B.js} +101 -53
  5. package/dist/chunks/{chunk-5VKKTHMP.js → chunk-553A6UFX.js} +10 -6
  6. package/dist/chunks/{chunk-6C33Y3DC.js → chunk-5KFTN63Q.js} +8 -8
  7. package/dist/chunks/{chunk-TAOVG4PS.js → chunk-7L4XVUFK.js} +2 -2
  8. package/dist/chunks/{chunk-4DR2FV6O.js → chunk-BBW6EGBQ.js} +1 -1
  9. package/dist/chunks/{chunk-LDXYSGPZ.js → chunk-C7UTFMYF.js} +2 -2
  10. package/dist/chunks/chunk-CHUU7VXC.js +2314 -0
  11. package/dist/chunks/{chunk-BHDZCUTT.js → chunk-DAOAZ2VQ.js} +1 -1
  12. package/dist/chunks/{chunk-CRZM5WM2.js → chunk-DED5G3HZ.js} +1 -1
  13. package/dist/chunks/{chunk-G6RXZLQ2.js → chunk-DF4AVQY3.js} +2 -2
  14. package/dist/chunks/{chunk-HNU5CXW4.js → chunk-FH2OHGXG.js} +2 -2
  15. package/dist/chunks/{chunk-7MF47FW3.js → chunk-FY3TMBQS.js} +1 -1
  16. package/dist/chunks/{chunk-5NTBJ33M.js → chunk-HUPHOH2F.js} +1 -1
  17. package/dist/chunks/{chunk-DVQ4SIWF.js → chunk-LUCCJW67.js} +1 -1
  18. package/dist/chunks/{chunk-NKJC5SI4.js → chunk-LUJPLXGG.js} +2 -2
  19. package/dist/chunks/{chunk-VGWGLBUC.js → chunk-MCTAPJSL.js} +1 -1
  20. package/dist/chunks/{chunk-L2JUC7NX.js → chunk-MGJMZIIT.js} +1 -1
  21. package/dist/chunks/{chunk-FBY3IEDZ.js → chunk-MUJZV257.js} +8 -8
  22. package/dist/chunks/{chunk-BJQTGP42.js → chunk-PVZBM6NU.js} +1 -1
  23. package/dist/chunks/{chunk-BRQBLRFB.js → chunk-QFP6FEBN.js} +1 -1
  24. package/dist/chunks/{chunk-7ZDERWUW.js → chunk-QHXUBID6.js} +2 -2
  25. package/dist/chunks/{chunk-HQXVCOH6.js → chunk-RW7LIX2Y.js} +1 -1
  26. package/dist/chunks/{chunk-AUSDBXUD.js → chunk-U73MZTAR.js} +2 -2
  27. package/dist/chunks/{chunk-537JTK2U.js → chunk-UG4457SI.js} +260 -102
  28. package/dist/chunks/{chunk-RFMC2QXQ.js → chunk-VDM5O3P6.js} +3 -3
  29. package/dist/chunks/{chunk-GE6G37P4.js → chunk-WCTFUOSJ.js} +1 -1
  30. package/dist/chunks/chunk-WYRFA4PX.js +692 -0
  31. package/dist/chunks/{chunk-UWKTUK3W.js → chunk-XLKXWNRG.js} +1 -1
  32. package/dist/chunks/{chunk-P56KWLXY.js → chunk-Z66S4G43.js} +1 -1
  33. package/dist/chunks/{compile-vercel-config-ZVY7LBE3.js → compile-vercel-config-V2SHBZFW.js} +2 -2
  34. package/dist/chunks/{delete-SKTJMJNP.js → delete-5RI2PRIT.js} +4 -4
  35. package/dist/chunks/{disable-AG7I6DPV.js → disable-JPKO7VCV.js} +4 -4
  36. package/dist/chunks/{discard-LUK6LBLT.js → discard-KXGXXDNX.js} +4 -4
  37. package/dist/chunks/{edit-3BR5HP3U.js → edit-VFUE5PVU.js} +5 -5
  38. package/dist/chunks/{enable-4JNLOKSM.js → enable-V2AX2FXX.js} +4 -4
  39. package/dist/chunks/{export-YLZ6QSHG.js → export-BG3TOT6G.js} +4 -4
  40. package/dist/chunks/{inspect-HUJLUQAV.js → inspect-3QVCZVKV.js} +6 -6
  41. package/dist/chunks/{list-RMA56KYZ.js → list-CWTYXKB5.js} +7 -7
  42. package/dist/chunks/{list-EPU4SB3E.js → list-Y2YMJWEY.js} +4 -4
  43. package/dist/chunks/{ls-7HHDYE6F.js → ls-SY2CP56I.js} +6 -6
  44. package/dist/chunks/{publish-6YE4OUDI.js → publish-75IJ4PZS.js} +4 -4
  45. package/dist/chunks/{query-X6Q4ZSZO.js → query-MLMGNGL2.js} +5 -5
  46. package/dist/chunks/{reorder-VFM23ESC.js → reorder-757V4BF5.js} +4 -4
  47. package/dist/chunks/{restore-VX34SXVF.js → restore-KV44XHFS.js} +4 -4
  48. package/dist/chunks/{rm-5KXF2PY3.js → rm-3EGKFLKW.js} +6 -6
  49. package/dist/chunks/{rule-inspect-JG7AE5TI.js → rule-inspect-AYUGCLVJ.js} +6 -6
  50. package/dist/chunks/{rules-XRJBT22L.js → rules-FUFDJOIP.js} +6 -6
  51. package/dist/chunks/{schema-IMD4VV73.js → schema-CI2XUYTW.js} +6 -6
  52. package/dist/chunks/{types-QNN5CDCB.js → types-M7LVCA3E.js} +3 -3
  53. package/dist/chunks/{update-4FMWTIJK.js → update-6EM4XIDW.js} +6 -6
  54. package/dist/commands/build/index.js +57 -34
  55. package/dist/commands/deploy/index.js +23 -24
  56. package/dist/commands/dev/index.js +56 -31
  57. package/dist/commands/env/index.js +36 -22
  58. package/dist/commands/link/index.js +21 -21
  59. package/dist/commands/list/index.js +7 -7
  60. package/dist/commands-bulk.js +1671 -2533
  61. package/dist/index.js +41 -21
  62. package/dist/version.mjs +1 -1
  63. package/package.json +19 -19
  64. package/dist/chunks/chunk-6CWW4JIG.js +0 -310
  65. package/dist/chunks/chunk-O7SQKNIT.js +0 -247
  66. package/dist/chunks/chunk-RJD5NYGF.js +0 -149
@@ -0,0 +1,2314 @@
1
+ import { createRequire as __createRequire } from 'node:module';
2
+ import { fileURLToPath as __fileURLToPath } from 'node:url';
3
+ import { dirname as __dirname_ } from 'node:path';
4
+ const require = __createRequire(import.meta.url);
5
+ const __filename = __fileURLToPath(import.meta.url);
6
+ const __dirname = __dirname_(__filename);
7
+ import {
8
+ getUpdateCommand
9
+ } from "./chunk-BBW6EGBQ.js";
10
+ import {
11
+ login
12
+ } from "./chunk-5KFTN63Q.js";
13
+ import {
14
+ apiCommand,
15
+ listSubcommand2 as listSubcommand,
16
+ loginCommand
17
+ } from "./chunk-4X7GBE5B.js";
18
+ import {
19
+ help
20
+ } from "./chunk-C7UTFMYF.js";
21
+ import {
22
+ global_path_default
23
+ } from "./chunk-UG4457SI.js";
24
+ import {
25
+ TelemetryClient
26
+ } from "./chunk-U3WLEFHU.js";
27
+ import {
28
+ getFlagsSpecification,
29
+ parseArguments,
30
+ printError,
31
+ require_strip_ansi
32
+ } from "./chunk-VDM5O3P6.js";
33
+ import {
34
+ packageName
35
+ } from "./chunk-ECRBC4HL.js";
36
+ import {
37
+ output_manager_default
38
+ } from "./chunk-ZQKJVHXY.js";
39
+ import {
40
+ require_source
41
+ } from "./chunk-S7KYDPEM.js";
42
+ import {
43
+ __commonJS,
44
+ __toESM
45
+ } from "./chunk-TZ2YI2VH.js";
46
+
47
+ // ../../node_modules/.pnpm/jaro-winkler@0.2.8/node_modules/jaro-winkler/index.js
48
+ var require_jaro_winkler = __commonJS({
49
+ "../../node_modules/.pnpm/jaro-winkler@0.2.8/node_modules/jaro-winkler/index.js"(exports, module) {
50
+ (function(root) {
51
+ "use strict";
52
+ function extend(a, b) {
53
+ for (var property in b) {
54
+ if (b.hasOwnProperty(property)) {
55
+ a[property] = b[property];
56
+ }
57
+ }
58
+ return a;
59
+ }
60
+ function distance2(s1, s2, options) {
61
+ var m = 0;
62
+ var defaults = { caseSensitive: true };
63
+ var settings = extend(defaults, options);
64
+ var i;
65
+ var j;
66
+ if (s1.length === 0 || s2.length === 0) {
67
+ return 0;
68
+ }
69
+ if (!settings.caseSensitive) {
70
+ s1 = s1.toUpperCase();
71
+ s2 = s2.toUpperCase();
72
+ }
73
+ if (s1 === s2) {
74
+ return 1;
75
+ }
76
+ var range = Math.floor(Math.max(s1.length, s2.length) / 2) - 1;
77
+ var s1Matches = new Array(s1.length);
78
+ var s2Matches = new Array(s2.length);
79
+ for (i = 0; i < s1.length; i++) {
80
+ var low = i >= range ? i - range : 0;
81
+ var high = i + range <= s2.length - 1 ? i + range : s2.length - 1;
82
+ for (j = low; j <= high; j++) {
83
+ if (s1Matches[i] !== true && s2Matches[j] !== true && s1[i] === s2[j]) {
84
+ ++m;
85
+ s1Matches[i] = s2Matches[j] = true;
86
+ break;
87
+ }
88
+ }
89
+ }
90
+ if (m === 0) {
91
+ return 0;
92
+ }
93
+ var k = 0;
94
+ var numTrans = 0;
95
+ for (i = 0; i < s1.length; i++) {
96
+ if (s1Matches[i] === true) {
97
+ for (j = k; j < s2.length; j++) {
98
+ if (s2Matches[j] === true) {
99
+ k = j + 1;
100
+ break;
101
+ }
102
+ }
103
+ if (s1[i] !== s2[j]) {
104
+ ++numTrans;
105
+ }
106
+ }
107
+ }
108
+ var weight = (m / s1.length + m / s2.length + (m - numTrans / 2) / m) / 3;
109
+ var l = 0;
110
+ var p = 0.1;
111
+ if (weight > 0.7) {
112
+ while (s1[l] === s2[l] && l < 4) {
113
+ ++l;
114
+ }
115
+ weight = weight + l * p * (1 - weight);
116
+ }
117
+ return weight;
118
+ }
119
+ if (typeof define === "function" && define.amd) {
120
+ define([], function() {
121
+ return distance2;
122
+ });
123
+ } else if (typeof exports === "object") {
124
+ module.exports = distance2;
125
+ } else {
126
+ root.distance = distance2;
127
+ }
128
+ })(exports);
129
+ }
130
+ });
131
+
132
+ // src/util/openapi/openapi-cache.ts
133
+ import { join } from "path";
134
+ import { readFile, writeFile, mkdir } from "fs/promises";
135
+
136
+ // src/util/openapi/constants.ts
137
+ var OPENAPI_URL = "https://openapi.vercel.sh/";
138
+ var CACHE_FILE = "openapi-spec.json";
139
+ var CACHE_TTL_MS = 24 * 60 * 60 * 1e3;
140
+ var FETCH_TIMEOUT_MS = 10 * 1e3;
141
+
142
+ // src/util/openapi/openapi-cache.ts
143
+ var OpenApiCache = class {
144
+ constructor() {
145
+ this.spec = null;
146
+ this.cachePath = join(global_path_default(), CACHE_FILE);
147
+ }
148
+ /**
149
+ * Check if the spec has been loaded
150
+ */
151
+ get isLoaded() {
152
+ return this.spec !== null;
153
+ }
154
+ /**
155
+ * Load the OpenAPI spec, using cache if available and fresh.
156
+ * Returns true if successful, false otherwise.
157
+ */
158
+ async load(forceRefresh = false) {
159
+ if (!forceRefresh) {
160
+ const cached = await this.readCache();
161
+ if (cached && !this.isExpired(cached.fetchedAt)) {
162
+ output_manager_default.debug("Using cached OpenAPI spec");
163
+ this.spec = cached.spec;
164
+ return true;
165
+ }
166
+ }
167
+ try {
168
+ output_manager_default.debug("Fetching OpenAPI spec from " + OPENAPI_URL);
169
+ this.spec = await this.fetchSpec();
170
+ await this.saveCache(this.spec);
171
+ return true;
172
+ } catch (err) {
173
+ output_manager_default.debug(`Failed to fetch OpenAPI spec: ${err}`);
174
+ const stale = await this.readCache();
175
+ if (stale) {
176
+ output_manager_default.debug("Using stale cached OpenAPI spec");
177
+ this.spec = stale.spec;
178
+ return true;
179
+ }
180
+ return false;
181
+ }
182
+ }
183
+ /**
184
+ * Load the OpenAPI spec with spinner UI.
185
+ * Returns true if successful, false otherwise.
186
+ */
187
+ async loadWithSpinner(forceRefresh = false) {
188
+ output_manager_default.spinner(
189
+ forceRefresh ? "Refreshing API endpoints..." : "Loading API endpoints..."
190
+ );
191
+ const success = await this.load(forceRefresh);
192
+ output_manager_default.stopSpinner();
193
+ return success;
194
+ }
195
+ /**
196
+ * Get all available endpoints from the loaded spec, sorted by path then method.
197
+ * Throws if spec hasn't been loaded yet.
198
+ */
199
+ getEndpoints() {
200
+ this.ensureLoaded();
201
+ const endpoints = this.extractEndpoints();
202
+ return this.sortEndpoints(endpoints);
203
+ }
204
+ /**
205
+ * Extract body fields from a requestBody schema.
206
+ * Throws if spec hasn't been loaded yet.
207
+ */
208
+ getBodyFields(endpoint) {
209
+ this.ensureLoaded();
210
+ if (!endpoint.requestBody?.content)
211
+ return [];
212
+ const jsonContent = endpoint.requestBody.content["application/json"];
213
+ if (!jsonContent?.schema)
214
+ return [];
215
+ const schema = this.resolveSchemaRef(jsonContent.schema);
216
+ if (!schema?.properties)
217
+ return [];
218
+ const requiredFields = new Set(schema.required || []);
219
+ const fields = [];
220
+ for (const [name, propSchema] of Object.entries(schema.properties)) {
221
+ const resolvedProp = this.resolveSchemaRef(propSchema);
222
+ let enumValues = resolvedProp?.enum || propSchema.enum;
223
+ if (!enumValues && (resolvedProp?.type === "array" || propSchema.type === "array")) {
224
+ const items = resolvedProp?.items || propSchema.items;
225
+ if (items) {
226
+ const resolvedItems = this.resolveSchemaRef(items);
227
+ enumValues = resolvedItems?.enum || items.enum;
228
+ }
229
+ }
230
+ fields.push({
231
+ name,
232
+ required: requiredFields.has(name),
233
+ description: resolvedProp?.description || propSchema.description,
234
+ type: resolvedProp?.type || propSchema.type,
235
+ enumValues
236
+ });
237
+ }
238
+ fields.sort((a, b) => {
239
+ if (a.required !== b.required) {
240
+ return a.required ? -1 : 1;
241
+ }
242
+ return a.name.localeCompare(b.name);
243
+ });
244
+ return fields;
245
+ }
246
+ /**
247
+ * Extract `x-vercel-cli.displayColumns` from the 200 response schema of an
248
+ * endpoint. Returns `null` when the spec has no display hint.
249
+ */
250
+ getDisplayColumns(endpoint) {
251
+ this.ensureLoaded();
252
+ const pathItem = this.spec.paths[endpoint.path];
253
+ if (!pathItem)
254
+ return null;
255
+ const operation = pathItem[endpoint.method.toLowerCase()];
256
+ if (!operation?.responses)
257
+ return null;
258
+ const ok = operation.responses["200"] || operation.responses["201"];
259
+ if (!ok)
260
+ return null;
261
+ const jsonContent = ok.content?.["application/json"];
262
+ if (!jsonContent?.schema)
263
+ return null;
264
+ return this.findDisplayColumns(jsonContent.schema);
265
+ }
266
+ findDisplayColumns(schema) {
267
+ const xCli = schema["x-vercel-cli"];
268
+ if (xCli?.displayColumns)
269
+ return xCli.displayColumns;
270
+ for (const key of ["oneOf", "allOf", "anyOf"]) {
271
+ const variants = schema[key];
272
+ if (variants) {
273
+ for (const sub of variants) {
274
+ const found = this.findDisplayColumns(sub);
275
+ if (found)
276
+ return found;
277
+ }
278
+ }
279
+ }
280
+ return null;
281
+ }
282
+ // ─────────────────────────────────────────────────────────────────────────────
283
+ // Private methods
284
+ // ─────────────────────────────────────────────────────────────────────────────
285
+ /**
286
+ * Ensure the spec is loaded before accessing it
287
+ */
288
+ ensureLoaded() {
289
+ if (!this.spec) {
290
+ throw new Error(
291
+ "OpenAPI spec not loaded. Call load() or loadWithSpinner() first."
292
+ );
293
+ }
294
+ }
295
+ /**
296
+ * Read cached spec from disk
297
+ */
298
+ async readCache() {
299
+ try {
300
+ const content = await readFile(this.cachePath, "utf-8");
301
+ return JSON.parse(content);
302
+ } catch {
303
+ return null;
304
+ }
305
+ }
306
+ /**
307
+ * Save spec to disk cache
308
+ */
309
+ async saveCache(spec) {
310
+ const cached = {
311
+ fetchedAt: Date.now(),
312
+ spec
313
+ };
314
+ const dir = join(this.cachePath, "..");
315
+ await mkdir(dir, { recursive: true });
316
+ await writeFile(this.cachePath, JSON.stringify(cached));
317
+ output_manager_default.debug("Saved OpenAPI spec to cache");
318
+ }
319
+ /**
320
+ * Fetch OpenAPI spec from remote with timeout
321
+ */
322
+ async fetchSpec() {
323
+ const controller = new AbortController();
324
+ const timeoutId = setTimeout(() => controller.abort(), FETCH_TIMEOUT_MS);
325
+ try {
326
+ const response = await fetch(OPENAPI_URL, { signal: controller.signal });
327
+ if (!response.ok) {
328
+ throw new Error(`Failed to fetch OpenAPI spec: ${response.status}`);
329
+ }
330
+ return await response.json();
331
+ } finally {
332
+ clearTimeout(timeoutId);
333
+ }
334
+ }
335
+ /**
336
+ * Check if cached spec is expired
337
+ */
338
+ isExpired(fetchedAt) {
339
+ return Date.now() - fetchedAt > CACHE_TTL_MS;
340
+ }
341
+ /**
342
+ * Sort endpoints by path, then by method
343
+ */
344
+ sortEndpoints(endpoints) {
345
+ return endpoints.sort((a, b) => {
346
+ const pathCompare = a.path.localeCompare(b.path);
347
+ if (pathCompare !== 0)
348
+ return pathCompare;
349
+ return a.method.localeCompare(b.method);
350
+ });
351
+ }
352
+ /**
353
+ * Extract all available endpoints from the spec
354
+ */
355
+ extractEndpoints() {
356
+ const endpoints = [];
357
+ for (const [path, pathItem] of Object.entries(this.spec.paths)) {
358
+ const methods = ["get", "post", "put", "patch", "delete"];
359
+ for (const method of methods) {
360
+ const operation = pathItem[method];
361
+ if (operation) {
362
+ const pathParams = pathItem.parameters || [];
363
+ const opParams = operation.parameters || [];
364
+ const allParams = [...pathParams, ...opParams];
365
+ endpoints.push({
366
+ path,
367
+ method: method.toUpperCase(),
368
+ summary: operation.summary || pathItem.summary || "",
369
+ description: operation.description || pathItem.description || "",
370
+ operationId: operation.operationId || "",
371
+ tags: operation.tags || [],
372
+ parameters: allParams,
373
+ requestBody: operation.requestBody
374
+ });
375
+ }
376
+ }
377
+ }
378
+ return endpoints;
379
+ }
380
+ /**
381
+ * Resolve a $ref to its actual schema
382
+ */
383
+ resolveSchemaRef(schema) {
384
+ if (!schema)
385
+ return void 0;
386
+ if (schema.$ref) {
387
+ const match = schema.$ref.match(/^#\/components\/schemas\/(.+)$/);
388
+ if (match && this.spec.components?.schemas) {
389
+ const resolved = this.spec.components.schemas[match[1]];
390
+ return this.resolveSchemaRef(resolved);
391
+ }
392
+ return void 0;
393
+ }
394
+ if (schema.allOf && schema.allOf.length > 0) {
395
+ const merged = { type: "object", properties: {}, required: [] };
396
+ for (const subSchema of schema.allOf) {
397
+ const resolved = this.resolveSchemaRef(subSchema);
398
+ if (resolved) {
399
+ if (resolved.properties) {
400
+ merged.properties = {
401
+ ...merged.properties,
402
+ ...resolved.properties
403
+ };
404
+ }
405
+ if (resolved.required) {
406
+ merged.required = [
407
+ ...merged.required || [],
408
+ ...resolved.required
409
+ ];
410
+ }
411
+ }
412
+ }
413
+ return merged;
414
+ }
415
+ return schema;
416
+ }
417
+ };
418
+
419
+ // src/util/openapi/matches-cli-api-tag.ts
420
+ async function matchesCliApiTag(tagHint) {
421
+ if (!tagHint || tagHint.startsWith("-") || tagHint.includes("/")) {
422
+ return false;
423
+ }
424
+ const cache = new OpenApiCache();
425
+ const loaded = await cache.load();
426
+ if (!loaded) {
427
+ return false;
428
+ }
429
+ const endpoints = cache.getEndpoints();
430
+ const lower = tagHint.toLowerCase();
431
+ return endpoints.some((ep) => ep.tags.some((t) => t.toLowerCase() === lower));
432
+ }
433
+ async function resolveOpenApiTagForProjectsCli() {
434
+ if (await matchesCliApiTag("projects")) {
435
+ return "projects";
436
+ }
437
+ if (await matchesCliApiTag("project")) {
438
+ return "project";
439
+ }
440
+ return null;
441
+ }
442
+ async function resolveOpenApiTagForTeamsCli() {
443
+ if (await matchesCliApiTag("teams")) {
444
+ return "teams";
445
+ }
446
+ if (await matchesCliApiTag("team")) {
447
+ return "team";
448
+ }
449
+ return null;
450
+ }
451
+
452
+ // src/commands/api/index.ts
453
+ var import_chalk3 = __toESM(require_source(), 1);
454
+
455
+ // src/util/telemetry/commands/api/index.ts
456
+ var ApiTelemetryClient = class extends TelemetryClient {
457
+ trackCliArgumentEndpoint(endpoint) {
458
+ if (endpoint) {
459
+ const normalized = this.normalizeEndpoint(endpoint);
460
+ this.trackCliArgument({
461
+ arg: "endpoint",
462
+ value: normalized
463
+ });
464
+ }
465
+ }
466
+ trackCliArgumentOperationId(operationId) {
467
+ if (operationId) {
468
+ this.trackCliArgument({
469
+ arg: "operationId",
470
+ value: operationId
471
+ });
472
+ }
473
+ }
474
+ trackCliOptionMethod(method) {
475
+ if (method) {
476
+ const validMethods = ["GET", "POST", "PUT", "DELETE", "PATCH", "HEAD"];
477
+ const upperMethod = method.toUpperCase();
478
+ const value = validMethods.includes(upperMethod) ? upperMethod : this.redactedValue;
479
+ this.trackCliOption({
480
+ option: "method",
481
+ value
482
+ });
483
+ }
484
+ }
485
+ trackCliOptionField(fields) {
486
+ if (fields && fields.length > 0) {
487
+ this.trackCliOption({
488
+ option: "field",
489
+ value: this.redactedArgumentsLength(fields)
490
+ });
491
+ }
492
+ }
493
+ trackCliOptionRawField(fields) {
494
+ if (fields && fields.length > 0) {
495
+ this.trackCliOption({
496
+ option: "raw-field",
497
+ value: this.redactedArgumentsLength(fields)
498
+ });
499
+ }
500
+ }
501
+ trackCliOptionHeader(headers) {
502
+ if (headers && headers.length > 0) {
503
+ this.trackCliOption({
504
+ option: "header",
505
+ value: this.redactedArgumentsLength(headers)
506
+ });
507
+ }
508
+ }
509
+ trackCliOptionInput(input) {
510
+ if (input) {
511
+ const value = input === "-" ? "stdin" : "file";
512
+ this.trackCliOption({
513
+ option: "input",
514
+ value
515
+ });
516
+ }
517
+ }
518
+ trackCliFlagPaginate(value) {
519
+ if (value) {
520
+ this.trackCliFlag("paginate");
521
+ }
522
+ }
523
+ trackCliFlagInclude(value) {
524
+ if (value) {
525
+ this.trackCliFlag("include");
526
+ }
527
+ }
528
+ trackCliFlagSilent(value) {
529
+ if (value) {
530
+ this.trackCliFlag("silent");
531
+ }
532
+ }
533
+ trackCliFlagVerbose(value) {
534
+ if (value) {
535
+ this.trackCliFlag("verbose");
536
+ }
537
+ }
538
+ trackCliFlagRaw(value) {
539
+ if (value) {
540
+ this.trackCliFlag("raw");
541
+ }
542
+ }
543
+ trackCliFlagRefresh(value) {
544
+ if (value) {
545
+ this.trackCliFlag("refresh");
546
+ }
547
+ }
548
+ trackCliOptionGenerate(format) {
549
+ if (format) {
550
+ const validFormats = ["curl"];
551
+ const value = validFormats.includes(format) ? format : this.redactedValue;
552
+ this.trackCliOption({
553
+ option: "generate",
554
+ value
555
+ });
556
+ }
557
+ }
558
+ trackCliFlagDangerouslySkipPermissions(value) {
559
+ if (value) {
560
+ this.trackCliFlag("dangerously-skip-permissions");
561
+ }
562
+ }
563
+ trackCliSubcommandList() {
564
+ this.trackCliSubcommand({ subcommand: "list", value: "list" });
565
+ }
566
+ trackCliOptionFormat(format) {
567
+ if (format) {
568
+ const validFormats = ["table", "json"];
569
+ const value = validFormats.includes(format) ? format : this.redactedValue;
570
+ this.trackCliOption({
571
+ option: "format",
572
+ value
573
+ });
574
+ }
575
+ }
576
+ /**
577
+ * Normalize endpoint by replacing IDs with placeholders for privacy
578
+ */
579
+ normalizeEndpoint(endpoint) {
580
+ return endpoint.replace(/\/dpl_[a-zA-Z0-9]+/g, "/:deploymentId").replace(/\/prj_[a-zA-Z0-9]+/g, "/:projectId").replace(/\/team_[a-zA-Z0-9]+/g, "/:teamId").replace(/\/[a-f0-9]{24}/g, "/:id").replace(/\/[a-f0-9-]{36}/g, "/:uuid");
581
+ }
582
+ };
583
+
584
+ // src/commands/api/request-builder.ts
585
+ import { readFile as readFile2 } from "fs/promises";
586
+ import { resolve } from "path";
587
+ async function buildRequest(endpoint, flags) {
588
+ const headers = {};
589
+ let body;
590
+ const customHeaders = flags["--header"] || [];
591
+ for (const header of customHeaders) {
592
+ const colonIndex = header.indexOf(":");
593
+ if (colonIndex > 0) {
594
+ const key = header.substring(0, colonIndex).trim();
595
+ const value = header.substring(colonIndex + 1).trim();
596
+ headers[key] = value;
597
+ }
598
+ }
599
+ const fields = flags["--field"] || [];
600
+ const rawFields = flags["--raw-field"] || [];
601
+ if (fields.length > 0 || rawFields.length > 0) {
602
+ body = {};
603
+ for (const field of fields) {
604
+ const { key, value } = await parseField(field, true);
605
+ body[key] = value;
606
+ }
607
+ for (const field of rawFields) {
608
+ const { key, value } = await parseField(field, false);
609
+ body[key] = value;
610
+ }
611
+ }
612
+ if (flags["--input"]) {
613
+ const inputPath = flags["--input"];
614
+ if (inputPath === "-") {
615
+ body = await readStdin();
616
+ } else {
617
+ body = await readFile2(resolve(inputPath), "utf-8");
618
+ }
619
+ if (typeof body === "string") {
620
+ try {
621
+ body = JSON.parse(body);
622
+ } catch {
623
+ }
624
+ }
625
+ }
626
+ let method = flags["--method"]?.toUpperCase() || "GET";
627
+ if (!flags["--method"] && body) {
628
+ method = "POST";
629
+ }
630
+ return {
631
+ url: endpoint,
632
+ method,
633
+ headers,
634
+ body
635
+ };
636
+ }
637
+ async function parseCliKeyValueField(field, typed) {
638
+ return parseField(field, typed);
639
+ }
640
+ async function parseField(field, typed) {
641
+ const eqIndex = field.indexOf("=");
642
+ if (eqIndex === -1) {
643
+ throw new Error(`Invalid field format: ${field}. Expected key=value`);
644
+ }
645
+ const key = field.substring(0, eqIndex);
646
+ let value = field.substring(eqIndex + 1);
647
+ if (typed && typeof value === "string") {
648
+ if (value.startsWith("@")) {
649
+ const filePath = value.substring(1);
650
+ if (filePath === "-") {
651
+ value = await readStdin();
652
+ } else {
653
+ value = await readFile2(resolve(filePath), "utf-8");
654
+ }
655
+ if (typeof value === "string") {
656
+ try {
657
+ value = JSON.parse(value);
658
+ } catch {
659
+ }
660
+ }
661
+ } else if (value === "true") {
662
+ value = true;
663
+ } else if (value === "false") {
664
+ value = false;
665
+ } else if (value === "null") {
666
+ value = null;
667
+ } else if (/^-?\d+$/.test(value)) {
668
+ value = parseInt(value, 10);
669
+ } else if (/^-?\d*\.\d+$/.test(value)) {
670
+ value = parseFloat(value);
671
+ } else if (value.startsWith("[") || value.startsWith("{")) {
672
+ try {
673
+ value = JSON.parse(value);
674
+ } catch {
675
+ }
676
+ }
677
+ }
678
+ return { key, value };
679
+ }
680
+ async function readStdin() {
681
+ const chunks = [];
682
+ for await (const chunk of process.stdin) {
683
+ chunks.push(Buffer.from(chunk));
684
+ }
685
+ return Buffer.concat(chunks).toString(
686
+ "utf-8"
687
+ );
688
+ }
689
+ function formatOutput(data, options) {
690
+ if (options.raw) {
691
+ if (typeof data === "string") {
692
+ return data;
693
+ }
694
+ return JSON.stringify(data);
695
+ }
696
+ return JSON.stringify(data, null, 2);
697
+ }
698
+ function generateCurlCommand(config, baseUrl) {
699
+ const parts = ["curl"];
700
+ if (config.method !== "GET") {
701
+ parts.push(`-X ${config.method}`);
702
+ }
703
+ parts.push(`-H 'Authorization: Bearer <TOKEN>'`);
704
+ for (const [key, value] of Object.entries(config.headers)) {
705
+ parts.push(`-H '${key}: ${escapeShellArg(value)}'`);
706
+ }
707
+ if (config.body) {
708
+ const bodyStr = typeof config.body === "string" ? config.body : JSON.stringify(config.body);
709
+ parts.push(`-H 'Content-Type: application/json'`);
710
+ parts.push(`-d '${escapeShellArg(bodyStr)}'`);
711
+ }
712
+ const fullUrl = `${baseUrl}${config.url}`;
713
+ parts.push(`'${fullUrl}'`);
714
+ return parts.join(" \\\n ");
715
+ }
716
+ function escapeShellArg(str) {
717
+ return str.replace(/'/g, "'\\''");
718
+ }
719
+
720
+ // src/commands/api/operation-request-builder.ts
721
+ import { readFile as readFile3 } from "fs/promises";
722
+ import { resolve as resolve2 } from "path";
723
+ var GLOBAL_CLI_QUERY_PARAMS = /* @__PURE__ */ new Set(["teamId", "slug"]);
724
+ async function parseOperationKeyValuePairs(endpoint, bodyFields, flags, positionalKeyValues) {
725
+ const pathParamNames = new Set(
726
+ endpoint.parameters.filter((p) => p.in === "path").map((p) => p.name)
727
+ );
728
+ const queryParamNames = new Set(
729
+ endpoint.parameters.filter((p) => p.in === "query").map((p) => p.name)
730
+ );
731
+ const headerParamNames = new Set(
732
+ endpoint.parameters.filter((p) => p.in === "header").map((p) => p.name)
733
+ );
734
+ const bodyFieldNames = new Set(bodyFields.map((f) => f.name));
735
+ const pathValues = {};
736
+ const queryValues = {};
737
+ const headerValues = {};
738
+ const body = {};
739
+ async function dispatchPair(field, typed) {
740
+ const eqIndex = field.indexOf("=");
741
+ if (eqIndex === -1) {
742
+ throw new Error(
743
+ `Invalid option "${field}". Expected key=value (or use flags -F / -f).`
744
+ );
745
+ }
746
+ const key = field.slice(0, eqIndex);
747
+ const param = endpoint.parameters.find((p) => p.name === key);
748
+ if (param?.in === "path") {
749
+ const { value } = await parseCliKeyValueField(field, false);
750
+ pathValues[key] = String(value);
751
+ return;
752
+ }
753
+ if (param?.in === "query") {
754
+ const { value } = await parseCliKeyValueField(field, typed);
755
+ queryValues[key] = typeof value === "object" && value !== null ? JSON.stringify(value) : String(value);
756
+ return;
757
+ }
758
+ if (param?.in === "header") {
759
+ const { value } = await parseCliKeyValueField(field, false);
760
+ headerValues[key] = String(value);
761
+ return;
762
+ }
763
+ if (param?.in === "cookie") {
764
+ throw new Error(
765
+ `Option "${key}" is cookie-based; set it via headers instead.`
766
+ );
767
+ }
768
+ if (bodyFieldNames.has(key)) {
769
+ const { value } = await parseCliKeyValueField(field, typed);
770
+ body[key] = value;
771
+ return;
772
+ }
773
+ if (!param && pathParamNames.has(key)) {
774
+ const { value } = await parseCliKeyValueField(field, false);
775
+ pathValues[key] = String(value);
776
+ return;
777
+ }
778
+ if (!param && queryParamNames.has(key)) {
779
+ const { value } = await parseCliKeyValueField(field, typed);
780
+ queryValues[key] = typeof value === "object" && value !== null ? JSON.stringify(value) : String(value);
781
+ return;
782
+ }
783
+ if (!param && headerParamNames.has(key)) {
784
+ const { value } = await parseCliKeyValueField(field, false);
785
+ headerValues[key] = String(value);
786
+ return;
787
+ }
788
+ throw new Error(
789
+ `Unknown option "${key}" for operation ${endpoint.operationId}. Check the API docs or run \`vercel api ls --format json\`.`
790
+ );
791
+ }
792
+ for (const field of flags["--field"] || []) {
793
+ await dispatchPair(field, true);
794
+ }
795
+ for (const field of flags["--raw-field"] || []) {
796
+ await dispatchPair(field, false);
797
+ }
798
+ for (const field of positionalKeyValues) {
799
+ await dispatchPair(field, true);
800
+ }
801
+ return { pathValues, queryValues, headerValues, body };
802
+ }
803
+ function getMissingRequiredOperationParams(endpoint, bodyFields, parsed, flags) {
804
+ const pathParams = endpoint.parameters.filter((p) => p.in === "path");
805
+ const missingPath = pathParams.filter(
806
+ (p) => parsed.pathValues[p.name] === void 0
807
+ );
808
+ const requiredQuery = endpoint.parameters.filter(
809
+ (p) => p.in === "query" && p.required && !GLOBAL_CLI_QUERY_PARAMS.has(p.name)
810
+ );
811
+ const missingQuery = requiredQuery.filter(
812
+ (p) => parsed.queryValues[p.name] === void 0
813
+ );
814
+ const requiredHeader = endpoint.parameters.filter(
815
+ (p) => p.in === "header" && p.required
816
+ );
817
+ const missingHeader = requiredHeader.filter(
818
+ (p) => parsed.headerValues[p.name] === void 0
819
+ );
820
+ const missingBody = bodyFields.filter(
821
+ (f) => f.required && parsed.body[f.name] === void 0 && !flags["--input"]
822
+ );
823
+ return {
824
+ path: missingPath,
825
+ query: missingQuery,
826
+ header: missingHeader,
827
+ body: missingBody
828
+ };
829
+ }
830
+ function getUnsetOptionalOperationParams(endpoint, bodyFields, parsed, flags) {
831
+ const unsetQuery = endpoint.parameters.filter(
832
+ (p) => p.in === "query" && parsed.queryValues[p.name] === void 0 && (!p.required || GLOBAL_CLI_QUERY_PARAMS.has(p.name))
833
+ );
834
+ const unsetHeader = endpoint.parameters.filter(
835
+ (p) => p.in === "header" && !p.required && parsed.headerValues[p.name] === void 0
836
+ );
837
+ const unsetBody = bodyFields.filter(
838
+ (f) => !f.required && parsed.body[f.name] === void 0 && !flags["--input"]
839
+ );
840
+ return {
841
+ query: unsetQuery,
842
+ header: unsetHeader,
843
+ body: unsetBody
844
+ };
845
+ }
846
+ async function buildRequestForResolvedOperation(endpoint, bodyFields, flags, positionalKeyValues) {
847
+ const headers = {};
848
+ const customHeaders = flags["--header"] || [];
849
+ for (const header of customHeaders) {
850
+ const colonIndex = header.indexOf(":");
851
+ if (colonIndex > 0) {
852
+ const key = header.substring(0, colonIndex).trim();
853
+ const value = header.substring(colonIndex + 1).trim();
854
+ headers[key] = value;
855
+ }
856
+ }
857
+ const method = (flags["--method"]?.toUpperCase() || endpoint.method).toUpperCase();
858
+ const pathParamNames = new Set(
859
+ endpoint.parameters.filter((p) => p.in === "path").map((p) => p.name)
860
+ );
861
+ const parsed = await parseOperationKeyValuePairs(
862
+ endpoint,
863
+ bodyFields,
864
+ flags,
865
+ positionalKeyValues
866
+ );
867
+ const { pathValues, queryValues, headerValues, body } = parsed;
868
+ for (const [k, v] of Object.entries(headerValues)) {
869
+ headers[k] = v;
870
+ }
871
+ let urlPath = endpoint.path;
872
+ for (const name of pathParamNames) {
873
+ const value = pathValues[name];
874
+ if (value === void 0) {
875
+ throw new Error(
876
+ `Missing required path option {${name}} for ${endpoint.operationId}.`
877
+ );
878
+ }
879
+ urlPath = urlPath.replace(`{${name}}`, encodeURIComponent(value));
880
+ }
881
+ if (/\{[^}]+\}/.test(urlPath)) {
882
+ throw new Error(
883
+ `Unresolved path placeholders in ${urlPath}. Provide values for all path options.`
884
+ );
885
+ }
886
+ const requiredQuery = endpoint.parameters.filter(
887
+ (p) => p.in === "query" && p.required && !GLOBAL_CLI_QUERY_PARAMS.has(p.name)
888
+ );
889
+ for (const p of requiredQuery) {
890
+ if (queryValues[p.name] === void 0) {
891
+ throw new Error(
892
+ `Missing required query option "${p.name}" for ${endpoint.operationId}.`
893
+ );
894
+ }
895
+ }
896
+ const requiredHeader = endpoint.parameters.filter(
897
+ (h) => h.in === "header" && h.required
898
+ );
899
+ for (const h of requiredHeader) {
900
+ if (headerValues[h.name] === void 0) {
901
+ throw new Error(
902
+ `Missing required header option "${h.name}" for ${endpoint.operationId}.`
903
+ );
904
+ }
905
+ }
906
+ const requiredBody = bodyFields.filter((f) => f.required);
907
+ for (const f of requiredBody) {
908
+ if (body[f.name] === void 0 && !flags["--input"]) {
909
+ throw new Error(
910
+ `Missing required body option "${f.name}" for ${endpoint.operationId}.`
911
+ );
912
+ }
913
+ }
914
+ const queryString = new URLSearchParams(queryValues).toString();
915
+ if (queryString) {
916
+ urlPath += (urlPath.includes("?") ? "&" : "?") + queryString;
917
+ }
918
+ let finalBody = Object.keys(body).length > 0 ? body : void 0;
919
+ if (flags["--input"]) {
920
+ const inputPath = flags["--input"];
921
+ let inputBody;
922
+ if (inputPath === "-") {
923
+ inputBody = await readStdin();
924
+ } else {
925
+ inputBody = await readFile3(resolve2(inputPath), "utf-8");
926
+ }
927
+ if (typeof inputBody === "string") {
928
+ try {
929
+ finalBody = JSON.parse(inputBody);
930
+ } catch {
931
+ finalBody = inputBody;
932
+ }
933
+ } else {
934
+ finalBody = inputBody;
935
+ }
936
+ }
937
+ if (method === "GET" || method === "HEAD") {
938
+ finalBody = void 0;
939
+ }
940
+ return {
941
+ url: urlPath,
942
+ method,
943
+ headers,
944
+ body: finalBody
945
+ };
946
+ }
947
+
948
+ // src/util/openapi/resolve-by-tag-operation.ts
949
+ function resolveEndpointByTagAndOperationId(endpoints, tag, operationHint) {
950
+ const tagLower = tag.toLowerCase();
951
+ const tagMatches = endpoints.filter(
952
+ (ep) => ep.tags.some((t) => t.toLowerCase() === tagLower)
953
+ );
954
+ if (tagMatches.length === 0) {
955
+ return {
956
+ ok: false,
957
+ reason: "no_tag",
958
+ tag,
959
+ tagMatches: [],
960
+ operationHint
961
+ };
962
+ }
963
+ const withOpId = tagMatches.filter((ep) => ep.operationId.length > 0);
964
+ if (withOpId.length === 0) {
965
+ return {
966
+ ok: false,
967
+ reason: "no_operation",
968
+ tag,
969
+ tagMatches,
970
+ operationHint
971
+ };
972
+ }
973
+ const hint = operationHint.trim();
974
+ const hintLower = hint.toLowerCase();
975
+ const exact = withOpId.filter((ep) => ep.operationId === hint);
976
+ if (exact.length === 1) {
977
+ return { ok: true, endpoint: exact[0] };
978
+ }
979
+ if (exact.length > 1) {
980
+ return {
981
+ ok: false,
982
+ reason: "ambiguous_operation",
983
+ tag,
984
+ tagMatches: exact,
985
+ operationHint: hint
986
+ };
987
+ }
988
+ const exactCi = withOpId.filter(
989
+ (ep) => ep.operationId.toLowerCase() === hintLower
990
+ );
991
+ if (exactCi.length === 1) {
992
+ return { ok: true, endpoint: exactCi[0] };
993
+ }
994
+ if (exactCi.length > 1) {
995
+ return {
996
+ ok: false,
997
+ reason: "ambiguous_operation",
998
+ tag,
999
+ tagMatches: exactCi,
1000
+ operationHint: hint
1001
+ };
1002
+ }
1003
+ return {
1004
+ ok: false,
1005
+ reason: "no_operation",
1006
+ tag,
1007
+ tagMatches,
1008
+ operationHint: hint
1009
+ };
1010
+ }
1011
+
1012
+ // src/util/openapi/try-openapi-fallback.ts
1013
+ async function tryOpenApiFallback(client, cliArgs, resolveTag) {
1014
+ if (!process.env.VERCEL_AUTO_API) {
1015
+ return null;
1016
+ }
1017
+ const operationHint = cliArgs[0];
1018
+ if (!operationHint || operationHint.startsWith("-")) {
1019
+ return null;
1020
+ }
1021
+ const tag = await resolveTag();
1022
+ if (!tag) {
1023
+ return null;
1024
+ }
1025
+ const apiFlagsSpec = getFlagsSpecification(apiCommand.options);
1026
+ let apiParsed;
1027
+ try {
1028
+ apiParsed = parseArguments(client.argv.slice(2), apiFlagsSpec, {
1029
+ permissive: true
1030
+ });
1031
+ } catch {
1032
+ return null;
1033
+ }
1034
+ const flags = apiParsed.flags;
1035
+ if (flags["--dangerously-skip-permissions"]) {
1036
+ client.dangerouslySkipPermissions = true;
1037
+ }
1038
+ if (flags["--help"]) {
1039
+ return printOperationHelpForTagCommand(flags, tag, operationHint);
1040
+ }
1041
+ return runTagOperation(client, {
1042
+ tag,
1043
+ operationId: operationHint,
1044
+ flags,
1045
+ positionalOperationFields: cliArgs.slice(1)
1046
+ });
1047
+ }
1048
+
1049
+ // src/commands/api/constants.ts
1050
+ var API_BASE_URL = "https://api.vercel.com";
1051
+
1052
+ // src/commands/api/format-utils.ts
1053
+ var import_chalk = __toESM(require_source(), 1);
1054
+ function colorizeMethod(method) {
1055
+ switch (method) {
1056
+ case "GET":
1057
+ return import_chalk.default.cyan(method);
1058
+ case "POST":
1059
+ return import_chalk.default.green(method);
1060
+ case "PUT":
1061
+ return import_chalk.default.yellow(method);
1062
+ case "PATCH":
1063
+ return import_chalk.default.blue(method);
1064
+ case "DELETE":
1065
+ return import_chalk.default.red(method);
1066
+ default:
1067
+ return method;
1068
+ }
1069
+ }
1070
+ function colorizeMethodPadded(method, width = 7) {
1071
+ const colored = colorizeMethod(method);
1072
+ const padding = " ".repeat(Math.max(0, width - method.length));
1073
+ return colored + padding;
1074
+ }
1075
+ function formatPathParam(paramName) {
1076
+ return import_chalk.default.cyan(`{${paramName}}`);
1077
+ }
1078
+ function formatTypeHint(type) {
1079
+ return import_chalk.default.dim(`[${type}]`);
1080
+ }
1081
+ function formatDescription(description) {
1082
+ if (!description)
1083
+ return "";
1084
+ return import_chalk.default.gray(` (${description})`);
1085
+ }
1086
+
1087
+ // src/commands/api/display-columns.ts
1088
+ var import_chalk2 = __toESM(require_source(), 1);
1089
+ function getByPath(obj, path) {
1090
+ let current = obj;
1091
+ for (const segment of path.split(".")) {
1092
+ if (current == null || typeof current !== "object")
1093
+ return void 0;
1094
+ current = current[segment];
1095
+ }
1096
+ return current;
1097
+ }
1098
+ function parseArrayColumns(data, columns) {
1099
+ const entries = Object.entries(columns);
1100
+ const first = entries[0];
1101
+ if (!first)
1102
+ return null;
1103
+ const bracketIdx = first[1].indexOf("[].");
1104
+ if (bracketIdx === -1)
1105
+ return null;
1106
+ const arrayKey = first[1].slice(0, bracketIdx);
1107
+ const rowColumns = {};
1108
+ for (const [label, path] of entries) {
1109
+ const prefix = path.slice(0, bracketIdx);
1110
+ if (prefix !== arrayKey || !path.startsWith(prefix + "[].")) {
1111
+ return null;
1112
+ }
1113
+ rowColumns[label] = path.slice(bracketIdx + 3);
1114
+ }
1115
+ const arr = getByPath(data, arrayKey);
1116
+ if (!Array.isArray(arr))
1117
+ return null;
1118
+ return { rows: arr, rowColumns };
1119
+ }
1120
+ function formatValue(value) {
1121
+ if (value === null || value === void 0)
1122
+ return import_chalk2.default.dim("\u2013");
1123
+ if (typeof value === "number") {
1124
+ if (value > 1e12 && value < 2e12) {
1125
+ return new Date(value).toISOString();
1126
+ }
1127
+ return String(value);
1128
+ }
1129
+ if (typeof value === "boolean")
1130
+ return String(value);
1131
+ if (typeof value === "string")
1132
+ return value;
1133
+ return JSON.stringify(value);
1134
+ }
1135
+ function renderCard(data, columns) {
1136
+ const entries = Object.entries(columns);
1137
+ const maxLabel = Math.max(...entries.map(([label]) => label.length));
1138
+ const lines = entries.map(([label, path]) => {
1139
+ const value = getByPath(data, path);
1140
+ return ` ${import_chalk2.default.gray(label.padEnd(maxLabel))} ${formatValue(value)}`;
1141
+ });
1142
+ return lines.join("\n");
1143
+ }
1144
+ function renderTable(rows, columns) {
1145
+ const entries = Object.entries(columns);
1146
+ const headerRow = entries.map(([label]) => label);
1147
+ const dataRows = rows.map(
1148
+ (row) => entries.map(([, path]) => formatValue(getByPath(row, path)))
1149
+ );
1150
+ const widths = entries.map(([label], colIdx) => {
1151
+ const dataMax = dataRows.reduce(
1152
+ (max, row) => Math.max(max, stripAnsi(row[colIdx]).length),
1153
+ 0
1154
+ );
1155
+ return Math.max(label.length, dataMax);
1156
+ });
1157
+ const header = headerRow.map((h, i) => import_chalk2.default.bold(h.padEnd(widths[i]))).join(" ");
1158
+ const body = dataRows.map(
1159
+ (row) => row.map((cell, i) => {
1160
+ const pad = widths[i] - stripAnsi(cell).length;
1161
+ return cell + " ".repeat(Math.max(0, pad));
1162
+ }).join(" ")
1163
+ );
1164
+ return [header, ...body].join("\n");
1165
+ }
1166
+ function stripAnsi(str) {
1167
+ return str.replace(/\x1b\[[0-9;]*m/g, "");
1168
+ }
1169
+
1170
+ // src/commands/api/index.ts
1171
+ async function api(client) {
1172
+ const telemetryClient = new ApiTelemetryClient({
1173
+ opts: { store: client.telemetryEventStore }
1174
+ });
1175
+ let parsedArgs;
1176
+ const flagsSpec = getFlagsSpecification(apiCommand.options);
1177
+ try {
1178
+ parsedArgs = parseArguments(client.argv.slice(2), flagsSpec, {
1179
+ permissive: true
1180
+ });
1181
+ } catch (err) {
1182
+ printError(err);
1183
+ return 1;
1184
+ }
1185
+ const { args, flags } = parsedArgs;
1186
+ const needHelp = flags["--help"];
1187
+ const firstArg = args[1];
1188
+ if (firstArg === "ls" || firstArg === "list") {
1189
+ const lsFlagsSpec = getFlagsSpecification(listSubcommand.options);
1190
+ let lsParsedArgs;
1191
+ try {
1192
+ lsParsedArgs = parseArguments(client.argv.slice(2), lsFlagsSpec);
1193
+ } catch (err) {
1194
+ printError(err);
1195
+ return 1;
1196
+ }
1197
+ const lsFlags = lsParsedArgs.flags;
1198
+ if (lsFlags["--help"]) {
1199
+ telemetryClient.trackCliFlagHelp("api", firstArg);
1200
+ output_manager_default.print(
1201
+ help(listSubcommand, {
1202
+ parent: apiCommand,
1203
+ columns: client.stderr.columns
1204
+ })
1205
+ );
1206
+ return 2;
1207
+ }
1208
+ telemetryClient.trackCliSubcommandList();
1209
+ if (lsFlags["--refresh"])
1210
+ telemetryClient.trackCliFlagRefresh(true);
1211
+ if (lsFlags["--format"])
1212
+ telemetryClient.trackCliOptionFormat(lsFlags["--format"]);
1213
+ return listEndpoints(
1214
+ client,
1215
+ lsFlags["--refresh"] ?? false,
1216
+ lsFlags["--format"] ?? "table"
1217
+ );
1218
+ }
1219
+ if (needHelp) {
1220
+ telemetryClient.trackCliFlagHelp("api");
1221
+ output_manager_default.print(help(apiCommand, { columns: client.stderr.columns }));
1222
+ return 2;
1223
+ }
1224
+ if (flags["--dangerously-skip-permissions"]) {
1225
+ client.dangerouslySkipPermissions = true;
1226
+ }
1227
+ let endpoint;
1228
+ let selectedMethod;
1229
+ let selectedBodyFields = [];
1230
+ if (!firstArg) {
1231
+ if (client.stdin.isTTY) {
1232
+ const selected = await promptEndpointSelection(
1233
+ client,
1234
+ flags["--refresh"] ?? false
1235
+ );
1236
+ if (!selected) {
1237
+ return 1;
1238
+ }
1239
+ endpoint = selected.finalUrl;
1240
+ selectedMethod = selected.method;
1241
+ selectedBodyFields = selected.bodyFields;
1242
+ } else {
1243
+ output_manager_default.error("Endpoint is required. Usage: vercel api <endpoint>");
1244
+ return 1;
1245
+ }
1246
+ } else {
1247
+ endpoint = firstArg;
1248
+ }
1249
+ if (endpoint && !endpoint.startsWith("/")) {
1250
+ output_manager_default.error(
1251
+ `Invalid arguments. Use an API path starting with /, or run \`${packageName} api\` interactively.`
1252
+ );
1253
+ return 1;
1254
+ }
1255
+ try {
1256
+ const resolvedUrl = new URL(endpoint, API_BASE_URL);
1257
+ if (resolvedUrl.origin !== API_BASE_URL) {
1258
+ output_manager_default.error(
1259
+ "Invalid endpoint: must be a Vercel API path, not an external URL"
1260
+ );
1261
+ return 1;
1262
+ }
1263
+ } catch {
1264
+ output_manager_default.error("Invalid endpoint URL format");
1265
+ return 1;
1266
+ }
1267
+ const finalFlags = { ...flags };
1268
+ if (selectedMethod && !flags["--method"]) {
1269
+ finalFlags["--method"] = selectedMethod;
1270
+ }
1271
+ if (selectedBodyFields.length > 0) {
1272
+ const existingFields = finalFlags["--field"] || [];
1273
+ finalFlags["--field"] = [...existingFields, ...selectedBodyFields];
1274
+ }
1275
+ let requestConfig;
1276
+ try {
1277
+ requestConfig = await buildRequest(endpoint, finalFlags);
1278
+ } catch (err) {
1279
+ printError(err);
1280
+ return 1;
1281
+ }
1282
+ telemetryClient.trackCliArgumentEndpoint(requestConfig.url);
1283
+ telemetryClient.trackCliArgumentOperationId(void 0);
1284
+ telemetryClient.trackCliOptionMethod(flags["--method"]);
1285
+ telemetryClient.trackCliOptionHeader(flags["--header"]);
1286
+ telemetryClient.trackCliOptionInput(flags["--input"]);
1287
+ if (flags["--paginate"])
1288
+ telemetryClient.trackCliFlagPaginate(true);
1289
+ if (flags["--include"])
1290
+ telemetryClient.trackCliFlagInclude(true);
1291
+ if (flags["--silent"])
1292
+ telemetryClient.trackCliFlagSilent(true);
1293
+ if (flags["--verbose"])
1294
+ telemetryClient.trackCliFlagVerbose(true);
1295
+ if (flags["--raw"])
1296
+ telemetryClient.trackCliFlagRaw(true);
1297
+ if (flags["--refresh"])
1298
+ telemetryClient.trackCliFlagRefresh(true);
1299
+ if (flags["--generate"])
1300
+ telemetryClient.trackCliOptionGenerate(flags["--generate"]);
1301
+ if (flags["--dangerously-skip-permissions"])
1302
+ telemetryClient.trackCliFlagDangerouslySkipPermissions(true);
1303
+ if (flags["--generate"] === "curl") {
1304
+ const curlCmd = generateCurlCommand(
1305
+ requestConfig,
1306
+ "https://api.vercel.com"
1307
+ );
1308
+ output_manager_default.log("");
1309
+ output_manager_default.log("Replace <TOKEN> with your auth token:");
1310
+ output_manager_default.log("");
1311
+ client.stdout.write(curlCmd + "\n");
1312
+ return 0;
1313
+ }
1314
+ return executeApiRequest(client, requestConfig, finalFlags);
1315
+ }
1316
+ async function printOperationHelpForTagCommand(flags, tag, operationId) {
1317
+ const openApi = new OpenApiCache();
1318
+ const loaded = await openApi.loadWithSpinner(flags["--refresh"] ?? false);
1319
+ if (!loaded) {
1320
+ output_manager_default.error("Could not load API specification");
1321
+ return 1;
1322
+ }
1323
+ const allEndpoints = openApi.getEndpoints();
1324
+ const resolved = resolveEndpointByTagAndOperationId(
1325
+ allEndpoints,
1326
+ tag,
1327
+ operationId
1328
+ );
1329
+ if (!resolved.ok) {
1330
+ printTagOperationResolveError(resolved, allEndpoints);
1331
+ return 1;
1332
+ }
1333
+ const ep = resolved.endpoint;
1334
+ const bodyFields = openApi.getBodyFields(ep);
1335
+ printOperationHelpDetails(ep, bodyFields, tag);
1336
+ return 2;
1337
+ }
1338
+ function printOperationHelpDetails(ep, bodyFields, tag) {
1339
+ const lines = [];
1340
+ lines.push("");
1341
+ lines.push(import_chalk3.default.bold(ep.operationId || "(operation)"));
1342
+ const blurb = ep.summary?.trim() || ep.description?.trim();
1343
+ if (blurb) {
1344
+ lines.push("");
1345
+ lines.push(import_chalk3.default.dim(blurb));
1346
+ }
1347
+ lines.push("");
1348
+ lines.push(import_chalk3.default.bold("Options"));
1349
+ lines.push("");
1350
+ const pathParams = ep.parameters.filter((p) => p.in === "path");
1351
+ const orderedParams = [
1352
+ ...pathParams,
1353
+ ...ep.parameters.filter((p) => p.in === "query"),
1354
+ ...ep.parameters.filter((p) => p.in === "header"),
1355
+ ...ep.parameters.filter((p) => p.in === "cookie")
1356
+ ];
1357
+ for (const p of orderedParams) {
1358
+ const globalNote = p.in === "query" && GLOBAL_CLI_QUERY_PARAMS.has(p.name) ? import_chalk3.default.dim(" (often set via --scope)") : "";
1359
+ let reqLabel;
1360
+ if (p.in === "query") {
1361
+ reqLabel = p.required && !GLOBAL_CLI_QUERY_PARAMS.has(p.name) ? import_chalk3.default.red("required") : import_chalk3.default.dim("optional");
1362
+ } else if (p.in === "path") {
1363
+ reqLabel = p.required !== false ? import_chalk3.default.red("required") : import_chalk3.default.dim("optional");
1364
+ } else if (p.in === "header") {
1365
+ reqLabel = p.required ? import_chalk3.default.red("required") : import_chalk3.default.dim("optional");
1366
+ } else {
1367
+ reqLabel = p.required ? import_chalk3.default.red("required") : import_chalk3.default.dim("optional");
1368
+ }
1369
+ lines.push(
1370
+ ` ${import_chalk3.default.cyan(p.name)} ${reqLabel}${globalNote}${formatDescription(p.description)}`
1371
+ );
1372
+ }
1373
+ for (const f of bodyFields) {
1374
+ const req = f.required ? import_chalk3.default.red("required") : import_chalk3.default.dim("optional");
1375
+ const typeHint = f.type ? ` ${formatTypeHint(f.type)}` : "";
1376
+ lines.push(
1377
+ ` ${import_chalk3.default.cyan(f.name)} ${req}${typeHint}${formatDescription(f.description)}`
1378
+ );
1379
+ }
1380
+ if (orderedParams.length === 0 && bodyFields.length === 0) {
1381
+ lines.push(import_chalk3.default.dim(" (none)"));
1382
+ }
1383
+ lines.push("");
1384
+ lines.push(import_chalk3.default.bold("Example"));
1385
+ const exampleSuffix = pathParams.length > 0 ? ` ${pathParams.map((p) => `${p.name}=<value>`).join(" ")}` : "";
1386
+ lines.push(
1387
+ import_chalk3.default.dim(` ${packageName} api ${tag} ${ep.operationId}${exampleSuffix}`)
1388
+ );
1389
+ lines.push("");
1390
+ output_manager_default.print(lines.join("\n"));
1391
+ }
1392
+ function printMissingOperationParamsHelp(endpoint, missing) {
1393
+ output_manager_default.error(
1394
+ `Missing required options for operation ${import_chalk3.default.bold(endpoint.operationId)}.`
1395
+ );
1396
+ output_manager_default.log(
1397
+ import_chalk3.default.dim(
1398
+ `Pass each as key=value after the operationId, or use -F key=value. Example: \`${packageName} api ${endpoint.tags[0] ?? "tag"} ${endpoint.operationId} idOrName=my-project\``
1399
+ )
1400
+ );
1401
+ output_manager_default.log("");
1402
+ output_manager_default.log(import_chalk3.default.bold("Options"));
1403
+ output_manager_default.log("");
1404
+ for (const p of missing.path) {
1405
+ output_manager_default.log(` ${import_chalk3.default.cyan(p.name)}${formatDescription(p.description)}`);
1406
+ }
1407
+ for (const p of missing.header) {
1408
+ output_manager_default.log(` ${import_chalk3.default.cyan(p.name)}${formatDescription(p.description)}`);
1409
+ }
1410
+ for (const p of missing.query) {
1411
+ output_manager_default.log(` ${import_chalk3.default.cyan(p.name)}${formatDescription(p.description)}`);
1412
+ }
1413
+ for (const f of missing.body) {
1414
+ const typeHint = f.type ? ` ${formatTypeHint(f.type)}` : "";
1415
+ output_manager_default.log(
1416
+ ` ${import_chalk3.default.cyan(f.name)}${typeHint}${formatDescription(f.description)}`
1417
+ );
1418
+ }
1419
+ output_manager_default.log("");
1420
+ }
1421
+ async function promptMissingParamsForTagOperation(client, endpoint, bodyFields, flags, positionalKeyValues) {
1422
+ const pos = [...positionalKeyValues];
1423
+ while (true) {
1424
+ const parsed = await (async () => {
1425
+ try {
1426
+ return await parseOperationKeyValuePairs(
1427
+ endpoint,
1428
+ bodyFields,
1429
+ flags,
1430
+ pos
1431
+ );
1432
+ } catch (err) {
1433
+ printError(err);
1434
+ return null;
1435
+ }
1436
+ })();
1437
+ if (parsed === null) {
1438
+ return null;
1439
+ }
1440
+ const missing = getMissingRequiredOperationParams(
1441
+ endpoint,
1442
+ bodyFields,
1443
+ parsed,
1444
+ flags
1445
+ );
1446
+ if (missing.path.length === 0 && missing.query.length === 0 && missing.header.length === 0 && missing.body.length === 0) {
1447
+ break;
1448
+ }
1449
+ for (const param of missing.path) {
1450
+ const value = await client.input.text({
1451
+ message: `Enter value for ${formatPathParam(param.name)}${formatDescription(param.description)}:`,
1452
+ validate: createRequiredValidator(param.name)
1453
+ });
1454
+ pos.push(`${param.name}=${value}`);
1455
+ }
1456
+ for (const param of missing.header) {
1457
+ const value = await client.input.text({
1458
+ message: `Enter value for header ${import_chalk3.default.cyan(param.name)}${formatDescription(param.description)}:`,
1459
+ validate: createRequiredValidator(param.name)
1460
+ });
1461
+ pos.push(`${param.name}=${value}`);
1462
+ }
1463
+ for (const param of missing.query) {
1464
+ const value = await client.input.text({
1465
+ message: `Enter value for ${import_chalk3.default.cyan(param.name)}${formatDescription(param.description)}:`,
1466
+ validate: createRequiredValidator(param.name)
1467
+ });
1468
+ pos.push(`${param.name}=${value}`);
1469
+ }
1470
+ for (const field of missing.body) {
1471
+ const value = await promptForBodyField(client, field, true);
1472
+ pos.push(`${field.name}=${value}`);
1473
+ }
1474
+ }
1475
+ return promptUnsetOptionalParamsForTagOperation(
1476
+ client,
1477
+ endpoint,
1478
+ bodyFields,
1479
+ flags,
1480
+ pos
1481
+ );
1482
+ }
1483
+ async function promptUnsetOptionalParamsForTagOperation(client, endpoint, bodyFields, flags, positionalKeyValues) {
1484
+ const pos = [...positionalKeyValues];
1485
+ const parsed = await (async () => {
1486
+ try {
1487
+ return await parseOperationKeyValuePairs(
1488
+ endpoint,
1489
+ bodyFields,
1490
+ flags,
1491
+ pos
1492
+ );
1493
+ } catch (err) {
1494
+ printError(err);
1495
+ return null;
1496
+ }
1497
+ })();
1498
+ if (parsed === null) {
1499
+ return null;
1500
+ }
1501
+ const unset = getUnsetOptionalOperationParams(
1502
+ endpoint,
1503
+ bodyFields,
1504
+ parsed,
1505
+ flags
1506
+ );
1507
+ if (unset.query.length === 0 && unset.header.length === 0 && unset.body.length === 0) {
1508
+ return pos;
1509
+ }
1510
+ if (unset.query.length > 0) {
1511
+ const selected = await client.input.checkbox({
1512
+ message: "Select optional query parameters to include:",
1513
+ pageSize: 20,
1514
+ choices: unset.query.map((p) => ({
1515
+ name: `${import_chalk3.default.cyan(p.name)}${GLOBAL_CLI_QUERY_PARAMS.has(p.name) ? import_chalk3.default.dim(" (team / scope; omit to use CLI default)") : ""}${formatDescription(p.description)}`,
1516
+ value: p.name
1517
+ }))
1518
+ });
1519
+ for (const paramName of selected) {
1520
+ const param = unset.query.find((p) => p.name === paramName);
1521
+ const value = await client.input.text({
1522
+ message: `Enter value for ${import_chalk3.default.cyan(param.name)}${formatDescription(param.description)}:`,
1523
+ validate: createRequiredValidator(param.name)
1524
+ });
1525
+ pos.push(`${param.name}=${value}`);
1526
+ }
1527
+ }
1528
+ if (unset.header.length > 0) {
1529
+ const selected = await client.input.checkbox({
1530
+ message: "Select optional header parameters to include:",
1531
+ pageSize: 20,
1532
+ choices: unset.header.map((p) => ({
1533
+ name: `${import_chalk3.default.cyan(p.name)}${formatDescription(p.description)}`,
1534
+ value: p.name
1535
+ }))
1536
+ });
1537
+ for (const paramName of selected) {
1538
+ const param = unset.header.find((p) => p.name === paramName);
1539
+ const value = await client.input.text({
1540
+ message: `Enter value for header ${import_chalk3.default.cyan(param.name)}${formatDescription(param.description)}:`,
1541
+ validate: createRequiredValidator(param.name)
1542
+ });
1543
+ pos.push(`${param.name}=${value}`);
1544
+ }
1545
+ }
1546
+ if (unset.body.length > 0) {
1547
+ const selected = await client.input.checkbox({
1548
+ message: "Select optional body fields to include:",
1549
+ pageSize: 20,
1550
+ choices: unset.body.map((f) => ({
1551
+ name: `${import_chalk3.default.cyan(f.name)}${f.type ? ` ${formatTypeHint(f.type)}` : ""}${formatDescription(f.description)}`,
1552
+ value: f.name
1553
+ }))
1554
+ });
1555
+ for (const fieldName of selected) {
1556
+ const field = unset.body.find((f) => f.name === fieldName);
1557
+ const value = await promptForBodyField(client, field, true);
1558
+ pos.push(`${field.name}=${value}`);
1559
+ }
1560
+ }
1561
+ return pos;
1562
+ }
1563
+ function printTagOperationResolveError(result, allEndpoints) {
1564
+ if (result.reason === "no_tag") {
1565
+ const tags = [...new Set(allEndpoints.flatMap((ep) => ep.tags || []))].sort();
1566
+ const preview = tags.slice(0, 25).join(", ");
1567
+ output_manager_default.error(
1568
+ `No operations use tag "${result.tag}".${tags.length > 0 ? ` Example tags: ${preview}${tags.length > 25 ? ", \u2026" : ""}.` : ""} Run \`vercel api ls --format json\` to inspect tags.`
1569
+ );
1570
+ return;
1571
+ }
1572
+ if (result.reason === "no_operation") {
1573
+ const ids = result.tagMatches.map((ep) => ep.operationId).filter(Boolean).sort();
1574
+ output_manager_default.error(
1575
+ `No operation matches "${result.operationHint}" under tag "${result.tag}".${ids.length > 0 ? ` Operations include: ${ids.slice(0, 20).join(", ")}${ids.length > 20 ? ", \u2026" : ""}.` : ""}`
1576
+ );
1577
+ return;
1578
+ }
1579
+ const lines = result.tagMatches.map(
1580
+ (ep) => ` ${ep.operationId} ${ep.method} ${ep.path}`
1581
+ );
1582
+ output_manager_default.error(
1583
+ `Multiple operations match "${result.operationHint}" under tag "${result.tag}":
1584
+ ${lines.join("\n")}`
1585
+ );
1586
+ }
1587
+ async function executeApiRequest(client, requestConfig, flags, displayColumns, options) {
1588
+ if (flags["--verbose"]) {
1589
+ output_manager_default.debug(`Request: ${requestConfig.method} ${requestConfig.url}`);
1590
+ if (Object.keys(requestConfig.headers).length > 0) {
1591
+ output_manager_default.debug(`Headers: ${JSON.stringify(requestConfig.headers)}`);
1592
+ }
1593
+ if (requestConfig.body) {
1594
+ output_manager_default.debug(
1595
+ `Body: ${typeof requestConfig.body === "string" ? requestConfig.body : JSON.stringify(requestConfig.body)}`
1596
+ );
1597
+ }
1598
+ }
1599
+ if (flags["--paginate"]) {
1600
+ return executePaginatedRequest(client, requestConfig, flags);
1601
+ }
1602
+ return executeSingleRequest(
1603
+ client,
1604
+ requestConfig,
1605
+ flags,
1606
+ displayColumns,
1607
+ options
1608
+ );
1609
+ }
1610
+ async function executeSingleRequest(client, config, flags, displayColumns, options) {
1611
+ try {
1612
+ const confirmed = await client.confirmMutatingOperation(
1613
+ config.url,
1614
+ config.method
1615
+ );
1616
+ if (!confirmed) {
1617
+ return 1;
1618
+ }
1619
+ const response = await client.fetch(config.url, {
1620
+ method: config.method,
1621
+ body: config.body,
1622
+ headers: config.headers,
1623
+ json: false
1624
+ });
1625
+ return handleResponse(
1626
+ client,
1627
+ response,
1628
+ flags,
1629
+ config.method,
1630
+ displayColumns,
1631
+ options
1632
+ );
1633
+ } catch (err) {
1634
+ output_manager_default.prettyError(err);
1635
+ return 1;
1636
+ }
1637
+ }
1638
+ async function executePaginatedRequest(client, config, flags) {
1639
+ const results = [];
1640
+ try {
1641
+ const confirmed = await client.confirmMutatingOperation(
1642
+ config.url,
1643
+ config.method
1644
+ );
1645
+ if (!confirmed) {
1646
+ return 1;
1647
+ }
1648
+ for await (const page of client.fetchPaginated(
1649
+ config.url,
1650
+ {
1651
+ method: config.method,
1652
+ body: config.body,
1653
+ headers: config.headers
1654
+ }
1655
+ )) {
1656
+ const data = extractPaginatedData(page);
1657
+ results.push(...data);
1658
+ }
1659
+ return outputResults(client, results, flags);
1660
+ } catch (err) {
1661
+ output_manager_default.prettyError(err);
1662
+ return 1;
1663
+ }
1664
+ }
1665
+ function extractPaginatedData(page) {
1666
+ for (const [key, value] of Object.entries(page)) {
1667
+ if (key !== "pagination" && Array.isArray(value)) {
1668
+ return value;
1669
+ }
1670
+ }
1671
+ const { pagination, ...rest } = page;
1672
+ return [rest];
1673
+ }
1674
+ async function handleResponse(client, response, flags, method, displayColumns, options) {
1675
+ if (flags["--include"]) {
1676
+ outputHeaders(client, response);
1677
+ }
1678
+ if (flags["--silent"]) {
1679
+ return response.ok ? 0 : 1;
1680
+ }
1681
+ const contentType = response.headers.get("content-type") || "";
1682
+ const isMutation = options?.tagOperation && method !== "GET";
1683
+ if (contentType.includes("application/json")) {
1684
+ const json = await response.json();
1685
+ if (flags["--verbose"]) {
1686
+ output_manager_default.debug(
1687
+ `Response status: ${response.status} ${response.statusText}`
1688
+ );
1689
+ }
1690
+ if (displayColumns && response.ok && !flags["--raw"]) {
1691
+ return outputWithDisplayColumns(client, json, displayColumns);
1692
+ }
1693
+ if (isMutation && !flags["--raw"]) {
1694
+ if (!response.ok) {
1695
+ return outputMutationResult(client, response, method, json);
1696
+ }
1697
+ return outputMutationResult(client, response, method);
1698
+ }
1699
+ return outputResults(client, json, flags);
1700
+ }
1701
+ const text = await response.text();
1702
+ if (isMutation && !flags["--raw"]) {
1703
+ return outputMutationResult(
1704
+ client,
1705
+ response,
1706
+ method,
1707
+ response.ok ? void 0 : text
1708
+ );
1709
+ }
1710
+ client.stdout.write(text);
1711
+ return response.ok ? 0 : 1;
1712
+ }
1713
+ function outputHeaders(client, response) {
1714
+ client.stdout.write(`HTTP ${response.status} ${response.statusText}
1715
+ `);
1716
+ response.headers.forEach((value, key) => {
1717
+ client.stdout.write(`${key}: ${value}
1718
+ `);
1719
+ });
1720
+ client.stdout.write("\n");
1721
+ }
1722
+ function outputWithDisplayColumns(client, data, columns) {
1723
+ const parsed = parseArrayColumns(data, columns);
1724
+ if (parsed) {
1725
+ client.stdout.write(renderTable(parsed.rows, parsed.rowColumns) + "\n");
1726
+ return 0;
1727
+ }
1728
+ if (Array.isArray(data)) {
1729
+ client.stdout.write(renderTable(data, columns) + "\n");
1730
+ } else if (data && typeof data === "object") {
1731
+ client.stdout.write(renderCard(data, columns) + "\n");
1732
+ } else {
1733
+ client.stdout.write(formatOutput(data, {}) + "\n");
1734
+ }
1735
+ return 0;
1736
+ }
1737
+ function outputMutationResult(client, response, method, errorBody) {
1738
+ const verb = method === "POST" ? "Created" : method === "PATCH" || method === "PUT" ? "Updated" : method === "DELETE" ? "Deleted" : "Done";
1739
+ if (response.ok) {
1740
+ client.stdout.write(
1741
+ `${import_chalk3.default.green("Success")} ${verb} ${import_chalk3.default.dim(`(${response.status})`)}
1742
+ `
1743
+ );
1744
+ return 0;
1745
+ }
1746
+ const errorMessage = extractErrorMessage(errorBody);
1747
+ const statusLine = `${import_chalk3.default.red("Error")} ${response.status} ${response.statusText}`;
1748
+ client.stdout.write(
1749
+ errorMessage ? `${statusLine}
1750
+ ${import_chalk3.default.dim(errorMessage)}
1751
+ ` : `${statusLine}
1752
+ `
1753
+ );
1754
+ return 1;
1755
+ }
1756
+ function extractErrorMessage(body) {
1757
+ if (!body)
1758
+ return null;
1759
+ if (typeof body === "string")
1760
+ return body;
1761
+ if (typeof body === "object" && body !== null) {
1762
+ const obj = body;
1763
+ if (typeof obj.message === "string")
1764
+ return obj.message;
1765
+ const err = obj.error;
1766
+ if (err && typeof err.message === "string")
1767
+ return err.message;
1768
+ }
1769
+ return null;
1770
+ }
1771
+ function outputResults(client, data, flags) {
1772
+ const formatted = formatOutput(data, {
1773
+ raw: flags["--raw"]
1774
+ });
1775
+ client.stdout.write(formatted + "\n");
1776
+ return 0;
1777
+ }
1778
+ async function promptEndpointSelection(client, forceRefresh) {
1779
+ try {
1780
+ const openApi = new OpenApiCache();
1781
+ const success = await openApi.loadWithSpinner(forceRefresh);
1782
+ if (!success) {
1783
+ output_manager_default.error("Could not load API specification for endpoint selection");
1784
+ return null;
1785
+ }
1786
+ const endpoints = openApi.getEndpoints();
1787
+ const selectedEndpoint = await promptForEndpoint(client, endpoints);
1788
+ const bodyFieldsSpec = openApi.getBodyFields(selectedEndpoint);
1789
+ const { finalUrl, bodyFields } = await promptForParameters(
1790
+ client,
1791
+ selectedEndpoint.path,
1792
+ selectedEndpoint.parameters,
1793
+ bodyFieldsSpec
1794
+ );
1795
+ return {
1796
+ path: selectedEndpoint.path,
1797
+ method: selectedEndpoint.method,
1798
+ finalUrl,
1799
+ bodyFields
1800
+ };
1801
+ } catch (err) {
1802
+ output_manager_default.stopSpinner();
1803
+ output_manager_default.debug(`Endpoint selection failed: ${err}`);
1804
+ return null;
1805
+ }
1806
+ }
1807
+ async function promptForEndpoint(client, endpoints) {
1808
+ const allChoices = endpoints.map((ep) => ({
1809
+ name: `${colorizeMethodPadded(ep.method)} ${ep.path}`,
1810
+ value: ep,
1811
+ // Show full description if available, otherwise show summary
1812
+ description: ep.description || ep.summary || void 0,
1813
+ // Include summary in searchable metadata
1814
+ summary: ep.summary,
1815
+ tags: ep.tags
1816
+ }));
1817
+ const total = allChoices.length;
1818
+ return client.input.search({
1819
+ message: `Search for an API endpoint (${total} available):`,
1820
+ source: async (term) => {
1821
+ if (!term) {
1822
+ return allChoices;
1823
+ }
1824
+ const lowerTerm = term.toLowerCase();
1825
+ return allChoices.filter((choice) => {
1826
+ const searchableText = [
1827
+ choice.name,
1828
+ choice.summary || "",
1829
+ choice.description || "",
1830
+ ...choice.tags || []
1831
+ ].join(" ").toLowerCase();
1832
+ return searchableText.includes(lowerTerm);
1833
+ });
1834
+ }
1835
+ });
1836
+ }
1837
+ async function listEndpoints(client, forceRefresh, format) {
1838
+ const openApi = new OpenApiCache();
1839
+ const success = await openApi.loadWithSpinner(forceRefresh);
1840
+ if (!success) {
1841
+ output_manager_default.error("Could not load API specification");
1842
+ return 1;
1843
+ }
1844
+ const endpoints = openApi.getEndpoints();
1845
+ if (format === "json") {
1846
+ return outputEndpointsAsJson(client, endpoints);
1847
+ }
1848
+ return outputEndpointsAsTable(endpoints);
1849
+ }
1850
+ function outputEndpointsAsJson(client, endpoints) {
1851
+ const jsonOutput = endpoints.map((ep) => ({
1852
+ method: ep.method,
1853
+ path: ep.path,
1854
+ summary: ep.summary || null,
1855
+ description: ep.description || null,
1856
+ operationId: ep.operationId || null,
1857
+ tags: ep.tags
1858
+ }));
1859
+ client.stdout.write(JSON.stringify(jsonOutput, null, 2) + "\n");
1860
+ return 0;
1861
+ }
1862
+ function groupEndpointsByPath(endpoints) {
1863
+ const grouped = /* @__PURE__ */ new Map();
1864
+ for (const ep of endpoints) {
1865
+ const existing = grouped.get(ep.path) || [];
1866
+ existing.push({ method: ep.method, summary: ep.summary });
1867
+ grouped.set(ep.path, existing);
1868
+ }
1869
+ const methodOrder = ["GET", "POST", "PUT", "PATCH", "DELETE"];
1870
+ for (const [path, methods] of grouped) {
1871
+ methods.sort(
1872
+ (a, b) => methodOrder.indexOf(a.method) - methodOrder.indexOf(b.method)
1873
+ );
1874
+ grouped.set(path, methods);
1875
+ }
1876
+ return grouped;
1877
+ }
1878
+ function outputEndpointsAsTable(endpoints) {
1879
+ const grouped = groupEndpointsByPath(endpoints);
1880
+ const methodWidth = 7;
1881
+ output_manager_default.log("");
1882
+ for (const [path, methods] of grouped) {
1883
+ output_manager_default.log(import_chalk3.default.bold(path));
1884
+ for (const { method, summary } of methods) {
1885
+ const coloredMethod = colorizeMethod(method);
1886
+ const paddedMethod = method.padEnd(methodWidth);
1887
+ const methodDisplay = coloredMethod + paddedMethod.slice(method.length);
1888
+ output_manager_default.log(` ${methodDisplay} ${import_chalk3.default.gray(summary || "")}`);
1889
+ }
1890
+ output_manager_default.log("");
1891
+ }
1892
+ output_manager_default.log(
1893
+ `${import_chalk3.default.bold(grouped.size.toString())} routes, ${import_chalk3.default.bold(endpoints.length.toString())} endpoints`
1894
+ );
1895
+ return 0;
1896
+ }
1897
+ function createRequiredValidator(fieldName) {
1898
+ return (input) => {
1899
+ if (!input.trim()) {
1900
+ return `${fieldName} is required`;
1901
+ }
1902
+ return true;
1903
+ };
1904
+ }
1905
+ function buildQueryString(params) {
1906
+ return Object.entries(params).map(([k, v]) => `${encodeURIComponent(k)}=${encodeURIComponent(v)}`).join("&");
1907
+ }
1908
+ async function promptForParameters(client, path, parameters, bodyFieldsSpec) {
1909
+ const globalParams = /* @__PURE__ */ new Set(["teamId", "slug"]);
1910
+ const pathParams = parameters.filter((p) => p.in === "path");
1911
+ const requiredQueryParams = parameters.filter(
1912
+ (p) => p.in === "query" && p.required && !globalParams.has(p.name)
1913
+ );
1914
+ const optionalQueryParams = parameters.filter(
1915
+ (p) => p.in === "query" && !p.required && !globalParams.has(p.name)
1916
+ );
1917
+ const requiredBodyFields = bodyFieldsSpec.filter((f) => f.required);
1918
+ const optionalBodyFields = bodyFieldsSpec.filter((f) => !f.required);
1919
+ let finalPath = path;
1920
+ for (const param of pathParams) {
1921
+ const value = await client.input.text({
1922
+ message: `Enter value for ${formatPathParam(param.name)}${formatDescription(param.description)}:`,
1923
+ validate: createRequiredValidator(param.name)
1924
+ });
1925
+ finalPath = finalPath.replace(`{${param.name}}`, encodeURIComponent(value));
1926
+ }
1927
+ const queryValues = {};
1928
+ for (const param of requiredQueryParams) {
1929
+ queryValues[param.name] = await client.input.text({
1930
+ message: `Enter value for ${import_chalk3.default.cyan(param.name)}${formatDescription(param.description)}:`,
1931
+ validate: createRequiredValidator(param.name)
1932
+ });
1933
+ }
1934
+ if (optionalQueryParams.length > 0) {
1935
+ const selectedOptionalParams = await client.input.checkbox({
1936
+ message: "Select optional query parameters to include:",
1937
+ pageSize: 20,
1938
+ choices: optionalQueryParams.map((p) => ({
1939
+ name: `${import_chalk3.default.cyan(p.name)}${formatDescription(p.description)}`,
1940
+ value: p.name
1941
+ }))
1942
+ });
1943
+ for (const paramName of selectedOptionalParams) {
1944
+ const param = optionalQueryParams.find((p) => p.name === paramName);
1945
+ queryValues[param.name] = await client.input.text({
1946
+ message: `Enter value for ${import_chalk3.default.cyan(param.name)}${formatDescription(param.description)}:`,
1947
+ validate: createRequiredValidator(param.name)
1948
+ });
1949
+ }
1950
+ }
1951
+ const bodyFieldValues = [];
1952
+ for (const field of requiredBodyFields) {
1953
+ const value = await promptForBodyField(client, field, true);
1954
+ bodyFieldValues.push(`${field.name}=${value}`);
1955
+ }
1956
+ if (optionalBodyFields.length > 0) {
1957
+ const selectedOptionalFields = await client.input.checkbox({
1958
+ message: "Select optional body fields to include:",
1959
+ pageSize: 20,
1960
+ choices: optionalBodyFields.map((f) => ({
1961
+ name: `${import_chalk3.default.cyan(f.name)}${f.type ? ` ${formatTypeHint(f.type)}` : ""}${formatDescription(f.description)}`,
1962
+ value: f.name
1963
+ }))
1964
+ });
1965
+ for (const fieldName of selectedOptionalFields) {
1966
+ const field = optionalBodyFields.find((f) => f.name === fieldName);
1967
+ const value = await promptForBodyField(client, field, true);
1968
+ bodyFieldValues.push(`${field.name}=${value}`);
1969
+ }
1970
+ }
1971
+ const queryString = buildQueryString(queryValues);
1972
+ if (queryString) {
1973
+ finalPath += `?${queryString}`;
1974
+ }
1975
+ return { finalUrl: finalPath, bodyFields: bodyFieldValues };
1976
+ }
1977
+ async function promptForBodyField(client, field, required) {
1978
+ const description = formatDescription(field.description);
1979
+ const optionalHint = required ? "" : import_chalk3.default.dim(" (optional)");
1980
+ if (field.type === "array" && field.enumValues && field.enumValues.length > 0) {
1981
+ const choices = field.enumValues.map((v) => ({
1982
+ name: String(v),
1983
+ value: String(v)
1984
+ }));
1985
+ const selected = await client.input.checkbox({
1986
+ message: `Select values for ${import_chalk3.default.cyan(field.name)}${optionalHint}${description}:`,
1987
+ choices,
1988
+ required
1989
+ });
1990
+ return JSON.stringify(selected);
1991
+ }
1992
+ if (field.enumValues && field.enumValues.length > 0) {
1993
+ const choices = field.enumValues.map((v) => ({
1994
+ name: String(v),
1995
+ value: String(v)
1996
+ }));
1997
+ if (!required) {
1998
+ choices.unshift({ name: import_chalk3.default.dim("(skip)"), value: "" });
1999
+ }
2000
+ return client.input.select({
2001
+ message: `Select value for ${import_chalk3.default.cyan(field.name)}${optionalHint}${description}:`,
2002
+ choices
2003
+ });
2004
+ }
2005
+ const typeHint = field.type ? ` ${formatTypeHint(field.type)}` : "";
2006
+ return client.input.text({
2007
+ message: `Enter value for ${import_chalk3.default.cyan(field.name)}${optionalHint}${typeHint}${description}:`,
2008
+ validate: required ? createRequiredValidator(field.name) : void 0
2009
+ });
2010
+ }
2011
+ async function runTagOperation(client, options) {
2012
+ const { tag, operationId, flags, positionalOperationFields } = options;
2013
+ const telemetryClient = new ApiTelemetryClient({
2014
+ opts: { store: client.telemetryEventStore }
2015
+ });
2016
+ const finalFlags = { ...flags };
2017
+ const openApi = new OpenApiCache();
2018
+ const loaded = await openApi.loadWithSpinner(
2019
+ finalFlags["--refresh"] ?? false
2020
+ );
2021
+ if (!loaded) {
2022
+ output_manager_default.error("Could not load API specification");
2023
+ return 1;
2024
+ }
2025
+ const allEndpoints = openApi.getEndpoints();
2026
+ const resolved = resolveEndpointByTagAndOperationId(
2027
+ allEndpoints,
2028
+ tag,
2029
+ operationId
2030
+ );
2031
+ if (!resolved.ok) {
2032
+ printTagOperationResolveError(resolved, allEndpoints);
2033
+ return 1;
2034
+ }
2035
+ const bodyFields = openApi.getBodyFields(resolved.endpoint);
2036
+ const displayColumns = openApi.getDisplayColumns(resolved.endpoint);
2037
+ let tagOperationPositional = positionalOperationFields;
2038
+ if (client.stdin.isTTY) {
2039
+ const prompted = await promptMissingParamsForTagOperation(
2040
+ client,
2041
+ resolved.endpoint,
2042
+ bodyFields,
2043
+ finalFlags,
2044
+ tagOperationPositional
2045
+ );
2046
+ if (prompted === null) {
2047
+ return 1;
2048
+ }
2049
+ tagOperationPositional = prompted;
2050
+ } else {
2051
+ try {
2052
+ const parsed = await parseOperationKeyValuePairs(
2053
+ resolved.endpoint,
2054
+ bodyFields,
2055
+ finalFlags,
2056
+ tagOperationPositional
2057
+ );
2058
+ const missing = getMissingRequiredOperationParams(
2059
+ resolved.endpoint,
2060
+ bodyFields,
2061
+ parsed,
2062
+ finalFlags
2063
+ );
2064
+ if (missing.path.length > 0 || missing.query.length > 0 || missing.header.length > 0 || missing.body.length > 0) {
2065
+ printMissingOperationParamsHelp(resolved.endpoint, missing);
2066
+ return 1;
2067
+ }
2068
+ } catch (err) {
2069
+ printError(err);
2070
+ return 1;
2071
+ }
2072
+ }
2073
+ let requestConfig;
2074
+ try {
2075
+ requestConfig = await buildRequestForResolvedOperation(
2076
+ resolved.endpoint,
2077
+ bodyFields,
2078
+ finalFlags,
2079
+ tagOperationPositional
2080
+ );
2081
+ } catch (err) {
2082
+ printError(err);
2083
+ return 1;
2084
+ }
2085
+ telemetryClient.trackCliArgumentEndpoint(tag);
2086
+ telemetryClient.trackCliArgumentOperationId(operationId);
2087
+ telemetryClient.trackCliOptionMethod(finalFlags["--method"]);
2088
+ telemetryClient.trackCliOptionHeader(finalFlags["--header"]);
2089
+ telemetryClient.trackCliOptionInput(finalFlags["--input"]);
2090
+ if (finalFlags["--paginate"])
2091
+ telemetryClient.trackCliFlagPaginate(true);
2092
+ if (finalFlags["--include"])
2093
+ telemetryClient.trackCliFlagInclude(true);
2094
+ if (finalFlags["--silent"])
2095
+ telemetryClient.trackCliFlagSilent(true);
2096
+ if (finalFlags["--verbose"])
2097
+ telemetryClient.trackCliFlagVerbose(true);
2098
+ if (finalFlags["--raw"])
2099
+ telemetryClient.trackCliFlagRaw(true);
2100
+ if (finalFlags["--refresh"])
2101
+ telemetryClient.trackCliFlagRefresh(true);
2102
+ if (finalFlags["--generate"])
2103
+ telemetryClient.trackCliOptionGenerate(finalFlags["--generate"]);
2104
+ if (finalFlags["--dangerously-skip-permissions"])
2105
+ telemetryClient.trackCliFlagDangerouslySkipPermissions(true);
2106
+ if (finalFlags["--generate"] === "curl") {
2107
+ const curlCmd = generateCurlCommand(
2108
+ requestConfig,
2109
+ "https://api.vercel.com"
2110
+ );
2111
+ output_manager_default.log("");
2112
+ output_manager_default.log("Replace <TOKEN> with your auth token:");
2113
+ output_manager_default.log("");
2114
+ client.stdout.write(curlCmd + "\n");
2115
+ return 0;
2116
+ }
2117
+ return executeApiRequest(client, requestConfig, finalFlags, displayColumns, {
2118
+ tagOperation: true
2119
+ });
2120
+ }
2121
+
2122
+ // src/util/upgrade.ts
2123
+ import { spawn } from "child_process";
2124
+ async function executeUpgrade() {
2125
+ const updateCommand = await getUpdateCommand();
2126
+ const [command, ...args] = updateCommand.split(" ");
2127
+ output_manager_default.log(`Upgrading Vercel CLI...`);
2128
+ output_manager_default.debug(`Executing: ${updateCommand}`);
2129
+ return new Promise((resolve3) => {
2130
+ const stdout = [];
2131
+ const stderr = [];
2132
+ const upgradeProcess = spawn(command, args, {
2133
+ stdio: ["inherit", "pipe", "pipe"],
2134
+ shell: false
2135
+ });
2136
+ upgradeProcess.stdout?.on("data", (data) => {
2137
+ stdout.push(data);
2138
+ });
2139
+ upgradeProcess.stderr?.on("data", (data) => {
2140
+ stderr.push(data);
2141
+ });
2142
+ upgradeProcess.on("error", (err) => {
2143
+ output_manager_default.error(`Failed to execute upgrade command: ${err.message}`);
2144
+ output_manager_default.log(`You can try running the command manually: ${updateCommand}`);
2145
+ resolve3(1);
2146
+ });
2147
+ upgradeProcess.on("close", (code) => {
2148
+ if (code === 0) {
2149
+ output_manager_default.success("Vercel CLI has been upgraded successfully!");
2150
+ } else {
2151
+ const stdoutStr = Buffer.concat(stdout).toString();
2152
+ const stderrStr = Buffer.concat(stderr).toString();
2153
+ if (stdoutStr) {
2154
+ output_manager_default.print(stdoutStr);
2155
+ }
2156
+ if (stderrStr) {
2157
+ output_manager_default.print(stderrStr);
2158
+ }
2159
+ output_manager_default.error(`Upgrade failed with exit code ${code ?? "unknown"}`);
2160
+ output_manager_default.log(
2161
+ `You can try running the command manually: ${updateCommand}`
2162
+ );
2163
+ }
2164
+ resolve3(code ?? 1);
2165
+ });
2166
+ });
2167
+ }
2168
+
2169
+ // src/commands/login/index.ts
2170
+ var import_chalk4 = __toESM(require_source(), 1);
2171
+
2172
+ // src/util/telemetry/commands/login/index.ts
2173
+ var LoginTelemetryClient = class extends TelemetryClient {
2174
+ /**
2175
+ * Tracks the state of the login process.
2176
+ * - `started` when the user initiates the login process.
2177
+ * - `canceled` when the user cancels the login process.
2178
+ * - `error` when the user encounters an error during the login process.
2179
+ * - `success` when the user successfully logs in.
2180
+ */
2181
+ trackState(...args) {
2182
+ this.trackLoginState(...args);
2183
+ }
2184
+ };
2185
+
2186
+ // src/commands/login/index.ts
2187
+ async function login2(client, options) {
2188
+ let parsedArgs = null;
2189
+ const flagsSpecification = getFlagsSpecification(loginCommand.options);
2190
+ const telemetry = new LoginTelemetryClient({
2191
+ opts: {
2192
+ store: client.telemetryEventStore
2193
+ }
2194
+ });
2195
+ try {
2196
+ if (options.shouldParseArgs) {
2197
+ parsedArgs = parseArguments(client.argv.slice(2), flagsSpecification);
2198
+ }
2199
+ } catch (error) {
2200
+ printError(error);
2201
+ return 1;
2202
+ }
2203
+ if (parsedArgs?.flags["--help"]) {
2204
+ telemetry.trackCliFlagHelp("login");
2205
+ output_manager_default.print(help(loginCommand, { columns: client.stderr.columns }));
2206
+ return 0;
2207
+ }
2208
+ if (parsedArgs?.flags["--token"]) {
2209
+ output_manager_default.error('`--token` may not be used with the "login" command');
2210
+ return 2;
2211
+ }
2212
+ if (options.shouldParseArgs && parsedArgs) {
2213
+ const obsoleteFlags = Object.keys(parsedArgs.flags).filter((flag) => {
2214
+ const flagKey = flag.replace("--", "");
2215
+ const option = loginCommand.options.find((o) => o.name === flagKey);
2216
+ if (!option || typeof option === "number")
2217
+ return;
2218
+ return "deprecated" in option && option.deprecated;
2219
+ });
2220
+ if (obsoleteFlags.length) {
2221
+ const flags = obsoleteFlags.map((f) => import_chalk4.default.bold(f)).join(", ");
2222
+ output_manager_default.warn(`The following flags are deprecated: ${flags}`);
2223
+ }
2224
+ const obsoleteArguments = parsedArgs.args.slice(1);
2225
+ if (obsoleteArguments.length) {
2226
+ const args = obsoleteArguments.map((a) => import_chalk4.default.bold(a)).join(", ");
2227
+ output_manager_default.warn(`The following arguments are deprecated: ${args}`);
2228
+ }
2229
+ if (obsoleteArguments.length || obsoleteFlags.length) {
2230
+ output_manager_default.print(
2231
+ `Read more in our ${output_manager_default.link("changelog", "https://vercel.com/changelog/new-vercel-cli-login-flow")}.
2232
+ `
2233
+ );
2234
+ }
2235
+ }
2236
+ telemetry.trackState("started");
2237
+ return await login(client, telemetry);
2238
+ }
2239
+
2240
+ // src/util/output/box.ts
2241
+ var import_chalk5 = __toESM(require_source(), 1);
2242
+ var import_strip_ansi = __toESM(require_strip_ansi(), 1);
2243
+ var border = ["\u2500", "\u256D", "\u256E", "\u2502", "\u2502", "\u2570", "\u256F"];
2244
+ var nothing = ["\u2500", "", "", "", "", "", ""];
2245
+ function box(message, {
2246
+ borderColor,
2247
+ padding = 1,
2248
+ textAlignment = "center",
2249
+ terminalColumns: cols = process.stdout.columns || process.env.COLUMNS && parseInt(process.env.COLUMNS, 10) || 80
2250
+ } = {}) {
2251
+ const lines = message.split(/\r?\n/).map((line) => [line, (0, import_strip_ansi.default)(line).length]);
2252
+ const maxLine = lines.reduce((p, [, len]) => Math.max(p, len), 0);
2253
+ const borderColorFn = borderColor && import_chalk5.default[borderColor] || import_chalk5.default.yellow;
2254
+ const clampedSidePadding = Math.max(1, padding * 3);
2255
+ const narrowMode = maxLine + 2 + clampedSidePadding * 2 > cols;
2256
+ const sidePadding = narrowMode ? 0 : clampedSidePadding;
2257
+ const innerWidth = Math.min(maxLine + sidePadding * 2, cols);
2258
+ const [hr, topLeft, topRight, left, right, bottomLeft, bottomRight] = narrowMode ? nothing : border;
2259
+ const spacerRow = narrowMode ? "\n".repeat(padding) : `${borderColorFn(`${left}${" ".repeat(innerWidth)}${right}`)}
2260
+ `.repeat(
2261
+ padding
2262
+ );
2263
+ const renderLine = ([line, len]) => {
2264
+ let leftPadding = 0;
2265
+ let rightPadding = 0;
2266
+ if (!narrowMode) {
2267
+ leftPadding = sidePadding;
2268
+ rightPadding = sidePadding;
2269
+ if (textAlignment === "center") {
2270
+ leftPadding += Math.floor((maxLine - len) / 2);
2271
+ rightPadding += maxLine - len - leftPadding + sidePadding;
2272
+ } else if (textAlignment === "right") {
2273
+ leftPadding += maxLine - len;
2274
+ } else if (textAlignment === "left") {
2275
+ rightPadding += maxLine - len;
2276
+ }
2277
+ }
2278
+ return borderColorFn(left) + " ".repeat(leftPadding) + line + " ".repeat(rightPadding) + borderColorFn(right);
2279
+ };
2280
+ return borderColorFn(`${topLeft}${hr.repeat(innerWidth)}${topRight}`) + "\n" + spacerRow + lines.map(renderLine).join("\n") + "\n" + spacerRow + borderColorFn(`${bottomLeft}${hr.repeat(innerWidth)}${bottomRight}`);
2281
+ }
2282
+
2283
+ // src/util/did-you-mean.ts
2284
+ var import_jaro_winkler = __toESM(require_jaro_winkler(), 1);
2285
+ var did_you_mean_default = didYouMean;
2286
+ function didYouMean(input, list, threshold = 0.5) {
2287
+ const rated = list.map((item) => [dashAwareDistance(input, item), item]);
2288
+ const found = rated.filter((item) => item[0] > threshold);
2289
+ if (found.length) {
2290
+ const highestRated = found.reduce((accu, curr) => {
2291
+ return accu[0] > curr[0] ? accu : curr;
2292
+ });
2293
+ return highestRated[1];
2294
+ }
2295
+ }
2296
+ function dashAwareDistance(word, dashWord) {
2297
+ const fullDistance = (0, import_jaro_winkler.default)(word, dashWord);
2298
+ const distances = dashWord.split("-").map((w) => (0, import_jaro_winkler.default)(w, word));
2299
+ const meanDistance = distances.reduce((accu, curr) => accu + curr) / distances.length;
2300
+ return fullDistance > meanDistance ? fullDistance : meanDistance;
2301
+ }
2302
+
2303
+ export {
2304
+ did_you_mean_default,
2305
+ OpenApiCache,
2306
+ matchesCliApiTag,
2307
+ resolveOpenApiTagForProjectsCli,
2308
+ resolveOpenApiTagForTeamsCli,
2309
+ api,
2310
+ tryOpenApiFallback,
2311
+ executeUpgrade,
2312
+ login2 as login,
2313
+ box
2314
+ };