@juangadm/pre-post 0.2.0 → 1.0.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 +102 -222
- package/dist/bin/cli.js +199 -347
- package/dist/bin/cli.js.map +1 -1
- package/dist/browser.d.ts +42 -11
- package/dist/browser.d.ts.map +1 -1
- package/dist/browser.js +371 -94
- 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 -35
- 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 +64 -0
- package/dist/commands/compare.js.map +1 -0
- package/dist/commands/detect.d.ts +20 -0
- package/dist/commands/detect.d.ts.map +1 -0
- package/dist/commands/detect.js +19 -0
- package/dist/commands/detect.js.map +1 -0
- package/dist/commands/doctor.d.ts +10 -0
- package/dist/commands/doctor.d.ts.map +1 -0
- package/dist/commands/doctor.js +38 -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 +28 -0
- package/dist/commands/pr.d.ts.map +1 -0
- package/dist/commands/pr.js +159 -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/config.d.ts +36 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +60 -0
- package/dist/config.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 +89 -0
- package/dist/diff-pool.js.map +1 -0
- package/dist/diff-worker.d.ts +29 -0
- package/dist/diff-worker.d.ts.map +1 -0
- package/dist/diff-worker.js +38 -0
- package/dist/diff-worker.js.map +1 -0
- package/dist/diff.d.ts +37 -0
- package/dist/diff.d.ts.map +1 -0
- package/dist/diff.js +171 -0
- package/dist/diff.js.map +1 -0
- package/dist/doctor.d.ts +38 -0
- package/dist/doctor.d.ts.map +1 -0
- package/dist/doctor.js +72 -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/filename.d.ts +2 -0
- package/dist/filename.d.ts.map +1 -1
- package/dist/filename.js +2 -1
- package/dist/filename.js.map +1 -1
- package/dist/git.d.ts +23 -0
- package/dist/git.d.ts.map +1 -0
- package/dist/git.js +86 -0
- package/dist/git.js.map +1 -0
- package/dist/github.d.ts +73 -0
- package/dist/github.d.ts.map +1 -0
- package/dist/github.js +240 -0
- package/dist/github.js.map +1 -0
- package/dist/index.d.ts +22 -22
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +17 -66
- package/dist/index.js.map +1 -1
- package/dist/pkg.d.ts +8 -0
- package/dist/pkg.d.ts.map +1 -0
- package/dist/pkg.js +35 -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 +107 -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 +41 -14
- package/dist/routes.d.ts.map +1 -1
- package/dist/routes.js +271 -141
- package/dist/routes.js.map +1 -1
- package/dist/run.d.ts +36 -0
- package/dist/run.d.ts.map +1 -0
- package/dist/run.js +128 -0
- package/dist/run.js.map +1 -0
- package/dist/sessions.d.ts +50 -0
- package/dist/sessions.d.ts.map +1 -0
- package/dist/sessions.js +74 -0
- package/dist/sessions.js.map +1 -0
- package/dist/types.d.ts +118 -41
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +1 -0
- package/dist/types.js.map +1 -1
- 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 -13
- package/skill/SKILL.md +31 -229
- 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 -149
- package/dist/upload.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/capture.d.ts
CHANGED
|
@@ -1,9 +1,4 @@
|
|
|
1
|
-
import { CaptureOptions, CaptureResult, BeforeAfterCaptureOptions, BeforeAfterCaptureResult
|
|
1
|
+
import { CaptureOptions, CaptureResult, BeforeAfterCaptureOptions, BeforeAfterCaptureResult } from './types.js';
|
|
2
2
|
export declare function captureScreenshot(options: CaptureOptions): Promise<CaptureResult>;
|
|
3
3
|
export declare function captureBeforeAfter(options: BeforeAfterCaptureOptions): Promise<BeforeAfterCaptureResult>;
|
|
4
|
-
/**
|
|
5
|
-
* Capture a URL at multiple viewports (desktop + mobile by default).
|
|
6
|
-
* Returns a map of viewport label → CaptureResult.
|
|
7
|
-
*/
|
|
8
|
-
export declare function captureResponsive(url: string, viewports?: ViewportConfig[]): Promise<Map<string, CaptureResult>>;
|
|
9
4
|
//# sourceMappingURL=capture.d.ts.map
|
package/dist/capture.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"capture.d.ts","sourceRoot":"","sources":["../src/capture.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,cAAc,EACd,aAAa,EACb,yBAAyB,EACzB,wBAAwB,
|
|
1
|
+
{"version":3,"file":"capture.d.ts","sourceRoot":"","sources":["../src/capture.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,cAAc,EACd,aAAa,EACb,yBAAyB,EACzB,wBAAwB,EACzB,MAAM,YAAY,CAAC;AAQpB,wBAAsB,iBAAiB,CAAC,OAAO,EAAE,cAAc,GAAG,OAAO,CAAC,aAAa,CAAC,CAYvF;AAED,wBAAsB,kBAAkB,CAAC,OAAO,EAAE,yBAAyB,GAAG,OAAO,CAAC,wBAAwB,CAAC,CAO9G"}
|
package/dist/capture.js
CHANGED
|
@@ -1,52 +1,29 @@
|
|
|
1
1
|
import { resolveViewport } from './viewport.js';
|
|
2
2
|
import { captureScreenshot as browserCapture } from './browser.js';
|
|
3
3
|
function normalizeOptions(input) {
|
|
4
|
-
|
|
5
|
-
return { url: input };
|
|
6
|
-
}
|
|
7
|
-
return input;
|
|
4
|
+
return typeof input === 'string' ? { url: input } : input;
|
|
8
5
|
}
|
|
9
6
|
export async function captureScreenshot(options) {
|
|
10
7
|
const viewport = resolveViewport(options.viewport);
|
|
11
|
-
|
|
8
|
+
return browserCapture(options.url, {
|
|
12
9
|
viewport,
|
|
13
10
|
fullPage: options.fullPage ?? false,
|
|
11
|
+
maxHeight: options.maxHeight,
|
|
12
|
+
scale: options.scale,
|
|
14
13
|
selector: options.selector,
|
|
14
|
+
settleTimeout: options.settleTimeout,
|
|
15
|
+
wait: options.wait,
|
|
16
|
+
auth: options.auth,
|
|
15
17
|
});
|
|
16
|
-
return {
|
|
17
|
-
image,
|
|
18
|
-
viewport,
|
|
19
|
-
url: options.url,
|
|
20
|
-
selector: options.selector,
|
|
21
|
-
};
|
|
22
18
|
}
|
|
23
19
|
export async function captureBeforeAfter(options) {
|
|
24
|
-
const sharedViewport = options.viewport;
|
|
25
20
|
const beforeOpts = normalizeOptions(options.before);
|
|
26
21
|
const afterOpts = normalizeOptions(options.after);
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
afterOpts.viewport = sharedViewport;
|
|
33
|
-
}
|
|
34
|
-
// Capture sequentially to reuse browser session
|
|
35
|
-
const before = await captureScreenshot(beforeOpts);
|
|
36
|
-
const after = await captureScreenshot(afterOpts);
|
|
22
|
+
if (options.viewport && !beforeOpts.viewport)
|
|
23
|
+
beforeOpts.viewport = options.viewport;
|
|
24
|
+
if (options.viewport && !afterOpts.viewport)
|
|
25
|
+
afterOpts.viewport = options.viewport;
|
|
26
|
+
const [before, after] = await Promise.all([captureScreenshot(beforeOpts), captureScreenshot(afterOpts)]);
|
|
37
27
|
return { before, after };
|
|
38
28
|
}
|
|
39
|
-
/**
|
|
40
|
-
* Capture a URL at multiple viewports (desktop + mobile by default).
|
|
41
|
-
* Returns a map of viewport label → CaptureResult.
|
|
42
|
-
*/
|
|
43
|
-
export async function captureResponsive(url, viewports = ['desktop', 'mobile']) {
|
|
44
|
-
const results = new Map();
|
|
45
|
-
for (const vp of viewports) {
|
|
46
|
-
const label = typeof vp === 'string' ? vp : `${vp.width}x${vp.height}`;
|
|
47
|
-
const result = await captureScreenshot({ url, viewport: vp });
|
|
48
|
-
results.set(label, result);
|
|
49
|
-
}
|
|
50
|
-
return results;
|
|
51
|
-
}
|
|
52
29
|
//# sourceMappingURL=capture.js.map
|
package/dist/capture.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"capture.js","sourceRoot":"","sources":["../src/capture.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"capture.js","sourceRoot":"","sources":["../src/capture.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAChD,OAAO,EAAE,iBAAiB,IAAI,cAAc,EAAE,MAAM,cAAc,CAAC;AAEnE,SAAS,gBAAgB,CAAC,KAA8B;IACtD,OAAO,OAAO,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC;AAC5D,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,iBAAiB,CAAC,OAAuB;IAC7D,MAAM,QAAQ,GAAG,eAAe,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;IACnD,OAAO,cAAc,CAAC,OAAO,CAAC,GAAG,EAAE;QACjC,QAAQ;QACR,QAAQ,EAAE,OAAO,CAAC,QAAQ,IAAI,KAAK;QACnC,SAAS,EAAE,OAAO,CAAC,SAAS;QAC5B,KAAK,EAAE,OAAO,CAAC,KAAK;QACpB,QAAQ,EAAE,OAAO,CAAC,QAAQ;QAC1B,aAAa,EAAE,OAAO,CAAC,aAAa;QACpC,IAAI,EAAE,OAAO,CAAC,IAAI;QAClB,IAAI,EAAE,OAAO,CAAC,IAAI;KACnB,CAAC,CAAC;AACL,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,kBAAkB,CAAC,OAAkC;IACzE,MAAM,UAAU,GAAG,gBAAgB,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;IACpD,MAAM,SAAS,GAAG,gBAAgB,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;IAClD,IAAI,OAAO,CAAC,QAAQ,IAAI,CAAC,UAAU,CAAC,QAAQ;QAAE,UAAU,CAAC,QAAQ,GAAG,OAAO,CAAC,QAAQ,CAAC;IACrF,IAAI,OAAO,CAAC,QAAQ,IAAI,CAAC,SAAS,CAAC,QAAQ;QAAE,SAAS,CAAC,QAAQ,GAAG,OAAO,CAAC,QAAQ,CAAC;IACnF,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC,CAAC,iBAAiB,CAAC,UAAU,CAAC,EAAE,iBAAiB,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;IACzG,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC;AAC3B,CAAC"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `pre-post <before> <after>` — compare two URLs (or two PNG files) without
|
|
3
|
+
* any GitHub involvement. Writes pre/post/diff images and prints a summary.
|
|
4
|
+
*/
|
|
5
|
+
import { PrRunResult } from '../types.js';
|
|
6
|
+
import { Settings } from '../config.js';
|
|
7
|
+
export interface CompareOptions extends Partial<Settings> {
|
|
8
|
+
before: string;
|
|
9
|
+
after: string;
|
|
10
|
+
routes?: string[];
|
|
11
|
+
wait?: number;
|
|
12
|
+
headers?: Record<string, string>;
|
|
13
|
+
output?: string;
|
|
14
|
+
log?: (msg: string) => void;
|
|
15
|
+
}
|
|
16
|
+
export declare function isImageFile(p: string): boolean;
|
|
17
|
+
export declare function runCompare(opts: CompareOptions): Promise<PrRunResult>;
|
|
18
|
+
//# sourceMappingURL=compare.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"compare.d.ts","sourceRoot":"","sources":["../../src/commands/compare.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAKH,OAAO,EAAE,WAAW,EAAuB,MAAM,aAAa,CAAC;AAC/D,OAAO,EAAmB,QAAQ,EAAE,MAAM,cAAc,CAAC;AAQzD,MAAM,WAAW,cAAe,SAAQ,OAAO,CAAC,QAAQ,CAAC;IACvD,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,GAAG,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;CAC7B;AAED,wBAAgB,WAAW,CAAC,CAAC,EAAE,MAAM,GAAG,OAAO,CAE9C;AAED,wBAAsB,UAAU,CAAC,IAAI,EAAE,cAAc,GAAG,OAAO,CAAC,WAAW,CAAC,CA6C3E"}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `pre-post <before> <after>` — compare two URLs (or two PNG files) without
|
|
3
|
+
* any GitHub involvement. Writes pre/post/diff images and prints a summary.
|
|
4
|
+
*/
|
|
5
|
+
import fs from 'fs';
|
|
6
|
+
import os from 'os';
|
|
7
|
+
import path from 'path';
|
|
8
|
+
import { resolveSettings } from '../config.js';
|
|
9
|
+
import { closeBrowser } from '../browser.js';
|
|
10
|
+
import { ensureBrowser } from '../doctor.js';
|
|
11
|
+
import { diffImages } from '../diff.js';
|
|
12
|
+
import { parseViewport } from '../viewport.js';
|
|
13
|
+
import { resolveAuth } from '../sessions.js';
|
|
14
|
+
import { isChanged, joinUrl, normalizeUrl, runTasks } from '../run.js';
|
|
15
|
+
export function isImageFile(p) {
|
|
16
|
+
return /\.png$/i.test(p) && fs.existsSync(p);
|
|
17
|
+
}
|
|
18
|
+
export async function runCompare(opts) {
|
|
19
|
+
const started = Date.now();
|
|
20
|
+
const outputDir = opts.output || path.join(os.tmpdir(), 'pre-post', 'compare', String(Date.now()));
|
|
21
|
+
fs.mkdirSync(outputDir, { recursive: true });
|
|
22
|
+
// Ad-hoc comparisons default to the first screen and one viewport; `pr` is the full-page path.
|
|
23
|
+
const settings = resolveSettings({}, { fullPage: false, viewports: ['desktop'], ...opts });
|
|
24
|
+
let outcomes;
|
|
25
|
+
let before = opts.before;
|
|
26
|
+
let after = opts.after;
|
|
27
|
+
if (isImageFile(before) && isImageFile(after)) {
|
|
28
|
+
const diff = diffImages(fs.readFileSync(before), fs.readFileSync(after));
|
|
29
|
+
const diffPath = path.join(outputDir, 'diff.png');
|
|
30
|
+
if (diff.highlight)
|
|
31
|
+
fs.writeFileSync(diffPath, diff.highlight);
|
|
32
|
+
outcomes = [{
|
|
33
|
+
route: path.basename(before),
|
|
34
|
+
resolvedRoute: before,
|
|
35
|
+
viewport: 'image',
|
|
36
|
+
status: isChanged(diff, settings.threshold, settings.minChangedPixels) ? 'changed' : 'unchanged',
|
|
37
|
+
changedRatio: diff.changedRatio,
|
|
38
|
+
sizeChanged: diff.sizeChanged,
|
|
39
|
+
files: { before, after, diff: diff.highlight ? diffPath : undefined },
|
|
40
|
+
}];
|
|
41
|
+
}
|
|
42
|
+
else {
|
|
43
|
+
before = normalizeUrl(before);
|
|
44
|
+
after = normalizeUrl(after);
|
|
45
|
+
const routes = opts.routes?.length ? opts.routes : ['/'];
|
|
46
|
+
const viewports = settings.viewports.map(parseViewport);
|
|
47
|
+
const tasks = [];
|
|
48
|
+
for (const route of routes) {
|
|
49
|
+
for (const vp of viewports) {
|
|
50
|
+
tasks.push({ route, resolvedRoute: route, viewport: vp.label, size: vp.size, beforeUrl: joinUrl(before, route), afterUrl: joinUrl(after, route) });
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
const auth = resolveAuth({ headers: opts.headers, urls: [before, after] });
|
|
54
|
+
await ensureBrowser();
|
|
55
|
+
try {
|
|
56
|
+
outcomes = await runTasks(tasks, { outputDir, ...settings, wait: opts.wait, auth, log: opts.log });
|
|
57
|
+
}
|
|
58
|
+
finally {
|
|
59
|
+
await closeBrowser();
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
return { repo: '', beforeBase: before, afterBase: after, outcomes, skippedDynamic: [], durationMs: Date.now() - started, markdown: '', outputDir };
|
|
63
|
+
}
|
|
64
|
+
//# sourceMappingURL=compare.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"compare.js","sourceRoot":"","sources":["../../src/commands/compare.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `pre-post detect` — which routes does this branch touch? Compact JSON for agents.
|
|
3
|
+
*/
|
|
4
|
+
import { Framework } from '../types.js';
|
|
5
|
+
export declare function runDetect(opts?: {
|
|
6
|
+
cwd?: string;
|
|
7
|
+
maxRoutes?: number;
|
|
8
|
+
framework?: Framework;
|
|
9
|
+
}): {
|
|
10
|
+
framework: Framework;
|
|
11
|
+
appRoot: string;
|
|
12
|
+
changedFiles: number;
|
|
13
|
+
routes: {
|
|
14
|
+
path: string;
|
|
15
|
+
confidence: "high" | "medium" | "low";
|
|
16
|
+
reason: string;
|
|
17
|
+
}[];
|
|
18
|
+
skippedDynamic: string[];
|
|
19
|
+
};
|
|
20
|
+
//# sourceMappingURL=detect.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"detect.d.ts","sourceRoot":"","sources":["../../src/commands/detect.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAKxC,wBAAgB,SAAS,CAAC,IAAI,GAAE;IAAE,GAAG,CAAC,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,SAAS,CAAA;CAAO;;;;;;;;;;EAU/F"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `pre-post detect` — which routes does this branch touch? Compact JSON for agents.
|
|
3
|
+
*/
|
|
4
|
+
import path from 'path';
|
|
5
|
+
import { loadConfig } from '../config.js';
|
|
6
|
+
import { repoRoot } from '../git.js';
|
|
7
|
+
import { detectRoutesForRepo } from '../routes.js';
|
|
8
|
+
export function runDetect(opts = {}) {
|
|
9
|
+
const root = repoRoot(opts.cwd);
|
|
10
|
+
const detection = detectRoutesForRepo({ cwd: root, config: loadConfig(root), maxRoutes: opts.maxRoutes, framework: opts.framework });
|
|
11
|
+
return {
|
|
12
|
+
framework: detection.framework,
|
|
13
|
+
appRoot: path.relative(root, detection.appRoot) || '.',
|
|
14
|
+
changedFiles: detection.changedFiles.length,
|
|
15
|
+
routes: detection.routes.map(r => ({ path: r.path, confidence: r.confidence, reason: r.reason })),
|
|
16
|
+
skippedDynamic: detection.skippedDynamic,
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
//# sourceMappingURL=detect.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"detect.js","sourceRoot":"","sources":["../../src/commands/detect.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,IAAI,MAAM,MAAM,CAAC;AAExB,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC1C,OAAO,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AACrC,OAAO,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAC;AAEnD,MAAM,UAAU,SAAS,CAAC,OAAoE,EAAE;IAC9F,MAAM,IAAI,GAAG,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAChC,MAAM,SAAS,GAAG,mBAAmB,CAAC,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,EAAE,UAAU,CAAC,IAAI,CAAC,EAAE,SAAS,EAAE,IAAI,CAAC,SAAS,EAAE,SAAS,EAAE,IAAI,CAAC,SAAS,EAAE,CAAC,CAAC;IACrI,OAAO;QACL,SAAS,EAAE,SAAS,CAAC,SAAS;QAC9B,OAAO,EAAE,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAC,OAAO,CAAC,IAAI,GAAG;QACtD,YAAY,EAAE,SAAS,CAAC,YAAY,CAAC,MAAM;QAC3C,MAAM,EAAE,SAAS,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,UAAU,EAAE,CAAC,CAAC,UAAU,EAAE,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC;QACjG,cAAc,EAAE,SAAS,CAAC,cAAc;KACzC,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `pre-post doctor` — the same checks `pr` performs, reported instead of enforced.
|
|
3
|
+
*/
|
|
4
|
+
export interface DoctorCheck {
|
|
5
|
+
name: string;
|
|
6
|
+
ok: boolean;
|
|
7
|
+
detail: string;
|
|
8
|
+
}
|
|
9
|
+
export declare function runDoctor(cwd?: string): Promise<DoctorCheck[]>;
|
|
10
|
+
//# sourceMappingURL=doctor.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"doctor.d.ts","sourceRoot":"","sources":["../../src/commands/doctor.ts"],"names":[],"mappings":"AAAA;;GAEG;AAWH,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,OAAO,CAAC;IACZ,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,wBAAsB,SAAS,CAAC,GAAG,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,EAAE,CAAC,CAsBpE"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `pre-post doctor` — the same checks `pr` performs, reported instead of enforced.
|
|
3
|
+
*/
|
|
4
|
+
import fs from 'fs';
|
|
5
|
+
import { browserDescription } from '../browser.js';
|
|
6
|
+
import { configPath, CONFIG_FILENAME, loadConfig } from '../config.js';
|
|
7
|
+
import { detectDevServer, ensureBrowser } from '../doctor.js';
|
|
8
|
+
import { GH_LOGIN_HINT } from '../errors.js';
|
|
9
|
+
import { repoRoot } from '../git.js';
|
|
10
|
+
import { getToken } from '../github.js';
|
|
11
|
+
import { closeBrowser } from '../browser.js';
|
|
12
|
+
export async function runDoctor(cwd) {
|
|
13
|
+
const checks = [];
|
|
14
|
+
try {
|
|
15
|
+
await ensureBrowser();
|
|
16
|
+
checks.push({ name: 'browser', ok: true, detail: browserDescription() });
|
|
17
|
+
}
|
|
18
|
+
catch (err) {
|
|
19
|
+
checks.push({ name: 'browser', ok: false, detail: err.message });
|
|
20
|
+
}
|
|
21
|
+
finally {
|
|
22
|
+
await closeBrowser();
|
|
23
|
+
}
|
|
24
|
+
checks.push(getToken() ? { name: 'github', ok: true, detail: 'token found' } : { name: 'github', ok: false, detail: GH_LOGIN_HINT });
|
|
25
|
+
const dev = await detectDevServer();
|
|
26
|
+
checks.push(dev ? { name: 'devserver', ok: true, detail: dev } : { name: 'devserver', ok: false, detail: 'none found on the usual ports' });
|
|
27
|
+
try {
|
|
28
|
+
const root = repoRoot(cwd);
|
|
29
|
+
const cfg = loadConfig(root);
|
|
30
|
+
checks.push(cfg.before ? { name: 'before', ok: true, detail: cfg.before } : { name: 'before', ok: false, detail: 'not set — pass --before once and it is saved' });
|
|
31
|
+
checks.push({ name: 'config', ok: true, detail: fs.existsSync(configPath(root)) ? CONFIG_FILENAME : 'none (defaults)' });
|
|
32
|
+
}
|
|
33
|
+
catch {
|
|
34
|
+
checks.push({ name: 'git', ok: false, detail: 'not a repository' });
|
|
35
|
+
}
|
|
36
|
+
return checks;
|
|
37
|
+
}
|
|
38
|
+
//# sourceMappingURL=doctor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"doctor.js","sourceRoot":"","sources":["../../src/commands/doctor.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,MAAM,IAAI,CAAC;AACpB,OAAO,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AACnD,OAAO,EAAE,UAAU,EAAE,eAAe,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AACvE,OAAO,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAC9D,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAC7C,OAAO,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AACrC,OAAO,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AACxC,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAQ7C,MAAM,CAAC,KAAK,UAAU,SAAS,CAAC,GAAY;IAC1C,MAAM,MAAM,GAAkB,EAAE,CAAC;IACjC,IAAI,CAAC;QACH,MAAM,aAAa,EAAE,CAAC;QACtB,MAAM,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,kBAAkB,EAAE,EAAE,CAAC,CAAC;IAC3E,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAG,GAAa,CAAC,OAAO,EAAE,CAAC,CAAC;IAC9E,CAAC;YAAS,CAAC;QACT,MAAM,YAAY,EAAE,CAAC;IACvB,CAAC;IACD,MAAM,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,aAAa,EAAE,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,aAAa,EAAE,CAAC,CAAC;IACrI,MAAM,GAAG,GAAG,MAAM,eAAe,EAAE,CAAC;IACpC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,WAAW,EAAE,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,WAAW,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,+BAA+B,EAAE,CAAC,CAAC;IAC5I,IAAI,CAAC;QACH,MAAM,IAAI,GAAG,QAAQ,CAAC,GAAG,CAAC,CAAC;QAC3B,MAAM,GAAG,GAAG,UAAU,CAAC,IAAI,CAAC,CAAC;QAC7B,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,8CAA8C,EAAE,CAAC,CAAC;QACnK,MAAM,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,CAAC,UAAU,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,iBAAiB,EAAE,CAAC,CAAC;IAC3H,CAAC;IAAC,MAAM,CAAC;QACP,MAAM,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,kBAAkB,EAAE,CAAC,CAAC;IACtE,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `pre-post login <url>` — open a real browser once, let the human sign in,
|
|
3
|
+
* and keep the session for future captures of that host.
|
|
4
|
+
*/
|
|
5
|
+
export declare function runLogin(url: string, log?: (msg: string) => void): Promise<string>;
|
|
6
|
+
//# sourceMappingURL=login.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"login.d.ts","sourceRoot":"","sources":["../../src/commands/login.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAcH,wBAAsB,QAAQ,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,GAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAoB,GAAG,OAAO,CAAC,MAAM,CAAC,CAiBvG"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `pre-post login <url>` — open a real browser once, let the human sign in,
|
|
3
|
+
* and keep the session for future captures of that host.
|
|
4
|
+
*/
|
|
5
|
+
import readline from 'readline';
|
|
6
|
+
import { launchHeadedBrowser } from '../doctor.js';
|
|
7
|
+
import { saveSession } from '../sessions.js';
|
|
8
|
+
import { normalizeUrl } from '../run.js';
|
|
9
|
+
function waitForEnter(prompt) {
|
|
10
|
+
return new Promise(resolve => {
|
|
11
|
+
const rl = readline.createInterface({ input: process.stdin, output: process.stderr });
|
|
12
|
+
rl.question(prompt, () => { rl.close(); resolve(); });
|
|
13
|
+
});
|
|
14
|
+
}
|
|
15
|
+
export async function runLogin(url, log = console.error) {
|
|
16
|
+
const target = normalizeUrl(url);
|
|
17
|
+
const host = new URL(target).hostname;
|
|
18
|
+
const browser = await launchHeadedBrowser();
|
|
19
|
+
try {
|
|
20
|
+
const ctx = await browser.newContext({ viewport: { width: 1280, height: 800 } });
|
|
21
|
+
const page = await ctx.newPage();
|
|
22
|
+
await page.goto(target, { waitUntil: 'domcontentloaded' }).catch(() => undefined);
|
|
23
|
+
log(`A browser window is open at ${target}.`);
|
|
24
|
+
await waitForEnter('Log in there, then press Enter here to save the session... ');
|
|
25
|
+
const state = await ctx.storageState();
|
|
26
|
+
const file = saveSession(host, state);
|
|
27
|
+
log(`Saved session for ${host} (${state.cookies.length} cookie(s)) to ${file}`);
|
|
28
|
+
return file;
|
|
29
|
+
}
|
|
30
|
+
finally {
|
|
31
|
+
await browser.close().catch(() => undefined);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
//# sourceMappingURL=login.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"login.js","sourceRoot":"","sources":["../../src/commands/login.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,QAAQ,MAAM,UAAU,CAAC;AAChC,OAAO,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAC;AACnD,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAC7C,OAAO,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AAEzC,SAAS,YAAY,CAAC,MAAc;IAClC,OAAO,IAAI,OAAO,CAAC,OAAO,CAAC,EAAE;QAC3B,MAAM,EAAE,GAAG,QAAQ,CAAC,eAAe,CAAC,EAAE,KAAK,EAAE,OAAO,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;QACtF,EAAE,CAAC,QAAQ,CAAC,MAAM,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC,KAAK,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;IACxD,CAAC,CAAC,CAAC;AACL,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,QAAQ,CAAC,GAAW,EAAE,MAA6B,OAAO,CAAC,KAAK;IACpF,MAAM,MAAM,GAAG,YAAY,CAAC,GAAG,CAAC,CAAC;IACjC,MAAM,IAAI,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,CAAC,QAAQ,CAAC;IACtC,MAAM,OAAO,GAAG,MAAM,mBAAmB,EAAE,CAAC;IAC5C,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,MAAM,OAAO,CAAC,UAAU,CAAC,EAAE,QAAQ,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,EAAE,CAAC,CAAC;QACjF,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,OAAO,EAAE,CAAC;QACjC,MAAM,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,EAAE,SAAS,EAAE,kBAAkB,EAAE,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,CAAC;QAClF,GAAG,CAAC,+BAA+B,MAAM,GAAG,CAAC,CAAC;QAC9C,MAAM,YAAY,CAAC,6DAA6D,CAAC,CAAC;QAClF,MAAM,KAAK,GAAG,MAAM,GAAG,CAAC,YAAY,EAAE,CAAC;QACvC,MAAM,IAAI,GAAG,WAAW,CAAC,IAAI,EAAE,KAAY,CAAC,CAAC;QAC7C,GAAG,CAAC,qBAAqB,IAAI,KAAK,KAAK,CAAC,OAAO,CAAC,MAAM,kBAAkB,IAAI,EAAE,CAAC,CAAC;QAChF,OAAO,IAAI,CAAC;IACd,CAAC;YAAS,CAAC;QACT,MAAM,OAAO,CAAC,KAAK,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,CAAC;IAC/C,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `pre-post pr` — the one-shot path: detect → capture → diff → publish → comment.
|
|
3
|
+
*/
|
|
4
|
+
import { Framework, PrRunResult } from '../types.js';
|
|
5
|
+
import { Settings } from '../config.js';
|
|
6
|
+
export interface PrCommandOptions extends Partial<Settings> {
|
|
7
|
+
cwd?: string;
|
|
8
|
+
before?: string;
|
|
9
|
+
after?: string;
|
|
10
|
+
routes?: string[];
|
|
11
|
+
framework?: Framework;
|
|
12
|
+
headers?: Record<string, string>;
|
|
13
|
+
cookies?: Array<{
|
|
14
|
+
name: string;
|
|
15
|
+
value: string;
|
|
16
|
+
}>;
|
|
17
|
+
wait?: number;
|
|
18
|
+
output?: string;
|
|
19
|
+
/** Capture and diff only; do not publish or comment */
|
|
20
|
+
dryRun?: boolean;
|
|
21
|
+
/** Publish assets but do not touch the PR */
|
|
22
|
+
comment?: boolean;
|
|
23
|
+
pr?: number;
|
|
24
|
+
version?: string;
|
|
25
|
+
log?: (msg: string) => void;
|
|
26
|
+
}
|
|
27
|
+
export declare function runPr(opts?: PrCommandOptions): Promise<PrRunResult>;
|
|
28
|
+
//# sourceMappingURL=pr.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pr.d.ts","sourceRoot":"","sources":["../../src/commands/pr.ts"],"names":[],"mappings":"AAAA;;GAEG;AAKH,OAAO,EAA+B,SAAS,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAClF,OAAO,EAA+B,QAAQ,EAAgB,MAAM,cAAc,CAAC;AAYnF,MAAM,WAAW,gBAAiB,SAAQ,OAAO,CAAC,QAAQ,CAAC;IACzD,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB,SAAS,CAAC,EAAE,SAAS,CAAC;IACtB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC,OAAO,CAAC,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACjD,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,uDAAuD;IACvD,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,6CAA6C;IAC7C,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,GAAG,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;CAC7B;AAWD,wBAAsB,KAAK,CAAC,IAAI,GAAE,gBAAqB,GAAG,OAAO,CAAC,WAAW,CAAC,CA0I7E"}
|
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `pre-post pr` — the one-shot path: detect → capture → diff → publish → comment.
|
|
3
|
+
*/
|
|
4
|
+
import fs from 'fs';
|
|
5
|
+
import os from 'os';
|
|
6
|
+
import path from 'path';
|
|
7
|
+
import { ARTIFACT_KINDS } from '../types.js';
|
|
8
|
+
import { loadConfig, resolveSettings, updateConfig } from '../config.js';
|
|
9
|
+
import { currentBranch, headSha, repoRoot, resolveOwnerRepo } from '../git.js';
|
|
10
|
+
import { detectRoutesForRepo, resolveSample } from '../routes.js';
|
|
11
|
+
import { closeBrowser } from '../browser.js';
|
|
12
|
+
import { parseViewport } from '../viewport.js';
|
|
13
|
+
import { authHint, detectDevServer, ensureBrowser, NeedsHumanError, probeUrl } from '../doctor.js';
|
|
14
|
+
import { findOpenPr, getPr, GitHub, publishAssets, requireToken, upsertStickyComment } from '../github.js';
|
|
15
|
+
import { buildComment, STICKY_MARKER } from '../report.js';
|
|
16
|
+
import { resolveAuth } from '../sessions.js';
|
|
17
|
+
import { readPackage } from '../pkg.js';
|
|
18
|
+
import { joinUrl, normalizeUrl, routeSlug, runTasks } from '../run.js';
|
|
19
|
+
function packageHomepage(root) {
|
|
20
|
+
const hp = readPackage(root)?.homepage;
|
|
21
|
+
return typeof hp === 'string' && /^https?:\/\//.test(hp) && !/github\.com/.test(hp) ? hp : undefined;
|
|
22
|
+
}
|
|
23
|
+
function runId(now) {
|
|
24
|
+
return now.toISOString().replace(/[-:]/g, '').replace('T', '-').slice(0, 15);
|
|
25
|
+
}
|
|
26
|
+
export async function runPr(opts = {}) {
|
|
27
|
+
const started = Date.now();
|
|
28
|
+
const log = opts.log ?? (() => undefined);
|
|
29
|
+
const root = repoRoot(opts.cwd);
|
|
30
|
+
const config = loadConfig(root);
|
|
31
|
+
const settings = resolveSettings(config, opts);
|
|
32
|
+
const ownerRepo = resolveOwnerRepo(root);
|
|
33
|
+
const branch = currentBranch(root);
|
|
34
|
+
// --- Production URL --------------------------------------------------------
|
|
35
|
+
const beforeRaw = opts.before || config.before || packageHomepage(root);
|
|
36
|
+
if (!beforeRaw) {
|
|
37
|
+
throw new NeedsHumanError('No production URL known for the "before" state. Re-run with --before https://your-production-url (it is saved to .pre-post.json for next time).');
|
|
38
|
+
}
|
|
39
|
+
const before = normalizeUrl(beforeRaw);
|
|
40
|
+
if (opts.before && config.before !== before) {
|
|
41
|
+
updateConfig(root, { before });
|
|
42
|
+
log('Saved production URL to .pre-post.json');
|
|
43
|
+
}
|
|
44
|
+
// --- GitHub access (checked before any time is spent) -----------------------
|
|
45
|
+
const gh = opts.dryRun ? null : new GitHub(requireToken());
|
|
46
|
+
// --- Start the slow, independent things now; they overlap route detection ----
|
|
47
|
+
const browserReady = ensureBrowser();
|
|
48
|
+
const prLookup = gh
|
|
49
|
+
? opts.pr ? getPr(gh, ownerRepo, opts.pr) : branch ? findOpenPr(gh, ownerRepo, branch) : Promise.resolve(null)
|
|
50
|
+
: Promise.resolve(null);
|
|
51
|
+
const devServer = opts.after || config.after ? Promise.resolve(opts.after || config.after) : detectDevServer();
|
|
52
|
+
// Headers alone are enough to probe production; cookies need the final URL list.
|
|
53
|
+
const headers = resolveAuth({ configHeaders: config.headers, headers: opts.headers, urls: [before] })?.headers ?? {};
|
|
54
|
+
const beforeProbe = probeUrl(before, headers);
|
|
55
|
+
// --- Routes (sync: git + import graph) ----------------------------------------
|
|
56
|
+
const samples = config.samples || {};
|
|
57
|
+
let routes;
|
|
58
|
+
let skippedDynamic = [];
|
|
59
|
+
if (opts.routes?.length) {
|
|
60
|
+
routes = opts.routes;
|
|
61
|
+
}
|
|
62
|
+
else {
|
|
63
|
+
const detection = detectRoutesForRepo({ cwd: root, config, maxRoutes: settings.maxRoutes, framework: opts.framework });
|
|
64
|
+
routes = detection.routes.map(r => r.path);
|
|
65
|
+
skippedDynamic = detection.skippedDynamic;
|
|
66
|
+
log(`Routes (${detection.framework}, ${detection.durationMs}ms): ${routes.length ? routes.join(', ') : 'none detected'}`);
|
|
67
|
+
for (const r of detection.routes)
|
|
68
|
+
log(` ${r.path.padEnd(28)} ${r.confidence.padEnd(6)} ${r.reason}`);
|
|
69
|
+
if (routes.length === 0) {
|
|
70
|
+
routes = ['/'];
|
|
71
|
+
log('No routes detected from the diff; capturing / only.');
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
// --- Dev server and reachability --------------------------------------------
|
|
75
|
+
const afterRaw = await devServer;
|
|
76
|
+
if (!afterRaw) {
|
|
77
|
+
throw new NeedsHumanError('No dev server found on the usual ports (3000, 5173, ...). Start it (e.g. npm run dev), then re-run — or pass --after http://localhost:PORT.');
|
|
78
|
+
}
|
|
79
|
+
const after = normalizeUrl(afterRaw);
|
|
80
|
+
if (!opts.after && !config.after)
|
|
81
|
+
log(`Dev server: ${after}`);
|
|
82
|
+
const [probe, afterProbe] = await Promise.all([beforeProbe, probeUrl(after, headers)]);
|
|
83
|
+
if (probe.status === null)
|
|
84
|
+
throw new NeedsHumanError(`Cannot reach ${before}. Check the URL (or your VPN) and re-run.`);
|
|
85
|
+
if (probe.status === 401 || probe.status === 403)
|
|
86
|
+
throw new NeedsHumanError(authHint({ url: before, vercel: probe.vercel }));
|
|
87
|
+
if (afterProbe.status === null)
|
|
88
|
+
throw new NeedsHumanError(`Cannot reach ${after}. Is the dev server running?`);
|
|
89
|
+
const auth = resolveAuth({ configHeaders: config.headers, headers: opts.headers, cookies: opts.cookies, cookieUrl: before, urls: [before, after] });
|
|
90
|
+
// --- Capture -------------------------------------------------------------------
|
|
91
|
+
const now = new Date();
|
|
92
|
+
const id = runId(now);
|
|
93
|
+
const outputDir = opts.output || path.join(os.tmpdir(), 'pre-post', ownerRepo.replace('/', '__'), id);
|
|
94
|
+
const viewports = settings.viewports.map(parseViewport);
|
|
95
|
+
const tasks = [];
|
|
96
|
+
for (const route of routes) {
|
|
97
|
+
const resolved = resolveSample(route, samples);
|
|
98
|
+
for (const vp of viewports) {
|
|
99
|
+
tasks.push({ route, resolvedRoute: resolved, viewport: vp.label, size: vp.size, beforeUrl: joinUrl(before, resolved), afterUrl: joinUrl(after, resolved) });
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
log(`Capturing ${tasks.length * 2} screenshots (${routes.length} route(s) × ${viewports.length} viewport(s)) ...`);
|
|
103
|
+
await browserReady;
|
|
104
|
+
let outcomes;
|
|
105
|
+
try {
|
|
106
|
+
outcomes = await runTasks(tasks, { outputDir, ...settings, wait: opts.wait, auth, log });
|
|
107
|
+
}
|
|
108
|
+
finally {
|
|
109
|
+
await closeBrowser();
|
|
110
|
+
}
|
|
111
|
+
// --- Publish -------------------------------------------------------------------
|
|
112
|
+
const pr = await prLookup;
|
|
113
|
+
const changed = outcomes.filter(o => o.status === 'changed' && o.files);
|
|
114
|
+
if (gh && changed.length) {
|
|
115
|
+
const folder = pr ? `pr-${pr.number}/${id}` : `branch/${routeSlug(branch || 'detached')}/${id}`;
|
|
116
|
+
const keyFor = (o, kind) => `${folder}/${routeSlug(o.route)}-${o.viewport}-${kind}.png`;
|
|
117
|
+
const files = [];
|
|
118
|
+
for (const o of changed) {
|
|
119
|
+
for (const kind of ARTIFACT_KINDS) {
|
|
120
|
+
const local = o.files[kind];
|
|
121
|
+
if (local)
|
|
122
|
+
files.push({ path: keyFor(o, kind), content: fs.readFileSync(local) });
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
log(`Publishing ${files.length} image(s) to ${ownerRepo}@${settings.assetsBranch} ...`);
|
|
126
|
+
const published = await publishAssets(gh, ownerRepo, settings.assetsBranch, files, pr ? `Screenshots for #${pr.number} (${id})` : `Screenshots for ${branch || 'detached'} (${id})`);
|
|
127
|
+
for (const o of changed) {
|
|
128
|
+
const urls = {};
|
|
129
|
+
for (const kind of ARTIFACT_KINDS)
|
|
130
|
+
if (o.files[kind])
|
|
131
|
+
urls[kind] = published.urls.get(keyFor(o, kind));
|
|
132
|
+
o.urls = urls;
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
const result = {
|
|
136
|
+
repo: ownerRepo,
|
|
137
|
+
prNumber: pr?.number,
|
|
138
|
+
beforeBase: before,
|
|
139
|
+
afterBase: after,
|
|
140
|
+
outcomes,
|
|
141
|
+
skippedDynamic,
|
|
142
|
+
durationMs: Date.now() - started,
|
|
143
|
+
markdown: '',
|
|
144
|
+
outputDir,
|
|
145
|
+
};
|
|
146
|
+
result.markdown = buildComment(result, { version: opts.version, headSha: headSha(root), now });
|
|
147
|
+
if (gh && (opts.comment ?? true)) {
|
|
148
|
+
if (pr) {
|
|
149
|
+
const comment = await upsertStickyComment(gh, ownerRepo, pr.number, result.markdown, STICKY_MARKER);
|
|
150
|
+
result.commentUrl = comment.html_url;
|
|
151
|
+
log(`${comment.created ? 'Posted' : 'Updated'} PR comment: ${comment.html_url}`);
|
|
152
|
+
}
|
|
153
|
+
else {
|
|
154
|
+
log(`No open PR for branch "${branch}". Open one and re-run, or paste the markdown below.`);
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
return result;
|
|
158
|
+
}
|
|
159
|
+
//# sourceMappingURL=pr.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pr.js","sourceRoot":"","sources":["../../src/commands/pr.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `pre-post prune` — delete screenshots for PRs closed more than N days ago.
|
|
3
|
+
*/
|
|
4
|
+
import { PruneResult } from '../github.js';
|
|
5
|
+
export declare function runPrune(opts?: {
|
|
6
|
+
cwd?: string;
|
|
7
|
+
days?: number;
|
|
8
|
+
dryRun?: boolean;
|
|
9
|
+
}): Promise<PruneResult>;
|
|
10
|
+
//# sourceMappingURL=prune.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prune.d.ts","sourceRoot":"","sources":["../../src/commands/prune.ts"],"names":[],"mappings":"AAAA;;GAEG;AAIH,OAAO,EAAuB,WAAW,EAAgB,MAAM,cAAc,CAAC;AAE9E,wBAAsB,QAAQ,CAAC,IAAI,GAAE;IAAE,GAAG,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,OAAO,CAAA;CAAO,GAAG,OAAO,CAAC,WAAW,CAAC,CAKjH"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `pre-post prune` — delete screenshots for PRs closed more than N days ago.
|
|
3
|
+
*/
|
|
4
|
+
import { loadConfig, resolveSettings } from '../config.js';
|
|
5
|
+
import { repoRoot, resolveOwnerRepo } from '../git.js';
|
|
6
|
+
import { GitHub, pruneAssets, requireToken } from '../github.js';
|
|
7
|
+
export async function runPrune(opts = {}) {
|
|
8
|
+
const root = repoRoot(opts.cwd);
|
|
9
|
+
const settings = resolveSettings(loadConfig(root), { pruneDays: opts.days });
|
|
10
|
+
const gh = new GitHub(requireToken('prune screenshots'));
|
|
11
|
+
return pruneAssets(gh, resolveOwnerRepo(root), settings.assetsBranch, settings.pruneDays, opts.dryRun);
|
|
12
|
+
}
|
|
13
|
+
//# sourceMappingURL=prune.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prune.js","sourceRoot":"","sources":["../../src/commands/prune.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,UAAU,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAC3D,OAAO,EAAE,QAAQ,EAAE,gBAAgB,EAAE,MAAM,WAAW,CAAC;AACvD,OAAO,EAAE,MAAM,EAAE,WAAW,EAAe,YAAY,EAAE,MAAM,cAAc,CAAC;AAE9E,MAAM,CAAC,KAAK,UAAU,QAAQ,CAAC,OAA0D,EAAE;IACzF,MAAM,IAAI,GAAG,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAChC,MAAM,QAAQ,GAAG,eAAe,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC;IAC7E,MAAM,EAAE,GAAG,IAAI,MAAM,CAAC,YAAY,CAAC,mBAAmB,CAAC,CAAC,CAAC;IACzD,OAAO,WAAW,CAAC,EAAE,EAAE,gBAAgB,CAAC,IAAI,CAAC,EAAE,QAAQ,CAAC,YAAY,EAAE,QAAQ,CAAC,SAAS,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;AACzG,CAAC"}
|