@depup/vercel 50.32.5-depup.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 (96) hide show
  1. package/LICENSE +202 -0
  2. package/README.md +38 -0
  3. package/changes.json +38 -0
  4. package/dist/chunks/chunk-2DLBVZWU.js +197 -0
  5. package/dist/chunks/chunk-2HSQ7YUK.js +93 -0
  6. package/dist/chunks/chunk-2IQTNMUG.js +86 -0
  7. package/dist/chunks/chunk-3FRG2XGZ.js +466 -0
  8. package/dist/chunks/chunk-3KMKI2FP.js +34 -0
  9. package/dist/chunks/chunk-3XFFP2BA.js +110 -0
  10. package/dist/chunks/chunk-4S3Y3ATR.js +5383 -0
  11. package/dist/chunks/chunk-7EHTK7LP.js +359 -0
  12. package/dist/chunks/chunk-7YHZDJ4G.js +116 -0
  13. package/dist/chunks/chunk-A3NYPUKZ.js +17 -0
  14. package/dist/chunks/chunk-AA7QEJFB.js +5204 -0
  15. package/dist/chunks/chunk-AHU7WNL2.js +24 -0
  16. package/dist/chunks/chunk-AKQZ7KG3.js +4172 -0
  17. package/dist/chunks/chunk-AQLVWVEN.js +39155 -0
  18. package/dist/chunks/chunk-BQ3DXZNT.js +968 -0
  19. package/dist/chunks/chunk-E65JE2CC.js +102 -0
  20. package/dist/chunks/chunk-EKPSCRJZ.js +26 -0
  21. package/dist/chunks/chunk-EOZFDJSY.js +18 -0
  22. package/dist/chunks/chunk-FDJURQMQ.js +4676 -0
  23. package/dist/chunks/chunk-FLKHKWZV.js +1854 -0
  24. package/dist/chunks/chunk-G6BUEBF5.js +192 -0
  25. package/dist/chunks/chunk-GBNIO3KP.js +771 -0
  26. package/dist/chunks/chunk-GGP5R3FU.js +129 -0
  27. package/dist/chunks/chunk-H5XJSH37.js +91 -0
  28. package/dist/chunks/chunk-IB5L4LKZ.js +1082 -0
  29. package/dist/chunks/chunk-IE7MNZ56.js +149 -0
  30. package/dist/chunks/chunk-IK7DLK2T.js +16112 -0
  31. package/dist/chunks/chunk-IUGPWINM.js +104 -0
  32. package/dist/chunks/chunk-J7HDA5GH.js +54 -0
  33. package/dist/chunks/chunk-JLYZNGYY.js +293 -0
  34. package/dist/chunks/chunk-JQ4NA5MX.js +250 -0
  35. package/dist/chunks/chunk-LL26LVRR.js +81 -0
  36. package/dist/chunks/chunk-LW5ZNGW7.js +127 -0
  37. package/dist/chunks/chunk-LWBSOTJP.js +1772 -0
  38. package/dist/chunks/chunk-MBGJBHYD.js +388 -0
  39. package/dist/chunks/chunk-NUKAG3YM.js +168 -0
  40. package/dist/chunks/chunk-O7I4ZOCC.js +58 -0
  41. package/dist/chunks/chunk-OWR3XNE3.js +48 -0
  42. package/dist/chunks/chunk-P3SKP5WM.js +27 -0
  43. package/dist/chunks/chunk-P4I4DMEU.js +342 -0
  44. package/dist/chunks/chunk-P5Q6F5IA.js +107 -0
  45. package/dist/chunks/chunk-PMSMUMUO.js +30 -0
  46. package/dist/chunks/chunk-QXRJ52T4.js +2977 -0
  47. package/dist/chunks/chunk-RQXPRFRM.js +90 -0
  48. package/dist/chunks/chunk-S7KYDPEM.js +1564 -0
  49. package/dist/chunks/chunk-SGGLJFUZ.js +68 -0
  50. package/dist/chunks/chunk-SOTR4CXR.js +34 -0
  51. package/dist/chunks/chunk-TEVP63TU.js +1717 -0
  52. package/dist/chunks/chunk-TNBMKNET.js +323 -0
  53. package/dist/chunks/chunk-TZ2YI2VH.js +87 -0
  54. package/dist/chunks/chunk-U6XOC6E4.js +903 -0
  55. package/dist/chunks/chunk-V5P25P7F.js +22 -0
  56. package/dist/chunks/chunk-WQ5CUZWR.js +333 -0
  57. package/dist/chunks/chunk-WU2BPWRP.js +12237 -0
  58. package/dist/chunks/chunk-XPKWKPWA.js +44 -0
  59. package/dist/chunks/chunk-XR53KVJD.js +33 -0
  60. package/dist/chunks/chunk-Y4JJYHUG.js +16 -0
  61. package/dist/chunks/chunk-YPQSDAEW.js +29 -0
  62. package/dist/chunks/chunk-ZB2UO4V2.js +135 -0
  63. package/dist/chunks/chunk-ZLCMHY2G.js +1528 -0
  64. package/dist/chunks/compile-vercel-config-XU3YY2CZ.js +32 -0
  65. package/dist/chunks/delete-EJ2V7KQO.js +144 -0
  66. package/dist/chunks/disable-BKRFMX4U.js +122 -0
  67. package/dist/chunks/discard-4WF34DXK.js +118 -0
  68. package/dist/chunks/edit-FQE7JGU3.js +509 -0
  69. package/dist/chunks/emit-flags-datafiles-QYKPNWPX.js +17 -0
  70. package/dist/chunks/enable-VCNMX63U.js +122 -0
  71. package/dist/chunks/export-3KNVJCQR.js +133 -0
  72. package/dist/chunks/list-43XQCGKH.js +382 -0
  73. package/dist/chunks/list-DUL6PHUR.js +394 -0
  74. package/dist/chunks/publish-CF7GVZK3.js +128 -0
  75. package/dist/chunks/query-KWKO7VWO.js +954 -0
  76. package/dist/chunks/reorder-GU65YMIN.js +259 -0
  77. package/dist/chunks/restore-Q7ENGWVJ.js +158 -0
  78. package/dist/chunks/routes-Q5CWG44T.js +20 -0
  79. package/dist/chunks/schema-PJKLO2K2.js +176 -0
  80. package/dist/chunks/stamp-RTPE2EBB.js +15 -0
  81. package/dist/chunks/types-563KUQRV.js +108 -0
  82. package/dist/chunks/update-route-version-E3V47KNI.js +13 -0
  83. package/dist/commands/build/index.js +1597 -0
  84. package/dist/commands/deploy/index.js +1711 -0
  85. package/dist/commands/dev/builder-worker.cjs +95 -0
  86. package/dist/commands/dev/index.js +20810 -0
  87. package/dist/commands/env/index.js +2154 -0
  88. package/dist/commands/link/index.js +225 -0
  89. package/dist/commands/list/index.js +528 -0
  90. package/dist/commands-bulk.js +29627 -0
  91. package/dist/get-latest-worker.cjs +272 -0
  92. package/dist/help.js +14 -0
  93. package/dist/index.js +24274 -0
  94. package/dist/vc.js +36 -0
  95. package/dist/version.mjs +1 -0
  96. package/package.json +254 -0
@@ -0,0 +1,954 @@
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
+ formatErrorJson,
9
+ formatQueryJson,
10
+ getDefaultAggregation,
11
+ getMeasures,
12
+ getQueryEngineEventName,
13
+ getRollupColumnName,
14
+ validateAggregation,
15
+ validateEvent,
16
+ validateGroupBy,
17
+ validateMeasure,
18
+ validateMutualExclusivity,
19
+ validateRequiredEvent
20
+ } from "./chunk-BQ3DXZNT.js";
21
+ import {
22
+ resolveTimeRange
23
+ } from "./chunk-IE7MNZ56.js";
24
+ import {
25
+ indent_default
26
+ } from "./chunk-A3NYPUKZ.js";
27
+ import {
28
+ getScope
29
+ } from "./chunk-3KMKI2FP.js";
30
+ import {
31
+ validateJsonOutput
32
+ } from "./chunk-XPKWKPWA.js";
33
+ import {
34
+ metricsCommand
35
+ } from "./chunk-2DLBVZWU.js";
36
+ import {
37
+ getLinkedProject
38
+ } from "./chunk-AQLVWVEN.js";
39
+ import "./chunk-P4I4DMEU.js";
40
+ import "./chunk-SOTR4CXR.js";
41
+ import {
42
+ table
43
+ } from "./chunk-LWBSOTJP.js";
44
+ import "./chunk-7EHTK7LP.js";
45
+ import {
46
+ require_ms
47
+ } from "./chunk-GGP5R3FU.js";
48
+ import {
49
+ getFlagsSpecification,
50
+ isAPIError,
51
+ parseArguments,
52
+ printError
53
+ } from "./chunk-ZLCMHY2G.js";
54
+ import "./chunk-3XFFP2BA.js";
55
+ import {
56
+ output_manager_default
57
+ } from "./chunk-FDJURQMQ.js";
58
+ import {
59
+ require_source
60
+ } from "./chunk-S7KYDPEM.js";
61
+ import {
62
+ __toESM
63
+ } from "./chunk-TZ2YI2VH.js";
64
+
65
+ // src/commands/metrics/text-output.ts
66
+ var import_chalk = __toESM(require_source(), 1);
67
+
68
+ // src/commands/metrics/time-utils.ts
69
+ var import_ms = __toESM(require_ms(), 1);
70
+ var MINUTE_MS = 60 * 1e3;
71
+ var HOUR_MS = 60 * MINUTE_MS;
72
+ var DAY_MS = 24 * HOUR_MS;
73
+ function toGranularityDuration(input) {
74
+ const milliseconds = (0, import_ms.default)(input);
75
+ if (milliseconds === void 0) {
76
+ throw new Error(
77
+ `Invalid granularity format "${input}". Use 1m, 5m, 15m, 1h, 4h, 1d.`
78
+ );
79
+ }
80
+ if (milliseconds >= DAY_MS) {
81
+ return { days: milliseconds / DAY_MS };
82
+ }
83
+ if (milliseconds >= HOUR_MS) {
84
+ return { hours: milliseconds / HOUR_MS };
85
+ }
86
+ return { minutes: milliseconds / MINUTE_MS };
87
+ }
88
+ function toGranularityMs(input) {
89
+ const milliseconds = (0, import_ms.default)(input);
90
+ if (milliseconds === void 0) {
91
+ throw new Error(`Invalid granularity format "${input}".`);
92
+ }
93
+ return milliseconds;
94
+ }
95
+ var GRANULARITY_THRESHOLDS = [
96
+ [1 * HOUR_MS, "1m", "1m"],
97
+ // ≤1h
98
+ [2 * HOUR_MS, "5m", "5m"],
99
+ // ≤2h
100
+ [12 * HOUR_MS, "15m", "5m"],
101
+ // ≤12h
102
+ [3 * DAY_MS, "1h", "1h"],
103
+ // ≤3d
104
+ [30 * DAY_MS, "4h", "4h"]
105
+ // ≤30d
106
+ ];
107
+ var FALLBACK_GRANULARITY = "1d";
108
+ function getAutoGranularity(rangeMs) {
109
+ for (const [maxRange, defaultG] of GRANULARITY_THRESHOLDS) {
110
+ if (rangeMs <= maxRange) {
111
+ return defaultG;
112
+ }
113
+ }
114
+ return FALLBACK_GRANULARITY;
115
+ }
116
+ function getMinGranularity(rangeMs) {
117
+ for (const [maxRange, , minG] of GRANULARITY_THRESHOLDS) {
118
+ if (rangeMs <= maxRange) {
119
+ return minG;
120
+ }
121
+ }
122
+ return FALLBACK_GRANULARITY;
123
+ }
124
+ function computeGranularity(rangeMs, explicit) {
125
+ if (!explicit) {
126
+ const auto = getAutoGranularity(rangeMs);
127
+ return {
128
+ duration: toGranularityDuration(auto),
129
+ adjusted: false
130
+ };
131
+ }
132
+ const minG = getMinGranularity(rangeMs);
133
+ const explicitMs = toGranularityMs(explicit);
134
+ const minMs = toGranularityMs(minG);
135
+ if (explicitMs < minMs) {
136
+ const rangeDays = Math.round(rangeMs / DAY_MS);
137
+ const rangeHours = Math.round(rangeMs / HOUR_MS);
138
+ const rangeLabel = rangeDays >= 1 ? `${rangeDays}-day` : `${rangeHours}-hour`;
139
+ return {
140
+ duration: toGranularityDuration(minG),
141
+ adjusted: true,
142
+ notice: `Granularity adjusted from ${explicit} to ${minG} for a ${rangeLabel} time range.`
143
+ };
144
+ }
145
+ return {
146
+ duration: toGranularityDuration(explicit),
147
+ adjusted: false
148
+ };
149
+ }
150
+ function roundTimeBoundaries(start, end, granularityMs) {
151
+ const flooredStart = new Date(
152
+ Math.floor(start.getTime() / granularityMs) * granularityMs
153
+ );
154
+ const ceiledEnd = new Date(
155
+ Math.ceil(end.getTime() / granularityMs) * granularityMs
156
+ );
157
+ return { start: flooredStart, end: ceiledEnd };
158
+ }
159
+ function toGranularityMsFromDuration(duration) {
160
+ if ("minutes" in duration) {
161
+ return duration.minutes * MINUTE_MS;
162
+ }
163
+ if ("hours" in duration) {
164
+ return duration.hours * HOUR_MS;
165
+ }
166
+ return duration.days * DAY_MS;
167
+ }
168
+
169
+ // src/commands/metrics/text-output.ts
170
+ var GROUP_KEY_DELIMITER = "";
171
+ var MAX_SPARKLINE_LENGTH = 120;
172
+ var COUNT_UNITS = /* @__PURE__ */ new Set(["count", "us dollars", "dollars"]);
173
+ var DURATION_UNITS = /* @__PURE__ */ new Set(["milliseconds", "seconds"]);
174
+ var BYTES_UNITS = /* @__PURE__ */ new Set([
175
+ "bytes",
176
+ "megabytes",
177
+ "gigabyte hours",
178
+ "gigabyte_hours"
179
+ ]);
180
+ var RATIO_UNITS = /* @__PURE__ */ new Set(["ratio", "percent"]);
181
+ var BLOCKS = ["\u2581", "\u2582", "\u2583", "\u2584", "\u2585", "\u2586", "\u2587", "\u2588"];
182
+ var MISSING_CHAR = "\xB7";
183
+ function normalizeUnit(unit) {
184
+ return unit.trim().toLowerCase().replace(/[_\s]+/g, " ");
185
+ }
186
+ function toGroupKey(groupValues) {
187
+ if (groupValues.length === 0) {
188
+ return "";
189
+ }
190
+ return groupValues.join(GROUP_KEY_DELIMITER);
191
+ }
192
+ function pad2(n) {
193
+ return String(n).padStart(2, "0");
194
+ }
195
+ function pad4(n) {
196
+ return String(n).padStart(4, "0");
197
+ }
198
+ function formatHumanMinute(date) {
199
+ return `${pad4(date.getUTCFullYear())}-${pad2(date.getUTCMonth() + 1)}-${pad2(date.getUTCDate())} ${pad2(date.getUTCHours())}:${pad2(date.getUTCMinutes())}`;
200
+ }
201
+ function formatPeriodBound(input) {
202
+ const date = new Date(input);
203
+ if (isNaN(date.getTime())) {
204
+ return input;
205
+ }
206
+ return formatHumanMinute(date);
207
+ }
208
+ function formatGranularity(granularity) {
209
+ if ("minutes" in granularity) {
210
+ return `${granularity.minutes}m`;
211
+ }
212
+ if ("hours" in granularity) {
213
+ return `${granularity.hours}h`;
214
+ }
215
+ return `${granularity.days}d`;
216
+ }
217
+ function formatUnitLabel(unit) {
218
+ switch (normalizeUnit(unit)) {
219
+ case "milliseconds":
220
+ return "ms";
221
+ case "seconds":
222
+ return "s";
223
+ case "us dollars":
224
+ return "USD";
225
+ case "gigabyte hours":
226
+ return "GB-h";
227
+ default:
228
+ return unit;
229
+ }
230
+ }
231
+ function isCountIntegerDisplay(measureType, aggregation) {
232
+ return measureType === "count" && aggregation === "sum";
233
+ }
234
+ function formatNumber(value, measureType, aggregation, opts) {
235
+ if (isCountIntegerDisplay(measureType, aggregation)) {
236
+ if (opts?.preserveFractionalCountSum && !Number.isInteger(value)) {
237
+ return formatDecimal(value);
238
+ }
239
+ return formatCount(value);
240
+ }
241
+ return formatDecimal(value);
242
+ }
243
+ function getStatColumns(measureType) {
244
+ if (measureType === "duration" || measureType === "ratio") {
245
+ return ["avg", "min", "max"];
246
+ }
247
+ return ["total", "avg", "min", "max"];
248
+ }
249
+ function toNumericValue(value) {
250
+ if (value === null || value === void 0) {
251
+ return null;
252
+ }
253
+ if (typeof value === "number") {
254
+ return Number.isFinite(value) ? value : null;
255
+ }
256
+ const parsed = Number(value);
257
+ return Number.isFinite(parsed) ? parsed : null;
258
+ }
259
+ function isNonNullNumber(value) {
260
+ return value !== null;
261
+ }
262
+ function isPointWithValue(point) {
263
+ return point.value !== null;
264
+ }
265
+ function getOrCreate(map, key, make) {
266
+ const existing = map.get(key);
267
+ if (existing !== void 0) {
268
+ return existing;
269
+ }
270
+ const created = make();
271
+ map.set(key, created);
272
+ return created;
273
+ }
274
+ function getGroupFieldValue(row, field) {
275
+ const value = row[field];
276
+ return value == null || value === "" ? "(not set)" : String(value);
277
+ }
278
+ function normalizeTimestampToIso(timestamp) {
279
+ const parsed = Date.parse(timestamp);
280
+ if (isNaN(parsed)) {
281
+ return null;
282
+ }
283
+ return new Date(parsed).toISOString();
284
+ }
285
+ function formatStatCell(column, stats, measureType, aggregation, periodStart, periodEnd) {
286
+ switch (column) {
287
+ case "total":
288
+ return formatNumber(stats.total, measureType, aggregation);
289
+ case "avg":
290
+ return formatNumber(stats.avg, measureType, aggregation, {
291
+ preserveFractionalCountSum: true
292
+ });
293
+ case "min": {
294
+ const ts = formatMinMaxTimestamp(
295
+ new Date(stats.min.timestamp),
296
+ periodStart,
297
+ periodEnd
298
+ );
299
+ return `${formatNumber(stats.min.value, measureType, aggregation)} at ${ts}`;
300
+ }
301
+ case "max": {
302
+ const ts = formatMinMaxTimestamp(
303
+ new Date(stats.max.timestamp),
304
+ periodStart,
305
+ periodEnd
306
+ );
307
+ return `${formatNumber(stats.max.value, measureType, aggregation)} at ${ts}`;
308
+ }
309
+ }
310
+ }
311
+ function buildExpectedTimestamps(periodStart, periodEnd, granularityMs) {
312
+ const start = Date.parse(periodStart);
313
+ const end = Date.parse(periodEnd);
314
+ if (isNaN(start) || isNaN(end) || granularityMs <= 0 || end <= start) {
315
+ return [];
316
+ }
317
+ const timestamps = [];
318
+ for (let current = start; current < end; current += granularityMs) {
319
+ timestamps.push(new Date(current).toISOString());
320
+ }
321
+ return timestamps;
322
+ }
323
+ function getMeasureType(unit) {
324
+ const normalized = normalizeUnit(unit);
325
+ if (COUNT_UNITS.has(normalized)) {
326
+ return "count";
327
+ }
328
+ if (DURATION_UNITS.has(normalized)) {
329
+ return "duration";
330
+ }
331
+ if (BYTES_UNITS.has(normalized)) {
332
+ return "bytes";
333
+ }
334
+ if (RATIO_UNITS.has(normalized)) {
335
+ return "ratio";
336
+ }
337
+ return "ratio";
338
+ }
339
+ function formatCount(n) {
340
+ return Math.round(n).toLocaleString("en-US");
341
+ }
342
+ function formatDecimal(n) {
343
+ if (!Number.isFinite(n)) {
344
+ return String(n);
345
+ }
346
+ if (n === 0 || Object.is(n, -0)) {
347
+ return "0";
348
+ }
349
+ const sign = n < 0 ? "-" : "";
350
+ const abs = Math.abs(n);
351
+ if (abs >= 1) {
352
+ return `${sign}${abs.toFixed(1)}`;
353
+ }
354
+ const exponent = Math.floor(Math.log10(abs));
355
+ const decimals = Math.min(20, Math.max(2, -exponent + 1));
356
+ const fixed = abs.toFixed(decimals);
357
+ const trimmed = fixed.replace(/(\.\d*?[1-9])0+$/, "$1").replace(/\.0+$/, "").replace(/\.$/, "");
358
+ return `${sign}${trimmed}`;
359
+ }
360
+ function formatMinMaxTimestamp(date, periodStart, periodEnd) {
361
+ const sameDay = periodStart.getUTCFullYear() === periodEnd.getUTCFullYear() && periodStart.getUTCMonth() === periodEnd.getUTCMonth() && periodStart.getUTCDate() === periodEnd.getUTCDate();
362
+ if (sameDay) {
363
+ return `${pad2(date.getUTCHours())}:${pad2(date.getUTCMinutes())}`;
364
+ }
365
+ const sameYear = periodStart.getUTCFullYear() === periodEnd.getUTCFullYear();
366
+ if (sameYear) {
367
+ return `${pad2(date.getUTCMonth() + 1)}-${pad2(date.getUTCDate())} ${pad2(date.getUTCHours())}:${pad2(date.getUTCMinutes())}`;
368
+ }
369
+ return `${pad4(date.getUTCFullYear())}-${pad2(date.getUTCMonth() + 1)}-${pad2(date.getUTCDate())} ${pad2(date.getUTCHours())}:${pad2(date.getUTCMinutes())}`;
370
+ }
371
+ function extractGroupedSeries(data, groupBy, rollupColumn, periodStart, periodEnd, granularityMs) {
372
+ const expectedTimestamps = buildExpectedTimestamps(
373
+ periodStart,
374
+ periodEnd,
375
+ granularityMs
376
+ );
377
+ const groups = [];
378
+ const groupValues = /* @__PURE__ */ new Map();
379
+ const valueByGroup = /* @__PURE__ */ new Map();
380
+ for (const row of data) {
381
+ const values = groupBy.map((field) => getGroupFieldValue(row, field));
382
+ const key = toGroupKey(values);
383
+ if (!groupValues.has(key)) {
384
+ groups.push(key);
385
+ groupValues.set(key, values);
386
+ }
387
+ const groupMap = getOrCreate(valueByGroup, key, () => /* @__PURE__ */ new Map());
388
+ const rawTimestamp = row.timestamp;
389
+ if (rawTimestamp.length === 0) {
390
+ continue;
391
+ }
392
+ const timestamp = normalizeTimestampToIso(rawTimestamp);
393
+ if (!timestamp) {
394
+ continue;
395
+ }
396
+ const numeric = toNumericValue(row[rollupColumn]);
397
+ groupMap.set(timestamp, numeric);
398
+ }
399
+ const series = /* @__PURE__ */ new Map();
400
+ for (const key of groups) {
401
+ const byTimestamp = valueByGroup.get(key);
402
+ if (!byTimestamp) {
403
+ continue;
404
+ }
405
+ const points = expectedTimestamps.map((timestamp) => ({
406
+ timestamp,
407
+ value: byTimestamp.has(timestamp) ? byTimestamp.get(timestamp) ?? null : null
408
+ }));
409
+ series.set(key, points);
410
+ }
411
+ return { groups, series, groupValues };
412
+ }
413
+ function computeGroupStats(points) {
414
+ const present = points.filter(isPointWithValue);
415
+ if (present.length === 0) {
416
+ return {
417
+ total: 0,
418
+ avg: 0,
419
+ min: { value: 0, timestamp: "" },
420
+ max: { value: 0, timestamp: "" },
421
+ count: 0,
422
+ allMissing: true
423
+ };
424
+ }
425
+ let total = 0;
426
+ let min = present[0];
427
+ let max = present[0];
428
+ for (const point of present) {
429
+ total += point.value;
430
+ if (point.value < min.value) {
431
+ min = point;
432
+ }
433
+ if (point.value > max.value) {
434
+ max = point;
435
+ }
436
+ }
437
+ return {
438
+ total,
439
+ avg: total / present.length,
440
+ min: { value: min.value, timestamp: min.timestamp },
441
+ max: { value: max.value, timestamp: max.timestamp },
442
+ count: present.length,
443
+ allMissing: false
444
+ };
445
+ }
446
+ var MAX_GROUP_VALUE_LENGTH = 60;
447
+ function ellipsizeMiddle(str, maxLength) {
448
+ if (str.length <= maxLength)
449
+ return str;
450
+ const endLength = Math.floor((maxLength - 1) / 2);
451
+ const startLength = maxLength - 1 - endLength;
452
+ return `${str.slice(0, startLength)}\u2026${str.slice(str.length - endLength)}`;
453
+ }
454
+ function downsample(values, maxLen) {
455
+ if (maxLen <= 0) {
456
+ return [];
457
+ }
458
+ if (values.length <= maxLen) {
459
+ return [...values];
460
+ }
461
+ const result = [];
462
+ for (let i = 0; i < maxLen; i++) {
463
+ const start = Math.floor(i * values.length / maxLen);
464
+ const end = Math.floor((i + 1) * values.length / maxLen);
465
+ const bucket = values.slice(start, Math.max(start + 1, end));
466
+ const nullCount = bucket.filter((value) => value === null).length;
467
+ if (nullCount === bucket.length || nullCount > bucket.length / 2) {
468
+ result.push(null);
469
+ continue;
470
+ }
471
+ const present = bucket.filter(isNonNullNumber);
472
+ const avg = present.reduce((sum, value) => sum + value, 0) / present.length;
473
+ result.push(avg);
474
+ }
475
+ return result;
476
+ }
477
+ function generateSparkline(values) {
478
+ const sampled = downsample(values, MAX_SPARKLINE_LENGTH);
479
+ if (sampled.length === 0) {
480
+ return "";
481
+ }
482
+ const present = sampled.filter(isNonNullNumber);
483
+ if (present.length === 0) {
484
+ return sampled.map(() => MISSING_CHAR).join("");
485
+ }
486
+ const min = Math.min(...present);
487
+ const max = Math.max(...present);
488
+ if (min === max) {
489
+ const block = min === 0 ? BLOCKS[0] : BLOCKS[BLOCKS.length - 1];
490
+ return sampled.map((value) => value === null ? MISSING_CHAR : block).join("");
491
+ }
492
+ const range = max - min;
493
+ return sampled.map((value) => {
494
+ if (value === null) {
495
+ return MISSING_CHAR;
496
+ }
497
+ const ratio = (value - min) / range;
498
+ const index = Math.max(
499
+ 0,
500
+ Math.min(BLOCKS.length - 1, Math.round(ratio * (BLOCKS.length - 1)))
501
+ );
502
+ return BLOCKS[index];
503
+ }).join("");
504
+ }
505
+ function formatMetadataHeader(opts) {
506
+ const rows = [
507
+ {
508
+ key: "Metric",
509
+ value: `${opts.event} / ${opts.measure} ${opts.aggregation}`
510
+ },
511
+ {
512
+ key: "Period",
513
+ value: `${formatPeriodBound(opts.periodStart)} to ${formatPeriodBound(opts.periodEnd)}`
514
+ },
515
+ {
516
+ key: "Interval",
517
+ value: formatGranularity(opts.granularity)
518
+ }
519
+ ];
520
+ if (opts.filter) {
521
+ rows.push({ key: "Filter", value: opts.filter });
522
+ }
523
+ if (opts.scope.type === "project-with-slug") {
524
+ rows.push({
525
+ key: "Project",
526
+ value: `${opts.projectName ?? opts.scope.projectName} (${opts.teamName ?? opts.scope.teamSlug})`
527
+ });
528
+ } else {
529
+ rows.push({
530
+ key: "Team",
531
+ value: `${opts.teamName ?? opts.scope.teamSlug} (all projects)`
532
+ });
533
+ }
534
+ if (opts.unit && normalizeUnit(opts.unit) !== "count") {
535
+ rows.push({ key: "Units", value: formatUnitLabel(opts.unit) });
536
+ }
537
+ if (typeof opts.groupCount === "number") {
538
+ rows.push({ key: "Groups", value: String(opts.groupCount) });
539
+ }
540
+ return rows.map((row) => `> ${import_chalk.default.gray(`${row.key}:`)} ${row.value}`).join("\n");
541
+ }
542
+ function formatSummaryTable(opts) {
543
+ const statColumns = getStatColumns(opts.measureType);
544
+ const header = [...opts.groupByFields, ...statColumns];
545
+ const rows = [header.map((name) => import_chalk.default.bold(import_chalk.default.cyan(name)))];
546
+ for (const row of opts.rows) {
547
+ const nextRow = row.groupValues.map(
548
+ (v) => ellipsizeMiddle(v, MAX_GROUP_VALUE_LENGTH)
549
+ );
550
+ if (row.stats.allMissing) {
551
+ nextRow.push(...statColumns.map(() => "--"));
552
+ rows.push(nextRow);
553
+ continue;
554
+ }
555
+ nextRow.push(
556
+ ...statColumns.map(
557
+ (column) => formatStatCell(
558
+ column,
559
+ row.stats,
560
+ opts.measureType,
561
+ opts.aggregation,
562
+ opts.periodStart,
563
+ opts.periodEnd
564
+ )
565
+ )
566
+ );
567
+ rows.push(nextRow);
568
+ }
569
+ const centeredColumns = /* @__PURE__ */ new Set(["min", "max"]);
570
+ const align = header.map(
571
+ (col) => centeredColumns.has(col) ? "c" : "r"
572
+ );
573
+ return indent_default(
574
+ table(rows, {
575
+ align,
576
+ hsep: 2
577
+ }),
578
+ 2
579
+ );
580
+ }
581
+ function formatSparklineSection(groupRows, sparklines, groupByFields) {
582
+ const lines = ["sparklines:"];
583
+ if (groupRows.length === 0) {
584
+ const sparkline = sparklines[0];
585
+ if (sparkline) {
586
+ lines.push(indent_default(sparkline, 2));
587
+ }
588
+ return lines.join("\n");
589
+ }
590
+ const rowsWithSparklines = groupRows.map((groupValues, index) => ({
591
+ groupValues,
592
+ sparkline: sparklines[index] ?? ""
593
+ }));
594
+ const rows = [
595
+ [...groupByFields, "sparkline"].map((name) => import_chalk.default.bold(import_chalk.default.cyan(name))),
596
+ ...rowsWithSparklines.map(({ groupValues, sparkline }) => [
597
+ ...groupValues.map((v) => ellipsizeMiddle(v, MAX_GROUP_VALUE_LENGTH)),
598
+ sparkline
599
+ ])
600
+ ];
601
+ const align = groupByFields.map(() => "r");
602
+ align.push("l");
603
+ lines.push(
604
+ indent_default(
605
+ table(rows, {
606
+ align,
607
+ hsep: 2
608
+ }),
609
+ 2
610
+ )
611
+ );
612
+ return lines.join("\n");
613
+ }
614
+ function formatText(response, opts) {
615
+ const rollupColumn = getRollupColumnName(opts.measure, opts.aggregation);
616
+ const measureSchema = getMeasures(opts.event).find(
617
+ (m) => m.name === opts.measure
618
+ );
619
+ const measureUnit = measureSchema?.unit;
620
+ const measureType = getMeasureType(measureUnit ?? "ratio");
621
+ const granularityMs = toGranularityMsFromDuration(opts.granularity);
622
+ const { groups, series, groupValues } = extractGroupedSeries(
623
+ response.data ?? [],
624
+ opts.groupBy,
625
+ rollupColumn,
626
+ opts.periodStart,
627
+ opts.periodEnd,
628
+ granularityMs
629
+ );
630
+ const metadata = formatMetadataHeader({
631
+ event: opts.event,
632
+ measure: opts.measure,
633
+ aggregation: opts.aggregation,
634
+ periodStart: opts.periodStart,
635
+ periodEnd: opts.periodEnd,
636
+ granularity: opts.granularity,
637
+ filter: opts.filter,
638
+ scope: opts.scope,
639
+ projectName: opts.projectName,
640
+ teamName: opts.teamName,
641
+ unit: measureUnit,
642
+ groupCount: opts.groupBy.length > 0 ? groups.length : void 0
643
+ });
644
+ if (groups.length === 0) {
645
+ return `${metadata}
646
+
647
+ No data found for this period.
648
+ `;
649
+ }
650
+ const summaryRows = [];
651
+ const groupRows = [];
652
+ const sparklineRows = [];
653
+ for (const key of groups) {
654
+ const points = series.get(key) ?? [];
655
+ const values = points.map((point) => point.value);
656
+ const currentGroupValues = groupValues.get(key) ?? [];
657
+ summaryRows.push({
658
+ groupValues: currentGroupValues,
659
+ stats: computeGroupStats(points)
660
+ });
661
+ groupRows.push(currentGroupValues);
662
+ sparklineRows.push(generateSparkline(values));
663
+ }
664
+ const summaryTable = formatSummaryTable({
665
+ rows: summaryRows,
666
+ groupByFields: opts.groupBy,
667
+ measureType,
668
+ aggregation: opts.aggregation,
669
+ periodStart: new Date(opts.periodStart),
670
+ periodEnd: new Date(opts.periodEnd)
671
+ });
672
+ const groupedOutput = opts.groupBy.length > 0;
673
+ const sparklineSection = formatSparklineSection(
674
+ groupedOutput ? groupRows : [],
675
+ sparklineRows,
676
+ opts.groupBy
677
+ );
678
+ const sections = [metadata, summaryTable, sparklineSection];
679
+ return `${sections.join("\n\n")}
680
+ `;
681
+ }
682
+
683
+ // src/commands/metrics/query.ts
684
+ function handleValidationError(result, jsonOutput, client) {
685
+ if (jsonOutput) {
686
+ client.stdout.write(
687
+ formatErrorJson(result.code, result.message, result.allowedValues)
688
+ );
689
+ } else {
690
+ output_manager_default.error(result.message);
691
+ if (result.allowedValues && result.allowedValues.length > 0) {
692
+ output_manager_default.print(
693
+ `
694
+ Available ${result.code === "UNKNOWN_EVENT" ? "events" : result.code === "UNKNOWN_MEASURE" ? "measures" : result.code === "INVALID_AGGREGATION" ? "aggregations" : "dimensions"}: ${result.allowedValues.join(", ")}
695
+ `
696
+ );
697
+ }
698
+ }
699
+ return 1;
700
+ }
701
+ function handleApiError(err, jsonOutput, client) {
702
+ let code;
703
+ let message;
704
+ switch (err.status) {
705
+ case 402:
706
+ code = "PAYMENT_REQUIRED";
707
+ message = "This feature requires an Observability Plus subscription. Upgrade at https://vercel.com/dashboard/settings/billing";
708
+ break;
709
+ case 403:
710
+ code = "FORBIDDEN";
711
+ message = "You do not have permission to query metrics for this project/team.";
712
+ break;
713
+ case 500:
714
+ code = "INTERNAL_ERROR";
715
+ message = "An internal error occurred. Please try again later.";
716
+ break;
717
+ case 504:
718
+ code = "TIMEOUT";
719
+ message = "The query timed out. Try a shorter time range or fewer groups.";
720
+ break;
721
+ default:
722
+ code = err.code || "BAD_REQUEST";
723
+ message = err.serverMessage || `API error (${err.status})`;
724
+ }
725
+ if (jsonOutput) {
726
+ client.stdout.write(formatErrorJson(code, message));
727
+ } else {
728
+ output_manager_default.error(message);
729
+ }
730
+ return 1;
731
+ }
732
+ async function resolveQueryScope(client, opts) {
733
+ if (opts.project || opts.all) {
734
+ const { team } = await getScope(client);
735
+ if (!team) {
736
+ const errMsg = "No team context found. Run `vercel switch` to select a team, or use `vercel link` in a project directory.";
737
+ if (opts.jsonOutput) {
738
+ client.stdout.write(formatErrorJson("NO_TEAM", errMsg));
739
+ } else {
740
+ output_manager_default.error(errMsg);
741
+ }
742
+ return 1;
743
+ }
744
+ if (opts.all) {
745
+ return {
746
+ scope: { type: "team-with-slug", teamSlug: team.slug },
747
+ accountId: team.id
748
+ };
749
+ }
750
+ return {
751
+ scope: {
752
+ type: "project-with-slug",
753
+ teamSlug: team.slug,
754
+ projectName: opts.project
755
+ },
756
+ accountId: team.id
757
+ };
758
+ }
759
+ const linkedProject = await getLinkedProject(client);
760
+ if (linkedProject.status === "error") {
761
+ return linkedProject.exitCode;
762
+ }
763
+ if (linkedProject.status === "not_linked") {
764
+ const errMsg = "No linked project found. Run `vercel link` to link a project, or use --project <name> or --all.";
765
+ if (opts.jsonOutput) {
766
+ client.stdout.write(formatErrorJson("NOT_LINKED", errMsg));
767
+ } else {
768
+ output_manager_default.error(errMsg);
769
+ }
770
+ return 1;
771
+ }
772
+ return {
773
+ scope: {
774
+ type: "project-with-slug",
775
+ teamSlug: linkedProject.org.slug,
776
+ projectName: linkedProject.project.name
777
+ },
778
+ accountId: linkedProject.org.id
779
+ };
780
+ }
781
+ async function query(client, telemetry) {
782
+ let parsedArgs;
783
+ const flagsSpecification = getFlagsSpecification(metricsCommand.options);
784
+ try {
785
+ parsedArgs = parseArguments(client.argv.slice(2), flagsSpecification);
786
+ } catch (err) {
787
+ printError(err);
788
+ return 1;
789
+ }
790
+ const flags = parsedArgs.flags;
791
+ const formatResult = validateJsonOutput(flags);
792
+ if (!formatResult.valid) {
793
+ output_manager_default.error(formatResult.error);
794
+ return 1;
795
+ }
796
+ const jsonOutput = formatResult.jsonOutput;
797
+ const eventFlag = flags["--event"];
798
+ const measure = flags["--measure"] ?? "count";
799
+ const aggregationFlag = flags["--aggregation"];
800
+ const groupBy = flags["--group-by"] ?? [];
801
+ const limit = flags["--limit"];
802
+ const filter = flags["--filter"];
803
+ const since = flags["--since"];
804
+ const until = flags["--until"];
805
+ const granularity = flags["--granularity"];
806
+ const project = flags["--project"];
807
+ const all = flags["--all"];
808
+ telemetry.trackCliOptionEvent(eventFlag);
809
+ telemetry.trackCliOptionMeasure(flags["--measure"]);
810
+ telemetry.trackCliOptionAggregation(aggregationFlag);
811
+ telemetry.trackCliOptionGroupBy(groupBy.length > 0 ? groupBy : void 0);
812
+ telemetry.trackCliOptionLimit(limit);
813
+ telemetry.trackCliOptionFilter(filter);
814
+ telemetry.trackCliOptionSince(since);
815
+ telemetry.trackCliOptionUntil(until);
816
+ telemetry.trackCliOptionGranularity(granularity);
817
+ telemetry.trackCliOptionProject(project);
818
+ telemetry.trackCliFlagAll(all);
819
+ telemetry.trackCliOptionFormat(flags["--format"]);
820
+ const requiredResult = validateRequiredEvent(eventFlag);
821
+ if (!requiredResult.valid) {
822
+ return handleValidationError(requiredResult, jsonOutput, client);
823
+ }
824
+ const event = requiredResult.value;
825
+ const aggregationInput = aggregationFlag ?? getDefaultAggregation(event, measure);
826
+ const eventResult = validateEvent(event);
827
+ if (!eventResult.valid) {
828
+ return handleValidationError(eventResult, jsonOutput, client);
829
+ }
830
+ const measureResult = validateMeasure(event, measure);
831
+ if (!measureResult.valid) {
832
+ return handleValidationError(measureResult, jsonOutput, client);
833
+ }
834
+ const aggResult = validateAggregation(event, measure, aggregationInput);
835
+ if (!aggResult.valid) {
836
+ return handleValidationError(aggResult, jsonOutput, client);
837
+ }
838
+ const aggregation = aggResult.value;
839
+ const groupByResult = validateGroupBy(event, groupBy);
840
+ if (!groupByResult.valid) {
841
+ return handleValidationError(groupByResult, jsonOutput, client);
842
+ }
843
+ const mutualResult = validateMutualExclusivity(all, project);
844
+ if (!mutualResult.valid) {
845
+ return handleValidationError(mutualResult, jsonOutput, client);
846
+ }
847
+ const scopeResult = await resolveQueryScope(client, {
848
+ project,
849
+ all,
850
+ jsonOutput
851
+ });
852
+ if (typeof scopeResult === "number") {
853
+ return scopeResult;
854
+ }
855
+ const { scope, accountId } = scopeResult;
856
+ let startTime;
857
+ let endTime;
858
+ try {
859
+ ({ startTime, endTime } = resolveTimeRange(since, until));
860
+ } catch (err) {
861
+ const errMsg = err instanceof Error ? err.message : String(err);
862
+ if (jsonOutput) {
863
+ client.stdout.write(formatErrorJson("INVALID_TIME", errMsg));
864
+ } else {
865
+ output_manager_default.error(errMsg);
866
+ }
867
+ return 1;
868
+ }
869
+ const rangeMs = endTime.getTime() - startTime.getTime();
870
+ const granResult = computeGranularity(rangeMs, granularity);
871
+ if (granResult.adjusted && granResult.notice) {
872
+ output_manager_default.log(`Notice: ${granResult.notice}`);
873
+ }
874
+ const rounded = roundTimeBoundaries(
875
+ startTime,
876
+ endTime,
877
+ toGranularityMsFromDuration(granResult.duration)
878
+ );
879
+ const rollupColumn = getRollupColumnName(measure, aggregation);
880
+ const body = {
881
+ reason: "agent",
882
+ scope,
883
+ event: getQueryEngineEventName(event),
884
+ rollups: { [rollupColumn]: { measure, aggregation } },
885
+ startTime: rounded.start.toISOString(),
886
+ endTime: rounded.end.toISOString(),
887
+ granularity: granResult.duration,
888
+ ...groupBy.length > 0 ? { groupBy } : {},
889
+ ...filter ? { filter } : {},
890
+ limit: limit ?? 10
891
+ };
892
+ const baseUrl = client.apiUrl === "https://api.vercel.com" ? "https://vercel.com" : client.apiUrl;
893
+ const metricsUrl = `${baseUrl}/api/observability/metrics`;
894
+ output_manager_default.spinner("Querying metrics...");
895
+ let response;
896
+ try {
897
+ response = await client.fetch(metricsUrl, {
898
+ method: "POST",
899
+ body: JSON.stringify(body),
900
+ headers: { "Content-Type": "application/json" },
901
+ accountId
902
+ });
903
+ } catch (err) {
904
+ if (isAPIError(err)) {
905
+ return handleApiError(err, jsonOutput, client);
906
+ }
907
+ const errMsg = err instanceof Error ? err.message : String(err);
908
+ if (jsonOutput) {
909
+ client.stdout.write(formatErrorJson("NETWORK_ERROR", errMsg));
910
+ } else {
911
+ output_manager_default.error(errMsg);
912
+ }
913
+ return 1;
914
+ } finally {
915
+ output_manager_default.stopSpinner();
916
+ }
917
+ if (jsonOutput) {
918
+ client.stdout.write(
919
+ formatQueryJson(
920
+ {
921
+ event,
922
+ measure,
923
+ aggregation,
924
+ groupBy,
925
+ filter,
926
+ startTime: rounded.start.toISOString(),
927
+ endTime: rounded.end.toISOString(),
928
+ granularity: granResult.duration
929
+ },
930
+ response
931
+ )
932
+ );
933
+ } else {
934
+ client.stdout.write(
935
+ formatText(response, {
936
+ event,
937
+ measure,
938
+ aggregation,
939
+ groupBy,
940
+ filter,
941
+ scope,
942
+ projectName: scope.type === "project-with-slug" ? scope.projectName : void 0,
943
+ teamName: scope.teamSlug,
944
+ periodStart: rounded.start.toISOString(),
945
+ periodEnd: rounded.end.toISOString(),
946
+ granularity: granResult.duration
947
+ })
948
+ );
949
+ }
950
+ return 0;
951
+ }
952
+ export {
953
+ query as default
954
+ };