@continuous-excellence/ze-great-dashboard-aws 0.31.46 → 0.31.47
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.
- package/dist/cli.js +2127 -384
- package/dist/index.js +2102 -359
- package/dist/lambda.mjs +2248 -1342
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -7,10 +7,10 @@ import { fileURLToPath as fileURLToPath2 } from "node:url";
|
|
|
7
7
|
import { createRequire } from "module";
|
|
8
8
|
var require2 = createRequire("/");
|
|
9
9
|
var _a;
|
|
10
|
-
var
|
|
10
|
+
var Worker2;
|
|
11
11
|
var isMarkedAsUntransferable;
|
|
12
12
|
try {
|
|
13
|
-
_a = require2("worker_threads"),
|
|
13
|
+
_a = require2("worker_threads"), Worker2 = _a.Worker, isMarkedAsUntransferable = _a.isMarkedAsUntransferable;
|
|
14
14
|
} catch (e) {
|
|
15
15
|
}
|
|
16
16
|
var u8 = Uint8Array;
|
|
@@ -90,13 +90,13 @@ var fdeb = new u8([
|
|
|
90
90
|
var clim = new u8([16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15]);
|
|
91
91
|
var freb = function(eb, start) {
|
|
92
92
|
var b = new u16(31);
|
|
93
|
-
for (var
|
|
94
|
-
b[
|
|
93
|
+
for (var i3 = 0; i3 < 31; ++i3) {
|
|
94
|
+
b[i3] = start += 1 << eb[i3 - 1];
|
|
95
95
|
}
|
|
96
96
|
var r = new i32(b[30]);
|
|
97
|
-
for (var
|
|
98
|
-
for (var j = b[
|
|
99
|
-
r[j] = j - b[
|
|
97
|
+
for (var i3 = 1; i3 < 30; ++i3) {
|
|
98
|
+
for (var j = b[i3]; j < b[i3 + 1]; ++j) {
|
|
99
|
+
r[j] = j - b[i3] << 5 | i3;
|
|
100
100
|
}
|
|
101
101
|
}
|
|
102
102
|
return { b, r };
|
|
@@ -119,25 +119,25 @@ var x;
|
|
|
119
119
|
var i;
|
|
120
120
|
var hMap = (function(cd, mb, r) {
|
|
121
121
|
var s = cd.length;
|
|
122
|
-
var
|
|
122
|
+
var i3 = 0;
|
|
123
123
|
var l = new u16(mb);
|
|
124
|
-
for (;
|
|
125
|
-
if (cd[
|
|
126
|
-
++l[cd[
|
|
124
|
+
for (; i3 < s; ++i3) {
|
|
125
|
+
if (cd[i3])
|
|
126
|
+
++l[cd[i3] - 1];
|
|
127
127
|
}
|
|
128
128
|
var le = new u16(mb);
|
|
129
|
-
for (
|
|
130
|
-
le[
|
|
129
|
+
for (i3 = 1; i3 < mb; ++i3) {
|
|
130
|
+
le[i3] = le[i3 - 1] + l[i3 - 1] << 1;
|
|
131
131
|
}
|
|
132
132
|
var co;
|
|
133
133
|
if (r) {
|
|
134
134
|
co = new u16(1 << mb);
|
|
135
135
|
var rvb = 15 - mb;
|
|
136
|
-
for (
|
|
137
|
-
if (cd[
|
|
138
|
-
var sv =
|
|
139
|
-
var r_1 = mb - cd[
|
|
140
|
-
var v = le[cd[
|
|
136
|
+
for (i3 = 0; i3 < s; ++i3) {
|
|
137
|
+
if (cd[i3]) {
|
|
138
|
+
var sv = i3 << 4 | cd[i3];
|
|
139
|
+
var r_1 = mb - cd[i3];
|
|
140
|
+
var v = le[cd[i3] - 1]++ << r_1;
|
|
141
141
|
for (var m = v | (1 << r_1) - 1; v <= m; ++v) {
|
|
142
142
|
co[rev[v] >> rvb] = sv;
|
|
143
143
|
}
|
|
@@ -145,9 +145,9 @@ var hMap = (function(cd, mb, r) {
|
|
|
145
145
|
}
|
|
146
146
|
} else {
|
|
147
147
|
co = new u16(s);
|
|
148
|
-
for (
|
|
149
|
-
if (cd[
|
|
150
|
-
co[
|
|
148
|
+
for (i3 = 0; i3 < s; ++i3) {
|
|
149
|
+
if (cd[i3]) {
|
|
150
|
+
co[i3] = rev[le[cd[i3] - 1]++] >> 15 - cd[i3];
|
|
151
151
|
}
|
|
152
152
|
}
|
|
153
153
|
}
|
|
@@ -224,9 +224,9 @@ var wbits16 = function(d, p, v) {
|
|
|
224
224
|
};
|
|
225
225
|
var hTree = function(d, mb) {
|
|
226
226
|
var t = [];
|
|
227
|
-
for (var
|
|
228
|
-
if (d[
|
|
229
|
-
t.push({ s:
|
|
227
|
+
for (var i3 = 0; i3 < d.length; ++i3) {
|
|
228
|
+
if (d[i3])
|
|
229
|
+
t.push({ s: i3, f: d[i3] });
|
|
230
230
|
}
|
|
231
231
|
var s = t.length;
|
|
232
232
|
var t2 = t.slice();
|
|
@@ -249,20 +249,20 @@ var hTree = function(d, mb) {
|
|
|
249
249
|
t[i1++] = { s: -1, f: l.f + r.f, l, r };
|
|
250
250
|
}
|
|
251
251
|
var maxSym = t2[0].s;
|
|
252
|
-
for (var
|
|
253
|
-
if (t2[
|
|
254
|
-
maxSym = t2[
|
|
252
|
+
for (var i3 = 1; i3 < s; ++i3) {
|
|
253
|
+
if (t2[i3].s > maxSym)
|
|
254
|
+
maxSym = t2[i3].s;
|
|
255
255
|
}
|
|
256
256
|
var tr = new u16(maxSym + 1);
|
|
257
257
|
var mbt = ln(t[i1 - 1], tr, 0);
|
|
258
258
|
if (mbt > mb) {
|
|
259
|
-
var
|
|
259
|
+
var i3 = 0, dt = 0;
|
|
260
260
|
var lft = mbt - mb, cst = 1 << lft;
|
|
261
261
|
t2.sort(function(a, b) {
|
|
262
262
|
return tr[b.s] - tr[a.s] || a.f - b.f;
|
|
263
263
|
});
|
|
264
|
-
for (;
|
|
265
|
-
var i2_1 = t2[
|
|
264
|
+
for (; i3 < s; ++i3) {
|
|
265
|
+
var i2_1 = t2[i3].s;
|
|
266
266
|
if (tr[i2_1] > mb) {
|
|
267
267
|
dt += cst - (1 << mbt - tr[i2_1]);
|
|
268
268
|
tr[i2_1] = mb;
|
|
@@ -271,14 +271,14 @@ var hTree = function(d, mb) {
|
|
|
271
271
|
}
|
|
272
272
|
dt >>= lft;
|
|
273
273
|
while (dt > 0) {
|
|
274
|
-
var i2_2 = t2[
|
|
274
|
+
var i2_2 = t2[i3].s;
|
|
275
275
|
if (tr[i2_2] < mb)
|
|
276
276
|
dt -= 1 << mb - tr[i2_2]++ - 1;
|
|
277
277
|
else
|
|
278
|
-
++
|
|
278
|
+
++i3;
|
|
279
279
|
}
|
|
280
|
-
for (;
|
|
281
|
-
var i2_3 = t2[
|
|
280
|
+
for (; i3 >= 0 && dt; --i3) {
|
|
281
|
+
var i2_3 = t2[i3].s;
|
|
282
282
|
if (tr[i2_3] == mb) {
|
|
283
283
|
--tr[i2_3];
|
|
284
284
|
++dt;
|
|
@@ -300,8 +300,8 @@ var lc = function(c) {
|
|
|
300
300
|
var w = function(v) {
|
|
301
301
|
cl[cli++] = v;
|
|
302
302
|
};
|
|
303
|
-
for (var
|
|
304
|
-
if (c[
|
|
303
|
+
for (var i3 = 1; i3 <= s; ++i3) {
|
|
304
|
+
if (c[i3] == cln && i3 != s)
|
|
305
305
|
++cls;
|
|
306
306
|
else {
|
|
307
307
|
if (!cln && cls > 2) {
|
|
@@ -321,15 +321,15 @@ var lc = function(c) {
|
|
|
321
321
|
while (cls--)
|
|
322
322
|
w(cln);
|
|
323
323
|
cls = 1;
|
|
324
|
-
cln = c[
|
|
324
|
+
cln = c[i3];
|
|
325
325
|
}
|
|
326
326
|
}
|
|
327
327
|
return { c: cl.subarray(0, cli), n: s };
|
|
328
328
|
};
|
|
329
329
|
var clen = function(cf, cl) {
|
|
330
330
|
var l = 0;
|
|
331
|
-
for (var
|
|
332
|
-
l += cf[
|
|
331
|
+
for (var i3 = 0; i3 < cl.length; ++i3)
|
|
332
|
+
l += cf[i3] * cl[i3];
|
|
333
333
|
return l;
|
|
334
334
|
};
|
|
335
335
|
var wfblk = function(out, pos, dat) {
|
|
@@ -339,22 +339,22 @@ var wfblk = function(out, pos, dat) {
|
|
|
339
339
|
out[o + 1] = s >> 8;
|
|
340
340
|
out[o + 2] = out[o] ^ 255;
|
|
341
341
|
out[o + 3] = out[o + 1] ^ 255;
|
|
342
|
-
for (var
|
|
343
|
-
out[o +
|
|
342
|
+
for (var i3 = 0; i3 < s; ++i3)
|
|
343
|
+
out[o + i3 + 4] = dat[i3];
|
|
344
344
|
return (o + 4 + s) * 8;
|
|
345
345
|
};
|
|
346
346
|
var wblk = function(dat, out, final, syms, lf, df, eb, li, bs, bl, p) {
|
|
347
347
|
wbits(out, p++, final);
|
|
348
348
|
++lf[256];
|
|
349
|
-
var
|
|
350
|
-
var
|
|
349
|
+
var _a3 = hTree(lf, 15), dlt = _a3.t, mlb = _a3.l;
|
|
350
|
+
var _b3 = hTree(df, 15), ddt = _b3.t, mdb = _b3.l;
|
|
351
351
|
var _c = lc(dlt), lclt = _c.c, nlc = _c.n;
|
|
352
352
|
var _d = lc(ddt), lcdt = _d.c, ndc = _d.n;
|
|
353
353
|
var lcfreq = new u16(19);
|
|
354
|
-
for (var
|
|
355
|
-
++lcfreq[lclt[
|
|
356
|
-
for (var
|
|
357
|
-
++lcfreq[lcdt[
|
|
354
|
+
for (var i3 = 0; i3 < lclt.length; ++i3)
|
|
355
|
+
++lcfreq[lclt[i3] & 31];
|
|
356
|
+
for (var i3 = 0; i3 < lcdt.length; ++i3)
|
|
357
|
+
++lcfreq[lcdt[i3] & 31];
|
|
358
358
|
var _e = hTree(lcfreq, 7), lct = _e.t, mlcb = _e.l;
|
|
359
359
|
var nlcc = 19;
|
|
360
360
|
for (; nlcc > 4 && !lct[clim[nlcc - 1]]; --nlcc)
|
|
@@ -373,24 +373,24 @@ var wblk = function(dat, out, final, syms, lf, df, eb, li, bs, bl, p) {
|
|
|
373
373
|
wbits(out, p + 5, ndc - 1);
|
|
374
374
|
wbits(out, p + 10, nlcc - 4);
|
|
375
375
|
p += 14;
|
|
376
|
-
for (var
|
|
377
|
-
wbits(out, p + 3 *
|
|
376
|
+
for (var i3 = 0; i3 < nlcc; ++i3)
|
|
377
|
+
wbits(out, p + 3 * i3, lct[clim[i3]]);
|
|
378
378
|
p += 3 * nlcc;
|
|
379
379
|
var lcts = [lclt, lcdt];
|
|
380
380
|
for (var it = 0; it < 2; ++it) {
|
|
381
381
|
var clct = lcts[it];
|
|
382
|
-
for (var
|
|
383
|
-
var len = clct[
|
|
382
|
+
for (var i3 = 0; i3 < clct.length; ++i3) {
|
|
383
|
+
var len = clct[i3] & 31;
|
|
384
384
|
wbits(out, p, llm[len]), p += lct[len];
|
|
385
385
|
if (len > 15)
|
|
386
|
-
wbits(out, p, clct[
|
|
386
|
+
wbits(out, p, clct[i3] >> 5 & 127), p += clct[i3] >> 12;
|
|
387
387
|
}
|
|
388
388
|
}
|
|
389
389
|
} else {
|
|
390
390
|
lm = flm, ll = flt, dm = fdm, dl = fdt;
|
|
391
391
|
}
|
|
392
|
-
for (var
|
|
393
|
-
var sym = syms[
|
|
392
|
+
for (var i3 = 0; i3 < li; ++i3) {
|
|
393
|
+
var sym = syms[i3];
|
|
394
394
|
if (sym > 255) {
|
|
395
395
|
var len = sym >> 18 & 31;
|
|
396
396
|
wbits16(out, p, lm[len + 257]), p += ll[len + 257];
|
|
@@ -423,36 +423,36 @@ var dflt = function(dat, lvl, plvl, pre, post, st) {
|
|
|
423
423
|
var msk_1 = (1 << plvl) - 1;
|
|
424
424
|
var prev = st.p || new u16(32768), head = st.h || new u16(msk_1 + 1);
|
|
425
425
|
var bs1_1 = Math.ceil(plvl / 3), bs2_1 = 2 * bs1_1;
|
|
426
|
-
var hsh = function(
|
|
427
|
-
return (dat[
|
|
426
|
+
var hsh = function(i4) {
|
|
427
|
+
return (dat[i4] ^ dat[i4 + 1] << bs1_1 ^ dat[i4 + 2] << bs2_1) & msk_1;
|
|
428
428
|
};
|
|
429
429
|
var syms = new i32(25e3);
|
|
430
430
|
var lf = new u16(288), df = new u16(32);
|
|
431
|
-
var lc_1 = 0, eb = 0,
|
|
432
|
-
for (;
|
|
433
|
-
var hv = hsh(
|
|
434
|
-
var imod =
|
|
431
|
+
var lc_1 = 0, eb = 0, i3 = st.i || 0, li = 0, wi = st.w || 0, bs = 0;
|
|
432
|
+
for (; i3 + 2 < s; ++i3) {
|
|
433
|
+
var hv = hsh(i3);
|
|
434
|
+
var imod = i3 & 32767, pimod = head[hv];
|
|
435
435
|
prev[imod] = pimod;
|
|
436
436
|
head[hv] = imod;
|
|
437
|
-
if (wi <=
|
|
438
|
-
var rem = s -
|
|
437
|
+
if (wi <= i3) {
|
|
438
|
+
var rem = s - i3;
|
|
439
439
|
if ((lc_1 > 7e3 || li > 24576) && (rem > 423 || !lst)) {
|
|
440
|
-
pos = wblk(dat, w, 0, syms, lf, df, eb, li, bs,
|
|
441
|
-
li = lc_1 = eb = 0, bs =
|
|
440
|
+
pos = wblk(dat, w, 0, syms, lf, df, eb, li, bs, i3 - bs, pos);
|
|
441
|
+
li = lc_1 = eb = 0, bs = i3;
|
|
442
442
|
for (var j = 0; j < 286; ++j)
|
|
443
443
|
lf[j] = 0;
|
|
444
444
|
for (var j = 0; j < 30; ++j)
|
|
445
445
|
df[j] = 0;
|
|
446
446
|
}
|
|
447
447
|
var l = 2, d = 0, ch_1 = c, dif = imod - pimod & 32767;
|
|
448
|
-
if (rem > 2 && hv == hsh(
|
|
448
|
+
if (rem > 2 && hv == hsh(i3 - dif)) {
|
|
449
449
|
var maxn = Math.min(n, rem) - 1;
|
|
450
|
-
var maxd = Math.min(32767,
|
|
450
|
+
var maxd = Math.min(32767, i3);
|
|
451
451
|
var ml = Math.min(258, rem);
|
|
452
452
|
while (dif <= maxd && --ch_1 && imod != pimod) {
|
|
453
|
-
if (dat[
|
|
453
|
+
if (dat[i3 + l] == dat[i3 + l - dif]) {
|
|
454
454
|
var nl = 0;
|
|
455
|
-
for (; nl < ml && dat[
|
|
455
|
+
for (; nl < ml && dat[i3 + nl] == dat[i3 + nl - dif]; ++nl)
|
|
456
456
|
;
|
|
457
457
|
if (nl > l) {
|
|
458
458
|
l = nl, d = dif;
|
|
@@ -461,7 +461,7 @@ var dflt = function(dat, lvl, plvl, pre, post, st) {
|
|
|
461
461
|
var mmd = Math.min(dif, nl - 2);
|
|
462
462
|
var md = 0;
|
|
463
463
|
for (var j = 0; j < mmd; ++j) {
|
|
464
|
-
var ti =
|
|
464
|
+
var ti = i3 - dif + j & 32767;
|
|
465
465
|
var pti = prev[ti];
|
|
466
466
|
var cd = ti - pti & 32767;
|
|
467
467
|
if (cd > md)
|
|
@@ -479,32 +479,32 @@ var dflt = function(dat, lvl, plvl, pre, post, st) {
|
|
|
479
479
|
eb += fleb[lin] + fdeb[din];
|
|
480
480
|
++lf[257 + lin];
|
|
481
481
|
++df[din];
|
|
482
|
-
wi =
|
|
482
|
+
wi = i3 + l;
|
|
483
483
|
++lc_1;
|
|
484
484
|
} else {
|
|
485
|
-
syms[li++] = dat[
|
|
486
|
-
++lf[dat[
|
|
485
|
+
syms[li++] = dat[i3];
|
|
486
|
+
++lf[dat[i3]];
|
|
487
487
|
}
|
|
488
488
|
}
|
|
489
489
|
}
|
|
490
|
-
for (
|
|
491
|
-
syms[li++] = dat[
|
|
492
|
-
++lf[dat[
|
|
490
|
+
for (i3 = Math.max(i3, wi); i3 < s; ++i3) {
|
|
491
|
+
syms[li++] = dat[i3];
|
|
492
|
+
++lf[dat[i3]];
|
|
493
493
|
}
|
|
494
|
-
pos = wblk(dat, w, lst, syms, lf, df, eb, li, bs,
|
|
494
|
+
pos = wblk(dat, w, lst, syms, lf, df, eb, li, bs, i3 - bs, pos);
|
|
495
495
|
if (!lst) {
|
|
496
496
|
st.r = pos & 7 | w[pos / 8 | 0] << 3;
|
|
497
497
|
pos -= 7;
|
|
498
|
-
st.h = head, st.p = prev, st.i =
|
|
498
|
+
st.h = head, st.p = prev, st.i = i3, st.w = wi;
|
|
499
499
|
}
|
|
500
500
|
} else {
|
|
501
|
-
for (var
|
|
502
|
-
var e =
|
|
501
|
+
for (var i3 = st.w || 0; i3 < s + lst; i3 += 65535) {
|
|
502
|
+
var e = i3 + 65535;
|
|
503
503
|
if (e >= s) {
|
|
504
504
|
w[pos / 8 | 0] = lst;
|
|
505
505
|
e = s;
|
|
506
506
|
}
|
|
507
|
-
pos = wfblk(w, pos + 1, dat.subarray(
|
|
507
|
+
pos = wfblk(w, pos + 1, dat.subarray(i3, e));
|
|
508
508
|
}
|
|
509
509
|
st.i = s;
|
|
510
510
|
}
|
|
@@ -512,11 +512,11 @@ var dflt = function(dat, lvl, plvl, pre, post, st) {
|
|
|
512
512
|
};
|
|
513
513
|
var crct = /* @__PURE__ */ (function() {
|
|
514
514
|
var t = new Int32Array(256);
|
|
515
|
-
for (var
|
|
516
|
-
var c =
|
|
515
|
+
for (var i3 = 0; i3 < 256; ++i3) {
|
|
516
|
+
var c = i3, k = 9;
|
|
517
517
|
while (--k)
|
|
518
518
|
c = (c & 1 && -306674912) ^ c >>> 1;
|
|
519
|
-
t[
|
|
519
|
+
t[i3] = c;
|
|
520
520
|
}
|
|
521
521
|
return t;
|
|
522
522
|
})();
|
|
@@ -525,8 +525,8 @@ var crc = function() {
|
|
|
525
525
|
return {
|
|
526
526
|
p: function(d) {
|
|
527
527
|
var cr = c;
|
|
528
|
-
for (var
|
|
529
|
-
cr = crct[cr & 255 ^ d[
|
|
528
|
+
for (var i3 = 0; i3 < d.length; ++i3)
|
|
529
|
+
cr = crct[cr & 255 ^ d[i3]] ^ cr >>> 8;
|
|
530
530
|
c = cr;
|
|
531
531
|
},
|
|
532
532
|
d: function() {
|
|
@@ -587,8 +587,8 @@ try {
|
|
|
587
587
|
function strToU8(str, latin1) {
|
|
588
588
|
if (latin1) {
|
|
589
589
|
var ar_1 = new u8(str.length);
|
|
590
|
-
for (var
|
|
591
|
-
ar_1[
|
|
590
|
+
for (var i3 = 0; i3 < str.length; ++i3)
|
|
591
|
+
ar_1[i3] = str.charCodeAt(i3);
|
|
592
592
|
return ar_1;
|
|
593
593
|
}
|
|
594
594
|
if (te)
|
|
@@ -599,19 +599,19 @@ function strToU8(str, latin1) {
|
|
|
599
599
|
var w = function(v) {
|
|
600
600
|
ar[ai++] = v;
|
|
601
601
|
};
|
|
602
|
-
for (var
|
|
602
|
+
for (var i3 = 0; i3 < l; ++i3) {
|
|
603
603
|
if (ai + 5 > ar.length) {
|
|
604
|
-
var n = new u8(ai + 8 + (l -
|
|
604
|
+
var n = new u8(ai + 8 + (l - i3 << 1));
|
|
605
605
|
n.set(ar);
|
|
606
606
|
ar = n;
|
|
607
607
|
}
|
|
608
|
-
var c = str.charCodeAt(
|
|
608
|
+
var c = str.charCodeAt(i3);
|
|
609
609
|
if (c < 128 || latin1)
|
|
610
610
|
w(c);
|
|
611
611
|
else if (c < 2048)
|
|
612
612
|
w(192 | c >> 6), w(128 | c & 63);
|
|
613
613
|
else if (c > 55295 && c < 57344)
|
|
614
|
-
c = 65536 + (c & 1023 << 10) | str.charCodeAt(++
|
|
614
|
+
c = 65536 + (c & 1023 << 10) | str.charCodeAt(++i3) & 1023, w(240 | c >> 18), w(128 | c >> 12 & 63), w(128 | c >> 6 & 63), w(128 | c & 63);
|
|
615
615
|
else
|
|
616
616
|
w(224 | c >> 12), w(128 | c >> 6 & 63), w(128 | c & 63);
|
|
617
617
|
}
|
|
@@ -630,7 +630,7 @@ var exfl = function(ex) {
|
|
|
630
630
|
return le;
|
|
631
631
|
};
|
|
632
632
|
var wzh = function(d, b, f, fn, u, c, ce, co) {
|
|
633
|
-
var
|
|
633
|
+
var fl3 = fn.length, ex = f.extra, col = co && co.length;
|
|
634
634
|
var exl = exfl(ex);
|
|
635
635
|
wbytes(d, b, ce != null ? 33639248 : 67324752), b += 4;
|
|
636
636
|
if (ce != null)
|
|
@@ -647,7 +647,7 @@ var wzh = function(d, b, f, fn, u, c, ce, co) {
|
|
|
647
647
|
wbytes(d, b + 4, c < 0 ? -c - 2 : c);
|
|
648
648
|
wbytes(d, b + 8, f.size);
|
|
649
649
|
}
|
|
650
|
-
wbytes(d, b + 12,
|
|
650
|
+
wbytes(d, b + 12, fl3);
|
|
651
651
|
wbytes(d, b + 14, exl), b += 16;
|
|
652
652
|
if (ce != null) {
|
|
653
653
|
wbytes(d, b, col);
|
|
@@ -655,7 +655,7 @@ var wzh = function(d, b, f, fn, u, c, ce, co) {
|
|
|
655
655
|
wbytes(d, b + 10, ce), b += 14;
|
|
656
656
|
}
|
|
657
657
|
d.set(fn, b);
|
|
658
|
-
b +=
|
|
658
|
+
b += fl3;
|
|
659
659
|
if (exl) {
|
|
660
660
|
for (var k in ex) {
|
|
661
661
|
var exf = ex[k], l = exf.length;
|
|
@@ -684,7 +684,7 @@ function zipSync(data, opts) {
|
|
|
684
684
|
var o = 0;
|
|
685
685
|
var tot = 0;
|
|
686
686
|
for (var fn in r) {
|
|
687
|
-
var
|
|
687
|
+
var _a3 = r[fn], file = _a3[0], p = _a3[1];
|
|
688
688
|
var compression = p.level == 0 ? 0 : 8;
|
|
689
689
|
var f = strToU8(fn), s = f.length;
|
|
690
690
|
var com = p.comment, m = com && strToU8(com), ms = m && m.length;
|
|
@@ -708,8 +708,8 @@ function zipSync(data, opts) {
|
|
|
708
708
|
tot += 76 + 2 * (s + exl) + (ms || 0) + l;
|
|
709
709
|
}
|
|
710
710
|
var out = new u8(tot + 22), oe = o, cdl = tot - o;
|
|
711
|
-
for (var
|
|
712
|
-
var f = files[
|
|
711
|
+
for (var i3 = 0; i3 < files.length; ++i3) {
|
|
712
|
+
var f = files[i3];
|
|
713
713
|
wzh(out, f.o, f, f.f, f.u, f.c.length);
|
|
714
714
|
var badd = 30 + f.f.length + exfl(f.extra);
|
|
715
715
|
out.set(f.c, f.o + badd);
|
|
@@ -730,9 +730,6 @@ import { join, resolve } from "node:path";
|
|
|
730
730
|
// packages/server/src/allowlist.ts
|
|
731
731
|
import { ZodError } from "zod";
|
|
732
732
|
|
|
733
|
-
// packages/server/src/adapters/azure-devops.ts
|
|
734
|
-
import { readFile } from "node:fs/promises";
|
|
735
|
-
|
|
736
733
|
// packages/shared/src/board-config.ts
|
|
737
734
|
import { z as z2 } from "zod";
|
|
738
735
|
|
|
@@ -793,6 +790,17 @@ var githubActionsBuildEventsSchema = z2.array(githubActionsBuildEventSchema).min
|
|
|
793
790
|
var attentionTreatments = ["beacon", "alarm", "steady"];
|
|
794
791
|
var attentionTreatmentSchema = z2.enum(attentionTreatments);
|
|
795
792
|
var httpValueJsonPathSchema = z2.string().regex(/^\$(?:\.[A-Za-z_][A-Za-z0-9_]*|\[\d+\])*$/, "must be a simple JSON path");
|
|
793
|
+
var testResultsArtifactSchema = z2.object({
|
|
794
|
+
artifact: z2.string().min(1).max(128),
|
|
795
|
+
entry: z2.string().regex(/^[A-Za-z0-9][A-Za-z0-9._-]*\.json$/, "must be a root-level JSON file")
|
|
796
|
+
});
|
|
797
|
+
var testCountPanelSchema = z2.object({
|
|
798
|
+
id: z2.string().min(1),
|
|
799
|
+
type: z2.literal("test-count"),
|
|
800
|
+
source: z2.string().min(1),
|
|
801
|
+
pipeline: z2.string().min(1),
|
|
802
|
+
test_results: testResultsArtifactSchema
|
|
803
|
+
});
|
|
796
804
|
var httpValueFactSchema = z2.object({
|
|
797
805
|
/** Stable address below the panel; labels and ordering may change without repointing it. */
|
|
798
806
|
id: z2.string().min(1),
|
|
@@ -852,7 +860,9 @@ var panelSchema = z2.looseObject({
|
|
|
852
860
|
/** Up to four independently fetched source-agnostic readings in one visual panel. */
|
|
853
861
|
facts: httpValueGroupedPanelSchema.shape.facts.optional(),
|
|
854
862
|
/** Optional GitHub Actions-only restriction on which workflow triggers count as build evidence. */
|
|
855
|
-
build_events: githubActionsBuildEventsSchema.optional()
|
|
863
|
+
build_events: githubActionsBuildEventsSchema.optional(),
|
|
864
|
+
/** Workflow-run artifact carrying a test-count panel's summary. */
|
|
865
|
+
test_results: testResultsArtifactSchema.optional()
|
|
856
866
|
}).superRefine((panel, ctx) => {
|
|
857
867
|
if ("display" in panel) {
|
|
858
868
|
ctx.addIssue({
|
|
@@ -862,6 +872,28 @@ var panelSchema = z2.looseObject({
|
|
|
862
872
|
params: { constraint: "display was removed; use density" }
|
|
863
873
|
});
|
|
864
874
|
}
|
|
875
|
+
if (panel.type === "test-count") {
|
|
876
|
+
if (!panel.source)
|
|
877
|
+
ctx.addIssue({ code: "custom", path: ["source"], message: "test-count requires a source" });
|
|
878
|
+
if (typeof panel.pipeline !== "string" || !panel.pipeline)
|
|
879
|
+
ctx.addIssue({
|
|
880
|
+
code: "custom",
|
|
881
|
+
path: ["pipeline"],
|
|
882
|
+
message: "test-count requires a workflow filename"
|
|
883
|
+
});
|
|
884
|
+
if (!panel.test_results)
|
|
885
|
+
ctx.addIssue({
|
|
886
|
+
code: "custom",
|
|
887
|
+
path: ["test_results"],
|
|
888
|
+
message: "test-count requires test_results artifact configuration"
|
|
889
|
+
});
|
|
890
|
+
} else if (panel.test_results) {
|
|
891
|
+
ctx.addIssue({
|
|
892
|
+
code: "custom",
|
|
893
|
+
path: ["test_results"],
|
|
894
|
+
message: "test_results is only supported by test-count panels"
|
|
895
|
+
});
|
|
896
|
+
}
|
|
865
897
|
if (panel.type !== "http-value") return;
|
|
866
898
|
if (panel.facts) {
|
|
867
899
|
if (panel.url !== void 0)
|
|
@@ -1237,6 +1269,18 @@ var pipelineStatusSchema = z4.object({
|
|
|
1237
1269
|
/** When this workflow run was last updated by its source, distinct from our observation time. */
|
|
1238
1270
|
sourceUpdatedAt: z4.iso.datetime().optional()
|
|
1239
1271
|
});
|
|
1272
|
+
var testCountSchema = z4.discriminatedUnion("status", [
|
|
1273
|
+
z4.object({
|
|
1274
|
+
type: z4.literal("test-count"),
|
|
1275
|
+
status: z4.literal("reported"),
|
|
1276
|
+
total: z4.number().int().nonnegative(),
|
|
1277
|
+
passed: z4.number().int().nonnegative().optional(),
|
|
1278
|
+
failed: z4.number().int().nonnegative().optional(),
|
|
1279
|
+
skipped: z4.number().int().nonnegative().optional()
|
|
1280
|
+
}),
|
|
1281
|
+
z4.object({ type: z4.literal("test-count"), status: z4.literal("pending") }),
|
|
1282
|
+
z4.object({ type: z4.literal("test-count"), status: z4.literal("not-reported") })
|
|
1283
|
+
]);
|
|
1240
1284
|
var pullRequestHealthItemSchema = z4.object({
|
|
1241
1285
|
label: z4.string().min(1),
|
|
1242
1286
|
status: pipelineStatusSchema.shape.status,
|
|
@@ -1295,301 +1339,2000 @@ var securityDetailsResponseSchema = z5.strictObject({
|
|
|
1295
1339
|
])
|
|
1296
1340
|
});
|
|
1297
1341
|
|
|
1298
|
-
// packages/server/src/adapters/
|
|
1299
|
-
import { z as
|
|
1300
|
-
|
|
1301
|
-
|
|
1302
|
-
|
|
1303
|
-
|
|
1304
|
-
pipeline: z6.number().int().positive()
|
|
1305
|
-
});
|
|
1306
|
-
var buildSchema = z6.object({
|
|
1307
|
-
id: z6.number().int().positive(),
|
|
1308
|
-
buildNumber: z6.string().min(1),
|
|
1309
|
-
status: z6.string().nullable().optional(),
|
|
1310
|
-
result: z6.string().nullable().optional(),
|
|
1311
|
-
sourceBranch: z6.string().min(1).nullable().optional(),
|
|
1312
|
-
startTime: z6.string().nullable().optional(),
|
|
1313
|
-
finishTime: z6.string().nullable().optional(),
|
|
1314
|
-
lastChangedDate: z6.string().nullable().optional()
|
|
1315
|
-
});
|
|
1316
|
-
var buildsSchema = z6.object({ value: z6.array(buildSchema) });
|
|
1317
|
-
var timelineSchema = z6.object({
|
|
1318
|
-
records: z6.array(
|
|
1319
|
-
z6.object({
|
|
1320
|
-
id: z6.string().min(1),
|
|
1321
|
-
parentId: z6.string().min(1).nullable().optional(),
|
|
1322
|
-
type: z6.string().min(1),
|
|
1323
|
-
name: z6.string().min(1),
|
|
1324
|
-
state: z6.string().nullable().optional()
|
|
1325
|
-
})
|
|
1326
|
-
)
|
|
1327
|
-
});
|
|
1328
|
-
function permittedAzureDevOpsCalls(panel, source) {
|
|
1329
|
-
const { panel: parsedPanel, source: parsedSource } = z6.object({ panel: pipelinePanelSchema, source: azureDevOpsSourceSchema }).parse({ panel, source });
|
|
1330
|
-
return [buildsCall(parsedPanel.pipeline, parsedSource)];
|
|
1331
|
-
}
|
|
1332
|
-
var delegatedTokenFileSchema = z6.object({
|
|
1333
|
-
accessToken: z6.string().min(1),
|
|
1334
|
-
expiresAt: z6.string().min(1)
|
|
1335
|
-
});
|
|
1336
|
-
function buildsCall(definitionId, source) {
|
|
1337
|
-
const url = apiUrl(source, "build/builds");
|
|
1338
|
-
url.searchParams.set("definitions", String(definitionId));
|
|
1339
|
-
if (source.branch) url.searchParams.set("branchName", adoBranch(source.branch));
|
|
1340
|
-
url.searchParams.set("queryOrder", "queueTimeDescending");
|
|
1341
|
-
url.searchParams.set("$top", "1");
|
|
1342
|
-
return { url: url.toString(), headers: new Headers({ accept: "application/json" }) };
|
|
1342
|
+
// packages/server/src/adapters/github-actions.ts
|
|
1343
|
+
import { z as z7 } from "zod";
|
|
1344
|
+
|
|
1345
|
+
// packages/server/src/credentials.ts
|
|
1346
|
+
function environmentCredentials(env = process.env) {
|
|
1347
|
+
return { get: (name) => env[name] };
|
|
1343
1348
|
}
|
|
1344
|
-
|
|
1345
|
-
|
|
1346
|
-
|
|
1347
|
-
|
|
1348
|
-
|
|
1349
|
-
|
|
1349
|
+
|
|
1350
|
+
// packages/server/src/github-auth.ts
|
|
1351
|
+
import { createSign } from "node:crypto";
|
|
1352
|
+
|
|
1353
|
+
// packages/server/src/upstream.ts
|
|
1354
|
+
function publicErrorMessage(kind) {
|
|
1355
|
+
switch (kind) {
|
|
1356
|
+
case "unreachable":
|
|
1357
|
+
return "The source could not be reached. Check its address and network connectivity.";
|
|
1358
|
+
case "unauthorized":
|
|
1359
|
+
return "The dashboard is not authorized to read this source. Check the configured access.";
|
|
1360
|
+
case "not-found":
|
|
1361
|
+
return "The configured source was not found. Check the board configuration.";
|
|
1362
|
+
case "no-runs":
|
|
1363
|
+
return "No matching workflow runs were found. Check the configured workflow and branch.";
|
|
1364
|
+
case "upstream-error":
|
|
1365
|
+
return "The source returned an unreadable response. Check the source service and configuration.";
|
|
1366
|
+
}
|
|
1350
1367
|
}
|
|
1351
|
-
function
|
|
1352
|
-
|
|
1368
|
+
function forwardValidators(requestHeaders, upstreamHeaders) {
|
|
1369
|
+
for (const name of ["if-none-match", "if-modified-since"]) {
|
|
1370
|
+
const value2 = requestHeaders.get(name);
|
|
1371
|
+
if (value2) upstreamHeaders.set(name, value2);
|
|
1372
|
+
}
|
|
1353
1373
|
}
|
|
1354
|
-
|
|
1355
|
-
|
|
1356
|
-
|
|
1357
|
-
var pipelinePanelSchema2 = z7.object({
|
|
1358
|
-
id: z7.string().min(1),
|
|
1359
|
-
type: z7.literal("pipeline-status"),
|
|
1360
|
-
source: z7.string().min(1),
|
|
1361
|
-
/** GitHub accepts a workflow filename or numeric workflow id in this URL segment. */
|
|
1362
|
-
pipeline: z7.string().min(1)
|
|
1363
|
-
});
|
|
1364
|
-
var pullRequestHealthPanelSchema = z7.object({
|
|
1365
|
-
id: z7.string().min(1),
|
|
1366
|
-
type: z7.literal("pull-request-health"),
|
|
1367
|
-
source: z7.string().min(1),
|
|
1368
|
-
base_branch: z7.string().min(1),
|
|
1369
|
-
update_workflows: z7.array(
|
|
1370
|
-
z7.object({
|
|
1371
|
-
workflow: z7.string().min(1),
|
|
1372
|
-
branch_prefixes: z7.array(z7.string().min(1)).min(1)
|
|
1373
|
-
})
|
|
1374
|
-
).min(1),
|
|
1375
|
-
build_workflow: z7.string().min(1),
|
|
1376
|
-
build_events: githubActionsBuildEventsSchema.optional()
|
|
1377
|
-
});
|
|
1378
|
-
var runSchema = z7.object({
|
|
1379
|
-
id: z7.number().int().positive().optional(),
|
|
1380
|
-
status: z7.string(),
|
|
1381
|
-
conclusion: z7.string().nullable(),
|
|
1382
|
-
name: z7.string().min(1),
|
|
1383
|
-
html_url: z7.url(),
|
|
1384
|
-
/** The GitHub Actions trigger that started this run. */
|
|
1385
|
-
event: z7.string().min(1).optional(),
|
|
1386
|
-
/** The branch that produced this run; absent for some event types. */
|
|
1387
|
-
head_branch: z7.string().min(1).nullable().optional(),
|
|
1388
|
-
// Timestamp quality should only remove timing advice, never make an otherwise useful run unreadable.
|
|
1389
|
-
run_started_at: z7.string().nullable().optional(),
|
|
1390
|
-
updated_at: z7.string().optional(),
|
|
1391
|
-
created_at: z7.string().optional()
|
|
1392
|
-
});
|
|
1393
|
-
var runsSchema = z7.object({ workflow_runs: z7.array(runSchema) });
|
|
1394
|
-
var jobsSchema = z7.object({
|
|
1395
|
-
jobs: z7.array(
|
|
1396
|
-
z7.object({
|
|
1397
|
-
name: z7.string().min(1),
|
|
1398
|
-
status: z7.string(),
|
|
1399
|
-
steps: z7.array(z7.object({ name: z7.string().min(1), status: z7.string() })).optional()
|
|
1400
|
-
})
|
|
1401
|
-
)
|
|
1402
|
-
});
|
|
1403
|
-
var pullRequestsSchema = z7.array(
|
|
1404
|
-
z7.object({
|
|
1405
|
-
number: z7.number().int().positive(),
|
|
1406
|
-
html_url: z7.url(),
|
|
1407
|
-
head: z7.object({ ref: z7.string().min(1) }),
|
|
1408
|
-
base: z7.object({ ref: z7.string().min(1) })
|
|
1409
|
-
})
|
|
1410
|
-
);
|
|
1411
|
-
function permittedGithubActionsCalls(panel, source, _credentials) {
|
|
1412
|
-
const { panel: parsedPanel, source: parsedSource } = z7.object({ panel: pipelinePanelSchema2, source: githubActionsSourceSchema }).parse({ panel, source });
|
|
1413
|
-
const url = new URL(
|
|
1414
|
-
`https://api.github.com/repos/${parsedSource.repo}/actions/workflows/${encodeURIComponent(parsedPanel.pipeline)}/runs`
|
|
1415
|
-
);
|
|
1416
|
-
if (parsedSource.branch) url.searchParams.set("branch", parsedSource.branch);
|
|
1417
|
-
url.searchParams.set("per_page", "1");
|
|
1418
|
-
return [{ url: url.toString(), headers: new Headers() }];
|
|
1374
|
+
function observedAt(upstreamDate) {
|
|
1375
|
+
const parsed = upstreamDate ? new Date(upstreamDate) : void 0;
|
|
1376
|
+
return parsed && !Number.isNaN(parsed.valueOf()) ? parsed.toISOString() : (/* @__PURE__ */ new Date()).toISOString();
|
|
1419
1377
|
}
|
|
1420
|
-
function
|
|
1421
|
-
const { panel: parsed } = z7.object({ panel: pullRequestHealthPanelSchema }).parse({ panel });
|
|
1378
|
+
function upstreamErrorEnvelope(args) {
|
|
1422
1379
|
return {
|
|
1423
|
-
|
|
1424
|
-
|
|
1425
|
-
|
|
1426
|
-
|
|
1427
|
-
|
|
1428
|
-
|
|
1429
|
-
|
|
1430
|
-
|
|
1380
|
+
panelId: args.panelId,
|
|
1381
|
+
state: "error",
|
|
1382
|
+
observedAt: observedAt(args.upstreamDate),
|
|
1383
|
+
link: publicLink(args.link),
|
|
1384
|
+
error: {
|
|
1385
|
+
kind: args.kind,
|
|
1386
|
+
// Raw failures regularly contain URLs, query values, response fragments, or credentials.
|
|
1387
|
+
// The specific evidence stays server-side; the browser gets this fixed actionable vocabulary.
|
|
1388
|
+
message: publicErrorMessage(args.kind)
|
|
1431
1389
|
}
|
|
1432
1390
|
};
|
|
1433
1391
|
}
|
|
1434
|
-
|
|
1435
|
-
|
|
1436
|
-
|
|
1437
|
-
|
|
1438
|
-
|
|
1439
|
-
|
|
1440
|
-
|
|
1441
|
-
}
|
|
1442
|
-
|
|
1443
|
-
|
|
1444
|
-
name: z8.string().min(1).nullable().optional(),
|
|
1445
|
-
status: z8.string(),
|
|
1446
|
-
ref: z8.string().min(1).nullable().optional(),
|
|
1447
|
-
created_at: z8.string().nullable().optional(),
|
|
1448
|
-
updated_at: z8.string().nullable().optional(),
|
|
1449
|
-
web_url: z8.url()
|
|
1450
|
-
});
|
|
1451
|
-
function permittedGitlabCiCalls(panel, source) {
|
|
1452
|
-
const { source: parsedSource } = z8.object({ panel: pipelinePanelSchema3, source: gitlabCiSourceSchema }).parse({ panel, source });
|
|
1453
|
-
return [pipelinesCall(parsedSource)];
|
|
1392
|
+
function publicLink(value2) {
|
|
1393
|
+
if (!value2) return null;
|
|
1394
|
+
try {
|
|
1395
|
+
const url = new URL(value2);
|
|
1396
|
+
url.search = "";
|
|
1397
|
+
url.hash = "";
|
|
1398
|
+
return url.toString();
|
|
1399
|
+
} catch {
|
|
1400
|
+
return null;
|
|
1401
|
+
}
|
|
1454
1402
|
}
|
|
1455
|
-
function
|
|
1456
|
-
|
|
1457
|
-
url.pathname = `${url.pathname.replace(/\/$/, "")}/api/v4/projects/${encodeURIComponent(source.project)}/pipelines`;
|
|
1458
|
-
url.searchParams.set("per_page", "1");
|
|
1459
|
-
if (source.branch) url.searchParams.set("ref", source.branch);
|
|
1460
|
-
return { url: url.toString(), headers: new Headers({ accept: "application/json" }) };
|
|
1403
|
+
function upstreamErrorResponse(envelope) {
|
|
1404
|
+
return new Response(JSON.stringify(envelope), { status: 200 });
|
|
1461
1405
|
}
|
|
1462
|
-
|
|
1463
|
-
|
|
1464
|
-
|
|
1465
|
-
|
|
1466
|
-
const grouped = httpValueGroupedPanelSchema.safeParse(panel);
|
|
1467
|
-
const urls = grouped.success ? grouped.data.facts.map((fact) => fact.url) : [z9.object({ panel: httpValueScalarPanelSchema }).parse({ panel }).panel.url];
|
|
1468
|
-
return urls.map(permittedCall);
|
|
1406
|
+
function upstreamErrorKind(status) {
|
|
1407
|
+
if (status === 401 || status === 403) return "unauthorized";
|
|
1408
|
+
if (status === 404) return "not-found";
|
|
1409
|
+
return "upstream-error";
|
|
1469
1410
|
}
|
|
1470
|
-
function
|
|
1471
|
-
const
|
|
1472
|
-
|
|
1473
|
-
throw new Error("http-value URLs must use http or https");
|
|
1474
|
-
return { url: url.toString(), headers: new Headers({ accept: "application/json, text/plain" }) };
|
|
1411
|
+
function safeNetworkCode(error) {
|
|
1412
|
+
const code = error && typeof error === "object" ? error.code : void 0;
|
|
1413
|
+
return code === "ECONNREFUSED" || code === "ENOTFOUND" || code === "ETIMEDOUT" || code === "EAI_AGAIN" ? code : void 0;
|
|
1475
1414
|
}
|
|
1476
1415
|
|
|
1477
|
-
// packages/server/src/
|
|
1478
|
-
var
|
|
1479
|
-
constructor(
|
|
1480
|
-
super(
|
|
1481
|
-
this.
|
|
1416
|
+
// packages/server/src/github-auth.ts
|
|
1417
|
+
var GithubAuthenticationError = class extends Error {
|
|
1418
|
+
constructor() {
|
|
1419
|
+
super("GitHub authentication could not be completed.");
|
|
1420
|
+
this.name = "GithubAuthenticationError";
|
|
1482
1421
|
}
|
|
1483
|
-
diagnostics;
|
|
1484
1422
|
};
|
|
1485
|
-
function
|
|
1486
|
-
|
|
1487
|
-
|
|
1488
|
-
|
|
1489
|
-
|
|
1490
|
-
|
|
1491
|
-
|
|
1492
|
-
|
|
1493
|
-
|
|
1494
|
-
const
|
|
1495
|
-
const
|
|
1496
|
-
|
|
1423
|
+
function createGithubClient(credentials, now = Date.now) {
|
|
1424
|
+
const tokens = /* @__PURE__ */ new Map();
|
|
1425
|
+
const pending = /* @__PURE__ */ new Map();
|
|
1426
|
+
async function installationToken(source, fetcher, refresh = false) {
|
|
1427
|
+
const app = source.github_app;
|
|
1428
|
+
if (!app) return void 0;
|
|
1429
|
+
const appId = requiredCredential(credentials, app.app_id_env);
|
|
1430
|
+
const privateKey = requiredCredential(credentials, app.private_key_env);
|
|
1431
|
+
const installationId = requiredCredential(credentials, app.installation_id_env);
|
|
1432
|
+
const cacheKey = `${appId}:${installationId}:${app.private_key_env}`;
|
|
1433
|
+
const cached = tokens.get(cacheKey);
|
|
1434
|
+
if (!refresh && cached && cached.expiresAt > now() + 6e4)
|
|
1435
|
+
return { token: cached.token, cacheKey };
|
|
1436
|
+
const existing = pending.get(cacheKey);
|
|
1437
|
+
if (existing) return { token: await existing, cacheKey };
|
|
1438
|
+
const exchange = exchangeInstallationToken({ appId, privateKey, installationId, fetcher, now }).then(({ token, expiresAt }) => {
|
|
1439
|
+
tokens.set(cacheKey, { token, expiresAt });
|
|
1440
|
+
return token;
|
|
1441
|
+
}).catch((error) => {
|
|
1442
|
+
if (error instanceof GithubAuthenticationError) throw error;
|
|
1443
|
+
throw new GithubAuthenticationError();
|
|
1444
|
+
});
|
|
1445
|
+
pending.set(cacheKey, exchange);
|
|
1446
|
+
try {
|
|
1447
|
+
return { token: await exchange, cacheKey };
|
|
1448
|
+
} finally {
|
|
1449
|
+
pending.delete(cacheKey);
|
|
1450
|
+
}
|
|
1497
1451
|
}
|
|
1498
|
-
return
|
|
1452
|
+
return {
|
|
1453
|
+
async get({ source, url, requestHeaders, fetcher }) {
|
|
1454
|
+
const headers = githubHeaders(requestHeaders);
|
|
1455
|
+
if (source.token_env)
|
|
1456
|
+
headers.set("authorization", `Bearer ${requiredCredential(credentials, source.token_env)}`);
|
|
1457
|
+
const appToken = await installationToken(source, fetcher);
|
|
1458
|
+
if (appToken) headers.set("authorization", `Bearer ${appToken.token}`);
|
|
1459
|
+
const response = await fetcher(url, { headers });
|
|
1460
|
+
if (!appToken || response.status !== 401) return response;
|
|
1461
|
+
tokens.delete(appToken.cacheKey);
|
|
1462
|
+
const refreshed = await installationToken(source, fetcher, true);
|
|
1463
|
+
if (!refreshed) return response;
|
|
1464
|
+
const replayHeaders = githubHeaders(requestHeaders);
|
|
1465
|
+
replayHeaders.set("authorization", `Bearer ${refreshed.token}`);
|
|
1466
|
+
return fetcher(url, { headers: replayHeaders });
|
|
1467
|
+
}
|
|
1468
|
+
};
|
|
1499
1469
|
}
|
|
1500
|
-
function
|
|
1501
|
-
|
|
1502
|
-
|
|
1503
|
-
|
|
1504
|
-
constraint: correctiveConstraint(issue)
|
|
1505
|
-
}));
|
|
1470
|
+
function githubHeaders(requestHeaders) {
|
|
1471
|
+
const headers = new Headers({ accept: "application/vnd.github+json" });
|
|
1472
|
+
forwardValidators(requestHeaders, headers);
|
|
1473
|
+
return headers;
|
|
1506
1474
|
}
|
|
1507
|
-
function
|
|
1508
|
-
|
|
1509
|
-
|
|
1510
|
-
|
|
1511
|
-
|
|
1512
|
-
|
|
1513
|
-
|
|
1514
|
-
|
|
1515
|
-
|
|
1516
|
-
|
|
1517
|
-
|
|
1518
|
-
|
|
1519
|
-
|
|
1520
|
-
|
|
1521
|
-
|
|
1522
|
-
|
|
1523
|
-
|
|
1475
|
+
async function exchangeInstallationToken(args) {
|
|
1476
|
+
let jwt;
|
|
1477
|
+
try {
|
|
1478
|
+
jwt = createAppJwt(args.appId, args.privateKey, args.now());
|
|
1479
|
+
} catch {
|
|
1480
|
+
throw new GithubAuthenticationError();
|
|
1481
|
+
}
|
|
1482
|
+
let response;
|
|
1483
|
+
try {
|
|
1484
|
+
response = await args.fetcher(
|
|
1485
|
+
`https://api.github.com/app/installations/${encodeURIComponent(args.installationId)}/access_tokens`,
|
|
1486
|
+
{
|
|
1487
|
+
method: "POST",
|
|
1488
|
+
headers: new Headers({
|
|
1489
|
+
accept: "application/vnd.github+json",
|
|
1490
|
+
authorization: `Bearer ${jwt}`,
|
|
1491
|
+
"content-type": "application/json"
|
|
1492
|
+
})
|
|
1493
|
+
}
|
|
1494
|
+
);
|
|
1495
|
+
} catch {
|
|
1496
|
+
throw new GithubAuthenticationError();
|
|
1524
1497
|
}
|
|
1498
|
+
if (!response.ok) throw new GithubAuthenticationError();
|
|
1499
|
+
const body = await response.json();
|
|
1500
|
+
if (!body.token || !body.expires_at) throw new GithubAuthenticationError();
|
|
1501
|
+
const expiresAt = new Date(body.expires_at).valueOf();
|
|
1502
|
+
if (!Number.isFinite(expiresAt)) throw new GithubAuthenticationError();
|
|
1503
|
+
return { token: body.token, expiresAt };
|
|
1525
1504
|
}
|
|
1526
|
-
|
|
1527
|
-
|
|
1528
|
-
|
|
1529
|
-
|
|
1505
|
+
function createAppJwt(appId, privateKey, now = Date.now()) {
|
|
1506
|
+
const issuedAt = Math.floor(now / 1e3) - 60;
|
|
1507
|
+
const header = base64url(JSON.stringify({ alg: "RS256", typ: "JWT" }));
|
|
1508
|
+
const payload = base64url(JSON.stringify({ iat: issuedAt, exp: issuedAt + 540, iss: appId }));
|
|
1509
|
+
const signingInput = `${header}.${payload}`;
|
|
1510
|
+
const signer = createSign("RSA-SHA256");
|
|
1511
|
+
signer.update(signingInput);
|
|
1512
|
+
signer.end();
|
|
1513
|
+
return `${signingInput}.${base64url(signer.sign(privateKey))}`;
|
|
1530
1514
|
}
|
|
1531
|
-
function
|
|
1532
|
-
const
|
|
1533
|
-
|
|
1534
|
-
|
|
1535
|
-
|
|
1536
|
-
|
|
1537
|
-
|
|
1538
|
-
|
|
1539
|
-
|
|
1540
|
-
|
|
1541
|
-
|
|
1542
|
-
|
|
1543
|
-
|
|
1544
|
-
|
|
1545
|
-
|
|
1546
|
-
|
|
1547
|
-
|
|
1548
|
-
|
|
1549
|
-
|
|
1550
|
-
|
|
1551
|
-
|
|
1552
|
-
|
|
1553
|
-
|
|
1554
|
-
|
|
1555
|
-
|
|
1556
|
-
|
|
1557
|
-
|
|
1558
|
-
|
|
1559
|
-
|
|
1560
|
-
|
|
1561
|
-
|
|
1562
|
-
|
|
1563
|
-
|
|
1564
|
-
|
|
1565
|
-
|
|
1566
|
-
|
|
1567
|
-
|
|
1568
|
-
|
|
1569
|
-
|
|
1570
|
-
|
|
1515
|
+
function requiredCredential(credentials, name) {
|
|
1516
|
+
const value2 = credentials.get(name);
|
|
1517
|
+
if (value2) return value2;
|
|
1518
|
+
throw new GithubAuthenticationError();
|
|
1519
|
+
}
|
|
1520
|
+
function base64url(value2) {
|
|
1521
|
+
return Buffer.from(value2).toString("base64url");
|
|
1522
|
+
}
|
|
1523
|
+
|
|
1524
|
+
// node_modules/fflate/esm/browser.js
|
|
1525
|
+
var u82 = Uint8Array;
|
|
1526
|
+
var u162 = Uint16Array;
|
|
1527
|
+
var i322 = Int32Array;
|
|
1528
|
+
var fleb2 = new u82([
|
|
1529
|
+
0,
|
|
1530
|
+
0,
|
|
1531
|
+
0,
|
|
1532
|
+
0,
|
|
1533
|
+
0,
|
|
1534
|
+
0,
|
|
1535
|
+
0,
|
|
1536
|
+
0,
|
|
1537
|
+
1,
|
|
1538
|
+
1,
|
|
1539
|
+
1,
|
|
1540
|
+
1,
|
|
1541
|
+
2,
|
|
1542
|
+
2,
|
|
1543
|
+
2,
|
|
1544
|
+
2,
|
|
1545
|
+
3,
|
|
1546
|
+
3,
|
|
1547
|
+
3,
|
|
1548
|
+
3,
|
|
1549
|
+
4,
|
|
1550
|
+
4,
|
|
1551
|
+
4,
|
|
1552
|
+
4,
|
|
1553
|
+
5,
|
|
1554
|
+
5,
|
|
1555
|
+
5,
|
|
1556
|
+
5,
|
|
1557
|
+
0,
|
|
1558
|
+
/* unused */
|
|
1559
|
+
0,
|
|
1560
|
+
0,
|
|
1561
|
+
/* impossible */
|
|
1562
|
+
0
|
|
1563
|
+
]);
|
|
1564
|
+
var fdeb2 = new u82([
|
|
1565
|
+
0,
|
|
1566
|
+
0,
|
|
1567
|
+
0,
|
|
1568
|
+
0,
|
|
1569
|
+
1,
|
|
1570
|
+
1,
|
|
1571
|
+
2,
|
|
1572
|
+
2,
|
|
1573
|
+
3,
|
|
1574
|
+
3,
|
|
1575
|
+
4,
|
|
1576
|
+
4,
|
|
1577
|
+
5,
|
|
1578
|
+
5,
|
|
1579
|
+
6,
|
|
1580
|
+
6,
|
|
1581
|
+
7,
|
|
1582
|
+
7,
|
|
1583
|
+
8,
|
|
1584
|
+
8,
|
|
1585
|
+
9,
|
|
1586
|
+
9,
|
|
1587
|
+
10,
|
|
1588
|
+
10,
|
|
1589
|
+
11,
|
|
1590
|
+
11,
|
|
1591
|
+
12,
|
|
1592
|
+
12,
|
|
1593
|
+
13,
|
|
1594
|
+
13,
|
|
1595
|
+
/* unused */
|
|
1596
|
+
0,
|
|
1597
|
+
0
|
|
1598
|
+
]);
|
|
1599
|
+
var clim2 = new u82([16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15]);
|
|
1600
|
+
var freb2 = function(eb, start) {
|
|
1601
|
+
var b = new u162(31);
|
|
1602
|
+
for (var i3 = 0; i3 < 31; ++i3) {
|
|
1603
|
+
b[i3] = start += 1 << eb[i3 - 1];
|
|
1604
|
+
}
|
|
1605
|
+
var r = new i322(b[30]);
|
|
1606
|
+
for (var i3 = 1; i3 < 30; ++i3) {
|
|
1607
|
+
for (var j = b[i3]; j < b[i3 + 1]; ++j) {
|
|
1608
|
+
r[j] = j - b[i3] << 5 | i3;
|
|
1609
|
+
}
|
|
1610
|
+
}
|
|
1611
|
+
return { b, r };
|
|
1612
|
+
};
|
|
1613
|
+
var _a2 = freb2(fleb2, 2);
|
|
1614
|
+
var fl2 = _a2.b;
|
|
1615
|
+
var revfl2 = _a2.r;
|
|
1616
|
+
fl2[28] = 258, revfl2[258] = 28;
|
|
1617
|
+
var _b2 = freb2(fdeb2, 0);
|
|
1618
|
+
var fd2 = _b2.b;
|
|
1619
|
+
var revfd2 = _b2.r;
|
|
1620
|
+
var rev2 = new u162(32768);
|
|
1621
|
+
for (i2 = 0; i2 < 32768; ++i2) {
|
|
1622
|
+
x2 = (i2 & 43690) >> 1 | (i2 & 21845) << 1;
|
|
1623
|
+
x2 = (x2 & 52428) >> 2 | (x2 & 13107) << 2;
|
|
1624
|
+
x2 = (x2 & 61680) >> 4 | (x2 & 3855) << 4;
|
|
1625
|
+
rev2[i2] = ((x2 & 65280) >> 8 | (x2 & 255) << 8) >> 1;
|
|
1626
|
+
}
|
|
1627
|
+
var x2;
|
|
1628
|
+
var i2;
|
|
1629
|
+
var hMap2 = (function(cd, mb, r) {
|
|
1630
|
+
var s = cd.length;
|
|
1631
|
+
var i3 = 0;
|
|
1632
|
+
var l = new u162(mb);
|
|
1633
|
+
for (; i3 < s; ++i3) {
|
|
1634
|
+
if (cd[i3])
|
|
1635
|
+
++l[cd[i3] - 1];
|
|
1636
|
+
}
|
|
1637
|
+
var le = new u162(mb);
|
|
1638
|
+
for (i3 = 1; i3 < mb; ++i3) {
|
|
1639
|
+
le[i3] = le[i3 - 1] + l[i3 - 1] << 1;
|
|
1640
|
+
}
|
|
1641
|
+
var co;
|
|
1642
|
+
if (r) {
|
|
1643
|
+
co = new u162(1 << mb);
|
|
1644
|
+
var rvb = 15 - mb;
|
|
1645
|
+
for (i3 = 0; i3 < s; ++i3) {
|
|
1646
|
+
if (cd[i3]) {
|
|
1647
|
+
var sv = i3 << 4 | cd[i3];
|
|
1648
|
+
var r_1 = mb - cd[i3];
|
|
1649
|
+
var v = le[cd[i3] - 1]++ << r_1;
|
|
1650
|
+
for (var m = v | (1 << r_1) - 1; v <= m; ++v) {
|
|
1651
|
+
co[rev2[v] >> rvb] = sv;
|
|
1652
|
+
}
|
|
1653
|
+
}
|
|
1654
|
+
}
|
|
1655
|
+
} else {
|
|
1656
|
+
co = new u162(s);
|
|
1657
|
+
for (i3 = 0; i3 < s; ++i3) {
|
|
1658
|
+
if (cd[i3]) {
|
|
1659
|
+
co[i3] = rev2[le[cd[i3] - 1]++] >> 15 - cd[i3];
|
|
1660
|
+
}
|
|
1661
|
+
}
|
|
1662
|
+
}
|
|
1663
|
+
return co;
|
|
1664
|
+
});
|
|
1665
|
+
var flt2 = new u82(288);
|
|
1666
|
+
for (i2 = 0; i2 < 144; ++i2)
|
|
1667
|
+
flt2[i2] = 8;
|
|
1668
|
+
var i2;
|
|
1669
|
+
for (i2 = 144; i2 < 256; ++i2)
|
|
1670
|
+
flt2[i2] = 9;
|
|
1671
|
+
var i2;
|
|
1672
|
+
for (i2 = 256; i2 < 280; ++i2)
|
|
1673
|
+
flt2[i2] = 7;
|
|
1674
|
+
var i2;
|
|
1675
|
+
for (i2 = 280; i2 < 288; ++i2)
|
|
1676
|
+
flt2[i2] = 8;
|
|
1677
|
+
var i2;
|
|
1678
|
+
var fdt2 = new u82(32);
|
|
1679
|
+
for (i2 = 0; i2 < 32; ++i2)
|
|
1680
|
+
fdt2[i2] = 5;
|
|
1681
|
+
var i2;
|
|
1682
|
+
var flrm = /* @__PURE__ */ hMap2(flt2, 9, 1);
|
|
1683
|
+
var fdrm = /* @__PURE__ */ hMap2(fdt2, 5, 1);
|
|
1684
|
+
var max = function(a) {
|
|
1685
|
+
var m = a[0];
|
|
1686
|
+
for (var i3 = 1; i3 < a.length; ++i3) {
|
|
1687
|
+
if (a[i3] > m)
|
|
1688
|
+
m = a[i3];
|
|
1689
|
+
}
|
|
1690
|
+
return m;
|
|
1691
|
+
};
|
|
1692
|
+
var bits = function(d, p, m) {
|
|
1693
|
+
var o = p / 8 | 0;
|
|
1694
|
+
return (d[o] | d[o + 1] << 8) >> (p & 7) & m;
|
|
1695
|
+
};
|
|
1696
|
+
var bits16 = function(d, p) {
|
|
1697
|
+
var o = p / 8 | 0;
|
|
1698
|
+
return (d[o] | d[o + 1] << 8 | d[o + 2] << 16) >> (p & 7);
|
|
1699
|
+
};
|
|
1700
|
+
var shft2 = function(p) {
|
|
1701
|
+
return (p + 7) / 8 | 0;
|
|
1702
|
+
};
|
|
1703
|
+
var slc2 = function(v, s, e) {
|
|
1704
|
+
if (s == null || s < 0)
|
|
1705
|
+
s = 0;
|
|
1706
|
+
if (e == null || e > v.length)
|
|
1707
|
+
e = v.length;
|
|
1708
|
+
return new u82(v.subarray(s, e));
|
|
1709
|
+
};
|
|
1710
|
+
var ec2 = [
|
|
1711
|
+
"unexpected EOF",
|
|
1712
|
+
"invalid block type",
|
|
1713
|
+
"invalid length/literal",
|
|
1714
|
+
"invalid distance",
|
|
1715
|
+
"stream finished",
|
|
1716
|
+
"no stream handler",
|
|
1717
|
+
,
|
|
1718
|
+
// determined by compression function
|
|
1719
|
+
"no callback",
|
|
1720
|
+
"invalid UTF-8 data",
|
|
1721
|
+
"extra field too long",
|
|
1722
|
+
"date not in range 1980-2099",
|
|
1723
|
+
"filename too long",
|
|
1724
|
+
"stream finishing",
|
|
1725
|
+
"invalid zip data"
|
|
1726
|
+
// determined by unknown compression method
|
|
1727
|
+
];
|
|
1728
|
+
var err2 = function(ind, msg, nt) {
|
|
1729
|
+
var e = new Error(msg || ec2[ind]);
|
|
1730
|
+
e.code = ind;
|
|
1731
|
+
if (Error.captureStackTrace)
|
|
1732
|
+
Error.captureStackTrace(e, err2);
|
|
1733
|
+
if (!nt)
|
|
1734
|
+
throw e;
|
|
1735
|
+
return e;
|
|
1736
|
+
};
|
|
1737
|
+
var inflt = function(dat, st, buf, dict) {
|
|
1738
|
+
var sl = dat.length, dl = dict ? dict.length : 0;
|
|
1739
|
+
if (!sl || st.f && !st.l)
|
|
1740
|
+
return buf || new u82(0);
|
|
1741
|
+
var noBuf = !buf;
|
|
1742
|
+
var resize = noBuf || st.i != 2;
|
|
1743
|
+
var noSt = st.i;
|
|
1744
|
+
if (noBuf)
|
|
1745
|
+
buf = new u82(sl * 3);
|
|
1746
|
+
var cbuf = function(l2) {
|
|
1747
|
+
var bl = buf.length;
|
|
1748
|
+
if (l2 > bl) {
|
|
1749
|
+
var nbuf = new u82(Math.max(bl * 2, l2));
|
|
1750
|
+
nbuf.set(buf);
|
|
1751
|
+
buf = nbuf;
|
|
1752
|
+
}
|
|
1753
|
+
};
|
|
1754
|
+
var final = st.f || 0, pos = st.p || 0, bt = st.b || 0, lm = st.l, dm = st.d, lbt = st.m, dbt = st.n;
|
|
1755
|
+
var tbts = sl * 8;
|
|
1756
|
+
do {
|
|
1757
|
+
if (!lm) {
|
|
1758
|
+
final = bits(dat, pos, 1);
|
|
1759
|
+
var type = bits(dat, pos + 1, 3);
|
|
1760
|
+
pos += 3;
|
|
1761
|
+
if (!type) {
|
|
1762
|
+
var s = shft2(pos) + 4, l = dat[s - 4] | dat[s - 3] << 8, t = s + l;
|
|
1763
|
+
if (t > sl) {
|
|
1764
|
+
if (noSt)
|
|
1765
|
+
err2(0);
|
|
1766
|
+
break;
|
|
1767
|
+
}
|
|
1768
|
+
if (resize)
|
|
1769
|
+
cbuf(bt + l);
|
|
1770
|
+
buf.set(dat.subarray(s, t), bt);
|
|
1771
|
+
st.b = bt += l, st.p = pos = t * 8, st.f = final;
|
|
1772
|
+
continue;
|
|
1773
|
+
} else if (type == 1)
|
|
1774
|
+
lm = flrm, dm = fdrm, lbt = 9, dbt = 5;
|
|
1775
|
+
else if (type == 2) {
|
|
1776
|
+
var hLit = bits(dat, pos, 31) + 257, hcLen = bits(dat, pos + 10, 15) + 4;
|
|
1777
|
+
var tl = hLit + bits(dat, pos + 5, 31) + 1;
|
|
1778
|
+
pos += 14;
|
|
1779
|
+
var ldt = new u82(tl);
|
|
1780
|
+
var clt = new u82(19);
|
|
1781
|
+
for (var i3 = 0; i3 < hcLen; ++i3) {
|
|
1782
|
+
clt[clim2[i3]] = bits(dat, pos + i3 * 3, 7);
|
|
1783
|
+
}
|
|
1784
|
+
pos += hcLen * 3;
|
|
1785
|
+
var clb = max(clt), clbmsk = (1 << clb) - 1;
|
|
1786
|
+
var clm = hMap2(clt, clb, 1);
|
|
1787
|
+
for (var i3 = 0; i3 < tl; ) {
|
|
1788
|
+
var r = clm[bits(dat, pos, clbmsk)];
|
|
1789
|
+
pos += r & 15;
|
|
1790
|
+
var s = r >> 4;
|
|
1791
|
+
if (s < 16) {
|
|
1792
|
+
ldt[i3++] = s;
|
|
1793
|
+
} else {
|
|
1794
|
+
var c = 0, n = 0;
|
|
1795
|
+
if (s == 16)
|
|
1796
|
+
n = 3 + bits(dat, pos, 3), pos += 2, c = ldt[i3 - 1];
|
|
1797
|
+
else if (s == 17)
|
|
1798
|
+
n = 3 + bits(dat, pos, 7), pos += 3;
|
|
1799
|
+
else if (s == 18)
|
|
1800
|
+
n = 11 + bits(dat, pos, 127), pos += 7;
|
|
1801
|
+
while (n--)
|
|
1802
|
+
ldt[i3++] = c;
|
|
1803
|
+
}
|
|
1804
|
+
}
|
|
1805
|
+
var lt = ldt.subarray(0, hLit), dt = ldt.subarray(hLit);
|
|
1806
|
+
lbt = max(lt);
|
|
1807
|
+
dbt = max(dt);
|
|
1808
|
+
lm = hMap2(lt, lbt, 1);
|
|
1809
|
+
dm = hMap2(dt, dbt, 1);
|
|
1810
|
+
} else
|
|
1811
|
+
err2(1);
|
|
1812
|
+
if (pos > tbts) {
|
|
1813
|
+
if (noSt)
|
|
1814
|
+
err2(0);
|
|
1815
|
+
break;
|
|
1816
|
+
}
|
|
1817
|
+
}
|
|
1818
|
+
if (resize)
|
|
1819
|
+
cbuf(bt + 131072);
|
|
1820
|
+
var lms = (1 << lbt) - 1, dms = (1 << dbt) - 1;
|
|
1821
|
+
var lpos = pos;
|
|
1822
|
+
for (; ; lpos = pos) {
|
|
1823
|
+
var c = lm[bits16(dat, pos) & lms], sym = c >> 4;
|
|
1824
|
+
pos += c & 15;
|
|
1825
|
+
if (pos > tbts) {
|
|
1826
|
+
if (noSt)
|
|
1827
|
+
err2(0);
|
|
1828
|
+
break;
|
|
1829
|
+
}
|
|
1830
|
+
if (!c)
|
|
1831
|
+
err2(2);
|
|
1832
|
+
if (sym < 256)
|
|
1833
|
+
buf[bt++] = sym;
|
|
1834
|
+
else if (sym == 256) {
|
|
1835
|
+
lpos = pos, lm = null;
|
|
1836
|
+
break;
|
|
1837
|
+
} else {
|
|
1838
|
+
var add = sym - 254;
|
|
1839
|
+
if (sym > 264) {
|
|
1840
|
+
var i3 = sym - 257, b = fleb2[i3];
|
|
1841
|
+
add = bits(dat, pos, (1 << b) - 1) + fl2[i3];
|
|
1842
|
+
pos += b;
|
|
1843
|
+
}
|
|
1844
|
+
var d = dm[bits16(dat, pos) & dms], dsym = d >> 4;
|
|
1845
|
+
if (!d)
|
|
1846
|
+
err2(3);
|
|
1847
|
+
pos += d & 15;
|
|
1848
|
+
var dt = fd2[dsym];
|
|
1849
|
+
if (dsym > 3) {
|
|
1850
|
+
var b = fdeb2[dsym];
|
|
1851
|
+
dt += bits16(dat, pos) & (1 << b) - 1, pos += b;
|
|
1852
|
+
}
|
|
1853
|
+
if (pos > tbts) {
|
|
1854
|
+
if (noSt)
|
|
1855
|
+
err2(0);
|
|
1856
|
+
break;
|
|
1857
|
+
}
|
|
1858
|
+
if (resize)
|
|
1859
|
+
cbuf(bt + 131072);
|
|
1860
|
+
var end = bt + add;
|
|
1861
|
+
if (bt < dt) {
|
|
1862
|
+
var shift = dl - dt, dend = Math.min(dt, end);
|
|
1863
|
+
if (shift + bt < 0)
|
|
1864
|
+
err2(3);
|
|
1865
|
+
for (; bt < dend; ++bt)
|
|
1866
|
+
buf[bt] = dict[shift + bt];
|
|
1867
|
+
}
|
|
1868
|
+
for (; bt < end; ++bt)
|
|
1869
|
+
buf[bt] = buf[bt - dt];
|
|
1870
|
+
}
|
|
1871
|
+
}
|
|
1872
|
+
st.l = lm, st.p = lpos, st.b = bt, st.f = final;
|
|
1873
|
+
if (lm)
|
|
1874
|
+
final = 1, st.m = lbt, st.d = dm, st.n = dbt;
|
|
1875
|
+
} while (!final);
|
|
1876
|
+
return bt != buf.length && noBuf ? slc2(buf, 0, bt) : buf.subarray(0, bt);
|
|
1877
|
+
};
|
|
1878
|
+
var et2 = /* @__PURE__ */ new u82(0);
|
|
1879
|
+
var b2 = function(d, b) {
|
|
1880
|
+
return d[b] | d[b + 1] << 8;
|
|
1881
|
+
};
|
|
1882
|
+
var b4 = function(d, b) {
|
|
1883
|
+
return (d[b] | d[b + 1] << 8 | d[b + 2] << 16 | d[b + 3] << 24) >>> 0;
|
|
1884
|
+
};
|
|
1885
|
+
var b8 = function(d, b) {
|
|
1886
|
+
return b4(d, b) + b4(d, b + 4) * 4294967296;
|
|
1887
|
+
};
|
|
1888
|
+
var Inflate = /* @__PURE__ */ (function() {
|
|
1889
|
+
function Inflate2(opts, cb) {
|
|
1890
|
+
if (typeof opts == "function")
|
|
1891
|
+
cb = opts, opts = {};
|
|
1892
|
+
this.ondata = cb;
|
|
1893
|
+
var dict = opts && opts.dictionary && opts.dictionary.subarray(-32768);
|
|
1894
|
+
this.s = { i: 0, b: dict ? dict.length : 0 };
|
|
1895
|
+
this.o = new u82(32768);
|
|
1896
|
+
this.p = new u82(0);
|
|
1897
|
+
if (dict)
|
|
1898
|
+
this.o.set(dict);
|
|
1899
|
+
}
|
|
1900
|
+
Inflate2.prototype.e = function(c) {
|
|
1901
|
+
if (!this.ondata)
|
|
1902
|
+
err2(5);
|
|
1903
|
+
if (this.d)
|
|
1904
|
+
err2(4);
|
|
1905
|
+
if (!this.p.length)
|
|
1906
|
+
this.p = c;
|
|
1907
|
+
else if (c.length) {
|
|
1908
|
+
var n = new u82(this.p.length + c.length);
|
|
1909
|
+
n.set(this.p), n.set(c, this.p.length), this.p = n;
|
|
1910
|
+
}
|
|
1911
|
+
};
|
|
1912
|
+
Inflate2.prototype.c = function(final) {
|
|
1913
|
+
this.s.i = +(this.d = final || false);
|
|
1914
|
+
var bts = this.s.b;
|
|
1915
|
+
var dt = inflt(this.p, this.s, this.o);
|
|
1916
|
+
this.ondata(slc2(dt, bts, this.s.b), this.d);
|
|
1917
|
+
this.o = slc2(dt, this.s.b - 32768), this.s.b = this.o.length;
|
|
1918
|
+
this.p = slc2(this.p, this.s.p / 8 | 0), this.s.p &= 7;
|
|
1919
|
+
};
|
|
1920
|
+
Inflate2.prototype.push = function(chunk, final) {
|
|
1921
|
+
this.e(chunk), this.c(final);
|
|
1922
|
+
};
|
|
1923
|
+
return Inflate2;
|
|
1924
|
+
})();
|
|
1925
|
+
var td2 = typeof TextDecoder != "undefined" && /* @__PURE__ */ new TextDecoder();
|
|
1926
|
+
var tds2 = 0;
|
|
1927
|
+
try {
|
|
1928
|
+
td2.decode(et2, { stream: true });
|
|
1929
|
+
tds2 = 1;
|
|
1930
|
+
} catch (e) {
|
|
1931
|
+
}
|
|
1932
|
+
var dutf8 = function(d) {
|
|
1933
|
+
for (var r = "", i3 = 0; ; ) {
|
|
1934
|
+
var c = d[i3++];
|
|
1935
|
+
var eb = (c > 127) + (c > 223) + (c > 239);
|
|
1936
|
+
if (i3 + eb > d.length)
|
|
1937
|
+
return { s: r, r: slc2(d, i3 - 1) };
|
|
1938
|
+
if (!eb)
|
|
1939
|
+
r += String.fromCharCode(c);
|
|
1940
|
+
else if (eb == 3) {
|
|
1941
|
+
c = ((c & 15) << 18 | (d[i3++] & 63) << 12 | (d[i3++] & 63) << 6 | d[i3++] & 63) - 65536, r += String.fromCharCode(55296 | c >> 10, 56320 | c & 1023);
|
|
1942
|
+
} else if (eb & 1)
|
|
1943
|
+
r += String.fromCharCode((c & 31) << 6 | d[i3++] & 63);
|
|
1944
|
+
else
|
|
1945
|
+
r += String.fromCharCode((c & 15) << 12 | (d[i3++] & 63) << 6 | d[i3++] & 63);
|
|
1946
|
+
}
|
|
1947
|
+
};
|
|
1948
|
+
function strFromU8(dat, latin1) {
|
|
1949
|
+
if (latin1) {
|
|
1950
|
+
var r = "";
|
|
1951
|
+
for (var i3 = 0; i3 < dat.length; i3 += 16384)
|
|
1952
|
+
r += String.fromCharCode.apply(null, dat.subarray(i3, i3 + 16384));
|
|
1953
|
+
return r;
|
|
1954
|
+
} else if (td2) {
|
|
1955
|
+
return td2.decode(dat);
|
|
1956
|
+
} else {
|
|
1957
|
+
var _a3 = dutf8(dat), s = _a3.s, r = _a3.r;
|
|
1958
|
+
if (r.length)
|
|
1959
|
+
err2(8);
|
|
1960
|
+
return s;
|
|
1961
|
+
}
|
|
1962
|
+
}
|
|
1963
|
+
var z64hs = function(d, b, l, z11, sc, su, off) {
|
|
1964
|
+
var nsc = sc == 4294967295, nsu = su == 4294967295, noff = off == 4294967295, e = b + l;
|
|
1965
|
+
var nf = nsc + nsu + noff;
|
|
1966
|
+
if (z11 && nf) {
|
|
1967
|
+
for (; b + 4 < e; b += 4 + b2(d, b + 2)) {
|
|
1968
|
+
if (b2(d, b) == 1) {
|
|
1969
|
+
return [
|
|
1970
|
+
nsc ? b8(d, b + 4 + 8 * nsu) : sc,
|
|
1971
|
+
nsu ? b8(d, b + 4) : su,
|
|
1972
|
+
noff ? b8(d, b + 4 + 8 * (nsu + nsc)) : off,
|
|
1973
|
+
1
|
|
1974
|
+
];
|
|
1975
|
+
}
|
|
1976
|
+
}
|
|
1977
|
+
if (z11 < 2)
|
|
1978
|
+
err2(13);
|
|
1979
|
+
}
|
|
1980
|
+
return [sc, su, off, 0];
|
|
1981
|
+
};
|
|
1982
|
+
var UnzipPassThrough = /* @__PURE__ */ (function() {
|
|
1983
|
+
function UnzipPassThrough2() {
|
|
1984
|
+
}
|
|
1985
|
+
UnzipPassThrough2.prototype.push = function(chunk, final) {
|
|
1986
|
+
this.ondata(null, chunk, final);
|
|
1987
|
+
};
|
|
1988
|
+
UnzipPassThrough2.compression = 0;
|
|
1989
|
+
return UnzipPassThrough2;
|
|
1990
|
+
})();
|
|
1991
|
+
var UnzipInflate = /* @__PURE__ */ (function() {
|
|
1992
|
+
function UnzipInflate2() {
|
|
1993
|
+
var _this = this;
|
|
1994
|
+
this.i = new Inflate(function(dat, final) {
|
|
1995
|
+
_this.ondata(null, dat, final);
|
|
1996
|
+
});
|
|
1997
|
+
}
|
|
1998
|
+
UnzipInflate2.prototype.push = function(chunk, final) {
|
|
1999
|
+
try {
|
|
2000
|
+
this.i.push(chunk, final);
|
|
2001
|
+
} catch (e) {
|
|
2002
|
+
this.ondata(e, null, final);
|
|
2003
|
+
}
|
|
2004
|
+
};
|
|
2005
|
+
UnzipInflate2.compression = 8;
|
|
2006
|
+
return UnzipInflate2;
|
|
2007
|
+
})();
|
|
2008
|
+
var Unzip = /* @__PURE__ */ (function() {
|
|
2009
|
+
function Unzip2(cb) {
|
|
2010
|
+
this.onfile = cb;
|
|
2011
|
+
this.k = [];
|
|
2012
|
+
this.o = {
|
|
2013
|
+
0: UnzipPassThrough
|
|
2014
|
+
};
|
|
2015
|
+
this.p = et2;
|
|
2016
|
+
}
|
|
2017
|
+
Unzip2.prototype.push = function(chunk, final) {
|
|
2018
|
+
var _this = this;
|
|
2019
|
+
if (!this.onfile)
|
|
2020
|
+
err2(5);
|
|
2021
|
+
if (!this.p)
|
|
2022
|
+
err2(4);
|
|
2023
|
+
if (this.c > 0) {
|
|
2024
|
+
var len = Math.min(this.c, chunk.length);
|
|
2025
|
+
var toAdd = chunk.subarray(0, len);
|
|
2026
|
+
this.c -= len;
|
|
2027
|
+
if (this.d)
|
|
2028
|
+
this.d.push(toAdd, !this.c);
|
|
2029
|
+
else
|
|
2030
|
+
this.k[0].push(toAdd);
|
|
2031
|
+
chunk = chunk.subarray(len);
|
|
2032
|
+
if (chunk.length)
|
|
2033
|
+
return this.push(chunk, final);
|
|
2034
|
+
} else {
|
|
2035
|
+
var f = 0, i3 = 0, is = void 0, buf = void 0;
|
|
2036
|
+
if (!this.p.length)
|
|
2037
|
+
buf = chunk;
|
|
2038
|
+
else if (!chunk.length)
|
|
2039
|
+
buf = this.p;
|
|
2040
|
+
else {
|
|
2041
|
+
buf = new u82(this.p.length + chunk.length);
|
|
2042
|
+
buf.set(this.p), buf.set(chunk, this.p.length);
|
|
2043
|
+
}
|
|
2044
|
+
var l = buf.length, oc = this.c, add = oc && this.d;
|
|
2045
|
+
var _loop_2 = function() {
|
|
2046
|
+
var sig = b4(buf, i3);
|
|
2047
|
+
if (sig == 67324752) {
|
|
2048
|
+
f = 1, is = i3;
|
|
2049
|
+
this_1.d = null;
|
|
2050
|
+
this_1.c = 0;
|
|
2051
|
+
var bf = b2(buf, i3 + 6), cmp_1 = b2(buf, i3 + 8), u = bf & 2048, dd = bf & 8, fnl = b2(buf, i3 + 26), es = b2(buf, i3 + 28);
|
|
2052
|
+
if (l > i3 + 30 + fnl + es) {
|
|
2053
|
+
var chks_3 = [];
|
|
2054
|
+
this_1.k.unshift(chks_3);
|
|
2055
|
+
f = 2;
|
|
2056
|
+
var lsc = b4(buf, i3 + 18), lsu = b4(buf, i3 + 22);
|
|
2057
|
+
var fn_1 = strFromU8(buf.subarray(i3 + 30, i3 += 30 + fnl), !u);
|
|
2058
|
+
var _a3 = z64hs(buf, i3, es, 2, lsc, lsu, 0), sc_1 = _a3[0], su_1 = _a3[1], z64 = _a3[3];
|
|
2059
|
+
if (dd)
|
|
2060
|
+
sc_1 = -1 - z64;
|
|
2061
|
+
i3 += es;
|
|
2062
|
+
this_1.c = sc_1;
|
|
2063
|
+
var d_1;
|
|
2064
|
+
var file_1 = {
|
|
2065
|
+
name: fn_1,
|
|
2066
|
+
compression: cmp_1,
|
|
2067
|
+
start: function() {
|
|
2068
|
+
if (!file_1.ondata)
|
|
2069
|
+
err2(5);
|
|
2070
|
+
if (!sc_1)
|
|
2071
|
+
file_1.ondata(null, et2, true);
|
|
2072
|
+
else {
|
|
2073
|
+
var ctr = _this.o[cmp_1];
|
|
2074
|
+
if (!ctr)
|
|
2075
|
+
file_1.ondata(err2(14, "unknown compression type " + cmp_1, 1), null, false);
|
|
2076
|
+
d_1 = sc_1 < 0 ? new ctr(fn_1) : new ctr(fn_1, sc_1, su_1);
|
|
2077
|
+
d_1.ondata = function(err3, dat3, final2) {
|
|
2078
|
+
file_1.ondata(err3, dat3, final2);
|
|
2079
|
+
};
|
|
2080
|
+
for (var _i = 0, chks_4 = chks_3; _i < chks_4.length; _i++) {
|
|
2081
|
+
var dat2 = chks_4[_i];
|
|
2082
|
+
d_1.push(dat2, false);
|
|
2083
|
+
}
|
|
2084
|
+
if (_this.k[0] == chks_3 && _this.c)
|
|
2085
|
+
_this.d = d_1;
|
|
2086
|
+
else
|
|
2087
|
+
d_1.push(et2, true);
|
|
2088
|
+
}
|
|
2089
|
+
},
|
|
2090
|
+
terminate: function() {
|
|
2091
|
+
if (d_1 && d_1.terminate)
|
|
2092
|
+
d_1.terminate();
|
|
2093
|
+
}
|
|
2094
|
+
};
|
|
2095
|
+
if (sc_1 >= 0)
|
|
2096
|
+
file_1.size = sc_1, file_1.originalSize = su_1;
|
|
2097
|
+
this_1.onfile(file_1);
|
|
2098
|
+
}
|
|
2099
|
+
return "break";
|
|
2100
|
+
} else if (oc) {
|
|
2101
|
+
if (sig == 134695760) {
|
|
2102
|
+
is = i3 += 12 + (oc == -2 && 8), f = 3, this_1.c = 0;
|
|
2103
|
+
return "break";
|
|
2104
|
+
} else if (sig == 33639248) {
|
|
2105
|
+
is = i3 -= 4, f = 3, this_1.c = 0;
|
|
2106
|
+
return "break";
|
|
2107
|
+
}
|
|
2108
|
+
}
|
|
2109
|
+
};
|
|
2110
|
+
var this_1 = this;
|
|
2111
|
+
for (; i3 < l - 4; ++i3) {
|
|
2112
|
+
var state_1 = _loop_2();
|
|
2113
|
+
if (state_1 === "break")
|
|
2114
|
+
break;
|
|
2115
|
+
}
|
|
2116
|
+
this.p = et2;
|
|
2117
|
+
if (oc < 0) {
|
|
2118
|
+
var dat = f ? buf.subarray(0, is - 12 - (oc == -2 && 8) - (b4(buf, is - 16) == 134695760 && 4)) : buf.subarray(0, i3);
|
|
2119
|
+
if (add)
|
|
2120
|
+
add.push(dat, !!f);
|
|
2121
|
+
else
|
|
2122
|
+
this.k[+(f == 2)].push(dat);
|
|
2123
|
+
}
|
|
2124
|
+
if (f & 2)
|
|
2125
|
+
return this.push(buf.subarray(i3), final);
|
|
2126
|
+
this.p = buf.subarray(i3);
|
|
2127
|
+
}
|
|
2128
|
+
if (final) {
|
|
2129
|
+
if (this.c)
|
|
2130
|
+
err2(13);
|
|
2131
|
+
this.p = null;
|
|
2132
|
+
}
|
|
2133
|
+
};
|
|
2134
|
+
Unzip2.prototype.register = function(decoder) {
|
|
2135
|
+
this.o[decoder.compression] = decoder;
|
|
2136
|
+
};
|
|
2137
|
+
return Unzip2;
|
|
2138
|
+
})();
|
|
2139
|
+
|
|
2140
|
+
// packages/server/src/workflow-artifact-summary.ts
|
|
2141
|
+
import { z as z6 } from "zod";
|
|
2142
|
+
var maxArtifactBytes = 64 * 1024;
|
|
2143
|
+
var testResultsSummarySchema = z6.object({
|
|
2144
|
+
schemaVersion: z6.literal(1),
|
|
2145
|
+
runId: z6.number().int().positive(),
|
|
2146
|
+
runAttempt: z6.number().int().positive(),
|
|
2147
|
+
headSha: z6.string().min(1),
|
|
2148
|
+
total: z6.number().int().nonnegative(),
|
|
2149
|
+
passed: z6.number().int().nonnegative().optional(),
|
|
2150
|
+
failed: z6.number().int().nonnegative().optional(),
|
|
2151
|
+
skipped: z6.number().int().nonnegative().optional(),
|
|
2152
|
+
metadata: z6.record(z6.string(), z6.unknown()).optional()
|
|
2153
|
+
}).superRefine((summary, ctx) => {
|
|
2154
|
+
const outcomeTotal = (summary.passed ?? 0) + (summary.failed ?? 0) + (summary.skipped ?? 0);
|
|
2155
|
+
for (const key of ["passed", "failed", "skipped"]) {
|
|
2156
|
+
if (summary[key] !== void 0 && summary[key] > summary.total)
|
|
2157
|
+
ctx.addIssue({ code: "custom", path: [key], message: "must not exceed total" });
|
|
2158
|
+
}
|
|
2159
|
+
if (outcomeTotal > summary.total)
|
|
2160
|
+
ctx.addIssue({ code: "custom", path: ["total"], message: "must cover the declared outcomes" });
|
|
2161
|
+
});
|
|
2162
|
+
async function readTestResultsArtifact(response, entry) {
|
|
2163
|
+
const reader = response.body?.getReader();
|
|
2164
|
+
if (!reader) throw new Error("Artifact archive has no readable body.");
|
|
2165
|
+
let compressedBytes = 0;
|
|
2166
|
+
let entryCount = 0;
|
|
2167
|
+
let outputBytes = 0;
|
|
2168
|
+
let complete = false;
|
|
2169
|
+
let failure2;
|
|
2170
|
+
const chunks = [];
|
|
2171
|
+
const archive = new Unzip((file) => {
|
|
2172
|
+
entryCount += 1;
|
|
2173
|
+
if (file.name !== entry || entryCount > 1) {
|
|
2174
|
+
failure2 = new Error("Artifact archive has an unexpected entry.");
|
|
2175
|
+
return;
|
|
2176
|
+
}
|
|
2177
|
+
if ((file.originalSize ?? 0) > maxArtifactBytes) {
|
|
2178
|
+
failure2 = new Error("Artifact entry exceeds the configured size limit.");
|
|
2179
|
+
return;
|
|
2180
|
+
}
|
|
2181
|
+
file.ondata = (error, data, final) => {
|
|
2182
|
+
if (error) {
|
|
2183
|
+
failure2 = error;
|
|
2184
|
+
return;
|
|
2185
|
+
}
|
|
2186
|
+
outputBytes += data.length;
|
|
2187
|
+
if (outputBytes > maxArtifactBytes) {
|
|
2188
|
+
failure2 = new Error("Artifact entry exceeds the configured size limit.");
|
|
2189
|
+
file.terminate();
|
|
2190
|
+
return;
|
|
2191
|
+
}
|
|
2192
|
+
chunks.push(data);
|
|
2193
|
+
if (final) complete = true;
|
|
2194
|
+
};
|
|
2195
|
+
file.start();
|
|
2196
|
+
});
|
|
2197
|
+
archive.register(UnzipInflate);
|
|
2198
|
+
try {
|
|
2199
|
+
for (; ; ) {
|
|
2200
|
+
const { done, value: value2 } = await reader.read();
|
|
2201
|
+
if (value2) {
|
|
2202
|
+
compressedBytes += value2.length;
|
|
2203
|
+
if (compressedBytes > maxArtifactBytes)
|
|
2204
|
+
throw new Error("Artifact archive exceeds the configured size limit.");
|
|
2205
|
+
archive.push(value2, done);
|
|
2206
|
+
} else if (done) archive.push(new Uint8Array(), true);
|
|
2207
|
+
if (done) break;
|
|
2208
|
+
if (failure2) throw failure2;
|
|
2209
|
+
}
|
|
2210
|
+
} finally {
|
|
2211
|
+
reader.releaseLock();
|
|
2212
|
+
}
|
|
2213
|
+
if (failure2) throw failure2;
|
|
2214
|
+
if (entryCount !== 1 || !complete)
|
|
2215
|
+
throw new Error("Artifact archive did not contain the configured summary.");
|
|
2216
|
+
return new TextDecoder("utf-8", { fatal: true }).decode(concat(chunks, outputBytes));
|
|
2217
|
+
}
|
|
2218
|
+
function concat(chunks, length) {
|
|
2219
|
+
const result = new Uint8Array(length);
|
|
2220
|
+
let offset = 0;
|
|
2221
|
+
for (const chunk of chunks) {
|
|
2222
|
+
result.set(chunk, offset);
|
|
2223
|
+
offset += chunk.length;
|
|
2224
|
+
}
|
|
2225
|
+
return result;
|
|
2226
|
+
}
|
|
2227
|
+
|
|
2228
|
+
// packages/server/src/adapters/github-actions.ts
|
|
2229
|
+
var pipelinePanelSchema = z7.object({
|
|
2230
|
+
id: z7.string().min(1),
|
|
2231
|
+
type: z7.literal("pipeline-status"),
|
|
2232
|
+
source: z7.string().min(1),
|
|
2233
|
+
/** GitHub accepts a workflow filename or numeric workflow id in this URL segment. */
|
|
2234
|
+
pipeline: z7.string().min(1)
|
|
2235
|
+
});
|
|
2236
|
+
var pullRequestHealthPanelSchema = z7.object({
|
|
2237
|
+
id: z7.string().min(1),
|
|
2238
|
+
type: z7.literal("pull-request-health"),
|
|
2239
|
+
source: z7.string().min(1),
|
|
2240
|
+
base_branch: z7.string().min(1),
|
|
2241
|
+
update_workflows: z7.array(
|
|
2242
|
+
z7.object({
|
|
2243
|
+
workflow: z7.string().min(1),
|
|
2244
|
+
branch_prefixes: z7.array(z7.string().min(1)).min(1)
|
|
2245
|
+
})
|
|
2246
|
+
).min(1),
|
|
2247
|
+
build_workflow: z7.string().min(1),
|
|
2248
|
+
build_events: githubActionsBuildEventsSchema.optional()
|
|
2249
|
+
});
|
|
2250
|
+
var runSchema = z7.object({
|
|
2251
|
+
id: z7.number().int().positive().optional(),
|
|
2252
|
+
run_attempt: z7.number().int().positive().optional(),
|
|
2253
|
+
head_sha: z7.string().min(1).optional(),
|
|
2254
|
+
status: z7.string(),
|
|
2255
|
+
conclusion: z7.string().nullable(),
|
|
2256
|
+
name: z7.string().min(1),
|
|
2257
|
+
html_url: z7.url(),
|
|
2258
|
+
/** The GitHub Actions trigger that started this run. */
|
|
2259
|
+
event: z7.string().min(1).optional(),
|
|
2260
|
+
/** The branch that produced this run; absent for some event types. */
|
|
2261
|
+
head_branch: z7.string().min(1).nullable().optional(),
|
|
2262
|
+
// Timestamp quality should only remove timing advice, never make an otherwise useful run unreadable.
|
|
2263
|
+
run_started_at: z7.string().nullable().optional(),
|
|
2264
|
+
updated_at: z7.string().optional(),
|
|
2265
|
+
created_at: z7.string().optional()
|
|
2266
|
+
});
|
|
2267
|
+
var artifactsSchema = z7.object({
|
|
2268
|
+
artifacts: z7.array(
|
|
2269
|
+
z7.object({ id: z7.number().int().positive(), name: z7.string().min(1), expired: z7.boolean() })
|
|
2270
|
+
)
|
|
2271
|
+
});
|
|
2272
|
+
var runsSchema = z7.object({ workflow_runs: z7.array(runSchema) });
|
|
2273
|
+
var jobsSchema = z7.object({
|
|
2274
|
+
jobs: z7.array(
|
|
2275
|
+
z7.object({
|
|
2276
|
+
name: z7.string().min(1),
|
|
2277
|
+
status: z7.string(),
|
|
2278
|
+
steps: z7.array(z7.object({ name: z7.string().min(1), status: z7.string() })).optional()
|
|
2279
|
+
})
|
|
2280
|
+
)
|
|
2281
|
+
});
|
|
2282
|
+
var pullRequestsSchema = z7.array(
|
|
2283
|
+
z7.object({
|
|
2284
|
+
number: z7.number().int().positive(),
|
|
2285
|
+
html_url: z7.url(),
|
|
2286
|
+
head: z7.object({ ref: z7.string().min(1) }),
|
|
2287
|
+
base: z7.object({ ref: z7.string().min(1) })
|
|
2288
|
+
})
|
|
2289
|
+
);
|
|
2290
|
+
function permittedGithubActionsCalls(panel, source, _credentials) {
|
|
2291
|
+
const { panel: parsedPanel, source: parsedSource } = z7.object({ panel: pipelinePanelSchema, source: githubActionsSourceSchema }).parse({ panel, source });
|
|
2292
|
+
const url = new URL(
|
|
2293
|
+
`https://api.github.com/repos/${parsedSource.repo}/actions/workflows/${encodeURIComponent(parsedPanel.pipeline)}/runs`
|
|
2294
|
+
);
|
|
2295
|
+
if (parsedSource.branch) url.searchParams.set("branch", parsedSource.branch);
|
|
2296
|
+
url.searchParams.set("per_page", "1");
|
|
2297
|
+
return [{ url: url.toString(), headers: new Headers() }];
|
|
2298
|
+
}
|
|
2299
|
+
function testCountCapabilities(panel, source) {
|
|
2300
|
+
return z7.object({ panel: testCountPanelSchema, source: githubActionsSourceSchema }).parse({ panel, source });
|
|
2301
|
+
}
|
|
2302
|
+
async function fetchGithubActionsTestCount(args) {
|
|
2303
|
+
const { panel, source } = testCountCapabilities(args.panel, args.source);
|
|
2304
|
+
const githubClient = githubClientFor(args);
|
|
2305
|
+
const noValidators = new Headers();
|
|
2306
|
+
let failureLink = sourceLinkForWorkflow(source, panel.pipeline);
|
|
2307
|
+
let failureObservedAt;
|
|
2308
|
+
try {
|
|
2309
|
+
const selected = await selectGithubWorkflowRun({
|
|
2310
|
+
...args,
|
|
2311
|
+
source,
|
|
2312
|
+
workflow: panel.pipeline,
|
|
2313
|
+
requestHeaders: noValidators,
|
|
2314
|
+
githubClient
|
|
2315
|
+
});
|
|
2316
|
+
if (!selected.response.ok) return testCountFailure(panel.id, source, selected.response);
|
|
2317
|
+
const { run } = selected;
|
|
2318
|
+
if (!run?.id)
|
|
2319
|
+
return testCountEnvelope(
|
|
2320
|
+
noRunEnvelope(panel.id, source, panel.pipeline, selected.response.headers.get("date"))
|
|
2321
|
+
);
|
|
2322
|
+
const link = run.html_url;
|
|
2323
|
+
const runObservedAt = selected.observedAt;
|
|
2324
|
+
failureLink = link;
|
|
2325
|
+
failureObservedAt = runObservedAt;
|
|
2326
|
+
if (run.status !== "completed")
|
|
2327
|
+
return testCountEnvelope({
|
|
2328
|
+
panelId: panel.id,
|
|
2329
|
+
state: "ok",
|
|
2330
|
+
observedAt: runObservedAt,
|
|
2331
|
+
link,
|
|
2332
|
+
signal: { type: "test-count", status: "pending" }
|
|
2333
|
+
});
|
|
2334
|
+
const artifactsResponse = await githubFetch(
|
|
2335
|
+
githubArtifactsCall(source, run.id, panel.test_results),
|
|
2336
|
+
{
|
|
2337
|
+
...args,
|
|
2338
|
+
source,
|
|
2339
|
+
requestHeaders: noValidators,
|
|
2340
|
+
githubClient
|
|
2341
|
+
}
|
|
2342
|
+
);
|
|
2343
|
+
if (!artifactsResponse.ok) return testCountFailure(panel.id, source, artifactsResponse, link);
|
|
2344
|
+
const artifactObservedAt = observedAt2(artifactsResponse.headers.get("date"));
|
|
2345
|
+
failureObservedAt = oldestObservation(runObservedAt, artifactObservedAt);
|
|
2346
|
+
const artifacts = artifactsSchema.parse(await artifactsResponse.json()).artifacts;
|
|
2347
|
+
const matches = artifacts.filter((artifact2) => artifact2.name === panel.test_results.artifact);
|
|
2348
|
+
if (matches.length === 0)
|
|
2349
|
+
return testCountEnvelope({
|
|
2350
|
+
panelId: panel.id,
|
|
2351
|
+
state: "ok",
|
|
2352
|
+
observedAt: oldestObservation(runObservedAt, artifactObservedAt),
|
|
2353
|
+
link,
|
|
2354
|
+
signal: { type: "test-count", status: "not-reported" }
|
|
2355
|
+
});
|
|
2356
|
+
if (matches.length !== 1 || matches[0]?.expired)
|
|
2357
|
+
return testCountEnvelope(
|
|
2358
|
+
errorEnvelope(
|
|
2359
|
+
panel.id,
|
|
2360
|
+
"upstream-error",
|
|
2361
|
+
"The test-results artifact is unavailable.",
|
|
2362
|
+
link
|
|
2363
|
+
)
|
|
2364
|
+
);
|
|
2365
|
+
const [artifact] = matches;
|
|
2366
|
+
if (!artifact)
|
|
2367
|
+
return testCountEnvelope(
|
|
2368
|
+
errorEnvelope(
|
|
2369
|
+
panel.id,
|
|
2370
|
+
"upstream-error",
|
|
2371
|
+
"The test-results artifact is unavailable.",
|
|
2372
|
+
link
|
|
2373
|
+
)
|
|
2374
|
+
);
|
|
2375
|
+
const archiveResponse = await githubFetch(githubArtifactDownloadCall(source, artifact.id), {
|
|
2376
|
+
...args,
|
|
2377
|
+
source,
|
|
2378
|
+
requestHeaders: noValidators,
|
|
2379
|
+
githubClient
|
|
2380
|
+
});
|
|
2381
|
+
if (!archiveResponse.ok) return testCountFailure(panel.id, source, archiveResponse, link);
|
|
2382
|
+
const archiveObservedAt = observedAt2(archiveResponse.headers.get("date"));
|
|
2383
|
+
failureObservedAt = oldestObservation(runObservedAt, artifactObservedAt, archiveObservedAt);
|
|
2384
|
+
const summary = testResultsSummarySchema.parse(
|
|
2385
|
+
JSON.parse(await readTestResultsArtifact(archiveResponse, panel.test_results.entry))
|
|
2386
|
+
);
|
|
2387
|
+
if (summary.runId !== run.id || summary.runAttempt !== run.run_attempt || summary.headSha !== run.head_sha)
|
|
2388
|
+
throw new Error("Test-results manifest does not belong to the selected workflow run.");
|
|
2389
|
+
return testCountEnvelope({
|
|
2390
|
+
panelId: panel.id,
|
|
2391
|
+
state: "ok",
|
|
2392
|
+
observedAt: oldestObservation(runObservedAt, artifactObservedAt, archiveObservedAt),
|
|
2393
|
+
link,
|
|
2394
|
+
signal: {
|
|
2395
|
+
type: "test-count",
|
|
2396
|
+
status: "reported",
|
|
2397
|
+
total: summary.total,
|
|
2398
|
+
...summary.passed === void 0 ? {} : { passed: summary.passed },
|
|
2399
|
+
...summary.failed === void 0 ? {} : { failed: summary.failed },
|
|
2400
|
+
...summary.skipped === void 0 ? {} : { skipped: summary.skipped }
|
|
2401
|
+
}
|
|
2402
|
+
});
|
|
2403
|
+
} catch (error) {
|
|
2404
|
+
return testCountEnvelope(
|
|
2405
|
+
errorEnvelope(
|
|
2406
|
+
panel.id,
|
|
2407
|
+
error instanceof GithubAuthenticationError ? "unauthorized" : "upstream-error",
|
|
2408
|
+
error,
|
|
2409
|
+
failureLink,
|
|
2410
|
+
failureObservedAt
|
|
2411
|
+
)
|
|
2412
|
+
);
|
|
2413
|
+
}
|
|
2414
|
+
}
|
|
2415
|
+
function pullRequestHealthCapabilities(panel) {
|
|
2416
|
+
const { panel: parsed } = z7.object({ panel: pullRequestHealthPanelSchema }).parse({ panel });
|
|
2417
|
+
return {
|
|
2418
|
+
panel: parsed,
|
|
2419
|
+
configuredUpdateWorkflow(workflow) {
|
|
2420
|
+
return parsed.update_workflows.find((candidate) => candidate.workflow === workflow);
|
|
2421
|
+
},
|
|
2422
|
+
permitsBuildBranch(branch) {
|
|
2423
|
+
return parsed.update_workflows.some(
|
|
2424
|
+
({ branch_prefixes }) => branch_prefixes.some((prefix) => branch.startsWith(prefix))
|
|
2425
|
+
);
|
|
2426
|
+
}
|
|
2427
|
+
};
|
|
2428
|
+
}
|
|
2429
|
+
function githubRunsCall(source, workflow, branch, event, perPage = 1, created) {
|
|
2430
|
+
const url = new URL(
|
|
2431
|
+
`https://api.github.com/repos/${source.repo}/actions/workflows/${encodeURIComponent(workflow)}/runs`
|
|
2432
|
+
);
|
|
2433
|
+
if (branch) url.searchParams.set("branch", branch);
|
|
2434
|
+
if (event) url.searchParams.set("event", event);
|
|
2435
|
+
if (created) url.searchParams.set("created", `>=${created}`);
|
|
2436
|
+
url.searchParams.set("per_page", String(perPage));
|
|
2437
|
+
return { url: url.toString(), headers: new Headers() };
|
|
2438
|
+
}
|
|
2439
|
+
function sourceLinkForRepository(source) {
|
|
2440
|
+
return `https://github.com/${source.repo}`;
|
|
2441
|
+
}
|
|
2442
|
+
async function fetchGithubActionsPipeline(args) {
|
|
2443
|
+
const parsedSource = githubActionsSourceSchema.parse(args.source);
|
|
2444
|
+
const parsedPanel = pipelinePanelSchema.parse(args.panel);
|
|
2445
|
+
const githubClient = githubClientFor(args);
|
|
2446
|
+
let selected;
|
|
2447
|
+
try {
|
|
2448
|
+
selected = await selectGithubWorkflowRun({
|
|
2449
|
+
...args,
|
|
2450
|
+
source: parsedSource,
|
|
2451
|
+
workflow: parsedPanel.pipeline,
|
|
2452
|
+
githubClient
|
|
2453
|
+
});
|
|
2454
|
+
} catch (error) {
|
|
2455
|
+
return {
|
|
2456
|
+
response: new Response(
|
|
2457
|
+
JSON.stringify(
|
|
2458
|
+
errorEnvelope(
|
|
2459
|
+
args.panel.id,
|
|
2460
|
+
error instanceof GithubAuthenticationError ? "unauthorized" : "unreachable",
|
|
2461
|
+
error,
|
|
2462
|
+
sourceLink(args.panel, args.source)
|
|
2463
|
+
)
|
|
2464
|
+
),
|
|
2465
|
+
{ status: 200 }
|
|
2466
|
+
),
|
|
2467
|
+
failure: {
|
|
2468
|
+
kind: error instanceof GithubAuthenticationError ? "unauthorized" : "unreachable",
|
|
2469
|
+
...safeNetworkCode(error) ? { networkCode: safeNetworkCode(error) } : {}
|
|
2470
|
+
}
|
|
2471
|
+
};
|
|
2472
|
+
}
|
|
2473
|
+
const upstream = selected.response;
|
|
2474
|
+
if (upstream.status === 304) return { response: upstream };
|
|
2475
|
+
if (!upstream.ok) return githubPipelineFailure(args, upstream);
|
|
2476
|
+
try {
|
|
2477
|
+
const run = selected.run;
|
|
2478
|
+
if (!run) {
|
|
2479
|
+
return {
|
|
2480
|
+
response: new Response(
|
|
2481
|
+
JSON.stringify(
|
|
2482
|
+
errorEnvelope(
|
|
2483
|
+
args.panel.id,
|
|
2484
|
+
"no-runs",
|
|
2485
|
+
parsedSource.branch ? `No workflow runs found for branch "${parsedSource.branch}". Check the source's branch setting.` : "No workflow runs found.",
|
|
2486
|
+
sourceLink(args.panel, args.source),
|
|
2487
|
+
observedAt2(upstream.headers.get("date"))
|
|
2488
|
+
)
|
|
2489
|
+
),
|
|
2490
|
+
{ status: 200 }
|
|
2491
|
+
),
|
|
2492
|
+
failure: { kind: "no-runs", upstreamStatus: upstream.status }
|
|
2493
|
+
};
|
|
2494
|
+
}
|
|
2495
|
+
const signal = {
|
|
2496
|
+
type: "pipeline-status",
|
|
2497
|
+
status: normalizeStatus(run.status, run.conclusion),
|
|
2498
|
+
rawStatus: run.conclusion ?? run.status,
|
|
2499
|
+
name: run.name,
|
|
2500
|
+
...run.head_branch ?? parsedSource.branch ? { branch: run.head_branch ?? parsedSource.branch } : {},
|
|
2501
|
+
...timestamp(run.updated_at) ? { sourceUpdatedAt: timestamp(run.updated_at) } : {},
|
|
2502
|
+
...timestamp(run.run_started_at) ? { runStartedAt: timestamp(run.run_started_at) } : {},
|
|
2503
|
+
...run.id !== void 0 ? { sourceRunId: String(run.id) } : {},
|
|
2504
|
+
...run.status === "completed" ? completedRunDuration(run) : {}
|
|
2505
|
+
};
|
|
2506
|
+
if (signal.status === "running" && run.id !== void 0) {
|
|
2507
|
+
const activity = await activeGithubActivity({
|
|
2508
|
+
source: parsedSource,
|
|
2509
|
+
runId: run.id,
|
|
2510
|
+
requestHeaders: args.requestHeaders,
|
|
2511
|
+
fetcher: args.fetcher,
|
|
2512
|
+
githubClient: githubClientFor(args)
|
|
2513
|
+
});
|
|
2514
|
+
if (activity) signal.activity = activity;
|
|
2515
|
+
}
|
|
2516
|
+
const envelope = {
|
|
2517
|
+
panelId: args.panel.id,
|
|
2518
|
+
state: "ok",
|
|
2519
|
+
observedAt: observedAt2(upstream.headers.get("date")),
|
|
2520
|
+
link: run.html_url,
|
|
2521
|
+
signal
|
|
2522
|
+
};
|
|
2523
|
+
return { envelope, response: upstream };
|
|
2524
|
+
} catch (error) {
|
|
2525
|
+
return {
|
|
2526
|
+
response: new Response(
|
|
2527
|
+
JSON.stringify(
|
|
2528
|
+
errorEnvelope(
|
|
2529
|
+
args.panel.id,
|
|
2530
|
+
"upstream-error",
|
|
2531
|
+
error,
|
|
2532
|
+
sourceLink(args.panel, args.source),
|
|
2533
|
+
observedAt2(upstream.headers.get("date"))
|
|
2534
|
+
)
|
|
2535
|
+
),
|
|
2536
|
+
{ status: 200 }
|
|
2537
|
+
),
|
|
2538
|
+
failure: { kind: "upstream-error", upstreamStatus: upstream.status }
|
|
2539
|
+
};
|
|
2540
|
+
}
|
|
2541
|
+
}
|
|
2542
|
+
function githubPipelineFailure(args, upstream) {
|
|
2543
|
+
return {
|
|
2544
|
+
response: new Response(
|
|
2545
|
+
JSON.stringify(
|
|
2546
|
+
errorEnvelope(
|
|
2547
|
+
args.panel.id,
|
|
2548
|
+
errorKind(upstream.status),
|
|
2549
|
+
`${upstream.status} ${upstream.statusText}`,
|
|
2550
|
+
sourceLink(args.panel, args.source),
|
|
2551
|
+
observedAt2(upstream.headers.get("date"))
|
|
2552
|
+
)
|
|
2553
|
+
),
|
|
2554
|
+
{ status: 200 }
|
|
2555
|
+
),
|
|
2556
|
+
failure: { kind: errorKind(upstream.status), upstreamStatus: upstream.status }
|
|
2557
|
+
};
|
|
2558
|
+
}
|
|
2559
|
+
function recentRunsCreatedAt(now = /* @__PURE__ */ new Date()) {
|
|
2560
|
+
return new Date(now.valueOf() - 30 * 24 * 60 * 60 * 1e3).toISOString();
|
|
2561
|
+
}
|
|
2562
|
+
function newestGithubRun(runs) {
|
|
2563
|
+
return runs.reduce((newest, candidate) => {
|
|
2564
|
+
if (!newest) return candidate;
|
|
2565
|
+
const candidateCreatedAt = Date.parse(candidate.created_at ?? "");
|
|
2566
|
+
const newestCreatedAt = Date.parse(newest.created_at ?? "");
|
|
2567
|
+
if (candidateCreatedAt > newestCreatedAt) return candidate;
|
|
2568
|
+
if (candidateCreatedAt < newestCreatedAt) return newest;
|
|
2569
|
+
return (candidate.id ?? 0) > (newest.id ?? 0) ? candidate : newest;
|
|
2570
|
+
}, void 0);
|
|
2571
|
+
}
|
|
2572
|
+
async function selectGithubWorkflowRun(args) {
|
|
2573
|
+
let response = await githubFetch(
|
|
2574
|
+
githubRunsCall(
|
|
2575
|
+
args.source,
|
|
2576
|
+
args.workflow,
|
|
2577
|
+
args.source.branch,
|
|
2578
|
+
void 0,
|
|
2579
|
+
100,
|
|
2580
|
+
recentRunsCreatedAt()
|
|
2581
|
+
),
|
|
2582
|
+
args
|
|
2583
|
+
);
|
|
2584
|
+
if (response.status === 304 || !response.ok)
|
|
2585
|
+
return { response, observedAt: observedAt2(response.headers.get("date")), run: void 0 };
|
|
2586
|
+
let runs = runsSchema.parse(await response.json()).workflow_runs;
|
|
2587
|
+
if (runs.length === 0) {
|
|
2588
|
+
response = await githubFetch(
|
|
2589
|
+
githubRunsCall(args.source, args.workflow, args.source.branch),
|
|
2590
|
+
args
|
|
2591
|
+
);
|
|
2592
|
+
if (response.status === 304 || !response.ok)
|
|
2593
|
+
return { response, observedAt: observedAt2(response.headers.get("date")), run: void 0 };
|
|
2594
|
+
runs = runsSchema.parse(await response.json()).workflow_runs;
|
|
2595
|
+
}
|
|
2596
|
+
return {
|
|
2597
|
+
response,
|
|
2598
|
+
observedAt: observedAt2(response.headers.get("date")),
|
|
2599
|
+
run: newestGithubRun(runs)
|
|
2600
|
+
};
|
|
2601
|
+
}
|
|
2602
|
+
async function activeGithubActivity(args) {
|
|
2603
|
+
const call = githubJobsCall(args.source, args.runId);
|
|
2604
|
+
try {
|
|
2605
|
+
const response = await githubFetch(call, args);
|
|
2606
|
+
if (!response.ok) return void 0;
|
|
2607
|
+
const jobs = jobsSchema.parse(await response.json()).jobs;
|
|
2608
|
+
const job = jobs.find((candidate) => candidate.status === "in_progress") ?? jobs.find((candidate) => candidate.status === "queued");
|
|
2609
|
+
if (!job) return void 0;
|
|
2610
|
+
const step = job.steps?.find((candidate) => candidate.status === "in_progress");
|
|
2611
|
+
return step ? { kind: "step", name: step.name, parent: job.name } : { kind: "job", name: job.name };
|
|
2612
|
+
} catch {
|
|
2613
|
+
return void 0;
|
|
2614
|
+
}
|
|
2615
|
+
}
|
|
2616
|
+
async function githubFetch(call, args) {
|
|
2617
|
+
return args.githubClient.get({
|
|
2618
|
+
source: args.source,
|
|
2619
|
+
url: call.url,
|
|
2620
|
+
requestHeaders: args.requestHeaders,
|
|
2621
|
+
fetcher: args.fetcher
|
|
2622
|
+
});
|
|
2623
|
+
}
|
|
2624
|
+
function githubClientFor(args) {
|
|
2625
|
+
return args.githubClient ?? createGithubClient(args.credentials ?? environmentCredentials());
|
|
2626
|
+
}
|
|
2627
|
+
function githubJobsCall(source, runId) {
|
|
2628
|
+
const url = new URL(`https://api.github.com/repos/${source.repo}/actions/runs/${runId}/jobs`);
|
|
2629
|
+
url.searchParams.set("per_page", "100");
|
|
2630
|
+
return { url: url.toString(), headers: new Headers() };
|
|
2631
|
+
}
|
|
2632
|
+
function githubArtifactsCall(source, runId, testResults) {
|
|
2633
|
+
const url = new URL(`https://api.github.com/repos/${source.repo}/actions/runs/${runId}/artifacts`);
|
|
2634
|
+
url.searchParams.set("name", testResults.artifact);
|
|
2635
|
+
url.searchParams.set("per_page", "100");
|
|
2636
|
+
return { url: url.toString(), headers: new Headers() };
|
|
2637
|
+
}
|
|
2638
|
+
function githubArtifactDownloadCall(source, artifactId) {
|
|
2639
|
+
return {
|
|
2640
|
+
url: `https://api.github.com/repos/${source.repo}/actions/artifacts/${artifactId}/zip`,
|
|
2641
|
+
headers: new Headers()
|
|
2642
|
+
};
|
|
2643
|
+
}
|
|
2644
|
+
function noRunEnvelope(panelId, source, pipeline, date) {
|
|
2645
|
+
return {
|
|
2646
|
+
panelId,
|
|
2647
|
+
state: "error",
|
|
2648
|
+
observedAt: observedAt2(date),
|
|
2649
|
+
link: sourceLinkForWorkflow(source, pipeline),
|
|
2650
|
+
error: {
|
|
2651
|
+
kind: "no-runs",
|
|
2652
|
+
message: "No matching workflow runs were found. Check the configured workflow and branch."
|
|
2653
|
+
}
|
|
2654
|
+
};
|
|
2655
|
+
}
|
|
2656
|
+
function testCountFailure(panelId, source, response, link = sourceLinkForRepository(source)) {
|
|
2657
|
+
return testCountEnvelope(
|
|
2658
|
+
errorEnvelope(
|
|
2659
|
+
panelId,
|
|
2660
|
+
errorKind(response.status),
|
|
2661
|
+
`${response.status} ${response.statusText}`,
|
|
2662
|
+
link,
|
|
2663
|
+
observedAt2(response.headers.get("date"))
|
|
2664
|
+
),
|
|
2665
|
+
{ kind: errorKind(response.status), upstreamStatus: response.status }
|
|
2666
|
+
);
|
|
2667
|
+
}
|
|
2668
|
+
function testCountEnvelope(envelope, failure2) {
|
|
2669
|
+
return { envelope, response: new Response(null), ...failure2 ? { failure: failure2 } : {} };
|
|
2670
|
+
}
|
|
2671
|
+
function oldestObservation(...values) {
|
|
2672
|
+
return values.reduce((oldest, value2) => Date.parse(value2) < Date.parse(oldest) ? value2 : oldest);
|
|
2673
|
+
}
|
|
2674
|
+
function completedRunDuration(run) {
|
|
2675
|
+
const startedAt = timestamp(run.run_started_at);
|
|
2676
|
+
const updatedAt = timestamp(run.updated_at);
|
|
2677
|
+
if (!startedAt || !updatedAt) return {};
|
|
2678
|
+
const durationMs = new Date(updatedAt).valueOf() - new Date(startedAt).valueOf();
|
|
2679
|
+
return Number.isFinite(durationMs) && durationMs >= 0 ? { durationMs } : {};
|
|
2680
|
+
}
|
|
2681
|
+
function timestamp(value2) {
|
|
2682
|
+
if (!value2 || !z7.iso.datetime().safeParse(value2).success) return void 0;
|
|
2683
|
+
return Number.isFinite(new Date(value2).valueOf()) ? value2 : void 0;
|
|
2684
|
+
}
|
|
2685
|
+
function normalizeStatus(status, conclusion) {
|
|
2686
|
+
if (status !== "completed") return "running";
|
|
2687
|
+
if (conclusion === "success") return "passed";
|
|
2688
|
+
if (conclusion === "failure" || conclusion === "timed_out") return "failed";
|
|
2689
|
+
if (conclusion === "cancelled") return "cancelled";
|
|
2690
|
+
return "unknown";
|
|
2691
|
+
}
|
|
2692
|
+
function errorKind(status) {
|
|
2693
|
+
return upstreamErrorKind(status);
|
|
2694
|
+
}
|
|
2695
|
+
function errorEnvelope(panelId, kind, error, link, observedAt4 = (/* @__PURE__ */ new Date()).toISOString()) {
|
|
2696
|
+
return upstreamErrorEnvelope({ panelId, kind, error, link, upstreamDate: observedAt4 });
|
|
2697
|
+
}
|
|
2698
|
+
function sourceLink(panel, source) {
|
|
2699
|
+
const parsedPanel = z7.object({ pipeline: z7.string().min(1) }).parse(panel);
|
|
2700
|
+
const parsedSource = githubActionsSourceSchema.parse(source);
|
|
2701
|
+
return sourceLinkForWorkflow(parsedSource, parsedPanel.pipeline);
|
|
2702
|
+
}
|
|
2703
|
+
function sourceLinkForWorkflow(source, pipeline) {
|
|
2704
|
+
return `https://github.com/${source.repo}/actions/workflows/${encodeURIComponent(pipeline)}`;
|
|
2705
|
+
}
|
|
2706
|
+
function observedAt2(value2) {
|
|
2707
|
+
return observedAt(value2);
|
|
2708
|
+
}
|
|
2709
|
+
|
|
2710
|
+
// packages/server/src/configuration-error.ts
|
|
2711
|
+
var ConfigurationError = class extends Error {
|
|
2712
|
+
constructor(message2, diagnostics) {
|
|
2713
|
+
super(message2);
|
|
2714
|
+
this.diagnostics = diagnostics;
|
|
2715
|
+
}
|
|
2716
|
+
diagnostics;
|
|
2717
|
+
};
|
|
2718
|
+
function configurationLocation(path) {
|
|
2719
|
+
return path.reduce(
|
|
2720
|
+
(location, part) => typeof part === "number" ? `${location}[${part}]` : `${location}${location ? "." : ""}${String(part)}`,
|
|
2721
|
+
""
|
|
2722
|
+
) || "configuration";
|
|
2723
|
+
}
|
|
2724
|
+
function boardConfigurationLocation(config, path) {
|
|
2725
|
+
const [record, key, ...rest] = path;
|
|
2726
|
+
if ((record === "boards" || record === "sources") && key !== void 0) {
|
|
2727
|
+
const entries = config && typeof config === "object" ? Reflect.get(config, record) : void 0;
|
|
2728
|
+
const index = entries && typeof entries === "object" ? Object.keys(entries).indexOf(String(key)) : -1;
|
|
2729
|
+
return configurationLocation([record, index, ...rest]);
|
|
2730
|
+
}
|
|
2731
|
+
return configurationLocation(path);
|
|
2732
|
+
}
|
|
2733
|
+
function schemaDiagnostics(error, locate, kind = "schema") {
|
|
2734
|
+
return error.issues.map((issue) => ({
|
|
2735
|
+
kind,
|
|
2736
|
+
location: locate(issue.path),
|
|
2737
|
+
constraint: correctiveConstraint(issue)
|
|
2738
|
+
}));
|
|
2739
|
+
}
|
|
2740
|
+
function correctiveConstraint(issue) {
|
|
2741
|
+
switch (issue.code) {
|
|
2742
|
+
case "invalid_type":
|
|
2743
|
+
return `Provide a value of type ${issue.expected}.`;
|
|
2744
|
+
case "too_big":
|
|
2745
|
+
return `Use ${issue.inclusive ? "at most" : "fewer than"} ${issue.maximum} ${issue.origin === "array" ? "entries" : issue.origin === "string" ? "characters" : "as the value"}.`;
|
|
2746
|
+
case "too_small":
|
|
2747
|
+
return `Use ${issue.inclusive ? "at least" : "more than"} ${issue.minimum} ${issue.origin === "array" ? "entries" : issue.origin === "string" ? "characters" : "as the value"}.`;
|
|
2748
|
+
// Format messages are fixed by our schemas (or Zod); unlike custom issues they contain no authored values.
|
|
2749
|
+
case "invalid_format":
|
|
2750
|
+
return issue.message;
|
|
2751
|
+
case "invalid_value":
|
|
2752
|
+
return "Use one of the values allowed by the board schema.";
|
|
2753
|
+
case "custom":
|
|
2754
|
+
return typeof issue.params?.constraint === "string" ? issue.params.constraint : "Correct this field according to the board schema.";
|
|
2755
|
+
default:
|
|
2756
|
+
return "Provide a value matching the board schema for this field.";
|
|
2757
|
+
}
|
|
2758
|
+
}
|
|
2759
|
+
|
|
2760
|
+
// packages/server/src/adapters/azure-devops.ts
|
|
2761
|
+
import { readFile } from "node:fs/promises";
|
|
2762
|
+
import { z as z8 } from "zod";
|
|
2763
|
+
var pipelinePanelSchema2 = z8.object({
|
|
2764
|
+
id: z8.string().min(1),
|
|
2765
|
+
type: z8.literal("pipeline-status"),
|
|
2766
|
+
source: z8.string().min(1),
|
|
2767
|
+
pipeline: z8.number().int().positive()
|
|
2768
|
+
});
|
|
2769
|
+
var buildSchema = z8.object({
|
|
2770
|
+
id: z8.number().int().positive(),
|
|
2771
|
+
buildNumber: z8.string().min(1),
|
|
2772
|
+
status: z8.string().nullable().optional(),
|
|
2773
|
+
result: z8.string().nullable().optional(),
|
|
2774
|
+
sourceBranch: z8.string().min(1).nullable().optional(),
|
|
2775
|
+
startTime: z8.string().nullable().optional(),
|
|
2776
|
+
finishTime: z8.string().nullable().optional(),
|
|
2777
|
+
lastChangedDate: z8.string().nullable().optional()
|
|
2778
|
+
});
|
|
2779
|
+
var buildsSchema = z8.object({ value: z8.array(buildSchema) });
|
|
2780
|
+
var timelineSchema = z8.object({
|
|
2781
|
+
records: z8.array(
|
|
2782
|
+
z8.object({
|
|
2783
|
+
id: z8.string().min(1),
|
|
2784
|
+
parentId: z8.string().min(1).nullable().optional(),
|
|
2785
|
+
type: z8.string().min(1),
|
|
2786
|
+
name: z8.string().min(1),
|
|
2787
|
+
state: z8.string().nullable().optional()
|
|
2788
|
+
})
|
|
2789
|
+
)
|
|
2790
|
+
});
|
|
2791
|
+
function permittedAzureDevOpsCalls(panel, source) {
|
|
2792
|
+
const { panel: parsedPanel, source: parsedSource } = z8.object({ panel: pipelinePanelSchema2, source: azureDevOpsSourceSchema }).parse({ panel, source });
|
|
2793
|
+
return [buildsCall(parsedPanel.pipeline, parsedSource)];
|
|
2794
|
+
}
|
|
2795
|
+
async function fetchAzureDevOpsPipeline(args) {
|
|
2796
|
+
const panel = pipelinePanelSchema2.parse(args.panel);
|
|
2797
|
+
const source = azureDevOpsSourceSchema.parse(args.source);
|
|
2798
|
+
const authorization = await azureDevOpsAuthorization(source, args.credentials);
|
|
2799
|
+
if (!authorization) {
|
|
2800
|
+
return {
|
|
2801
|
+
response: errorResponse(
|
|
2802
|
+
errorEnvelope2(
|
|
2803
|
+
panel.id,
|
|
2804
|
+
"unauthorized",
|
|
2805
|
+
"Azure DevOps credentials are not available.",
|
|
2806
|
+
sourceLink2(panel.pipeline, source)
|
|
2807
|
+
)
|
|
2808
|
+
),
|
|
2809
|
+
failure: { kind: "unauthorized" }
|
|
2810
|
+
};
|
|
2811
|
+
}
|
|
2812
|
+
const call = buildsCall(panel.pipeline, source);
|
|
2813
|
+
copyValidators(args.requestHeaders, call.headers);
|
|
2814
|
+
call.headers.set("authorization", authorization);
|
|
2815
|
+
let upstream;
|
|
2816
|
+
try {
|
|
2817
|
+
upstream = await args.fetcher(call.url, { headers: call.headers });
|
|
2818
|
+
} catch (error) {
|
|
2819
|
+
return {
|
|
2820
|
+
response: errorResponse(
|
|
2821
|
+
errorEnvelope2(panel.id, "unreachable", error, sourceLink2(panel.pipeline, source))
|
|
2822
|
+
),
|
|
2823
|
+
failure: {
|
|
2824
|
+
kind: "unreachable",
|
|
2825
|
+
...safeNetworkCode(error) ? { networkCode: safeNetworkCode(error) } : {}
|
|
1571
2826
|
}
|
|
2827
|
+
};
|
|
2828
|
+
}
|
|
2829
|
+
if (upstream.status === 304) return { response: upstream };
|
|
2830
|
+
if (!upstream.ok) {
|
|
2831
|
+
return {
|
|
2832
|
+
response: errorResponse(
|
|
2833
|
+
errorEnvelope2(
|
|
2834
|
+
panel.id,
|
|
2835
|
+
errorKind2(upstream.status),
|
|
2836
|
+
`${upstream.status} ${upstream.statusText}`,
|
|
2837
|
+
sourceLink2(panel.pipeline, source),
|
|
2838
|
+
observedAt3(upstream.headers.get("date"))
|
|
2839
|
+
)
|
|
2840
|
+
),
|
|
2841
|
+
failure: { kind: errorKind2(upstream.status), upstreamStatus: upstream.status }
|
|
2842
|
+
};
|
|
2843
|
+
}
|
|
2844
|
+
try {
|
|
2845
|
+
const build = buildsSchema.parse(await upstream.json()).value[0];
|
|
2846
|
+
if (!build) {
|
|
2847
|
+
return {
|
|
2848
|
+
response: errorResponse(
|
|
2849
|
+
errorEnvelope2(
|
|
2850
|
+
panel.id,
|
|
2851
|
+
"no-runs",
|
|
2852
|
+
source.branch ? `No builds found for branch "${source.branch}". Check the source's branch setting.` : "No builds found.",
|
|
2853
|
+
sourceLink2(panel.pipeline, source),
|
|
2854
|
+
observedAt3(upstream.headers.get("date"))
|
|
2855
|
+
)
|
|
2856
|
+
),
|
|
2857
|
+
failure: { kind: "no-runs", upstreamStatus: upstream.status }
|
|
2858
|
+
};
|
|
2859
|
+
}
|
|
2860
|
+
const signal = {
|
|
2861
|
+
type: "pipeline-status",
|
|
2862
|
+
status: normalizeStatus2(build.status, build.result),
|
|
2863
|
+
rawStatus: build.result ?? build.status ?? "unknown",
|
|
2864
|
+
name: build.buildNumber,
|
|
2865
|
+
...build.sourceBranch ?? source.branch ? { branch: build.sourceBranch ?? source.branch } : {},
|
|
2866
|
+
...timestamp2(build.startTime) ? { runStartedAt: timestamp2(build.startTime) } : {},
|
|
2867
|
+
...timestamp2(build.lastChangedDate) ? { sourceUpdatedAt: timestamp2(build.lastChangedDate) } : {},
|
|
2868
|
+
sourceRunId: String(build.id),
|
|
2869
|
+
...completedBuildDuration(build)
|
|
2870
|
+
};
|
|
2871
|
+
if (signal.status === "running") {
|
|
2872
|
+
const activity = await activeAzureDevOpsActivity({
|
|
2873
|
+
buildId: build.id,
|
|
2874
|
+
source,
|
|
2875
|
+
fetcher: args.fetcher,
|
|
2876
|
+
authorization: call.headers.get("authorization") ?? ""
|
|
2877
|
+
});
|
|
2878
|
+
if (activity) signal.activity = activity;
|
|
1572
2879
|
}
|
|
2880
|
+
return {
|
|
2881
|
+
envelope: {
|
|
2882
|
+
panelId: panel.id,
|
|
2883
|
+
state: "ok",
|
|
2884
|
+
observedAt: observedAt3(upstream.headers.get("date")),
|
|
2885
|
+
link: buildLink(build.id, source),
|
|
2886
|
+
signal
|
|
2887
|
+
},
|
|
2888
|
+
response: upstream
|
|
2889
|
+
};
|
|
2890
|
+
} catch (error) {
|
|
2891
|
+
return {
|
|
2892
|
+
response: errorResponse(
|
|
2893
|
+
errorEnvelope2(
|
|
2894
|
+
panel.id,
|
|
2895
|
+
"upstream-error",
|
|
2896
|
+
error,
|
|
2897
|
+
sourceLink2(panel.pipeline, source),
|
|
2898
|
+
observedAt3(upstream.headers.get("date"))
|
|
2899
|
+
)
|
|
2900
|
+
),
|
|
2901
|
+
failure: { kind: "upstream-error", upstreamStatus: upstream.status }
|
|
2902
|
+
};
|
|
1573
2903
|
}
|
|
1574
|
-
return allowed;
|
|
1575
2904
|
}
|
|
1576
|
-
|
|
2905
|
+
var delegatedTokenFileSchema = z8.object({
|
|
2906
|
+
accessToken: z8.string().min(1),
|
|
2907
|
+
expiresAt: z8.string().min(1)
|
|
2908
|
+
});
|
|
2909
|
+
async function azureDevOpsAuthorization(source, credentials) {
|
|
2910
|
+
if (source.token_env) {
|
|
2911
|
+
const token = credentials.get(source.token_env);
|
|
2912
|
+
return token ? `Basic ${btoa(`:${token}`)}` : void 0;
|
|
2913
|
+
}
|
|
2914
|
+
if (!source.entra_token_file_env) return void 0;
|
|
2915
|
+
const tokenFile = credentials.get(source.entra_token_file_env);
|
|
2916
|
+
if (!tokenFile) return void 0;
|
|
2917
|
+
try {
|
|
2918
|
+
const token = delegatedTokenFileSchema.parse(JSON.parse(await readFile(tokenFile, "utf8")));
|
|
2919
|
+
const expiresAt = Date.parse(token.expiresAt);
|
|
2920
|
+
if (!Number.isFinite(expiresAt) || expiresAt <= Date.now()) return void 0;
|
|
2921
|
+
return `Bearer ${token.accessToken}`;
|
|
2922
|
+
} catch {
|
|
2923
|
+
return void 0;
|
|
2924
|
+
}
|
|
2925
|
+
}
|
|
2926
|
+
function buildsCall(definitionId, source) {
|
|
2927
|
+
const url = apiUrl(source, "build/builds");
|
|
2928
|
+
url.searchParams.set("definitions", String(definitionId));
|
|
2929
|
+
if (source.branch) url.searchParams.set("branchName", adoBranch(source.branch));
|
|
2930
|
+
url.searchParams.set("queryOrder", "queueTimeDescending");
|
|
2931
|
+
url.searchParams.set("$top", "1");
|
|
2932
|
+
return { url: url.toString(), headers: new Headers({ accept: "application/json" }) };
|
|
2933
|
+
}
|
|
2934
|
+
function timelineCall(buildId, source) {
|
|
2935
|
+
return {
|
|
2936
|
+
url: apiUrl(source, `build/builds/${buildId}/timeline`).toString(),
|
|
2937
|
+
headers: new Headers({ accept: "application/json" })
|
|
2938
|
+
};
|
|
2939
|
+
}
|
|
2940
|
+
function apiUrl(source, suffix) {
|
|
2941
|
+
const url = new URL(
|
|
2942
|
+
`https://dev.azure.com/${encodeURIComponent(source.organization)}/${encodeURIComponent(source.project)}/_apis/${suffix}`
|
|
2943
|
+
);
|
|
2944
|
+
url.searchParams.set("api-version", "7.1");
|
|
2945
|
+
return url;
|
|
2946
|
+
}
|
|
2947
|
+
function adoBranch(branch) {
|
|
2948
|
+
return branch.startsWith("refs/") ? branch : `refs/heads/${branch}`;
|
|
2949
|
+
}
|
|
2950
|
+
async function activeAzureDevOpsActivity(args) {
|
|
2951
|
+
const call = timelineCall(args.buildId, args.source);
|
|
2952
|
+
call.headers.set("authorization", args.authorization);
|
|
2953
|
+
try {
|
|
2954
|
+
const response = await args.fetcher(call.url, { headers: call.headers });
|
|
2955
|
+
if (!response.ok) return void 0;
|
|
2956
|
+
const records = timelineSchema.parse(await response.json()).records;
|
|
2957
|
+
const active = records.find((record) => record.state === "inProgress");
|
|
2958
|
+
if (!active) return void 0;
|
|
2959
|
+
const parent = active.parentId ? records.find((record) => record.id === active.parentId) : void 0;
|
|
2960
|
+
const kind = active.type.toLowerCase();
|
|
2961
|
+
return {
|
|
2962
|
+
kind: kind === "stage" ? "stage" : kind === "job" ? "job" : "step",
|
|
2963
|
+
name: active.name,
|
|
2964
|
+
...parent ? { parent: parent.name } : {}
|
|
2965
|
+
};
|
|
2966
|
+
} catch {
|
|
2967
|
+
return void 0;
|
|
2968
|
+
}
|
|
2969
|
+
}
|
|
2970
|
+
function normalizeStatus2(status, result) {
|
|
2971
|
+
if (status === "notStarted" || status === "postponed" || status === "inProgress" || status === "cancelling")
|
|
2972
|
+
return "running";
|
|
2973
|
+
if (status !== "completed") return "unknown";
|
|
2974
|
+
if (result === "succeeded") return "passed";
|
|
2975
|
+
if (result === "failed") return "failed";
|
|
2976
|
+
if (result === "partiallySucceeded") return "warning";
|
|
2977
|
+
if (result === "canceled") return "cancelled";
|
|
2978
|
+
return "unknown";
|
|
2979
|
+
}
|
|
2980
|
+
function completedBuildDuration(build) {
|
|
2981
|
+
const startedAt = timestamp2(build.startTime);
|
|
2982
|
+
const finishedAt = timestamp2(build.finishTime);
|
|
2983
|
+
if (!startedAt || !finishedAt) return {};
|
|
2984
|
+
const durationMs = new Date(finishedAt).valueOf() - new Date(startedAt).valueOf();
|
|
2985
|
+
return Number.isFinite(durationMs) && durationMs >= 0 ? { durationMs } : {};
|
|
2986
|
+
}
|
|
2987
|
+
function timestamp2(value2) {
|
|
2988
|
+
if (!value2 || !z8.iso.datetime().safeParse(value2).success) return void 0;
|
|
2989
|
+
return Number.isFinite(new Date(value2).valueOf()) ? value2 : void 0;
|
|
2990
|
+
}
|
|
2991
|
+
function copyValidators(requestHeaders, upstreamHeaders) {
|
|
2992
|
+
forwardValidators(requestHeaders, upstreamHeaders);
|
|
2993
|
+
}
|
|
2994
|
+
function buildLink(buildId, source) {
|
|
2995
|
+
return `https://dev.azure.com/${encodeURIComponent(source.organization)}/${encodeURIComponent(source.project)}/_build/results?buildId=${buildId}`;
|
|
2996
|
+
}
|
|
2997
|
+
function sourceLink2(definitionId, source) {
|
|
2998
|
+
return `https://dev.azure.com/${encodeURIComponent(source.organization)}/${encodeURIComponent(source.project)}/_build?definitionId=${definitionId}`;
|
|
2999
|
+
}
|
|
3000
|
+
function errorResponse(envelope) {
|
|
3001
|
+
return upstreamErrorResponse(envelope);
|
|
3002
|
+
}
|
|
3003
|
+
function errorEnvelope2(panelId, kind, error, link, date) {
|
|
3004
|
+
return upstreamErrorEnvelope({ panelId, kind, error, link, upstreamDate: date });
|
|
3005
|
+
}
|
|
3006
|
+
function errorKind2(status) {
|
|
3007
|
+
return upstreamErrorKind(status);
|
|
3008
|
+
}
|
|
3009
|
+
function observedAt3(value2) {
|
|
3010
|
+
return observedAt(value2);
|
|
3011
|
+
}
|
|
3012
|
+
|
|
3013
|
+
// packages/server/src/adapters/gitlab-ci.ts
|
|
3014
|
+
import { z as z9 } from "zod";
|
|
3015
|
+
var pipelinePanelSchema3 = z9.object({
|
|
3016
|
+
id: z9.string().min(1),
|
|
3017
|
+
type: z9.literal("pipeline-status"),
|
|
3018
|
+
source: z9.string().min(1)
|
|
3019
|
+
});
|
|
3020
|
+
var pipelineSchema = z9.object({
|
|
3021
|
+
id: z9.number().int().positive(),
|
|
3022
|
+
name: z9.string().min(1).nullable().optional(),
|
|
3023
|
+
status: z9.string(),
|
|
3024
|
+
ref: z9.string().min(1).nullable().optional(),
|
|
3025
|
+
created_at: z9.string().nullable().optional(),
|
|
3026
|
+
updated_at: z9.string().nullable().optional(),
|
|
3027
|
+
web_url: z9.url()
|
|
3028
|
+
});
|
|
3029
|
+
function permittedGitlabCiCalls(panel, source) {
|
|
3030
|
+
const { source: parsedSource } = z9.object({ panel: pipelinePanelSchema3, source: gitlabCiSourceSchema }).parse({ panel, source });
|
|
3031
|
+
return [pipelinesCall(parsedSource)];
|
|
3032
|
+
}
|
|
3033
|
+
async function fetchGitlabCiPipeline(args) {
|
|
3034
|
+
const panel = pipelinePanelSchema3.parse(args.panel);
|
|
3035
|
+
const source = gitlabCiSourceSchema.parse(args.source);
|
|
3036
|
+
const token = args.credentials.get(source.token_env);
|
|
3037
|
+
if (!token)
|
|
3038
|
+
return failure(
|
|
3039
|
+
panel.id,
|
|
3040
|
+
"unauthorized",
|
|
3041
|
+
"GitLab credentials are not available.",
|
|
3042
|
+
sourceLink3(source)
|
|
3043
|
+
);
|
|
3044
|
+
const call = pipelinesCall(source);
|
|
3045
|
+
forwardValidators(args.requestHeaders, call.headers);
|
|
3046
|
+
call.headers.set("private-token", token);
|
|
3047
|
+
let upstream;
|
|
3048
|
+
try {
|
|
3049
|
+
upstream = await args.fetcher(call.url, { headers: call.headers });
|
|
3050
|
+
} catch (error) {
|
|
3051
|
+
return failure(panel.id, "unreachable", error, sourceLink3(source), void 0, {
|
|
3052
|
+
kind: "unreachable",
|
|
3053
|
+
...safeNetworkCode(error) ? { networkCode: safeNetworkCode(error) } : {}
|
|
3054
|
+
});
|
|
3055
|
+
}
|
|
3056
|
+
if (upstream.status === 304) return { response: upstream };
|
|
3057
|
+
if (!upstream.ok) {
|
|
3058
|
+
const kind = upstreamErrorKind(upstream.status);
|
|
3059
|
+
return failure(
|
|
3060
|
+
panel.id,
|
|
3061
|
+
kind,
|
|
3062
|
+
`${upstream.status} ${upstream.statusText}`,
|
|
3063
|
+
sourceLink3(source),
|
|
3064
|
+
upstream.headers.get("date"),
|
|
3065
|
+
{ kind, upstreamStatus: upstream.status }
|
|
3066
|
+
);
|
|
3067
|
+
}
|
|
3068
|
+
try {
|
|
3069
|
+
const pipeline = z9.array(pipelineSchema).parse(await upstream.json())[0];
|
|
3070
|
+
if (!pipeline) {
|
|
3071
|
+
const detail = source.branch ? `No pipelines found for ref "${source.branch}". Check the source's branch setting.` : "No pipelines found.";
|
|
3072
|
+
return failure(
|
|
3073
|
+
panel.id,
|
|
3074
|
+
"no-runs",
|
|
3075
|
+
detail,
|
|
3076
|
+
sourceLink3(source),
|
|
3077
|
+
upstream.headers.get("date"),
|
|
3078
|
+
{
|
|
3079
|
+
kind: "no-runs",
|
|
3080
|
+
upstreamStatus: upstream.status
|
|
3081
|
+
}
|
|
3082
|
+
);
|
|
3083
|
+
}
|
|
3084
|
+
const signal = {
|
|
3085
|
+
type: "pipeline-status",
|
|
3086
|
+
status: normalizeStatus3(pipeline.status),
|
|
3087
|
+
rawStatus: pipeline.status,
|
|
3088
|
+
name: pipeline.name ?? `Pipeline #${pipeline.id}`,
|
|
3089
|
+
...pipeline.ref ?? source.branch ? { branch: pipeline.ref ?? source.branch } : {},
|
|
3090
|
+
...timestamp3(pipeline.created_at) ? { runStartedAt: timestamp3(pipeline.created_at) } : {},
|
|
3091
|
+
...timestamp3(pipeline.updated_at) ? { sourceUpdatedAt: timestamp3(pipeline.updated_at) } : {},
|
|
3092
|
+
sourceRunId: String(pipeline.id)
|
|
3093
|
+
};
|
|
3094
|
+
const envelope = {
|
|
3095
|
+
panelId: panel.id,
|
|
3096
|
+
state: "ok",
|
|
3097
|
+
observedAt: observedAt(upstream.headers.get("date")),
|
|
3098
|
+
link: publicLink(pipeline.web_url),
|
|
3099
|
+
signal
|
|
3100
|
+
};
|
|
3101
|
+
return { envelope, response: upstream };
|
|
3102
|
+
} catch (error) {
|
|
3103
|
+
return failure(
|
|
3104
|
+
panel.id,
|
|
3105
|
+
"upstream-error",
|
|
3106
|
+
error,
|
|
3107
|
+
sourceLink3(source),
|
|
3108
|
+
upstream.headers.get("date"),
|
|
3109
|
+
{ kind: "upstream-error", upstreamStatus: upstream.status }
|
|
3110
|
+
);
|
|
3111
|
+
}
|
|
3112
|
+
}
|
|
3113
|
+
function pipelinesCall(source) {
|
|
3114
|
+
const url = new URL(source.url);
|
|
3115
|
+
url.pathname = `${url.pathname.replace(/\/$/, "")}/api/v4/projects/${encodeURIComponent(source.project)}/pipelines`;
|
|
3116
|
+
url.searchParams.set("per_page", "1");
|
|
3117
|
+
if (source.branch) url.searchParams.set("ref", source.branch);
|
|
3118
|
+
return { url: url.toString(), headers: new Headers({ accept: "application/json" }) };
|
|
3119
|
+
}
|
|
3120
|
+
function sourceLink3(source) {
|
|
3121
|
+
const url = new URL(source.url);
|
|
3122
|
+
url.pathname = `${url.pathname.replace(/\/$/, "")}/${source.project.split("/").map(encodeURIComponent).join("/")}/-/pipelines`;
|
|
3123
|
+
return url.toString();
|
|
3124
|
+
}
|
|
3125
|
+
function normalizeStatus3(status) {
|
|
3126
|
+
if (["created", "waiting_for_resource", "preparing", "pending", "running"].includes(status))
|
|
3127
|
+
return "running";
|
|
3128
|
+
if (status === "success") return "passed";
|
|
3129
|
+
if (status === "failed") return "failed";
|
|
3130
|
+
if (status === "canceled") return "cancelled";
|
|
3131
|
+
if (["manual", "skipped", "scheduled"].includes(status)) return "warning";
|
|
3132
|
+
return "unknown";
|
|
3133
|
+
}
|
|
3134
|
+
function timestamp3(value2) {
|
|
3135
|
+
if (!value2 || !z9.iso.datetime().safeParse(value2).success) return void 0;
|
|
3136
|
+
return Number.isFinite(new Date(value2).valueOf()) ? value2 : void 0;
|
|
3137
|
+
}
|
|
3138
|
+
function failure(panelId, kind, error, link, date, failure2) {
|
|
3139
|
+
return {
|
|
3140
|
+
response: upstreamErrorResponse(
|
|
3141
|
+
upstreamErrorEnvelope({ panelId, kind, error, link, upstreamDate: date })
|
|
3142
|
+
),
|
|
3143
|
+
...failure2 ? { failure: failure2 } : { failure: { kind } }
|
|
3144
|
+
};
|
|
3145
|
+
}
|
|
3146
|
+
|
|
3147
|
+
// packages/server/src/adapters/http-value.ts
|
|
3148
|
+
import { z as z10 } from "zod";
|
|
3149
|
+
function permittedHttpValueCalls(panel) {
|
|
3150
|
+
const grouped = httpValueGroupedPanelSchema.safeParse(panel);
|
|
3151
|
+
const urls = grouped.success ? grouped.data.facts.map((fact) => fact.url) : [z10.object({ panel: httpValueScalarPanelSchema }).parse({ panel }).panel.url];
|
|
3152
|
+
return urls.map(permittedCall);
|
|
3153
|
+
}
|
|
3154
|
+
async function fetchHttpValue(args) {
|
|
3155
|
+
const panel = httpValueScalarPanelSchema.parse(args.panel);
|
|
3156
|
+
const [call] = permittedHttpValueCalls(args.panel);
|
|
3157
|
+
if (!call) throw new Error("http-value adapter declared no permitted call");
|
|
3158
|
+
forwardValidators(args.requestHeaders, call.headers);
|
|
3159
|
+
let upstream;
|
|
3160
|
+
try {
|
|
3161
|
+
upstream = await args.fetcher(call.url, { headers: call.headers });
|
|
3162
|
+
} catch (error) {
|
|
3163
|
+
return {
|
|
3164
|
+
response: errorResponse2("unreachable", error, panel),
|
|
3165
|
+
failure: {
|
|
3166
|
+
kind: "unreachable",
|
|
3167
|
+
...safeNetworkCode(error) ? { networkCode: safeNetworkCode(error) } : {}
|
|
3168
|
+
}
|
|
3169
|
+
};
|
|
3170
|
+
}
|
|
3171
|
+
if (upstream.status === 304) return { response: upstream };
|
|
3172
|
+
if (!upstream.ok) {
|
|
3173
|
+
return {
|
|
3174
|
+
response: errorResponse2(
|
|
3175
|
+
upstreamErrorKind(upstream.status),
|
|
3176
|
+
`${upstream.status} ${upstream.statusText}`,
|
|
3177
|
+
panel,
|
|
3178
|
+
upstream
|
|
3179
|
+
),
|
|
3180
|
+
failure: { kind: upstreamErrorKind(upstream.status), upstreamStatus: upstream.status }
|
|
3181
|
+
};
|
|
3182
|
+
}
|
|
3183
|
+
try {
|
|
3184
|
+
const text = await upstream.text();
|
|
3185
|
+
const value2 = panel.json_path ? extractJsonPath(JSON.parse(text), panel.json_path) : parseValue(text);
|
|
3186
|
+
const signal = { type: "http-value", value: value2 };
|
|
3187
|
+
return {
|
|
3188
|
+
envelope: {
|
|
3189
|
+
panelId: panel.id,
|
|
3190
|
+
state: "ok",
|
|
3191
|
+
observedAt: observedAt(upstream.headers.get("date")),
|
|
3192
|
+
link: publicLink(panel.link ?? panel.url),
|
|
3193
|
+
signal
|
|
3194
|
+
},
|
|
3195
|
+
response: upstream
|
|
3196
|
+
};
|
|
3197
|
+
} catch (error) {
|
|
3198
|
+
return {
|
|
3199
|
+
response: errorResponse2("upstream-error", error, panel, upstream),
|
|
3200
|
+
failure: { kind: "upstream-error", upstreamStatus: upstream.status }
|
|
3201
|
+
};
|
|
3202
|
+
}
|
|
3203
|
+
}
|
|
3204
|
+
function permittedCall(value2) {
|
|
3205
|
+
const url = new URL(value2);
|
|
3206
|
+
if (url.protocol !== "http:" && url.protocol !== "https:")
|
|
3207
|
+
throw new Error("http-value URLs must use http or https");
|
|
3208
|
+
return { url: url.toString(), headers: new Headers({ accept: "application/json, text/plain" }) };
|
|
3209
|
+
}
|
|
3210
|
+
function parseValue(text) {
|
|
3211
|
+
const trimmed = text.trim();
|
|
3212
|
+
try {
|
|
3213
|
+
const parsed = JSON.parse(trimmed);
|
|
3214
|
+
if (typeof parsed === "string" || typeof parsed === "number" || typeof parsed === "boolean")
|
|
3215
|
+
return parsed;
|
|
3216
|
+
} catch {
|
|
3217
|
+
}
|
|
3218
|
+
return trimmed;
|
|
3219
|
+
}
|
|
3220
|
+
function extractJsonPath(value2, path) {
|
|
3221
|
+
let current = value2;
|
|
3222
|
+
const segments = path === "$" ? [] : path.slice(1).split(/\.|\[|\]/).filter(Boolean);
|
|
3223
|
+
for (const segment of segments) {
|
|
3224
|
+
if (typeof current !== "object" || current === null || !(segment in current))
|
|
3225
|
+
throw new Error(`JSON path ${path} was not found`);
|
|
3226
|
+
current = current[segment];
|
|
3227
|
+
}
|
|
3228
|
+
if (typeof current !== "string" && typeof current !== "number" && typeof current !== "boolean") {
|
|
3229
|
+
throw new Error(`JSON path ${path} did not select a scalar value`);
|
|
3230
|
+
}
|
|
3231
|
+
return current;
|
|
3232
|
+
}
|
|
3233
|
+
function errorResponse2(kind, error, panel, response) {
|
|
3234
|
+
return upstreamErrorResponse(
|
|
3235
|
+
upstreamErrorEnvelope({
|
|
3236
|
+
panelId: panel.id,
|
|
3237
|
+
kind,
|
|
3238
|
+
error,
|
|
3239
|
+
link: panel.link ?? panel.url,
|
|
3240
|
+
upstreamDate: response?.headers.get("date")
|
|
3241
|
+
})
|
|
3242
|
+
);
|
|
3243
|
+
}
|
|
3244
|
+
|
|
3245
|
+
// packages/server/src/panel-adapters.ts
|
|
3246
|
+
function readPanelAdapter(panel, source) {
|
|
1577
3247
|
if (panel.type === "pipeline-status" && source?.type === "github-actions") {
|
|
1578
3248
|
permittedGithubActionsCalls(panel, source);
|
|
1579
|
-
return {
|
|
3249
|
+
return {
|
|
3250
|
+
destination: () => "https://api.github.com",
|
|
3251
|
+
fetch: ({ source: _configuredSource, ...args }) => fetchGithubActionsPipeline({ ...args, source })
|
|
3252
|
+
};
|
|
3253
|
+
}
|
|
3254
|
+
if (panel.type === "test-count" && source?.type === "github-actions") {
|
|
3255
|
+
testCountCapabilities(panel, source);
|
|
3256
|
+
return {
|
|
3257
|
+
destination: () => "https://api.github.com",
|
|
3258
|
+
fetch: ({ source: _configuredSource, ...args }) => fetchGithubActionsTestCount({ ...args, source })
|
|
3259
|
+
};
|
|
1580
3260
|
}
|
|
1581
3261
|
if (panel.type === "pipeline-status" && source?.type === "azure-devops") {
|
|
1582
3262
|
permittedAzureDevOpsCalls(panel, source);
|
|
1583
|
-
return {
|
|
3263
|
+
return {
|
|
3264
|
+
destination: () => "https://dev.azure.com",
|
|
3265
|
+
fetch: ({ source: _configuredSource, ...args }) => fetchAzureDevOpsPipeline({ ...args, source })
|
|
3266
|
+
};
|
|
1584
3267
|
}
|
|
1585
3268
|
if (panel.type === "pipeline-status" && source?.type === "gitlab-ci") {
|
|
1586
3269
|
permittedGitlabCiCalls(panel, source);
|
|
1587
|
-
return {
|
|
3270
|
+
return {
|
|
3271
|
+
destination: (_panel, resolvedSource) => resolvedSource && "url" in resolvedSource && typeof resolvedSource.url === "string" ? resolvedSource.url : "https://gitlab.com",
|
|
3272
|
+
fetch: ({ source: _configuredSource, ...args }) => fetchGitlabCiPipeline({ ...args, source })
|
|
3273
|
+
};
|
|
1588
3274
|
}
|
|
1589
3275
|
if (panel.type === "http-value") {
|
|
1590
3276
|
permittedHttpValueCalls(panel);
|
|
1591
|
-
return {
|
|
3277
|
+
return {
|
|
3278
|
+
destination: (configuredPanel) => configuredPanel.url ?? "",
|
|
3279
|
+
...panel.facts ? {} : { fetch: (args) => fetchHttpValue(args) }
|
|
3280
|
+
};
|
|
3281
|
+
}
|
|
3282
|
+
return void 0;
|
|
3283
|
+
}
|
|
3284
|
+
|
|
3285
|
+
// packages/server/src/allowlist.ts
|
|
3286
|
+
function deriveValidatedAllowlist(config) {
|
|
3287
|
+
return derive(config, true);
|
|
3288
|
+
}
|
|
3289
|
+
function derive(config, rejectUnsupported) {
|
|
3290
|
+
const allowed = /* @__PURE__ */ new Map();
|
|
3291
|
+
for (const [boardName, board] of Object.entries(config.boards)) {
|
|
3292
|
+
for (const panel of board.panels) {
|
|
3293
|
+
const source = panel.source ? config.sources[panel.source] : void 0;
|
|
3294
|
+
try {
|
|
3295
|
+
const capability = panelCapability(panel, source);
|
|
3296
|
+
if (capability.kind === "unsupported") {
|
|
3297
|
+
if (rejectUnsupported) throw new Error("no bounded operations");
|
|
3298
|
+
continue;
|
|
3299
|
+
}
|
|
3300
|
+
if (capability.kind === "server")
|
|
3301
|
+
allowed.set(`${boardName}/${panel.id}`, new Set(capability.operations));
|
|
3302
|
+
} catch (error) {
|
|
3303
|
+
if (rejectUnsupported) {
|
|
3304
|
+
const location = `boards[${Object.keys(config.boards).indexOf(boardName)}].panels[${board.panels.indexOf(panel)}]`;
|
|
3305
|
+
throw new ConfigurationError(
|
|
3306
|
+
unsupportedPanelOperation(boardName, panel, source, error).message,
|
|
3307
|
+
error instanceof ZodError ? schemaDiagnostics(
|
|
3308
|
+
error,
|
|
3309
|
+
([subject, ...path]) => {
|
|
3310
|
+
const root = subject === "source" ? ["sources", Object.keys(config.sources).indexOf(panel.source ?? "")] : [
|
|
3311
|
+
"boards",
|
|
3312
|
+
Object.keys(config.boards).indexOf(boardName),
|
|
3313
|
+
"panels",
|
|
3314
|
+
board.panels.indexOf(panel)
|
|
3315
|
+
];
|
|
3316
|
+
return configurationLocation([...root, ...path]);
|
|
3317
|
+
},
|
|
3318
|
+
"panel-admission"
|
|
3319
|
+
) : [
|
|
3320
|
+
{
|
|
3321
|
+
kind: "panel-admission",
|
|
3322
|
+
location,
|
|
3323
|
+
constraint: "Use a supported panel/source combination with bounded HTTP(S) operations."
|
|
3324
|
+
}
|
|
3325
|
+
]
|
|
3326
|
+
);
|
|
3327
|
+
}
|
|
3328
|
+
throw error;
|
|
3329
|
+
}
|
|
3330
|
+
}
|
|
1592
3331
|
}
|
|
3332
|
+
return allowed;
|
|
3333
|
+
}
|
|
3334
|
+
function panelCapability(panel, source) {
|
|
3335
|
+
if (readPanelAdapter(panel, source)) return { kind: "server", operations: ["read"] };
|
|
1593
3336
|
if (panel.type === "pull-request-health" && source?.type === "github-actions") {
|
|
1594
3337
|
pullRequestHealthCapabilities(panel);
|
|
1595
3338
|
return {
|