@juangadm/pre-post 0.3.0 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +174 -233
- package/dist/baseline.d.ts +119 -0
- package/dist/baseline.d.ts.map +1 -0
- package/dist/baseline.js +316 -0
- package/dist/baseline.js.map +1 -0
- package/dist/bin/cli.js +243 -458
- package/dist/bin/cli.js.map +1 -1
- package/dist/browser.d.ts +68 -25
- package/dist/browser.d.ts.map +1 -1
- package/dist/browser.js +500 -105
- package/dist/browser.js.map +1 -1
- package/dist/capture.d.ts +1 -6
- package/dist/capture.d.ts.map +1 -1
- package/dist/capture.js +12 -36
- package/dist/capture.js.map +1 -1
- package/dist/commands/compare.d.ts +18 -0
- package/dist/commands/compare.d.ts.map +1 -0
- package/dist/commands/compare.js +82 -0
- package/dist/commands/compare.js.map +1 -0
- package/dist/commands/detect.d.ts +25 -0
- package/dist/commands/detect.d.ts.map +1 -0
- package/dist/commands/detect.js +22 -0
- package/dist/commands/detect.js.map +1 -0
- package/dist/commands/doctor.d.ts +42 -0
- package/dist/commands/doctor.d.ts.map +1 -0
- package/dist/commands/doctor.js +119 -0
- package/dist/commands/doctor.js.map +1 -0
- package/dist/commands/login.d.ts +6 -0
- package/dist/commands/login.d.ts.map +1 -0
- package/dist/commands/login.js +34 -0
- package/dist/commands/login.js.map +1 -0
- package/dist/commands/pr.d.ts +32 -0
- package/dist/commands/pr.d.ts.map +1 -0
- package/dist/commands/pr.js +259 -0
- package/dist/commands/pr.js.map +1 -0
- package/dist/commands/prune.d.ts +10 -0
- package/dist/commands/prune.d.ts.map +1 -0
- package/dist/commands/prune.js +13 -0
- package/dist/commands/prune.js.map +1 -0
- package/dist/comparison.d.ts +104 -0
- package/dist/comparison.d.ts.map +1 -0
- package/dist/comparison.js +236 -0
- package/dist/comparison.js.map +1 -0
- package/dist/config.d.ts +46 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +82 -0
- package/dist/config.js.map +1 -0
- package/dist/deployments.d.ts +71 -0
- package/dist/deployments.d.ts.map +1 -0
- package/dist/deployments.js +204 -0
- package/dist/deployments.js.map +1 -0
- package/dist/diff-pool.d.ts +17 -0
- package/dist/diff-pool.d.ts.map +1 -0
- package/dist/diff-pool.js +92 -0
- package/dist/diff-pool.js.map +1 -0
- package/dist/diff-worker.d.ts +32 -0
- package/dist/diff-worker.d.ts.map +1 -0
- package/dist/diff-worker.js +39 -0
- package/dist/diff-worker.js.map +1 -0
- package/dist/diff.d.ts +47 -0
- package/dist/diff.d.ts.map +1 -0
- package/dist/diff.js +281 -0
- package/dist/diff.js.map +1 -0
- package/dist/doctor.d.ts +79 -0
- package/dist/doctor.d.ts.map +1 -0
- package/dist/doctor.js +138 -0
- package/dist/doctor.js.map +1 -0
- package/dist/errors.d.ts +38 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +59 -0
- package/dist/errors.js.map +1 -0
- package/dist/git.d.ts +61 -0
- package/dist/git.d.ts.map +1 -0
- package/dist/git.js +182 -0
- package/dist/git.js.map +1 -0
- package/dist/github.d.ts +163 -0
- package/dist/github.d.ts.map +1 -0
- package/dist/github.js +411 -0
- package/dist/github.js.map +1 -0
- package/dist/index.d.ts +22 -23
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +17 -67
- package/dist/index.js.map +1 -1
- package/dist/landing.d.ts +48 -0
- package/dist/landing.d.ts.map +1 -0
- package/dist/landing.js +93 -0
- package/dist/landing.js.map +1 -0
- package/dist/pkg.d.ts +17 -0
- package/dist/pkg.d.ts.map +1 -0
- package/dist/pkg.js +49 -0
- package/dist/pkg.js.map +1 -0
- package/dist/report.d.ts +20 -0
- package/dist/report.d.ts.map +1 -0
- package/dist/report.js +130 -0
- package/dist/report.js.map +1 -0
- package/dist/routes/imports.d.ts +46 -0
- package/dist/routes/imports.d.ts.map +1 -0
- package/dist/routes/imports.js +208 -0
- package/dist/routes/imports.js.map +1 -0
- package/dist/routes/vite.d.ts +15 -0
- package/dist/routes/vite.d.ts.map +1 -0
- package/dist/routes/vite.js +130 -0
- package/dist/routes/vite.js.map +1 -0
- package/dist/routes.d.ts +65 -11
- package/dist/routes.d.ts.map +1 -1
- package/dist/routes.js +346 -141
- package/dist/routes.js.map +1 -1
- package/dist/run.d.ts +116 -0
- package/dist/run.d.ts.map +1 -0
- package/dist/run.js +316 -0
- package/dist/run.js.map +1 -0
- package/dist/sameness.d.ts +91 -0
- package/dist/sameness.d.ts.map +1 -0
- package/dist/sameness.js +157 -0
- package/dist/sameness.js.map +1 -0
- package/dist/sessions.d.ts +50 -0
- package/dist/sessions.d.ts.map +1 -0
- package/dist/sessions.js +80 -0
- package/dist/sessions.js.map +1 -0
- package/dist/shift.d.ts +67 -0
- package/dist/shift.d.ts.map +1 -0
- package/dist/shift.js +184 -0
- package/dist/shift.js.map +1 -0
- package/dist/types.d.ts +179 -68
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +1 -0
- package/dist/types.js.map +1 -1
- package/dist/url.d.ts +12 -0
- package/dist/url.d.ts.map +1 -0
- package/dist/url.js +30 -0
- package/dist/url.js.map +1 -0
- package/dist/viewport.d.ts +6 -1
- package/dist/viewport.d.ts.map +1 -1
- package/dist/viewport.js +13 -7
- package/dist/viewport.js.map +1 -1
- package/package.json +21 -14
- package/skill/SKILL.md +56 -221
- package/dist/clipboard.d.ts +0 -9
- package/dist/clipboard.d.ts.map +0 -1
- package/dist/clipboard.js +0 -26
- package/dist/clipboard.js.map +0 -1
- package/dist/upload.d.ts +0 -39
- package/dist/upload.d.ts.map +0 -1
- package/dist/upload.js +0 -159
- package/dist/upload.js.map +0 -1
- package/dist/video.d.ts +0 -19
- package/dist/video.d.ts.map +0 -1
- package/dist/video.js +0 -263
- package/dist/video.js.map +0 -1
- package/skill/scripts/adapters/0x0st.sh +0 -36
- package/skill/scripts/adapters/blob.sh +0 -55
- package/skill/scripts/adapters/git-native.sh +0 -51
- package/skill/scripts/upload-and-copy.sh +0 -230
package/dist/diff.js
ADDED
|
@@ -0,0 +1,281 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pixel diff between two PNG screenshots.
|
|
3
|
+
*
|
|
4
|
+
* Pure JS (pixelmatch + pngjs): no native build step, works everywhere the
|
|
5
|
+
* CLI runs. Produces a change ratio, the bounding box of the change, a
|
|
6
|
+
* highlight image, and tight crops of before/after around the change.
|
|
7
|
+
*/
|
|
8
|
+
import pixelmatch from 'pixelmatch';
|
|
9
|
+
import { PNG } from 'pngjs';
|
|
10
|
+
import { alignBefore, detectShift, insertedBand } from './shift.js';
|
|
11
|
+
const DIFF_COLOR = [255, 0, 0];
|
|
12
|
+
const AA_COLOR = [255, 200, 0];
|
|
13
|
+
/** Background used to pad images of different sizes. */
|
|
14
|
+
const PAD_COLOR = [255, 255, 255];
|
|
15
|
+
/**
|
|
16
|
+
* pixelmatch per-pixel colour distance (0..1).
|
|
17
|
+
*
|
|
18
|
+
* Calibrated, not chosen. At the old 0.1 a 600x320 card recoloured from #ffffff
|
|
19
|
+
* to #e6e6e6 — plainly visible, a sixth of the viewport — reported *zero*
|
|
20
|
+
* changed pixels, and `rung-6-section` measured 1649 CSS px² instead of 67539.
|
|
21
|
+
* The ladder never caught it because every rung varies painted *area* while the
|
|
22
|
+
* threshold governs *contrast*, so nothing in the suite moved along that axis.
|
|
23
|
+
* `contrast-*` is that missing axis.
|
|
24
|
+
*
|
|
25
|
+
* Measured across the fixtures, changed CSS px² by threshold:
|
|
26
|
+
*
|
|
27
|
+
* 0.1 0.05 0.03 0.02 0.01
|
|
28
|
+
* contrast-25 0 191754 191754 191754 191754
|
|
29
|
+
* contrast-15 0 191758 191758 191758 191758
|
|
30
|
+
* contrast-10 0 0 191758 191758 191758
|
|
31
|
+
* contrast-05 0 0 0 0 191762
|
|
32
|
+
* rung-6 1649 1649 67539 67539 67539
|
|
33
|
+
* noise-* 0 0 0 0 0
|
|
34
|
+
*
|
|
35
|
+
* Every no-op stays at zero the whole way down, and so does the strongest
|
|
36
|
+
* real-world check available: the same page captured from two different
|
|
37
|
+
* deployments, which reports 0 at every value above, desktop and mobile.
|
|
38
|
+
*
|
|
39
|
+
* 0.02 catches every delta a reader would call visible and keeps a margin above
|
|
40
|
+
* the floor for sites noisier than the ones measured. 0.01 was also clean here;
|
|
41
|
+
* the margin is deliberate, since the alternative to a marginal false positive
|
|
42
|
+
* is silently publishing "No visual changes" about a page that changed.
|
|
43
|
+
*/
|
|
44
|
+
const PIXEL_THRESHOLD = 0.02;
|
|
45
|
+
/** No crop when the change covers more than this fraction of the canvas. */
|
|
46
|
+
const CROP_MAX_RATIO = 0.5;
|
|
47
|
+
/**
|
|
48
|
+
* A shift is only worth reporting when putting the two sides back in register
|
|
49
|
+
* accounts for most of the difference. This is the whole test: an offset that
|
|
50
|
+
* does not remove the pixels it claims to explain is not the story.
|
|
51
|
+
*
|
|
52
|
+
* Judged over the rows Pre and Post share. Content Post gained is excluded
|
|
53
|
+
* from both sides of the comparison, because an insertion is the reason for
|
|
54
|
+
* the move rather than evidence against it: a page pushed down by a banner
|
|
55
|
+
* would otherwise be refused for the size of the banner.
|
|
56
|
+
*
|
|
57
|
+
* Measured on the shift ladder, as a share of the changed pixels over those
|
|
58
|
+
* shared rows: every true shift leaves 0.23 or less, and the horizontal
|
|
59
|
+
* reflow — the one case no vertical offset explains — leaves 0.45. This sits
|
|
60
|
+
* in the empty band between, nearer the real changes so a genuine shift
|
|
61
|
+
* carrying a larger change still reads as one. Erring low is deliberate:
|
|
62
|
+
* rejecting a shift falls back to the old behaviour, while claiming one that
|
|
63
|
+
* isn't there tells a reviewer something untrue.
|
|
64
|
+
*/
|
|
65
|
+
const MAX_ALIGNED_SHARE = 0.3;
|
|
66
|
+
function padTo(src, width, height, bg) {
|
|
67
|
+
if (src.width === width && src.height === height)
|
|
68
|
+
return src;
|
|
69
|
+
const out = new PNG({ width, height });
|
|
70
|
+
for (let i = 0; i < out.data.length; i += 4) {
|
|
71
|
+
out.data[i] = bg[0];
|
|
72
|
+
out.data[i + 1] = bg[1];
|
|
73
|
+
out.data[i + 2] = bg[2];
|
|
74
|
+
out.data[i + 3] = 255;
|
|
75
|
+
}
|
|
76
|
+
PNG.bitblt(src, out, 0, 0, src.width, src.height, 0, 0);
|
|
77
|
+
return out;
|
|
78
|
+
}
|
|
79
|
+
function crop(src, region) {
|
|
80
|
+
const out = new PNG({ width: region.width, height: region.height });
|
|
81
|
+
PNG.bitblt(src, out, region.x, region.y, region.width, region.height, 0, 0);
|
|
82
|
+
return encode(out);
|
|
83
|
+
}
|
|
84
|
+
function encode(png) {
|
|
85
|
+
return PNG.sync.write(png, { deflateLevel: 4, filterType: 4 });
|
|
86
|
+
}
|
|
87
|
+
/** Box-filter downscale by an integer factor. */
|
|
88
|
+
export function downscale(src, factor) {
|
|
89
|
+
if (factor <= 1)
|
|
90
|
+
return src;
|
|
91
|
+
const w = Math.max(1, Math.floor(src.width / factor));
|
|
92
|
+
const h = Math.max(1, Math.floor(src.height / factor));
|
|
93
|
+
const out = new PNG({ width: w, height: h });
|
|
94
|
+
const n = factor * factor;
|
|
95
|
+
for (let y = 0; y < h; y++) {
|
|
96
|
+
for (let x = 0; x < w; x++) {
|
|
97
|
+
let r = 0, g = 0, b = 0, a = 0;
|
|
98
|
+
for (let dy = 0; dy < factor; dy++) {
|
|
99
|
+
let i = ((y * factor + dy) * src.width + x * factor) * 4;
|
|
100
|
+
for (let dx = 0; dx < factor; dx++, i += 4) {
|
|
101
|
+
r += src.data[i];
|
|
102
|
+
g += src.data[i + 1];
|
|
103
|
+
b += src.data[i + 2];
|
|
104
|
+
a += src.data[i + 3];
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
const o = (y * w + x) * 4;
|
|
108
|
+
out.data[o] = r / n;
|
|
109
|
+
out.data[o + 1] = g / n;
|
|
110
|
+
out.data[o + 2] = b / n;
|
|
111
|
+
out.data[o + 3] = a / n;
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
return out;
|
|
115
|
+
}
|
|
116
|
+
export function decodePng(buffer) {
|
|
117
|
+
return PNG.sync.read(buffer);
|
|
118
|
+
}
|
|
119
|
+
/** Diff-coloured pixels within a row range, for weighing one band against another. */
|
|
120
|
+
function countChangedRows(diff, y0, y1) {
|
|
121
|
+
const { width, data } = diff;
|
|
122
|
+
let count = 0;
|
|
123
|
+
for (let y = Math.max(0, y0); y < Math.min(diff.height, y1); y++) {
|
|
124
|
+
const row = y * width * 4;
|
|
125
|
+
for (let x = 0; x < width; x++) {
|
|
126
|
+
const i = row + x * 4;
|
|
127
|
+
if (data[i] === DIFF_COLOR[0] && data[i + 1] === DIFF_COLOR[1] && data[i + 2] === DIFF_COLOR[2])
|
|
128
|
+
count++;
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
return count;
|
|
132
|
+
}
|
|
133
|
+
/** Bounding box of pixels painted with the diff color. */
|
|
134
|
+
function boundingBox(diff) {
|
|
135
|
+
const { width, height, data } = diff;
|
|
136
|
+
let minX = width, minY = height, maxX = -1, maxY = -1;
|
|
137
|
+
for (let y = 0; y < height; y++) {
|
|
138
|
+
const row = y * width * 4;
|
|
139
|
+
for (let x = 0; x < width; x++) {
|
|
140
|
+
const i = row + x * 4;
|
|
141
|
+
if (data[i] === DIFF_COLOR[0] && data[i + 1] === DIFF_COLOR[1] && data[i + 2] === DIFF_COLOR[2]) {
|
|
142
|
+
if (x < minX)
|
|
143
|
+
minX = x;
|
|
144
|
+
if (x > maxX)
|
|
145
|
+
maxX = x;
|
|
146
|
+
if (y < minY)
|
|
147
|
+
minY = y;
|
|
148
|
+
if (y > maxY)
|
|
149
|
+
maxY = y;
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
if (maxX < 0)
|
|
154
|
+
return null;
|
|
155
|
+
return { x: minX, y: minY, width: maxX - minX + 1, height: maxY - minY + 1 };
|
|
156
|
+
}
|
|
157
|
+
/** Expand a region by padding and to a minimum size, clamped to the canvas. */
|
|
158
|
+
export function expandRegion(region, canvas, padding, min) {
|
|
159
|
+
let x0 = region.x - padding;
|
|
160
|
+
let y0 = region.y - padding;
|
|
161
|
+
let x1 = region.x + region.width + padding;
|
|
162
|
+
let y1 = region.y + region.height + padding;
|
|
163
|
+
const grow = (lo, hi, target, limit) => {
|
|
164
|
+
const size = hi - lo;
|
|
165
|
+
if (size < target) {
|
|
166
|
+
const extra = target - size;
|
|
167
|
+
lo -= Math.floor(extra / 2);
|
|
168
|
+
hi += Math.ceil(extra / 2);
|
|
169
|
+
}
|
|
170
|
+
if (lo < 0) {
|
|
171
|
+
hi -= lo;
|
|
172
|
+
lo = 0;
|
|
173
|
+
}
|
|
174
|
+
if (hi > limit) {
|
|
175
|
+
lo -= hi - limit;
|
|
176
|
+
hi = limit;
|
|
177
|
+
}
|
|
178
|
+
return [Math.max(0, lo), Math.min(limit, hi)];
|
|
179
|
+
};
|
|
180
|
+
[x0, x1] = grow(x0, x1, Math.min(min.width, canvas.width), canvas.width);
|
|
181
|
+
[y0, y1] = grow(y0, y1, Math.min(min.height, canvas.height), canvas.height);
|
|
182
|
+
return { x: x0, y: y0, width: x1 - x0, height: y1 - y0 };
|
|
183
|
+
}
|
|
184
|
+
/**
|
|
185
|
+
* Compare two PNG buffers. Images of different sizes are padded onto a shared
|
|
186
|
+
* canvas so a height change shows up as a change rather than an error.
|
|
187
|
+
*/
|
|
188
|
+
export function diffImages(beforePng, afterPng, options = {}) {
|
|
189
|
+
const bg = PAD_COLOR;
|
|
190
|
+
const a = decodePng(beforePng);
|
|
191
|
+
const b = decodePng(afterPng);
|
|
192
|
+
const width = Math.max(a.width, b.width);
|
|
193
|
+
const height = Math.max(a.height, b.height);
|
|
194
|
+
const sizeChanged = a.width !== b.width || a.height !== b.height;
|
|
195
|
+
const before = padTo(a, width, height, bg);
|
|
196
|
+
const after = padTo(b, width, height, bg);
|
|
197
|
+
const diff = new PNG({ width, height });
|
|
198
|
+
const changedPixels = pixelmatch(before.data, after.data, diff.data, width, height, {
|
|
199
|
+
threshold: PIXEL_THRESHOLD,
|
|
200
|
+
includeAA: false,
|
|
201
|
+
alpha: 0.5,
|
|
202
|
+
diffColor: DIFF_COLOR,
|
|
203
|
+
aaColor: AA_COLOR,
|
|
204
|
+
diffMask: false,
|
|
205
|
+
});
|
|
206
|
+
// A vertical shift repaints everything below where it starts, so the raw
|
|
207
|
+
// bounding box covers most of the page and the crop guards below refuse to
|
|
208
|
+
// zoom in. Comparing Post put back in register with Pre isolates the change
|
|
209
|
+
// the branch actually made, which is small enough to crop and to describe.
|
|
210
|
+
let shift;
|
|
211
|
+
let alignedBefore;
|
|
212
|
+
let alignedDiff;
|
|
213
|
+
if (changedPixels > 0) {
|
|
214
|
+
const candidate = detectShift(before, after);
|
|
215
|
+
if (candidate) {
|
|
216
|
+
const aligned = alignBefore(before, candidate, bg);
|
|
217
|
+
const diffOfAligned = new PNG({ width, height });
|
|
218
|
+
const alignedChangedPixels = pixelmatch(aligned.data, after.data, diffOfAligned.data, width, height, {
|
|
219
|
+
threshold: PIXEL_THRESHOLD,
|
|
220
|
+
includeAA: false,
|
|
221
|
+
alpha: 0.5,
|
|
222
|
+
diffColor: DIFF_COLOR,
|
|
223
|
+
aaColor: AA_COLOR,
|
|
224
|
+
diffMask: false,
|
|
225
|
+
});
|
|
226
|
+
// Weigh the offset only on rows both sides have. Whatever Post put in
|
|
227
|
+
// the gap is new content, and it still counts as a change -- it just
|
|
228
|
+
// does not get a vote on whether the move happened.
|
|
229
|
+
const gap = insertedBand(candidate);
|
|
230
|
+
const insertedChanged = gap ? countChangedRows(diffOfAligned, gap.y, gap.y + gap.height) : 0;
|
|
231
|
+
const rawInGap = gap ? countChangedRows(diff, gap.y, gap.y + gap.height) : 0;
|
|
232
|
+
const mappedChanged = alignedChangedPixels - insertedChanged;
|
|
233
|
+
const rawMapped = changedPixels - rawInGap;
|
|
234
|
+
if (mappedChanged <= rawMapped * MAX_ALIGNED_SHARE) {
|
|
235
|
+
shift = {
|
|
236
|
+
dy: candidate.dy,
|
|
237
|
+
from: candidate.from,
|
|
238
|
+
alignedChangedPixels,
|
|
239
|
+
alignedChangedRatio: alignedChangedPixels / (width * height),
|
|
240
|
+
};
|
|
241
|
+
alignedBefore = aligned;
|
|
242
|
+
alignedDiff = diffOfAligned;
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
const region = changedPixels > 0 ? boundingBox(diff) : null;
|
|
247
|
+
const result = {
|
|
248
|
+
changedRatio: changedPixels / (width * height),
|
|
249
|
+
changedPixels,
|
|
250
|
+
width,
|
|
251
|
+
height,
|
|
252
|
+
region,
|
|
253
|
+
sizeChanged,
|
|
254
|
+
// Identical pages need no highlight; skip the downscale + deflate.
|
|
255
|
+
highlight: region && options.highlight !== false
|
|
256
|
+
? encode(downscale(diff, options.highlightDownscale ?? 1))
|
|
257
|
+
: undefined,
|
|
258
|
+
shift,
|
|
259
|
+
};
|
|
260
|
+
// With a shift, crop what is left once the move is undone; without one, crop
|
|
261
|
+
// the change itself. A pure shift leaves nothing over and gets no crop: the
|
|
262
|
+
// sentence is the report, and the full pages are already published.
|
|
263
|
+
const cropFrom = alignedBefore ?? before;
|
|
264
|
+
const cropRegion = alignedDiff ? boundingBox(alignedDiff) : region;
|
|
265
|
+
if (cropRegion) {
|
|
266
|
+
const area = cropRegion.width * cropRegion.height;
|
|
267
|
+
if (area / (width * height) <= CROP_MAX_RATIO) {
|
|
268
|
+
const expanded = expandRegion(cropRegion, { width, height }, options.padding ?? 80, options.minCrop ?? { width: 800, height: 400 });
|
|
269
|
+
// Only crop when it meaningfully zooms in.
|
|
270
|
+
if (expanded.width * expanded.height < width * height * 0.8) {
|
|
271
|
+
result.crop = {
|
|
272
|
+
before: crop(cropFrom, expanded),
|
|
273
|
+
after: crop(after, expanded),
|
|
274
|
+
region: expanded,
|
|
275
|
+
};
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
return result;
|
|
280
|
+
}
|
|
281
|
+
//# sourceMappingURL=diff.js.map
|
package/dist/diff.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"diff.js","sourceRoot":"","sources":["../src/diff.ts"],"names":[],"mappings":"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"}
|
package/dist/doctor.d.ts
ADDED
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Preflight: browser present, GitHub auth, dev server, target reachability.
|
|
3
|
+
* Fixes what it can (installs the headless shell) and otherwise stops with
|
|
4
|
+
* exactly one sentence telling the human what to do.
|
|
5
|
+
*/
|
|
6
|
+
import { HttpStatusError } from './errors.js';
|
|
7
|
+
export { NeedsHumanError } from './errors.js';
|
|
8
|
+
/**
|
|
9
|
+
* Launch (and install if needed) the shared headless browser. The instance
|
|
10
|
+
* stays open for the captures that follow, so this is the launch, not a probe.
|
|
11
|
+
*/
|
|
12
|
+
export declare function ensureBrowser(): Promise<void>;
|
|
13
|
+
/** Headed browser for `pre-post login`; caller owns and closes it. */
|
|
14
|
+
export declare function launchHeadedBrowser(): Promise<import("playwright-core").Browser>;
|
|
15
|
+
/**
|
|
16
|
+
* Is this a dev server, or just something listening?
|
|
17
|
+
*
|
|
18
|
+
* A reachable socket used to be enough, and it is not: on macOS, AirPlay
|
|
19
|
+
* Receiver holds port 5000 and answers every request 403 with no body. The
|
|
20
|
+
* probe adopted it, the 403 was read as access control, and the run advised
|
|
21
|
+
* signing in to a system service — in place of "no dev server is running",
|
|
22
|
+
* which is the one thing that was true. It bit precisely when nothing else was
|
|
23
|
+
* listening, the case the message exists to describe.
|
|
24
|
+
*
|
|
25
|
+
* So the bar is a plausible *app* response, not a reachable port:
|
|
26
|
+
*
|
|
27
|
+
* - 401/403 never qualifies. That is a wall or a stranger; either way there is
|
|
28
|
+
* no site behind it to capture, and inferring a dev server from one is how
|
|
29
|
+
* the above happened.
|
|
30
|
+
* - A redirect does. Locale prefixes and trailing slashes make it ordinary, and
|
|
31
|
+
* there is no body to inspect, so the status is all there is to go on. If it
|
|
32
|
+
* leads somewhere sign-in shaped, `landing.ts` catches that at capture time
|
|
33
|
+
* with a message about the wall rather than about ports.
|
|
34
|
+
* - Anything else has to have served an HTML document. This deliberately keeps
|
|
35
|
+
* a 404 or a 500 that renders a page: a dev server with no `/` route, or one
|
|
36
|
+
* with a compile error, is still the dev server, and refusing it would send
|
|
37
|
+
* someone hunting for a server they are already running.
|
|
38
|
+
*/
|
|
39
|
+
export declare function looksLikeDevServer(result: ProbeResult): boolean;
|
|
40
|
+
export interface DevServerScan {
|
|
41
|
+
/** Base URL of the dev server, or null when none of the ports had one. */
|
|
42
|
+
url: string | null;
|
|
43
|
+
/** Ports that answered but are not serving a site — worth naming, not using. */
|
|
44
|
+
ignored: Array<{
|
|
45
|
+
port: number;
|
|
46
|
+
status: number;
|
|
47
|
+
}>;
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Probe the usual ports and say what was found *and* what was passed over.
|
|
51
|
+
*
|
|
52
|
+
* `doctor` reports the ignored ports because "nothing on the usual ports" is
|
|
53
|
+
* confusing when something is plainly listening on one of them.
|
|
54
|
+
*/
|
|
55
|
+
export declare function scanDevServers(ports?: number[]): Promise<DevServerScan>;
|
|
56
|
+
/** Find a running local dev server. Returns its base URL or null. */
|
|
57
|
+
export declare function detectDevServer(ports?: number[]): Promise<string | null>;
|
|
58
|
+
export interface ProbeResult {
|
|
59
|
+
/** HTTP status, or null when the host could not be reached at all */
|
|
60
|
+
status: number | null;
|
|
61
|
+
vercel: boolean;
|
|
62
|
+
/** Response Content-Type, lowercased and without parameters. */
|
|
63
|
+
contentType?: string;
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Probe a base URL with the headers we will use for capture.
|
|
67
|
+
*/
|
|
68
|
+
export declare function probeUrl(url: string, headers?: Record<string, string>, options?: {
|
|
69
|
+
timeoutMs?: number;
|
|
70
|
+
redirect?: RequestRedirect;
|
|
71
|
+
}): Promise<ProbeResult>;
|
|
72
|
+
/**
|
|
73
|
+
* Explain a 401/403 in one actionable sentence. Accepts a probe result or the typed capture error.
|
|
74
|
+
*/
|
|
75
|
+
export declare function authHint(target: HttpStatusError | {
|
|
76
|
+
url: string;
|
|
77
|
+
vercel: boolean;
|
|
78
|
+
}): string;
|
|
79
|
+
//# sourceMappingURL=doctor.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"doctor.d.ts","sourceRoot":"","sources":["../src/doctor.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAIH,OAAO,EAAwB,eAAe,EAAqC,MAAM,aAAa,CAAC;AACvG,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAe9C;;;GAGG;AACH,wBAAsB,aAAa,IAAI,OAAO,CAAC,IAAI,CAAC,CAMnD;AAED,sEAAsE;AACtE,wBAAsB,mBAAmB,+CAMxC;AAoBD;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,WAAW,GAAG,OAAO,CAM/D;AAED,MAAM,WAAW,aAAa;IAC5B,0EAA0E;IAC1E,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;IACnB,gFAAgF;IAChF,OAAO,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CAClD;AAED;;;;;GAKG;AACH,wBAAsB,cAAc,CAAC,KAAK,GAAE,MAAM,EAAc,GAAG,OAAO,CAAC,aAAa,CAAC,CAWxF;AAED,qEAAqE;AACrE,wBAAsB,eAAe,CAAC,KAAK,GAAE,MAAM,EAAc,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAEzF;AAED,MAAM,WAAW,WAAW;IAC1B,qEAAqE;IACrE,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,MAAM,EAAE,OAAO,CAAC;IAChB,gEAAgE;IAChE,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED;;GAEG;AACH,wBAAsB,QAAQ,CAC5B,GAAG,EAAE,MAAM,EACX,OAAO,GAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAM,EACpC,OAAO,GAAE;IAAE,SAAS,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,eAAe,CAAA;CAAO,GAC/D,OAAO,CAAC,WAAW,CAAC,CAQtB;AAED;;GAEG;AACH,wBAAgB,QAAQ,CAAC,MAAM,EAAE,eAAe,GAAG;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,OAAO,CAAA;CAAE,GAAG,MAAM,CAO3F"}
|
package/dist/doctor.js
ADDED
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Preflight: browser present, GitHub auth, dev server, target reachability.
|
|
3
|
+
* Fixes what it can (installs the headless shell) and otherwise stops with
|
|
4
|
+
* exactly one sentence telling the human what to do.
|
|
5
|
+
*/
|
|
6
|
+
import { getBrowser, launchBrowserOrInstall } from './browser.js';
|
|
7
|
+
import { hostOf } from './url.js';
|
|
8
|
+
import { BrowserNotFoundError, NeedsHumanError, isVercelResponse } from './errors.js';
|
|
9
|
+
export { NeedsHumanError } from './errors.js';
|
|
10
|
+
const INSTALL_HINT = 'Run: npx playwright-core install chromium-headless-shell (or set PLAYWRIGHT_CHROMIUM_EXECUTABLE_PATH), then re-run.';
|
|
11
|
+
function explainBrowserFailure(err) {
|
|
12
|
+
if (err instanceof BrowserNotFoundError) {
|
|
13
|
+
throw new NeedsHumanError(err.installed
|
|
14
|
+
? `Chromium was installed but cannot launch. ${INSTALL_HINT}`
|
|
15
|
+
: `Chromium could not be installed automatically. ${INSTALL_HINT}`);
|
|
16
|
+
}
|
|
17
|
+
throw err;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Launch (and install if needed) the shared headless browser. The instance
|
|
21
|
+
* stays open for the captures that follow, so this is the launch, not a probe.
|
|
22
|
+
*/
|
|
23
|
+
export async function ensureBrowser() {
|
|
24
|
+
try {
|
|
25
|
+
await getBrowser();
|
|
26
|
+
}
|
|
27
|
+
catch (err) {
|
|
28
|
+
explainBrowserFailure(err);
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
/** Headed browser for `pre-post login`; caller owns and closes it. */
|
|
32
|
+
export async function launchHeadedBrowser() {
|
|
33
|
+
try {
|
|
34
|
+
return await launchBrowserOrInstall({ headless: false });
|
|
35
|
+
}
|
|
36
|
+
catch (err) {
|
|
37
|
+
explainBrowserFailure(err);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Ports worth asking, most likely first: the winner is the earliest that
|
|
42
|
+
* answers, so order is only ever a tie-break between two live servers.
|
|
43
|
+
*
|
|
44
|
+
* Order is not what keeps AirPlay out — `looksLikeDevServer` is, on every
|
|
45
|
+
* platform and at any position. 5000 sits last because on macOS it usually
|
|
46
|
+
* belongs to AirPlay Receiver rather than to a dev server, so it is the
|
|
47
|
+
* weakest guess in the list, not because being last protects anything. 7000,
|
|
48
|
+
* its sibling, is left out entirely: no framework defaults to it, so it has
|
|
49
|
+
* nothing to weigh against the noise.
|
|
50
|
+
*/
|
|
51
|
+
const DEV_PORTS = [3000, 3001, 3002, 5173, 5174, 4173, 4321, 8080, 8000, 4200, 5000];
|
|
52
|
+
/** An HTML document. `probeUrl` has already lowercased and dropped parameters. */
|
|
53
|
+
function isHtml(contentType) {
|
|
54
|
+
return contentType === 'text/html' || contentType === 'application/xhtml+xml';
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Is this a dev server, or just something listening?
|
|
58
|
+
*
|
|
59
|
+
* A reachable socket used to be enough, and it is not: on macOS, AirPlay
|
|
60
|
+
* Receiver holds port 5000 and answers every request 403 with no body. The
|
|
61
|
+
* probe adopted it, the 403 was read as access control, and the run advised
|
|
62
|
+
* signing in to a system service — in place of "no dev server is running",
|
|
63
|
+
* which is the one thing that was true. It bit precisely when nothing else was
|
|
64
|
+
* listening, the case the message exists to describe.
|
|
65
|
+
*
|
|
66
|
+
* So the bar is a plausible *app* response, not a reachable port:
|
|
67
|
+
*
|
|
68
|
+
* - 401/403 never qualifies. That is a wall or a stranger; either way there is
|
|
69
|
+
* no site behind it to capture, and inferring a dev server from one is how
|
|
70
|
+
* the above happened.
|
|
71
|
+
* - A redirect does. Locale prefixes and trailing slashes make it ordinary, and
|
|
72
|
+
* there is no body to inspect, so the status is all there is to go on. If it
|
|
73
|
+
* leads somewhere sign-in shaped, `landing.ts` catches that at capture time
|
|
74
|
+
* with a message about the wall rather than about ports.
|
|
75
|
+
* - Anything else has to have served an HTML document. This deliberately keeps
|
|
76
|
+
* a 404 or a 500 that renders a page: a dev server with no `/` route, or one
|
|
77
|
+
* with a compile error, is still the dev server, and refusing it would send
|
|
78
|
+
* someone hunting for a server they are already running.
|
|
79
|
+
*/
|
|
80
|
+
export function looksLikeDevServer(result) {
|
|
81
|
+
const { status, contentType } = result;
|
|
82
|
+
if (status === null)
|
|
83
|
+
return false;
|
|
84
|
+
if (status === 401 || status === 403)
|
|
85
|
+
return false;
|
|
86
|
+
if (status >= 300 && status < 400)
|
|
87
|
+
return true;
|
|
88
|
+
return isHtml(contentType);
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Probe the usual ports and say what was found *and* what was passed over.
|
|
92
|
+
*
|
|
93
|
+
* `doctor` reports the ignored ports because "nothing on the usual ports" is
|
|
94
|
+
* confusing when something is plainly listening on one of them.
|
|
95
|
+
*/
|
|
96
|
+
export async function scanDevServers(ports = DEV_PORTS) {
|
|
97
|
+
const results = await Promise.all(ports.map(async (port) => ({
|
|
98
|
+
port,
|
|
99
|
+
...(await probeUrl(`http://localhost:${port}/`, {}, { timeoutMs: 1500, redirect: 'manual' })),
|
|
100
|
+
})));
|
|
101
|
+
const scan = { url: null, ignored: [] };
|
|
102
|
+
for (const result of results) {
|
|
103
|
+
if (looksLikeDevServer(result))
|
|
104
|
+
scan.url ??= `http://localhost:${result.port}`;
|
|
105
|
+
else if (result.status !== null)
|
|
106
|
+
scan.ignored.push({ port: result.port, status: result.status });
|
|
107
|
+
}
|
|
108
|
+
return scan;
|
|
109
|
+
}
|
|
110
|
+
/** Find a running local dev server. Returns its base URL or null. */
|
|
111
|
+
export async function detectDevServer(ports = DEV_PORTS) {
|
|
112
|
+
return (await scanDevServers(ports)).url;
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Probe a base URL with the headers we will use for capture.
|
|
116
|
+
*/
|
|
117
|
+
export async function probeUrl(url, headers = {}, options = {}) {
|
|
118
|
+
try {
|
|
119
|
+
const res = await fetch(url, { method: 'GET', headers, redirect: options.redirect ?? 'follow', signal: AbortSignal.timeout(options.timeoutMs ?? 10_000) });
|
|
120
|
+
const contentType = res.headers.get('content-type')?.split(';')[0].trim().toLowerCase();
|
|
121
|
+
return { status: res.status, vercel: isVercelResponse(res.headers), contentType: contentType || undefined };
|
|
122
|
+
}
|
|
123
|
+
catch {
|
|
124
|
+
return { status: null, vercel: false };
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* Explain a 401/403 in one actionable sentence. Accepts a probe result or the typed capture error.
|
|
129
|
+
*/
|
|
130
|
+
export function authHint(target) {
|
|
131
|
+
const { url, vercel } = target;
|
|
132
|
+
const host = hostOf(url);
|
|
133
|
+
if (vercel || host.endsWith('.vercel.app')) {
|
|
134
|
+
return `${host} is protected by Vercel Deployment Protection. Either set VERCEL_AUTOMATION_BYPASS_SECRET (Project → Settings → Deployment Protection → Protection Bypass for Automation) or run: npx pre-post login ${url}`;
|
|
135
|
+
}
|
|
136
|
+
return `${host} requires a login. Run: npx pre-post login ${url} (opens a browser once, saves the session locally)`;
|
|
137
|
+
}
|
|
138
|
+
//# sourceMappingURL=doctor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"doctor.js","sourceRoot":"","sources":["../src/doctor.ts"],"names":[],"mappings":"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"}
|
package/dist/errors.d.ts
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Typed errors shared across modules. Thrown at the source, mapped once in the CLI.
|
|
3
|
+
*/
|
|
4
|
+
/** A human must do exactly one thing; the message is that one sentence. Exit code 3. */
|
|
5
|
+
export declare class NeedsHumanError extends Error {
|
|
6
|
+
constructor(message: string);
|
|
7
|
+
}
|
|
8
|
+
/** The main document answered with an HTTP status that means "not for you" (401/403). */
|
|
9
|
+
export declare class HttpStatusError extends Error {
|
|
10
|
+
readonly status: number;
|
|
11
|
+
readonly url: string;
|
|
12
|
+
/** Response looked like it came from Vercel (deployment protection). */
|
|
13
|
+
readonly vercel: boolean;
|
|
14
|
+
constructor(status: number, url: string,
|
|
15
|
+
/** Response looked like it came from Vercel (deployment protection). */
|
|
16
|
+
vercel?: boolean);
|
|
17
|
+
}
|
|
18
|
+
export type NavigationFailure = 'refused' | 'timeout' | 'dns' | 'other';
|
|
19
|
+
/** page.goto failed before any document arrived. */
|
|
20
|
+
export declare class NavigationError extends Error {
|
|
21
|
+
readonly kind: NavigationFailure;
|
|
22
|
+
readonly url: string;
|
|
23
|
+
constructor(kind: NavigationFailure, url: string, cause: Error);
|
|
24
|
+
}
|
|
25
|
+
export declare class BrowserNotFoundError extends Error {
|
|
26
|
+
readonly cause?: (Error | null) | undefined;
|
|
27
|
+
readonly installed: boolean;
|
|
28
|
+
constructor(cause?: (Error | null) | undefined, /** true when an install just ran and launch still failed */ installed?: boolean);
|
|
29
|
+
}
|
|
30
|
+
export declare class GitHubError extends Error {
|
|
31
|
+
readonly status: number;
|
|
32
|
+
constructor(status: number, message: string);
|
|
33
|
+
}
|
|
34
|
+
export declare const GH_LOGIN_HINT = "Run: gh auth login (or set GH_TOKEN with repo access), then re-run.";
|
|
35
|
+
export declare function isVercelResponse(headers: {
|
|
36
|
+
get(name: string): string | null;
|
|
37
|
+
}): boolean;
|
|
38
|
+
//# sourceMappingURL=errors.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,wFAAwF;AACxF,qBAAa,eAAgB,SAAQ,KAAK;gBAC5B,OAAO,EAAE,MAAM;CAI5B;AAED,yFAAyF;AACzF,qBAAa,eAAgB,SAAQ,KAAK;aAEtB,MAAM,EAAE,MAAM;aACd,GAAG,EAAE,MAAM;IAC3B,wEAAwE;aACxD,MAAM;gBAHN,MAAM,EAAE,MAAM,EACd,GAAG,EAAE,MAAM;IAC3B,wEAAwE;IACxD,MAAM,UAAQ;CAKjC;AAED,MAAM,MAAM,iBAAiB,GAAG,SAAS,GAAG,SAAS,GAAG,KAAK,GAAG,OAAO,CAAC;AAExE,oDAAoD;AACpD,qBAAa,eAAgB,SAAQ,KAAK;aACZ,IAAI,EAAE,iBAAiB;aAAkB,GAAG,EAAE,MAAM;gBAApD,IAAI,EAAE,iBAAiB,EAAkB,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK;CAI/F;AAED,qBAAa,oBAAqB,SAAQ,KAAK;aACjB,KAAK,CAAC,GAAE,KAAK,GAAG,IAAI;aAA+E,SAAS;gBAA5G,KAAK,CAAC,GAAE,KAAK,GAAG,IAAI,aAAA,EAAE,4DAA4D,CAAiB,SAAS,UAAQ;CAIjJ;AAED,qBAAa,WAAY,SAAQ,KAAK;aACR,MAAM,EAAE,MAAM;gBAAd,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM;CAI5D;AAED,eAAO,MAAM,aAAa,0EAA0E,CAAC;AAErG,wBAAgB,gBAAgB,CAAC,OAAO,EAAE;IAAE,GAAG,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAAA;CAAE,GAAG,OAAO,CAEvF"}
|
package/dist/errors.js
ADDED
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Typed errors shared across modules. Thrown at the source, mapped once in the CLI.
|
|
3
|
+
*/
|
|
4
|
+
/** A human must do exactly one thing; the message is that one sentence. Exit code 3. */
|
|
5
|
+
export class NeedsHumanError extends Error {
|
|
6
|
+
constructor(message) {
|
|
7
|
+
super(message);
|
|
8
|
+
this.name = 'NeedsHumanError';
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
/** The main document answered with an HTTP status that means "not for you" (401/403). */
|
|
12
|
+
export class HttpStatusError extends Error {
|
|
13
|
+
status;
|
|
14
|
+
url;
|
|
15
|
+
vercel;
|
|
16
|
+
constructor(status, url,
|
|
17
|
+
/** Response looked like it came from Vercel (deployment protection). */
|
|
18
|
+
vercel = false) {
|
|
19
|
+
super(`${status} for ${url}`);
|
|
20
|
+
this.status = status;
|
|
21
|
+
this.url = url;
|
|
22
|
+
this.vercel = vercel;
|
|
23
|
+
this.name = 'HttpStatusError';
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
/** page.goto failed before any document arrived. */
|
|
27
|
+
export class NavigationError extends Error {
|
|
28
|
+
kind;
|
|
29
|
+
url;
|
|
30
|
+
constructor(kind, url, cause) {
|
|
31
|
+
super(cause.message.split('\n')[0]);
|
|
32
|
+
this.kind = kind;
|
|
33
|
+
this.url = url;
|
|
34
|
+
this.name = 'NavigationError';
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
export class BrowserNotFoundError extends Error {
|
|
38
|
+
cause;
|
|
39
|
+
installed;
|
|
40
|
+
constructor(cause, /** true when an install just ran and launch still failed */ installed = false) {
|
|
41
|
+
super('No usable Chromium found');
|
|
42
|
+
this.cause = cause;
|
|
43
|
+
this.installed = installed;
|
|
44
|
+
this.name = 'BrowserNotFoundError';
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
export class GitHubError extends Error {
|
|
48
|
+
status;
|
|
49
|
+
constructor(status, message) {
|
|
50
|
+
super(message);
|
|
51
|
+
this.status = status;
|
|
52
|
+
this.name = 'GitHubError';
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
export const GH_LOGIN_HINT = 'Run: gh auth login (or set GH_TOKEN with repo access), then re-run.';
|
|
56
|
+
export function isVercelResponse(headers) {
|
|
57
|
+
return Boolean(headers.get('x-vercel-id') || headers.get('server')?.toLowerCase().includes('vercel'));
|
|
58
|
+
}
|
|
59
|
+
//# sourceMappingURL=errors.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,wFAAwF;AACxF,MAAM,OAAO,eAAgB,SAAQ,KAAK;IACxC,YAAY,OAAe;QACzB,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,iBAAiB,CAAC;IAChC,CAAC;CACF;AAED,yFAAyF;AACzF,MAAM,OAAO,eAAgB,SAAQ,KAAK;IAEtB;IACA;IAEA;IAJlB,YACkB,MAAc,EACd,GAAW;IAC3B,wEAAwE;IACxD,SAAS,KAAK;QAE9B,KAAK,CAAC,GAAG,MAAM,QAAQ,GAAG,EAAE,CAAC,CAAC;QALd,WAAM,GAAN,MAAM,CAAQ;QACd,QAAG,GAAH,GAAG,CAAQ;QAEX,WAAM,GAAN,MAAM,CAAQ;QAG9B,IAAI,CAAC,IAAI,GAAG,iBAAiB,CAAC;IAChC,CAAC;CACF;AAID,oDAAoD;AACpD,MAAM,OAAO,eAAgB,SAAQ,KAAK;IACZ;IAAyC;IAArE,YAA4B,IAAuB,EAAkB,GAAW,EAAE,KAAY;QAC5F,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QADV,SAAI,GAAJ,IAAI,CAAmB;QAAkB,QAAG,GAAH,GAAG,CAAQ;QAE9E,IAAI,CAAC,IAAI,GAAG,iBAAiB,CAAC;IAChC,CAAC;CACF;AAED,MAAM,OAAO,oBAAqB,SAAQ,KAAK;IACjB;IAAmG;IAA/H,YAA4B,KAAoB,EAAE,4DAA4D,CAAiB,YAAY,KAAK;QAC9I,KAAK,CAAC,0BAA0B,CAAC,CAAC;QADR,UAAK,GAAL,KAAK,CAAe;QAA+E,cAAS,GAAT,SAAS,CAAQ;QAE9I,IAAI,CAAC,IAAI,GAAG,sBAAsB,CAAC;IACrC,CAAC;CACF;AAED,MAAM,OAAO,WAAY,SAAQ,KAAK;IACR;IAA5B,YAA4B,MAAc,EAAE,OAAe;QACzD,KAAK,CAAC,OAAO,CAAC,CAAC;QADW,WAAM,GAAN,MAAM,CAAQ;QAExC,IAAI,CAAC,IAAI,GAAG,aAAa,CAAC;IAC5B,CAAC;CACF;AAED,MAAM,CAAC,MAAM,aAAa,GAAG,uEAAuE,CAAC;AAErG,MAAM,UAAU,gBAAgB,CAAC,OAA6C;IAC5E,OAAO,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,aAAa,CAAC,IAAI,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,WAAW,EAAE,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAAC;AACxG,CAAC"}
|