@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
|
@@ -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"}
|
package/dist/filename.d.ts
CHANGED
|
@@ -9,6 +9,8 @@ export interface FilenameOptions {
|
|
|
9
9
|
timestamp?: Date;
|
|
10
10
|
/** Suffix (before/after/diff) */
|
|
11
11
|
suffix?: 'before' | 'after' | 'diff';
|
|
12
|
+
/** Output format — determines file extension (default: 'png') */
|
|
13
|
+
format?: 'png' | 'gif';
|
|
12
14
|
}
|
|
13
15
|
/**
|
|
14
16
|
* Generate a semantic filename for screenshots.
|
package/dist/filename.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"filename.d.ts","sourceRoot":"","sources":["../src/filename.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,eAAe;IAC9B,kCAAkC;IAClC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,+BAA+B;IAC/B,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,qDAAqD;IACrD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,iCAAiC;IACjC,SAAS,CAAC,EAAE,IAAI,CAAC;IACjB,iCAAiC;IACjC,MAAM,CAAC,EAAE,QAAQ,GAAG,OAAO,GAAG,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"filename.d.ts","sourceRoot":"","sources":["../src/filename.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,eAAe;IAC9B,kCAAkC;IAClC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,+BAA+B;IAC/B,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,qDAAqD;IACrD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,iCAAiC;IACjC,SAAS,CAAC,EAAE,IAAI,CAAC;IACjB,iCAAiC;IACjC,MAAM,CAAC,EAAE,QAAQ,GAAG,OAAO,GAAG,MAAM,CAAC;IACrC,iEAAiE;IACjE,MAAM,CAAC,EAAE,KAAK,GAAG,KAAK,CAAC;CACxB;AAkDD;;;;;;;;;GASG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,eAAe,GAAG,MAAM,CA0BjE"}
|
package/dist/filename.js
CHANGED
|
@@ -71,6 +71,7 @@ export function generateFilename(options) {
|
|
|
71
71
|
.toISOString()
|
|
72
72
|
.replace(/[:.]/g, '-')
|
|
73
73
|
.slice(0, 19);
|
|
74
|
-
|
|
74
|
+
const ext = options.format === 'gif' ? 'gif' : 'png';
|
|
75
|
+
return `${pageName}${elementPart}${suffixPart}-${timestamp}.${ext}`;
|
|
75
76
|
}
|
|
76
77
|
//# sourceMappingURL=filename.js.map
|
package/dist/filename.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"filename.js","sourceRoot":"","sources":["../src/filename.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"filename.js","sourceRoot":"","sources":["../src/filename.ts"],"names":[],"mappings":"AAeA;;;GAGG;AACH,SAAS,OAAO,CAAC,IAAY;IAC3B,OAAO,IAAI;SACR,WAAW,EAAE;SACb,OAAO,CAAC,aAAa,EAAE,GAAG,CAAC;SAC3B,OAAO,CAAC,QAAQ,EAAE,EAAE,CAAC;SACrB,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;AAClB,CAAC;AAED;;;;;;GAMG;AACH,SAAS,kBAAkB,CAAC,GAAW;IACrC,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,CAAC;QAE5B,uDAAuD;QACvD,IAAI,MAAM,CAAC,QAAQ,KAAK,OAAO,EAAE,CAAC;YAChC,MAAM,KAAK,GAAG,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;YACzC,MAAM,QAAQ,GAAG,KAAK,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;YACzC,OAAO,QAAQ,CAAC,OAAO,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC,CAAC,mBAAmB;QAC9D,CAAC;QAED,wCAAwC;QACxC,IAAI,QAAQ,GAAG,MAAM,CAAC,QAAQ,CAAC;QAE/B,kCAAkC;QAClC,QAAQ,GAAG,QAAQ,CAAC,OAAO,CAAC,YAAY,EAAE,EAAE,CAAC,CAAC;QAE9C,kCAAkC;QAClC,IAAI,CAAC,QAAQ,EAAE,CAAC;YACd,OAAO,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;QAC/C,CAAC;QAED,+BAA+B;QAC/B,OAAO,QAAQ,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;IACtC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,SAAS,CAAC;IACnB,CAAC;AACH,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,UAAU,gBAAgB,CAAC,OAAwB;IACvD,0CAA0C;IAC1C,IAAI,QAAQ,GAAG,MAAM,CAAC;IACtB,IAAI,OAAO,CAAC,SAAS,EAAE,CAAC;QACtB,QAAQ,GAAG,OAAO,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;IACxC,CAAC;SAAM,IAAI,OAAO,CAAC,GAAG,EAAE,CAAC;QACvB,MAAM,OAAO,GAAG,kBAAkB,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;QAChD,IAAI,OAAO,EAAE,CAAC;YACZ,QAAQ,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;QAC9B,CAAC;IACH,CAAC;IAED,mCAAmC;IACnC,MAAM,WAAW,GAAG,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,OAAO,CAAC,OAAO,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;IAE9E,gCAAgC;IAChC,MAAM,UAAU,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;IAE9D,qDAAqD;IACrD,MAAM,SAAS,GAAG,CAAC,OAAO,CAAC,SAAS,IAAI,IAAI,IAAI,EAAE,CAAC;SAChD,WAAW,EAAE;SACb,OAAO,CAAC,OAAO,EAAE,GAAG,CAAC;SACrB,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;IAEhB,MAAM,GAAG,GAAG,OAAO,CAAC,MAAM,KAAK,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC;IACrD,OAAO,GAAG,QAAQ,GAAG,WAAW,GAAG,UAAU,IAAI,SAAS,IAAI,GAAG,EAAE,CAAC;AACtE,CAAC"}
|
package/dist/git.d.ts
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Thin git helpers. Every call is a single short-lived subprocess.
|
|
3
|
+
*/
|
|
4
|
+
export declare function git(args: string[], cwd?: string): string;
|
|
5
|
+
export declare function repoRoot(cwd?: string): string;
|
|
6
|
+
export declare function currentBranch(cwd?: string): string | null;
|
|
7
|
+
export declare function headSha(cwd?: string): string | null;
|
|
8
|
+
/**
|
|
9
|
+
* Parse "owner/repo" from a remote URL. Supports HTTPS, SSH, and proxy URLs
|
|
10
|
+
* whose last two path segments are owner/repo.
|
|
11
|
+
*/
|
|
12
|
+
export declare function parseOwnerRepo(remoteUrl: string): string | null;
|
|
13
|
+
export declare function resolveOwnerRepo(cwd?: string): string;
|
|
14
|
+
/** Default branch of origin (main/master/...), best effort. */
|
|
15
|
+
export declare function defaultBranch(cwd?: string): string;
|
|
16
|
+
/** Merge base between HEAD and the default branch, or null when unknown. */
|
|
17
|
+
export declare function mergeBase(cwd?: string): string | null;
|
|
18
|
+
/**
|
|
19
|
+
* Files changed on this branch relative to the default branch, plus anything
|
|
20
|
+
* staged, unstaged, or untracked. Paths are relative to the repo root.
|
|
21
|
+
*/
|
|
22
|
+
export declare function changedFiles(cwd?: string, diffTarget?: string): string[];
|
|
23
|
+
//# sourceMappingURL=git.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"git.d.ts","sourceRoot":"","sources":["../src/git.ts"],"names":[],"mappings":"AAAA;;GAEG;AAIH,wBAAgB,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,GAAG,SAAgB,GAAG,MAAM,CAE/D;AAUD,wBAAgB,QAAQ,CAAC,GAAG,SAAgB,GAAG,MAAM,CAIpD;AAED,wBAAgB,aAAa,CAAC,GAAG,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAGzD;AAED,wBAAgB,OAAO,CAAC,GAAG,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAEnD;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAK/D;AAED,wBAAgB,gBAAgB,CAAC,GAAG,CAAC,EAAE,MAAM,GAAG,MAAM,CASrD;AAED,+DAA+D;AAC/D,wBAAgB,aAAa,CAAC,GAAG,CAAC,EAAE,MAAM,GAAG,MAAM,CASlD;AAED,4EAA4E;AAC5E,wBAAgB,SAAS,CAAC,GAAG,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAIrD;AAMD;;;GAGG;AACH,wBAAgB,YAAY,CAAC,GAAG,SAAgB,EAAE,UAAU,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAS/E"}
|
package/dist/git.js
ADDED
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Thin git helpers. Every call is a single short-lived subprocess.
|
|
3
|
+
*/
|
|
4
|
+
import { execFileSync } from 'child_process';
|
|
5
|
+
export function git(args, cwd = process.cwd()) {
|
|
6
|
+
return execFileSync('git', args, { cwd, encoding: 'utf-8', stdio: ['ignore', 'pipe', 'pipe'] }).trim();
|
|
7
|
+
}
|
|
8
|
+
function tryGit(args, cwd) {
|
|
9
|
+
try {
|
|
10
|
+
return git(args, cwd);
|
|
11
|
+
}
|
|
12
|
+
catch {
|
|
13
|
+
return null;
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
export function repoRoot(cwd = process.cwd()) {
|
|
17
|
+
const root = tryGit(['rev-parse', '--show-toplevel'], cwd);
|
|
18
|
+
if (!root)
|
|
19
|
+
throw new Error('Not inside a git repository.');
|
|
20
|
+
return root;
|
|
21
|
+
}
|
|
22
|
+
export function currentBranch(cwd) {
|
|
23
|
+
const b = tryGit(['rev-parse', '--abbrev-ref', 'HEAD'], cwd);
|
|
24
|
+
return b && b !== 'HEAD' ? b : null;
|
|
25
|
+
}
|
|
26
|
+
export function headSha(cwd) {
|
|
27
|
+
return tryGit(['rev-parse', 'HEAD'], cwd);
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Parse "owner/repo" from a remote URL. Supports HTTPS, SSH, and proxy URLs
|
|
31
|
+
* whose last two path segments are owner/repo.
|
|
32
|
+
*/
|
|
33
|
+
export function parseOwnerRepo(remoteUrl) {
|
|
34
|
+
const std = remoteUrl.match(/github\.com[/:]([^/]+\/[^/]+?)(?:\.git)?\/?$/);
|
|
35
|
+
if (std)
|
|
36
|
+
return std[1];
|
|
37
|
+
const fallback = remoteUrl.match(/\/([^/]+\/[^/]+?)(?:\.git)?\/?$/);
|
|
38
|
+
return fallback ? fallback[1] : null;
|
|
39
|
+
}
|
|
40
|
+
export function resolveOwnerRepo(cwd) {
|
|
41
|
+
const env = process.env.GH_REPO || process.env.GITHUB_REPOSITORY;
|
|
42
|
+
if (env)
|
|
43
|
+
return env;
|
|
44
|
+
const url = tryGit(['remote', 'get-url', 'origin'], cwd);
|
|
45
|
+
const parsed = url ? parseOwnerRepo(url) : null;
|
|
46
|
+
if (!parsed) {
|
|
47
|
+
throw new Error('Cannot determine GitHub repository. Set GH_REPO=owner/repo.');
|
|
48
|
+
}
|
|
49
|
+
return parsed;
|
|
50
|
+
}
|
|
51
|
+
/** Default branch of origin (main/master/...), best effort. */
|
|
52
|
+
export function defaultBranch(cwd) {
|
|
53
|
+
const ref = tryGit(['symbolic-ref', '--short', 'refs/remotes/origin/HEAD'], cwd);
|
|
54
|
+
if (ref)
|
|
55
|
+
return ref.replace(/^origin\//, '');
|
|
56
|
+
const found = lines(tryGit([
|
|
57
|
+
'for-each-ref', '--format=%(refname:short)',
|
|
58
|
+
'refs/remotes/origin/main', 'refs/remotes/origin/master', 'refs/heads/main', 'refs/heads/master',
|
|
59
|
+
], cwd));
|
|
60
|
+
const first = found[0]?.replace(/^origin\//, '');
|
|
61
|
+
return first || 'main';
|
|
62
|
+
}
|
|
63
|
+
/** Merge base between HEAD and the default branch, or null when unknown. */
|
|
64
|
+
export function mergeBase(cwd) {
|
|
65
|
+
const base = defaultBranch(cwd);
|
|
66
|
+
return tryGit(['merge-base', `origin/${base}`, 'HEAD'], cwd)
|
|
67
|
+
|| tryGit(['merge-base', base, 'HEAD'], cwd);
|
|
68
|
+
}
|
|
69
|
+
function lines(out) {
|
|
70
|
+
return out ? out.split('\n').map(l => l.trim()).filter(Boolean) : [];
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Files changed on this branch relative to the default branch, plus anything
|
|
74
|
+
* staged, unstaged, or untracked. Paths are relative to the repo root.
|
|
75
|
+
*/
|
|
76
|
+
export function changedFiles(cwd = process.cwd(), diffTarget) {
|
|
77
|
+
const files = new Set();
|
|
78
|
+
const root = repoRoot(cwd);
|
|
79
|
+
const target = diffTarget || mergeBase(root) || 'HEAD';
|
|
80
|
+
lines(tryGit(['diff', '--name-only', target], root)).forEach(f => files.add(f));
|
|
81
|
+
lines(tryGit(['diff', '--name-only', '--cached'], root)).forEach(f => files.add(f));
|
|
82
|
+
lines(tryGit(['diff', '--name-only'], root)).forEach(f => files.add(f));
|
|
83
|
+
lines(tryGit(['ls-files', '--others', '--exclude-standard'], root)).forEach(f => files.add(f));
|
|
84
|
+
return Array.from(files);
|
|
85
|
+
}
|
|
86
|
+
//# sourceMappingURL=git.js.map
|
package/dist/git.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"git.js","sourceRoot":"","sources":["../src/git.ts"],"names":[],"mappings":"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"}
|
package/dist/github.d.ts
ADDED
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* GitHub REST client used for:
|
|
3
|
+
* - finding the open PR for a branch
|
|
4
|
+
* - publishing screenshots to an orphan assets branch (Git Data API, one commit per run)
|
|
5
|
+
* - upserting a sticky PR comment
|
|
6
|
+
* - pruning old assets
|
|
7
|
+
*
|
|
8
|
+
* Authentication: GH_TOKEN / GITHUB_TOKEN, else the gh CLI's stored token.
|
|
9
|
+
*/
|
|
10
|
+
export { GitHubError } from './errors.js';
|
|
11
|
+
export declare const API_BASE: string;
|
|
12
|
+
export declare function getToken(): string | null;
|
|
13
|
+
/** A token, or the one sentence telling the human how to get one. */
|
|
14
|
+
export declare function requireToken(purpose?: string): string;
|
|
15
|
+
export declare class GitHub {
|
|
16
|
+
private readonly token;
|
|
17
|
+
private readonly base;
|
|
18
|
+
constructor(token: string, base?: string);
|
|
19
|
+
request<T = any>(method: string, path: string, body?: unknown): Promise<T>;
|
|
20
|
+
}
|
|
21
|
+
export interface PullRequestRef {
|
|
22
|
+
number: number;
|
|
23
|
+
html_url: string;
|
|
24
|
+
head: {
|
|
25
|
+
sha: string;
|
|
26
|
+
ref: string;
|
|
27
|
+
};
|
|
28
|
+
base: {
|
|
29
|
+
ref: string;
|
|
30
|
+
};
|
|
31
|
+
title: string;
|
|
32
|
+
}
|
|
33
|
+
export declare function findOpenPr(gh: GitHub, ownerRepo: string, branch: string): Promise<PullRequestRef | null>;
|
|
34
|
+
export declare function getPr(gh: GitHub, ownerRepo: string, number: number): Promise<PullRequestRef & {
|
|
35
|
+
state: string;
|
|
36
|
+
closed_at: string | null;
|
|
37
|
+
merged_at: string | null;
|
|
38
|
+
}>;
|
|
39
|
+
export interface AssetFile {
|
|
40
|
+
/** Path inside the assets branch, e.g. "pr-42/20260115-1200/home-desktop-post.png" */
|
|
41
|
+
path: string;
|
|
42
|
+
content: Buffer;
|
|
43
|
+
}
|
|
44
|
+
export interface PublishResult {
|
|
45
|
+
sha: string;
|
|
46
|
+
/** path → raw-rendering blob URL */
|
|
47
|
+
urls: Map<string, string>;
|
|
48
|
+
}
|
|
49
|
+
export declare function blobUrl(ownerRepo: string, sha: string, filePath: string): string;
|
|
50
|
+
/**
|
|
51
|
+
* Publish files to `branch` as a single commit. Creates the branch as an
|
|
52
|
+
* orphan (no parents) when it does not exist. Retries once on a ref race.
|
|
53
|
+
*/
|
|
54
|
+
export declare function publishAssets(gh: GitHub, ownerRepo: string, branch: string, files: AssetFile[], message: string): Promise<PublishResult>;
|
|
55
|
+
export interface CommentResult {
|
|
56
|
+
html_url: string;
|
|
57
|
+
created: boolean;
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Create or update the single pre-post comment on a PR, identified by `marker`.
|
|
61
|
+
*/
|
|
62
|
+
export declare function upsertStickyComment(gh: GitHub, ownerRepo: string, prNumber: number, body: string, marker: string): Promise<CommentResult>;
|
|
63
|
+
export interface PruneResult {
|
|
64
|
+
removed: string[];
|
|
65
|
+
kept: string[];
|
|
66
|
+
sha?: string;
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Remove `pr-<n>/` folders on the assets branch whose PR closed more than
|
|
70
|
+
* `olderThanDays` ago. One commit; no history rewrite.
|
|
71
|
+
*/
|
|
72
|
+
export declare function pruneAssets(gh: GitHub, ownerRepo: string, branch: string, olderThanDays: number, dryRun?: boolean): Promise<PruneResult>;
|
|
73
|
+
//# sourceMappingURL=github.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"github.d.ts","sourceRoot":"","sources":["../src/github.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAIH,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAE1C,eAAO,MAAM,QAAQ,QAAyD,CAAC;AAE/E,wBAAgB,QAAQ,IAAI,MAAM,GAAG,IAAI,CASxC;AAED,qEAAqE;AACrE,wBAAgB,YAAY,CAAC,OAAO,SAAwB,GAAG,MAAM,CAIpE;AAED,qBAAa,MAAM;IACL,OAAO,CAAC,QAAQ,CAAC,KAAK;IAAU,OAAO,CAAC,QAAQ,CAAC,IAAI;gBAApC,KAAK,EAAE,MAAM,EAAmB,IAAI,SAAW;IAEtE,OAAO,CAAC,CAAC,GAAG,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC,CAAC,CAAC;CA2BjF;AAED,MAAM,WAAW,cAAc;IAC7B,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAE,CAAC;IACnC,IAAI,EAAE;QAAE,GAAG,EAAE,MAAM,CAAA;KAAE,CAAC;IACtB,KAAK,EAAE,MAAM,CAAC;CACf;AAED,wBAAsB,UAAU,CAAC,EAAE,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC,CAO9G;AAED,wBAAsB,KAAK,CAAC,EAAE,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,GAAG;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,CAAC,CAE1K;AAED,MAAM,WAAW,SAAS;IACxB,sFAAsF;IACtF,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,aAAa;IAC5B,GAAG,EAAE,MAAM,CAAC;IACZ,oCAAoC;IACpC,IAAI,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAC3B;AAED,wBAAgB,OAAO,CAAC,SAAS,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAGhF;AAeD;;;GAGG;AACH,wBAAsB,aAAa,CACjC,EAAE,EAAE,MAAM,EACV,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,SAAS,EAAE,EAClB,OAAO,EAAE,MAAM,GACd,OAAO,CAAC,aAAa,CAAC,CAqDxB;AAED,MAAM,WAAW,aAAa;IAC5B,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,OAAO,CAAC;CAClB;AAED;;GAEG;AACH,wBAAsB,mBAAmB,CACvC,EAAE,EAAE,MAAM,EACV,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,MAAM,GACb,OAAO,CAAC,aAAa,CAAC,CAexB;AAED,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED;;;GAGG;AACH,wBAAsB,WAAW,CAC/B,EAAE,EAAE,MAAM,EACV,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,MAAM,EACd,aAAa,EAAE,MAAM,EACrB,MAAM,UAAQ,GACb,OAAO,CAAC,WAAW,CAAC,CA8DtB"}
|
package/dist/github.js
ADDED
|
@@ -0,0 +1,240 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* GitHub REST client used for:
|
|
3
|
+
* - finding the open PR for a branch
|
|
4
|
+
* - publishing screenshots to an orphan assets branch (Git Data API, one commit per run)
|
|
5
|
+
* - upserting a sticky PR comment
|
|
6
|
+
* - pruning old assets
|
|
7
|
+
*
|
|
8
|
+
* Authentication: GH_TOKEN / GITHUB_TOKEN, else the gh CLI's stored token.
|
|
9
|
+
*/
|
|
10
|
+
import { execFileSync } from 'child_process';
|
|
11
|
+
import { GitHubError, NeedsHumanError, GH_LOGIN_HINT } from './errors.js';
|
|
12
|
+
export { GitHubError } from './errors.js';
|
|
13
|
+
export const API_BASE = process.env.GITHUB_API_URL || 'https://api.github.com';
|
|
14
|
+
export function getToken() {
|
|
15
|
+
const env = process.env.GH_TOKEN || process.env.GITHUB_TOKEN;
|
|
16
|
+
if (env)
|
|
17
|
+
return env;
|
|
18
|
+
try {
|
|
19
|
+
const out = execFileSync('gh', ['auth', 'token'], { encoding: 'utf-8', stdio: ['ignore', 'pipe', 'ignore'] }).trim();
|
|
20
|
+
return out || null;
|
|
21
|
+
}
|
|
22
|
+
catch {
|
|
23
|
+
return null;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
/** A token, or the one sentence telling the human how to get one. */
|
|
27
|
+
export function requireToken(purpose = 'publish screenshots') {
|
|
28
|
+
const token = getToken();
|
|
29
|
+
if (!token)
|
|
30
|
+
throw new NeedsHumanError(`GitHub access is needed to ${purpose}. ${GH_LOGIN_HINT}`);
|
|
31
|
+
return token;
|
|
32
|
+
}
|
|
33
|
+
export class GitHub {
|
|
34
|
+
token;
|
|
35
|
+
base;
|
|
36
|
+
constructor(token, base = API_BASE) {
|
|
37
|
+
this.token = token;
|
|
38
|
+
this.base = base;
|
|
39
|
+
}
|
|
40
|
+
async request(method, path, body) {
|
|
41
|
+
const res = await fetch(`${this.base}${path}`, {
|
|
42
|
+
method,
|
|
43
|
+
headers: {
|
|
44
|
+
Authorization: `Bearer ${this.token}`,
|
|
45
|
+
Accept: 'application/vnd.github+json',
|
|
46
|
+
'X-GitHub-Api-Version': '2022-11-28',
|
|
47
|
+
'User-Agent': 'pre-post',
|
|
48
|
+
...(body ? { 'Content-Type': 'application/json' } : {}),
|
|
49
|
+
},
|
|
50
|
+
body: body ? JSON.stringify(body) : undefined,
|
|
51
|
+
});
|
|
52
|
+
if (res.status === 204)
|
|
53
|
+
return undefined;
|
|
54
|
+
const text = await res.text();
|
|
55
|
+
let json = null;
|
|
56
|
+
try {
|
|
57
|
+
json = text ? JSON.parse(text) : null;
|
|
58
|
+
}
|
|
59
|
+
catch { /* non-JSON */ }
|
|
60
|
+
if (res.status === 401 || (res.status === 403 && !/rate limit/i.test(json?.message || ''))) {
|
|
61
|
+
throw new NeedsHumanError(`GitHub rejected the token (${res.status}). ${GH_LOGIN_HINT}`);
|
|
62
|
+
}
|
|
63
|
+
if (!res.ok) {
|
|
64
|
+
const msg = json?.message || text || res.statusText;
|
|
65
|
+
throw new GitHubError(res.status, `GitHub ${method} ${path} → ${res.status}: ${msg}`);
|
|
66
|
+
}
|
|
67
|
+
return json;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
export async function findOpenPr(gh, ownerRepo, branch) {
|
|
71
|
+
const owner = ownerRepo.split('/')[0];
|
|
72
|
+
const prs = await gh.request('GET', `/repos/${ownerRepo}/pulls?state=open&head=${encodeURIComponent(`${owner}:${branch}`)}&per_page=1`);
|
|
73
|
+
return prs[0] ?? null;
|
|
74
|
+
}
|
|
75
|
+
export async function getPr(gh, ownerRepo, number) {
|
|
76
|
+
return gh.request('GET', `/repos/${ownerRepo}/pulls/${number}`);
|
|
77
|
+
}
|
|
78
|
+
export function blobUrl(ownerRepo, sha, filePath) {
|
|
79
|
+
const encoded = filePath.split('/').map(encodeURIComponent).join('/');
|
|
80
|
+
return `https://github.com/${ownerRepo}/blob/${sha}/${encoded}?raw=true`;
|
|
81
|
+
}
|
|
82
|
+
async function mapLimit(items, limit, fn) {
|
|
83
|
+
const results = new Array(items.length);
|
|
84
|
+
let next = 0;
|
|
85
|
+
const workers = Array.from({ length: Math.min(limit, items.length) }, async () => {
|
|
86
|
+
while (next < items.length) {
|
|
87
|
+
const i = next++;
|
|
88
|
+
results[i] = await fn(items[i]);
|
|
89
|
+
}
|
|
90
|
+
});
|
|
91
|
+
await Promise.all(workers);
|
|
92
|
+
return results;
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Publish files to `branch` as a single commit. Creates the branch as an
|
|
96
|
+
* orphan (no parents) when it does not exist. Retries once on a ref race.
|
|
97
|
+
*/
|
|
98
|
+
export async function publishAssets(gh, ownerRepo, branch, files, message) {
|
|
99
|
+
if (files.length === 0)
|
|
100
|
+
throw new Error('publishAssets: no files');
|
|
101
|
+
// 1. Blobs in parallel (content is base64; 6 at a time keeps well under abuse limits).
|
|
102
|
+
const blobs = await mapLimit(files, 6, async (f) => {
|
|
103
|
+
const res = await gh.request('POST', `/repos/${ownerRepo}/git/blobs`, {
|
|
104
|
+
content: f.content.toString('base64'),
|
|
105
|
+
encoding: 'base64',
|
|
106
|
+
});
|
|
107
|
+
return { path: f.path, sha: res.sha };
|
|
108
|
+
});
|
|
109
|
+
for (let attempt = 0; attempt < 3; attempt++) {
|
|
110
|
+
// 2. Current head of the assets branch (if any).
|
|
111
|
+
let parentSha = null;
|
|
112
|
+
let baseTree;
|
|
113
|
+
try {
|
|
114
|
+
const ref = await gh.request('GET', `/repos/${ownerRepo}/git/ref/${encodeURIComponent(`heads/${branch}`)}`);
|
|
115
|
+
parentSha = ref.object.sha;
|
|
116
|
+
const commit = await gh.request('GET', `/repos/${ownerRepo}/git/commits/${parentSha}`);
|
|
117
|
+
baseTree = commit.tree.sha;
|
|
118
|
+
}
|
|
119
|
+
catch (err) {
|
|
120
|
+
if (!(err instanceof GitHubError) || err.status !== 404)
|
|
121
|
+
throw err;
|
|
122
|
+
}
|
|
123
|
+
// 3. One tree, one commit.
|
|
124
|
+
const tree = await gh.request('POST', `/repos/${ownerRepo}/git/trees`, {
|
|
125
|
+
...(baseTree ? { base_tree: baseTree } : {}),
|
|
126
|
+
tree: blobs.map(b => ({ path: b.path, mode: '100644', type: 'blob', sha: b.sha })),
|
|
127
|
+
});
|
|
128
|
+
const commit = await gh.request('POST', `/repos/${ownerRepo}/git/commits`, {
|
|
129
|
+
message,
|
|
130
|
+
tree: tree.sha,
|
|
131
|
+
parents: parentSha ? [parentSha] : [],
|
|
132
|
+
});
|
|
133
|
+
// 4. Move the ref (create when missing). A 422 here means another run raced us; retry.
|
|
134
|
+
try {
|
|
135
|
+
if (parentSha) {
|
|
136
|
+
await gh.request('PATCH', `/repos/${ownerRepo}/git/refs/${encodeURIComponent(`heads/${branch}`)}`, { sha: commit.sha, force: false });
|
|
137
|
+
}
|
|
138
|
+
else {
|
|
139
|
+
await gh.request('POST', `/repos/${ownerRepo}/git/refs`, { ref: `refs/heads/${branch}`, sha: commit.sha });
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
catch (err) {
|
|
143
|
+
if (err instanceof GitHubError && (err.status === 422 || err.status === 409) && attempt < 2)
|
|
144
|
+
continue;
|
|
145
|
+
throw err;
|
|
146
|
+
}
|
|
147
|
+
const urls = new Map();
|
|
148
|
+
for (const f of files)
|
|
149
|
+
urls.set(f.path, blobUrl(ownerRepo, commit.sha, f.path));
|
|
150
|
+
return { sha: commit.sha, urls };
|
|
151
|
+
}
|
|
152
|
+
throw new Error(`Could not update ${branch} after 3 attempts (concurrent runs?)`);
|
|
153
|
+
}
|
|
154
|
+
/**
|
|
155
|
+
* Create or update the single pre-post comment on a PR, identified by `marker`.
|
|
156
|
+
*/
|
|
157
|
+
export async function upsertStickyComment(gh, ownerRepo, prNumber, body, marker) {
|
|
158
|
+
for (let page = 1; page <= 5; page++) {
|
|
159
|
+
const comments = await gh.request('GET', `/repos/${ownerRepo}/issues/${prNumber}/comments?per_page=100&page=${page}`);
|
|
160
|
+
const existing = comments.find(c => c.body?.includes(marker));
|
|
161
|
+
if (existing) {
|
|
162
|
+
const updated = await gh.request('PATCH', `/repos/${ownerRepo}/issues/comments/${existing.id}`, { body });
|
|
163
|
+
return { html_url: updated.html_url, created: false };
|
|
164
|
+
}
|
|
165
|
+
if (comments.length < 100)
|
|
166
|
+
break;
|
|
167
|
+
}
|
|
168
|
+
const created = await gh.request('POST', `/repos/${ownerRepo}/issues/${prNumber}/comments`, { body });
|
|
169
|
+
return { html_url: created.html_url, created: true };
|
|
170
|
+
}
|
|
171
|
+
/**
|
|
172
|
+
* Remove `pr-<n>/` folders on the assets branch whose PR closed more than
|
|
173
|
+
* `olderThanDays` ago. One commit; no history rewrite.
|
|
174
|
+
*/
|
|
175
|
+
export async function pruneAssets(gh, ownerRepo, branch, olderThanDays, dryRun = false) {
|
|
176
|
+
let headSha;
|
|
177
|
+
try {
|
|
178
|
+
const ref = await gh.request('GET', `/repos/${ownerRepo}/git/ref/${encodeURIComponent(`heads/${branch}`)}`);
|
|
179
|
+
headSha = ref.object.sha;
|
|
180
|
+
}
|
|
181
|
+
catch (err) {
|
|
182
|
+
if (err instanceof GitHubError && err.status === 404)
|
|
183
|
+
return { removed: [], kept: [] };
|
|
184
|
+
throw err;
|
|
185
|
+
}
|
|
186
|
+
const commit = await gh.request('GET', `/repos/${ownerRepo}/git/commits/${headSha}`);
|
|
187
|
+
const tree = await gh.request('GET', `/repos/${ownerRepo}/git/trees/${commit.tree.sha}?recursive=1`);
|
|
188
|
+
const folders = new Map();
|
|
189
|
+
for (const entry of tree.tree) {
|
|
190
|
+
const m = entry.path.match(/^pr-(\d+)\//);
|
|
191
|
+
if (m && entry.type === 'blob') {
|
|
192
|
+
const n = Number(m[1]);
|
|
193
|
+
const list = folders.get(n);
|
|
194
|
+
if (list)
|
|
195
|
+
list.push(entry.path);
|
|
196
|
+
else
|
|
197
|
+
folders.set(n, [entry.path]);
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
const cutoff = Date.now() - olderThanDays * 86_400_000;
|
|
201
|
+
const removed = [];
|
|
202
|
+
const kept = [];
|
|
203
|
+
const deletions = [];
|
|
204
|
+
const entries = Array.from(folders.entries()).sort((a, b) => a[0] - b[0]);
|
|
205
|
+
const staleFlags = await mapLimit(entries, 6, async ([n]) => {
|
|
206
|
+
try {
|
|
207
|
+
const pr = await getPr(gh, ownerRepo, n);
|
|
208
|
+
const closedAt = pr.merged_at || pr.closed_at;
|
|
209
|
+
return pr.state === 'closed' && Boolean(closedAt) && new Date(closedAt).getTime() < cutoff;
|
|
210
|
+
}
|
|
211
|
+
catch (err) {
|
|
212
|
+
if (err instanceof GitHubError && err.status === 404)
|
|
213
|
+
return true;
|
|
214
|
+
throw err;
|
|
215
|
+
}
|
|
216
|
+
});
|
|
217
|
+
entries.forEach(([n, paths], i) => {
|
|
218
|
+
if (staleFlags[i]) {
|
|
219
|
+
removed.push(`pr-${n}`);
|
|
220
|
+
deletions.push(...paths);
|
|
221
|
+
}
|
|
222
|
+
else {
|
|
223
|
+
kept.push(`pr-${n}`);
|
|
224
|
+
}
|
|
225
|
+
});
|
|
226
|
+
if (dryRun || deletions.length === 0)
|
|
227
|
+
return { removed, kept };
|
|
228
|
+
const newTree = await gh.request('POST', `/repos/${ownerRepo}/git/trees`, {
|
|
229
|
+
base_tree: commit.tree.sha,
|
|
230
|
+
tree: deletions.map(p => ({ path: p, mode: '100644', type: 'blob', sha: null })),
|
|
231
|
+
});
|
|
232
|
+
const newCommit = await gh.request('POST', `/repos/${ownerRepo}/git/commits`, {
|
|
233
|
+
message: `Prune screenshots for ${removed.length} closed PR(s)`,
|
|
234
|
+
tree: newTree.sha,
|
|
235
|
+
parents: [headSha],
|
|
236
|
+
});
|
|
237
|
+
await gh.request('PATCH', `/repos/${ownerRepo}/git/refs/${encodeURIComponent(`heads/${branch}`)}`, { sha: newCommit.sha });
|
|
238
|
+
return { removed, kept, sha: newCommit.sha };
|
|
239
|
+
}
|
|
240
|
+
//# sourceMappingURL=github.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"github.js","sourceRoot":"","sources":["../src/github.ts"],"names":[],"mappings":"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"}
|