vercel 51.5.1 → 51.7.0

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