binary-collections 2.0.10 → 2.0.11
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/.puppeterrc.cjs +25 -0
- package/binaries/binary-executor.cjs +138 -3
- package/binaries/clean-nodemodule.cjs +138 -3
- package/binaries/clean-nodemodules.cjs +138 -3
- package/binaries/dev.cjs +138 -3
- package/binaries/empty.cjs +138 -3
- package/binaries/git-reduce-size.cjs +138 -3
- package/binaries/javakill.cjs +138 -3
- package/binaries/kill-night-crows.bat +7 -0
- package/binaries/kill-night-crows.ps1 +172 -0
- package/binaries/kill-process.cjs +138 -3
- package/binaries/nodekill.cjs +138 -3
- package/binaries/prod.cjs +138 -3
- package/binaries/py +111 -0
- package/binaries/py.cjs +178 -0
- package/binaries/py.cmd +49 -0
- package/binaries/rmfind.cjs +138 -3
- package/binaries/rmx.cjs +138 -3
- package/binaries/submodule-token.cjs +138 -3
- package/binaries/test-cjs +10 -0
- package/binaries/test-cjs.cjs +178 -0
- package/binaries/test-cjs.cmd +11 -0
- package/binaries/yarn-clean +32 -0
- package/binaries/yarn-clean.cjs +178 -0
- package/binaries/yarn-clean.cmd +30 -0
- package/binaries/yarn-clean.py +148 -0
- package/lib/binary-collections-config.cjs +1 -1
- package/lib/binary-collections-config.mjs +1 -1
- package/lib/binary-collections.cjs +167 -106
- package/lib/binary-collections.mjs +108 -94
- package/lib/changelog.cjs +61 -13
- package/lib/changelog.mjs +1 -1
- package/lib/{chunk-AI4CVPJ7.mjs → chunk-2CBJCW7E.mjs} +4 -4
- package/lib/chunk-34IQDTLZ.mjs +27 -0
- package/lib/chunk-3HFFECCI.mjs +27 -0
- package/lib/{chunk-SBNDSKG5.mjs → chunk-4UHL4WVN.mjs} +1 -1
- package/lib/chunk-7XTEJHOE.mjs +193 -0
- package/lib/chunk-AJDD5DZM.mjs +109 -0
- package/lib/chunk-BZWVHODJ.mjs +62 -0
- package/lib/{chunk-BEZKJ25G.mjs → chunk-FCDQGYBF.mjs} +5 -9
- package/lib/chunk-GEYA2USY.mjs +207 -0
- package/lib/chunk-ID2WBTE2.mjs +80 -0
- package/lib/chunk-JXFOHKDM.mjs +239 -0
- package/lib/{chunk-DI5MDPSN.mjs → chunk-N436BNBK.mjs} +192 -64
- package/lib/chunk-NCXAP7AA.mjs +31 -0
- package/lib/chunk-PDN26I7O.mjs +188 -0
- package/lib/{chunk-E6FDDAOO.mjs → chunk-RWLXRTYP.mjs} +1 -1
- package/lib/{chunk-BDCHCWHD.mjs → chunk-TOIVAQF7.mjs} +4 -4
- package/lib/chunk-V5SKYJUB.mjs +136 -0
- package/lib/{chunk-HMRMTYZM.mjs → chunk-WSRETQCA.mjs} +21 -2
- package/lib/chunk-XA3SNBPA.mjs +184 -0
- package/lib/chunk-YYLIQQKF.mjs +31 -0
- package/lib/{chunk-V3N3JEUF.mjs → chunk-Z6JLYU2J.mjs} +60 -13
- package/lib/{chunk-O6SWBEOQ.mjs → chunk-ZDMWBSYF.mjs} +2 -2
- package/lib/clean-github-actions-caches.cjs +63 -15
- package/lib/clean-github-actions-caches.mjs +3 -3
- package/lib/del-gradle.cjs +61 -13
- package/lib/del-gradle.js +1 -0
- package/lib/del-gradle.mjs +1 -1
- package/lib/del-node-modules.cjs +143 -148
- package/lib/del-node-modules.js +210 -14
- package/lib/del-node-modules.mjs +148 -17
- package/lib/del-ps.cjs +61 -13
- package/lib/del-ps.js +1 -0
- package/lib/del-ps.mjs +1 -1
- package/lib/del-yarn-caches.cjs +61 -13
- package/lib/del-yarn-caches.mjs +1 -1
- package/lib/find-node-modules-cli.js +1 -0
- package/lib/free-chatgpt.cjs +253 -47
- package/lib/free-chatgpt.mjs +2 -2
- package/lib/git/gitattributes.cjs +1 -0
- package/lib/git/gitattributes.d.cts +7 -2
- package/lib/git/gitattributes.mjs +1 -1
- package/lib/git/line-endings.cjs +2 -1
- package/lib/git/line-endings.mjs +2 -2
- package/lib/git/undo-commit-cli.cjs +110 -0
- package/lib/git/undo-commit-cli.d.ts +1 -0
- package/lib/git/undo-commit-cli.js +4 -0
- package/lib/git/undo-commit-cli.mjs +14 -0
- package/lib/git/undo-commit.cjs +81 -0
- package/lib/git/undo-commit.d.cts +1 -0
- package/lib/git/undo-commit.mjs +7 -0
- package/lib/git/undo-staged-cli.cjs +110 -0
- package/lib/git/undo-staged-cli.d.ts +1 -0
- package/lib/git/undo-staged-cli.js +4 -0
- package/lib/git/undo-staged-cli.mjs +14 -0
- package/lib/git/undo-staged.cjs +81 -0
- package/lib/git/undo-staged.d.cts +1 -0
- package/lib/git/undo-staged.mjs +7 -0
- package/lib/git/user-config.cjs +61 -14
- package/lib/git/user-config.mjs +2 -2
- package/lib/git-diff-cli.cjs +255 -49
- package/lib/git-diff-cli.d.ts +1 -0
- package/lib/git-diff-cli.js +1 -0
- package/lib/git-diff-cli.mjs +5 -4
- package/lib/git-diff.cjs +254 -49
- package/lib/git-diff.mjs +4 -4
- package/lib/git-fix.cjs +64 -16
- package/lib/git-fix.mjs +10 -10
- package/lib/git-purge.cjs +61 -13
- package/lib/git-purge.mjs +1 -1
- package/lib/kill-night-crows.cjs +87 -0
- package/lib/kill-night-crows.d.mts +1 -0
- package/lib/kill-night-crows.mjs +65 -0
- package/lib/npm-run-series.cjs +60 -13
- package/lib/npm-run-series.mjs +1 -1
- package/lib/package-resolutions-updater-cli.cjs +560 -0
- package/lib/package-resolutions-updater-cli.d.mts +1 -0
- package/lib/package-resolutions-updater-cli.mjs +124 -0
- package/lib/package-resolutions-updater.cjs +174 -154
- package/lib/package-resolutions-updater.d.mts +32 -1
- package/lib/package-resolutions-updater.mjs +16 -294
- package/lib/php-cs-fixer-staged.cjs +105 -0
- package/lib/php-cs-fixer-staged.d.cts +2 -0
- package/lib/php-cs-fixer-staged.mjs +117 -0
- package/lib/print-directory-tree.cjs +62 -14
- package/lib/print-directory-tree.mjs +2 -2
- package/lib/ps/connected-domain.d.ts +1 -1
- package/lib/ps/index.js +1 -0
- package/lib/remove-module.cjs +61 -13
- package/lib/remove-module.mjs +1 -1
- package/lib/rmpath.cjs +63 -15
- package/lib/rmpath.mjs +2 -2
- package/lib/submodule-install.cjs +62 -15
- package/lib/submodule-install.mjs +3 -3
- package/lib/submodule-remove-cli.cjs +5 -1
- package/lib/submodule-remove-cli.mjs +1 -1
- package/lib/submodule-remove.cjs +4 -1
- package/lib/submodule-remove.mjs +1 -1
- package/lib/utils/chatgpt.cjs +192 -34
- package/lib/utils/chatgpt.js +210 -43
- package/lib/utils/chatgpt.mjs +1 -1
- package/lib/utils/findEnvFiles.cjs +107 -0
- package/lib/utils/findEnvFiles.d.ts +8 -0
- package/lib/utils/findEnvFiles.js +121 -0
- package/lib/utils/findEnvFiles.mjs +8 -0
- package/lib/utils/findWorkspaceRoot.cjs +70 -0
- package/lib/utils/findWorkspaceRoot.d.ts +9 -0
- package/lib/utils/findWorkspaceRoot.js +57 -0
- package/lib/utils/findWorkspaceRoot.mjs +40 -0
- package/lib/utils/index.cjs +60 -13
- package/lib/utils/index.mjs +1 -1
- package/lib/utils/isGithubTokenValid.cjs +64 -0
- package/lib/utils/isGithubTokenValid.d.ts +7 -0
- package/lib/utils/isGithubTokenValid.js +48 -0
- package/lib/utils/isGithubTokenValid.mjs +36 -0
- package/lib/yarn-reinstall.cjs +61 -13
- package/lib/yarn-reinstall.mjs +1 -1
- package/package.json +107 -93
- package/readme.md +33 -34
- package/releases/readme.md +1 -1
- package/requirements.txt +1 -0
- package/lib/chunk-4EWQC6GZ.mjs +0 -382
- package/lib/chunk-4ZI7BQKQ.mjs +0 -381
- package/lib/chunk-5J2BEPY5.mjs +0 -83
- package/lib/chunk-AGZYRDC2.mjs +0 -323
- package/lib/chunk-HN52G2YL.mjs +0 -305
- package/lib/chunk-HO6GHCOB.mjs +0 -385
- package/lib/chunk-LEM5OMRP.mjs +0 -384
- package/lib/chunk-RCP7DHVY.mjs +0 -190
- package/lib/chunk-U6SO4QEV.mjs +0 -320
- package/lib/chunk-XD6BJK6Q.mjs +0 -351
- package/lib/chunk-YXSFGA2D.mjs +0 -383
- package/lib/git/gitattributes.d.ts +0 -33
- package/lib/git/gitattributes.js +0 -223
|
@@ -0,0 +1,239 @@
|
|
|
1
|
+
import { createRequire } from 'module'; const require = createRequire(import.meta.url);
|
|
2
|
+
import {
|
|
3
|
+
findEnvFiles
|
|
4
|
+
} from "./chunk-ID2WBTE2.mjs";
|
|
5
|
+
import {
|
|
6
|
+
require_utils
|
|
7
|
+
} from "./chunk-Z6JLYU2J.mjs";
|
|
8
|
+
import {
|
|
9
|
+
__toESM,
|
|
10
|
+
init_esm_shims
|
|
11
|
+
} from "./chunk-QQ4A6DLD.mjs";
|
|
12
|
+
|
|
13
|
+
// src/package-resolutions-updater.mjs
|
|
14
|
+
init_esm_shims();
|
|
15
|
+
var utils = __toESM(require_utils(), 1);
|
|
16
|
+
import * as dotenv from "dotenv";
|
|
17
|
+
import fs from "fs";
|
|
18
|
+
import https from "https";
|
|
19
|
+
import os from "os";
|
|
20
|
+
import path from "path";
|
|
21
|
+
var projectDir = process.cwd();
|
|
22
|
+
var envPath = path.join(projectDir, ".env");
|
|
23
|
+
var args = utils.getArgs();
|
|
24
|
+
if (!fs.existsSync(envPath)) {
|
|
25
|
+
const envFiles = findEnvFiles(projectDir, (file) => {
|
|
26
|
+
const content = fs.readFileSync(file, "utf-8");
|
|
27
|
+
return /GITHUB_TOKEN|ACCESS_TOKEN/.test(content);
|
|
28
|
+
});
|
|
29
|
+
if (envFiles.length > 0) {
|
|
30
|
+
envPath = envFiles[0];
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
if (fs.existsSync(envPath)) {
|
|
34
|
+
dotenv.config({ path: envPath, quiet: true, override: true });
|
|
35
|
+
}
|
|
36
|
+
var ACCESS_TOKEN = process.env.GITHUB_TOKEN || process.env.ACCESS_TOKEN;
|
|
37
|
+
if (args.help || args.h) {
|
|
38
|
+
showHelp();
|
|
39
|
+
}
|
|
40
|
+
function showHelp() {
|
|
41
|
+
const helpText = `
|
|
42
|
+
GitHub Package Resolutions Updater
|
|
43
|
+
Usage:
|
|
44
|
+
node src/package-resolutions-updater.mjs [options]
|
|
45
|
+
Options:
|
|
46
|
+
--help, -h Show this help message
|
|
47
|
+
Description:
|
|
48
|
+
Updates the commit hashes in package.json's 'resolutions' field for GitHub tarball URLs to point to the latest commit SHA of the corresponding repository and branch.
|
|
49
|
+
Features:
|
|
50
|
+
- Parses GitHub URLs to extract repository owner, name, and branch.
|
|
51
|
+
- Fetches the latest commit SHA across all branches using GitHub's API.
|
|
52
|
+
- Replaces the old branch or commit in the URL with the latest SHA.
|
|
53
|
+
- Overwrites package.json with the updated URLs.
|
|
54
|
+
Requirements:
|
|
55
|
+
- GitHub Personal Access Token (GITHUB_TOKEN) via .env
|
|
56
|
+
- ESM support (type: "module" in package.json)
|
|
57
|
+
- Node.js v18+ recommended
|
|
58
|
+
Dependencies:
|
|
59
|
+
- ansi-colors \u2013 for styled terminal output
|
|
60
|
+
- dotenv \u2013 to load GitHub token from .env
|
|
61
|
+
Examples:
|
|
62
|
+
node src/package-resolutions-updater.mjs
|
|
63
|
+
node src/package-resolutions-updater.mjs --help
|
|
64
|
+
|
|
65
|
+
`;
|
|
66
|
+
console.log(helpText);
|
|
67
|
+
process.exit(0);
|
|
68
|
+
}
|
|
69
|
+
var GITHUB_USER_AGENTS = [
|
|
70
|
+
"octokit-rest.js/19.0.7",
|
|
71
|
+
"GitHub CLI/2.40.0",
|
|
72
|
+
"Mozilla/5.0 (compatible; GitHubCopilot/1.0)",
|
|
73
|
+
"PostmanRuntime/7.32.3",
|
|
74
|
+
"binary-collections-resolver/1.0 (+https://github.com/dimaslanjaka/bin)"
|
|
75
|
+
];
|
|
76
|
+
var userAgentDir = path.join(os.tmpdir(), "nodejs");
|
|
77
|
+
var userAgentFile = path.join(userAgentDir, "useragent.txt");
|
|
78
|
+
var selectedUserAgent;
|
|
79
|
+
try {
|
|
80
|
+
if (!fs.existsSync(userAgentDir)) fs.mkdirSync(userAgentDir, { recursive: true });
|
|
81
|
+
if (fs.existsSync(userAgentFile)) {
|
|
82
|
+
const fileAgent = fs.readFileSync(userAgentFile, "utf-8").trim();
|
|
83
|
+
if (GITHUB_USER_AGENTS.includes(fileAgent)) {
|
|
84
|
+
selectedUserAgent = fileAgent;
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
if (!selectedUserAgent) {
|
|
88
|
+
selectedUserAgent = GITHUB_USER_AGENTS[Math.floor(Math.random() * GITHUB_USER_AGENTS.length)];
|
|
89
|
+
fs.writeFileSync(userAgentFile, selectedUserAgent, "utf-8");
|
|
90
|
+
}
|
|
91
|
+
} catch (_e) {
|
|
92
|
+
selectedUserAgent = GITHUB_USER_AGENTS[Math.floor(Math.random() * GITHUB_USER_AGENTS.length)];
|
|
93
|
+
}
|
|
94
|
+
function fetchJson(url) {
|
|
95
|
+
const headers = {
|
|
96
|
+
"User-Agent": selectedUserAgent,
|
|
97
|
+
Accept: "application/vnd.github.v3+json",
|
|
98
|
+
"X-GitHub-Api-Version": "2022-11-28",
|
|
99
|
+
...ACCESS_TOKEN ? { Authorization: `token ${ACCESS_TOKEN}` } : {}
|
|
100
|
+
};
|
|
101
|
+
return new Promise((resolve, reject) => {
|
|
102
|
+
https.get(url, { headers }, (res) => {
|
|
103
|
+
let data = "";
|
|
104
|
+
res.on("data", (chunk) => data += chunk);
|
|
105
|
+
res.on("end", () => {
|
|
106
|
+
try {
|
|
107
|
+
const json = JSON.parse(data);
|
|
108
|
+
if (res.statusCode < 200 || res.statusCode >= 300) {
|
|
109
|
+
return reject(
|
|
110
|
+
new Error(`GitHub API Error ${res.statusCode}: ${json.message || "Unknown error"}
|
|
111
|
+
URL: ${url}`)
|
|
112
|
+
);
|
|
113
|
+
}
|
|
114
|
+
resolve(json);
|
|
115
|
+
} catch {
|
|
116
|
+
reject(new Error(`Invalid JSON from: ${url}`));
|
|
117
|
+
}
|
|
118
|
+
});
|
|
119
|
+
}).on("error", reject);
|
|
120
|
+
});
|
|
121
|
+
}
|
|
122
|
+
async function getLatestCommit(owner, repo, branch = "main") {
|
|
123
|
+
var _a, _b, _c, _d;
|
|
124
|
+
const url = `https://api.github.com/repos/${owner}/${repo}/commits/${branch}`;
|
|
125
|
+
const json = await fetchJson(url);
|
|
126
|
+
const sha = json.sha;
|
|
127
|
+
const dateStr = ((_b = (_a = json.commit) == null ? void 0 : _a.committer) == null ? void 0 : _b.date) || ((_d = (_c = json.commit) == null ? void 0 : _c.author) == null ? void 0 : _d.date);
|
|
128
|
+
if (!sha || !dateStr) {
|
|
129
|
+
console.log(json);
|
|
130
|
+
throw new Error(`Missing SHA or date for ${owner}/${repo}@${branch}`);
|
|
131
|
+
}
|
|
132
|
+
return {
|
|
133
|
+
owner,
|
|
134
|
+
repo,
|
|
135
|
+
branch,
|
|
136
|
+
sha,
|
|
137
|
+
date: new Date(dateStr).toISOString()
|
|
138
|
+
};
|
|
139
|
+
}
|
|
140
|
+
async function getLatestCommitAcrossBranches(owner, repo) {
|
|
141
|
+
const branches = await fetchJson(`https://api.github.com/repos/${owner}/${repo}/branches`);
|
|
142
|
+
const commits = await Promise.all(
|
|
143
|
+
branches.map(async ({ name, commit }) => {
|
|
144
|
+
var _a, _b, _c, _d;
|
|
145
|
+
const commitSha = commit == null ? void 0 : commit.sha;
|
|
146
|
+
if (!commitSha) {
|
|
147
|
+
console.warn(`No commit SHA for '${owner}/${repo}' branch: ${name}`);
|
|
148
|
+
return { branch: name, sha: "", date: /* @__PURE__ */ new Date(0) };
|
|
149
|
+
}
|
|
150
|
+
try {
|
|
151
|
+
const commitData = await fetchJson(`https://api.github.com/repos/${owner}/${repo}/commits/${commitSha}`);
|
|
152
|
+
const dateStr = ((_b = (_a = commitData.commit) == null ? void 0 : _a.committer) == null ? void 0 : _b.date) || ((_d = (_c = commitData.commit) == null ? void 0 : _c.author) == null ? void 0 : _d.date);
|
|
153
|
+
const date = dateStr ? new Date(dateStr) : /* @__PURE__ */ new Date(0);
|
|
154
|
+
return { branch: name, sha: commitData.sha, date };
|
|
155
|
+
} catch (e) {
|
|
156
|
+
console.warn(`Failed to fetch commit for ${name}: ${e.message}`);
|
|
157
|
+
return { branch: name, sha: commitSha, date: /* @__PURE__ */ new Date(0) };
|
|
158
|
+
}
|
|
159
|
+
})
|
|
160
|
+
);
|
|
161
|
+
const latest = commits.reduce((a, b) => a.date > b.date ? a : b, { date: /* @__PURE__ */ new Date(0) });
|
|
162
|
+
return {
|
|
163
|
+
owner,
|
|
164
|
+
repo,
|
|
165
|
+
branch: latest.branch,
|
|
166
|
+
sha: latest.sha,
|
|
167
|
+
date: latest.date.toISOString()
|
|
168
|
+
};
|
|
169
|
+
}
|
|
170
|
+
function replaceRawWithLatestHash(url, latestHash) {
|
|
171
|
+
const match = url.match(/^https:\/\/github\.com\/([^/]+)\/([^/]+)\/raw\/([^/]+)\/(.+)$/);
|
|
172
|
+
if (!match) throw new Error("Invalid GitHub raw URL");
|
|
173
|
+
const [, owner, repo, _oldHash, path2] = match;
|
|
174
|
+
return `https://github.com/${owner}/${repo}/raw/${latestHash}/${path2}`;
|
|
175
|
+
}
|
|
176
|
+
function splitGitHubRefPath(refPath) {
|
|
177
|
+
const segments = refPath.split("/").filter(Boolean);
|
|
178
|
+
if (segments.length === 0) {
|
|
179
|
+
return { branch: "", remainder: null };
|
|
180
|
+
}
|
|
181
|
+
if (segments[0] === "refs" && segments[1] === "heads" && segments.length >= 3) {
|
|
182
|
+
return {
|
|
183
|
+
branch: segments[2],
|
|
184
|
+
remainder: segments.slice(3).join("/") || null
|
|
185
|
+
};
|
|
186
|
+
}
|
|
187
|
+
let branchSegmentCount = 1;
|
|
188
|
+
if (segments[0] === "refs") {
|
|
189
|
+
if ((segments[1] === "tags" || segments[1] === "remotes" || segments[1] === "pull") && segments.length >= 3) {
|
|
190
|
+
branchSegmentCount = segments[1] === "tags" ? 3 : 4;
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
const branch = segments.slice(0, branchSegmentCount).join("/");
|
|
194
|
+
const remainder = segments.slice(branchSegmentCount).join("/");
|
|
195
|
+
return {
|
|
196
|
+
branch,
|
|
197
|
+
remainder: remainder || null
|
|
198
|
+
};
|
|
199
|
+
}
|
|
200
|
+
function parseGitHubUrl(url) {
|
|
201
|
+
const ghRepoRoot = /^https:\/\/github\.com\/([^/]+)\/([^/]+)\/?$/;
|
|
202
|
+
const ghTreeOrBlob = /^https:\/\/github\.com\/([^/]+)\/([^/]+)\/(tree|blob)\/([^/]+(?:\/[^/]+)*)/;
|
|
203
|
+
const ghRaw = /^https:\/\/raw\.githubusercontent\.com\/([^/]+)\/([^/]+)\/(.+)$/;
|
|
204
|
+
const ghDotComRaw = /^https:\/\/github\.com\/([^/]+)\/([^/]+)\/raw\/(.+)$/;
|
|
205
|
+
let match;
|
|
206
|
+
if (match = url.match(ghRaw)) {
|
|
207
|
+
const [, owner, repo, rawPath] = match;
|
|
208
|
+
const { branch, remainder } = splitGitHubRefPath(rawPath);
|
|
209
|
+
return {
|
|
210
|
+
owner,
|
|
211
|
+
repo,
|
|
212
|
+
branch,
|
|
213
|
+
url: `https://raw.githubusercontent.com/${owner}/${repo}/${branch}${remainder ? `/${remainder}` : ""}`
|
|
214
|
+
};
|
|
215
|
+
}
|
|
216
|
+
if (match = url.match(ghDotComRaw)) {
|
|
217
|
+
const [, owner, repo, rawPath] = match;
|
|
218
|
+
const { branch } = splitGitHubRefPath(rawPath);
|
|
219
|
+
return { owner, repo, branch, url };
|
|
220
|
+
}
|
|
221
|
+
if (match = url.match(ghTreeOrBlob)) {
|
|
222
|
+
const [, owner, repo, , branchPath] = match;
|
|
223
|
+
const { branch } = splitGitHubRefPath(branchPath);
|
|
224
|
+
return { owner, repo, branch, url };
|
|
225
|
+
}
|
|
226
|
+
if (match = url.match(ghRepoRoot)) {
|
|
227
|
+
const [, owner, repo] = match;
|
|
228
|
+
return { owner, repo, url };
|
|
229
|
+
}
|
|
230
|
+
throw new Error(`Unsupported GitHub URL: ${url}`);
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
export {
|
|
234
|
+
fetchJson,
|
|
235
|
+
getLatestCommit,
|
|
236
|
+
getLatestCommitAcrossBranches,
|
|
237
|
+
replaceRawWithLatestHash,
|
|
238
|
+
parseGitHubUrl
|
|
239
|
+
};
|
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
import { createRequire } from 'module'; const require = createRequire(import.meta.url);
|
|
2
2
|
import {
|
|
3
|
-
__filename,
|
|
4
|
-
__require,
|
|
5
3
|
init_esm_shims
|
|
6
4
|
} from "./chunk-QQ4A6DLD.mjs";
|
|
7
5
|
|
|
@@ -11,10 +9,19 @@ import fs from "fs-extra";
|
|
|
11
9
|
import puppeteer from "puppeteer-extra";
|
|
12
10
|
import StealthPlugin from "puppeteer-extra-plugin-stealth";
|
|
13
11
|
import path from "upath";
|
|
14
|
-
import { pathToFileURL } from "url";
|
|
15
12
|
var COOKIE_DIR = path.join(process.cwd(), "tmp", "cookies");
|
|
16
13
|
var DEFAULT_COOKIE_PATH = path.join(COOKIE_DIR, "cookies.json");
|
|
14
|
+
var NAVIGATION_TIMEOUT_MS = 9e4;
|
|
15
|
+
var NETWORK_IDLE_TIMEOUT_MS = 15e3;
|
|
16
|
+
var MAX_INLINE_QUESTION_FILE_BYTES = 2 * 1024;
|
|
17
17
|
fs.ensureDirSync(COOKIE_DIR);
|
|
18
|
+
async function gotoWithFallback(page, url) {
|
|
19
|
+
await page.goto(url, { waitUntil: "domcontentloaded", timeout: NAVIGATION_TIMEOUT_MS });
|
|
20
|
+
try {
|
|
21
|
+
await page.waitForNetworkIdle({ idleTime: 1e3, timeout: NETWORK_IDLE_TIMEOUT_MS });
|
|
22
|
+
} catch {
|
|
23
|
+
}
|
|
24
|
+
}
|
|
18
25
|
async function saveCookies(page, path2 = DEFAULT_COOKIE_PATH) {
|
|
19
26
|
const cookies = await page.cookies();
|
|
20
27
|
fs.writeFileSync(path2, JSON.stringify(cookies, null, 2));
|
|
@@ -33,7 +40,7 @@ async function navigatePage(page, url) {
|
|
|
33
40
|
if (cookies) {
|
|
34
41
|
await page.setCookie(...cookies);
|
|
35
42
|
}
|
|
36
|
-
await page
|
|
43
|
+
await gotoWithFallback(page, url);
|
|
37
44
|
await page.evaluate(() => {
|
|
38
45
|
window.__domStillUpdating = true;
|
|
39
46
|
if (window.__domObserver) {
|
|
@@ -73,46 +80,151 @@ function loadCookies(cookieFilePath = DEFAULT_COOKIE_PATH) {
|
|
|
73
80
|
return JSON.parse(fs.readFileSync(cookieFilePath));
|
|
74
81
|
}
|
|
75
82
|
async function writeQuestion(page, question) {
|
|
76
|
-
const questions = question.split("\n");
|
|
77
83
|
const promptTextarea = await page.waitForSelector("#prompt-textarea", { timeout: 3e4 });
|
|
78
84
|
if (!promptTextarea) {
|
|
79
85
|
console.log(
|
|
80
86
|
"Cannot find the prompt input on the webpage. Please check whether you have access to chat.openai.com without logging in via your browser."
|
|
81
87
|
);
|
|
82
|
-
}
|
|
83
|
-
await page.evaluate(() => {
|
|
84
|
-
document.querySelector("#prompt-textarea").innerHTML = `<p></p>`;
|
|
85
|
-
});
|
|
86
|
-
if (questions.length === 1) {
|
|
87
|
-
await page.type("#prompt-textarea", questions[0], { delay: 100 });
|
|
88
88
|
return;
|
|
89
89
|
}
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
if (
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
90
|
+
await page.evaluate((text) => {
|
|
91
|
+
const promptEl = document.querySelector("#prompt-textarea");
|
|
92
|
+
if (!promptEl) {
|
|
93
|
+
return;
|
|
94
|
+
}
|
|
95
|
+
promptEl.focus();
|
|
96
|
+
promptEl.innerHTML = "";
|
|
97
|
+
const lines = String(text).split("\n");
|
|
98
|
+
for (const line of lines) {
|
|
99
|
+
const p = document.createElement("p");
|
|
100
|
+
p.textContent = line;
|
|
101
|
+
promptEl.appendChild(p);
|
|
96
102
|
}
|
|
103
|
+
promptEl.dispatchEvent(new InputEvent("beforeinput", { bubbles: true, inputType: "insertFromPaste", data: text }));
|
|
104
|
+
promptEl.dispatchEvent(new InputEvent("input", { bubbles: true, inputType: "insertFromPaste", data: text }));
|
|
105
|
+
promptEl.dispatchEvent(new Event("change", { bubbles: true }));
|
|
106
|
+
}, question);
|
|
107
|
+
const hasPromptText = await page.evaluate(() => {
|
|
108
|
+
const promptEl = document.querySelector("#prompt-textarea");
|
|
109
|
+
return Boolean(promptEl && promptEl.textContent && promptEl.textContent.trim().length > 0);
|
|
110
|
+
});
|
|
111
|
+
if (!hasPromptText) {
|
|
112
|
+
console.log("Prompt state not updated by DOM injection. Falling back to keyboard insertText.");
|
|
113
|
+
await promptTextarea.click({ clickCount: 1 });
|
|
114
|
+
await page.keyboard.down("Control");
|
|
115
|
+
await page.keyboard.press("KeyA");
|
|
116
|
+
await page.keyboard.up("Control");
|
|
117
|
+
await page.keyboard.insertText(question);
|
|
97
118
|
}
|
|
98
119
|
}
|
|
99
120
|
async function clickSubmitButton(page) {
|
|
121
|
+
console.log("Attempting to click the submit button...");
|
|
100
122
|
try {
|
|
101
|
-
const
|
|
102
|
-
|
|
123
|
+
const userMessageCountBefore = await page.$$eval('[data-message-author-role="user"]', (elements) => elements.length);
|
|
124
|
+
const waitForSubmit = async (timeout = 5e3) => {
|
|
125
|
+
try {
|
|
126
|
+
await page.waitForFunction(
|
|
127
|
+
(previousCount) => {
|
|
128
|
+
const currentCount = document.querySelectorAll('[data-message-author-role="user"]').length;
|
|
129
|
+
return currentCount > previousCount;
|
|
130
|
+
},
|
|
131
|
+
{ timeout },
|
|
132
|
+
userMessageCountBefore
|
|
133
|
+
);
|
|
134
|
+
return true;
|
|
135
|
+
} catch {
|
|
136
|
+
return false;
|
|
137
|
+
}
|
|
138
|
+
};
|
|
139
|
+
await page.waitForFunction(() => {
|
|
140
|
+
const candidates = [
|
|
141
|
+
document.querySelector('[data-testid="fruitjuice-send-button"]'),
|
|
142
|
+
document.querySelector("#composer-submit-button"),
|
|
143
|
+
document.querySelector('[data-testid="send-button"]')
|
|
144
|
+
].filter(Boolean);
|
|
145
|
+
return candidates.some((button) => {
|
|
146
|
+
const isDisabled = button.disabled || button.getAttribute("aria-disabled") === "true";
|
|
147
|
+
const isVisible = button.offsetParent !== null;
|
|
148
|
+
return !isDisabled && isVisible;
|
|
149
|
+
});
|
|
150
|
+
}, { timeout: 5e3 }).catch(() => {
|
|
151
|
+
});
|
|
152
|
+
const buttonDetails = await page.evaluate(() => {
|
|
153
|
+
const selectors = [
|
|
154
|
+
'[data-testid="fruitjuice-send-button"]',
|
|
155
|
+
"#composer-submit-button",
|
|
156
|
+
'[data-testid="send-button"]'
|
|
157
|
+
];
|
|
158
|
+
const details = selectors.map((selector) => {
|
|
159
|
+
const el = document.querySelector(selector);
|
|
160
|
+
const exists = Boolean(el);
|
|
161
|
+
const disabled = exists ? Boolean(el.disabled || el.getAttribute("aria-disabled") === "true") : null;
|
|
162
|
+
const visible = exists ? el.offsetParent !== null : null;
|
|
163
|
+
return { selector, exists, disabled, visible };
|
|
164
|
+
});
|
|
165
|
+
return details;
|
|
103
166
|
});
|
|
104
|
-
|
|
105
|
-
|
|
167
|
+
console.log(`Submit button details: ${JSON.stringify(buttonDetails)}`);
|
|
168
|
+
const clickable = buttonDetails.find((item) => item.exists && item.visible && item.disabled === false);
|
|
169
|
+
const selectedSelector = clickable ? clickable.selector : null;
|
|
170
|
+
if (selectedSelector) {
|
|
171
|
+
await page.click(selectedSelector);
|
|
172
|
+
console.log(`Clicked submit button selector: ${selectedSelector}`);
|
|
173
|
+
if (await waitForSubmit(5e3)) {
|
|
174
|
+
console.log("Submission detected after selector click.");
|
|
175
|
+
return true;
|
|
176
|
+
}
|
|
177
|
+
const forcedClickWorked = await page.evaluate((selector) => {
|
|
178
|
+
const el = document.querySelector(selector);
|
|
179
|
+
if (!el) {
|
|
180
|
+
return false;
|
|
181
|
+
}
|
|
182
|
+
el.click();
|
|
183
|
+
return true;
|
|
184
|
+
}, selectedSelector);
|
|
185
|
+
if (forcedClickWorked) {
|
|
186
|
+
console.log(`Forced DOM click on selector: ${selectedSelector}`);
|
|
187
|
+
if (await waitForSubmit(5e3)) {
|
|
188
|
+
console.log("Submission detected after forced DOM click.");
|
|
189
|
+
return true;
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
console.log("Submit button path did not submit. Trying Enter key fallback on prompt.");
|
|
194
|
+
await page.focus("#prompt-textarea");
|
|
195
|
+
await page.keyboard.press("Enter");
|
|
196
|
+
if (await waitForSubmit(5e3)) {
|
|
197
|
+
console.log("Submission detected after Enter key fallback.");
|
|
198
|
+
return true;
|
|
199
|
+
}
|
|
200
|
+
const didRequestSubmit = await page.evaluate(() => {
|
|
201
|
+
const prompt = document.querySelector("#prompt-textarea");
|
|
202
|
+
if (!prompt) {
|
|
203
|
+
return false;
|
|
204
|
+
}
|
|
205
|
+
const form = prompt.closest("form");
|
|
206
|
+
if (!form) {
|
|
207
|
+
return false;
|
|
208
|
+
}
|
|
209
|
+
if (typeof form.requestSubmit === "function") {
|
|
210
|
+
form.requestSubmit();
|
|
211
|
+
} else {
|
|
212
|
+
form.submit();
|
|
213
|
+
}
|
|
214
|
+
return true;
|
|
106
215
|
});
|
|
107
|
-
if (
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
216
|
+
if (didRequestSubmit) {
|
|
217
|
+
console.log("Triggered form submit fallback.");
|
|
218
|
+
if (await waitForSubmit(5e3)) {
|
|
219
|
+
console.log("Submission detected after form submit fallback.");
|
|
220
|
+
return true;
|
|
221
|
+
}
|
|
113
222
|
}
|
|
223
|
+
console.log("Failed to submit prompt after all strategies.");
|
|
224
|
+
return false;
|
|
114
225
|
} catch (e) {
|
|
115
226
|
console.log(`Failed to click the send button: ${e}`);
|
|
227
|
+
return false;
|
|
116
228
|
}
|
|
117
229
|
}
|
|
118
230
|
var lastMessageId = null;
|
|
@@ -185,11 +297,15 @@ async function isLoggedIn(page) {
|
|
|
185
297
|
return result === true;
|
|
186
298
|
}
|
|
187
299
|
async function createBrowser(browserOptions = {}) {
|
|
300
|
+
const windowsChromeExecutable = "C:\\Program Files\\Google\\Chrome\\Application\\chrome.exe";
|
|
301
|
+
const hasWindowsChrome = process.platform === "win32" && fs.existsSync(windowsChromeExecutable);
|
|
188
302
|
const defaultOptions = {
|
|
189
303
|
headless: false,
|
|
304
|
+
defaultViewport: null,
|
|
190
305
|
userDataDir: path.join(process.cwd(), "tmp/puppeteer-profile"),
|
|
191
306
|
// Windows-specific options to handle browser launch issues
|
|
192
307
|
args: [
|
|
308
|
+
"--start-maximized",
|
|
193
309
|
"--no-sandbox",
|
|
194
310
|
"--disable-setuid-sandbox",
|
|
195
311
|
"--disable-dev-shm-usage",
|
|
@@ -202,10 +318,9 @@ async function createBrowser(browserOptions = {}) {
|
|
|
202
318
|
"--disable-renderer-backgrounding"
|
|
203
319
|
],
|
|
204
320
|
ignoreDefaultArgs: ["--disable-extensions"],
|
|
205
|
-
...
|
|
206
|
-
//
|
|
207
|
-
executablePath:
|
|
208
|
-
// Let Puppeteer find Chrome automatically
|
|
321
|
+
...hasWindowsChrome && {
|
|
322
|
+
// Prefer local Chrome installation when present on Windows.
|
|
323
|
+
executablePath: windowsChromeExecutable
|
|
209
324
|
}
|
|
210
325
|
};
|
|
211
326
|
try {
|
|
@@ -215,8 +330,12 @@ async function createBrowser(browserOptions = {}) {
|
|
|
215
330
|
try {
|
|
216
331
|
return await puppeteer.use(StealthPlugin()).launch({
|
|
217
332
|
headless: browserOptions.headless || false,
|
|
218
|
-
|
|
333
|
+
defaultViewport: null,
|
|
334
|
+
args: ["--start-maximized", "--no-sandbox", "--disable-setuid-sandbox"],
|
|
219
335
|
ignoreDefaultArgs: false,
|
|
336
|
+
...hasWindowsChrome && {
|
|
337
|
+
executablePath: windowsChromeExecutable
|
|
338
|
+
},
|
|
220
339
|
...browserOptions
|
|
221
340
|
});
|
|
222
341
|
} catch (fallbackError) {
|
|
@@ -241,7 +360,11 @@ async function loginToChatGpt() {
|
|
|
241
360
|
if (loginButtonExists) {
|
|
242
361
|
console.log("Login button found, clicking to log in...");
|
|
243
362
|
await page.click('[data-testid="login-button"]');
|
|
244
|
-
await page.waitForNavigation({ waitUntil: "
|
|
363
|
+
await page.waitForNavigation({ waitUntil: "domcontentloaded", timeout: NAVIGATION_TIMEOUT_MS });
|
|
364
|
+
try {
|
|
365
|
+
await page.waitForNetworkIdle({ idleTime: 1e3, timeout: NETWORK_IDLE_TIMEOUT_MS });
|
|
366
|
+
} catch {
|
|
367
|
+
}
|
|
245
368
|
console.log("Login process completed.");
|
|
246
369
|
} else {
|
|
247
370
|
console.log("No login required - user appears to be already logged in.");
|
|
@@ -251,6 +374,7 @@ async function runChatGpt(chatgptOptions = {}) {
|
|
|
251
374
|
const headless = chatgptOptions.headless !== void 0 ? chatgptOptions.headless : true;
|
|
252
375
|
const questionFile = chatgptOptions.questionFile;
|
|
253
376
|
let question = chatgptOptions.question;
|
|
377
|
+
let shouldUploadQuestionFile = Boolean(questionFile);
|
|
254
378
|
const responseFile = chatgptOptions.responseFile || path.join(process.cwd(), "tmp", "response.txt");
|
|
255
379
|
const noInputProvided = !question && !questionFile;
|
|
256
380
|
const questionIsEmpty = question && question.trim().length === 0;
|
|
@@ -258,6 +382,22 @@ async function runChatGpt(chatgptOptions = {}) {
|
|
|
258
382
|
if (noInputProvided || questionIsEmpty || questionFileIsEmpty) {
|
|
259
383
|
throw new Error("You must provide a question or a question file.");
|
|
260
384
|
}
|
|
385
|
+
if (!question && questionFile) {
|
|
386
|
+
if (!fs.existsSync(questionFile)) {
|
|
387
|
+
throw new Error(`Question file does not exist: ${questionFile}`);
|
|
388
|
+
}
|
|
389
|
+
const questionFileStats = fs.statSync(questionFile);
|
|
390
|
+
if (questionFileStats.size <= MAX_INLINE_QUESTION_FILE_BYTES) {
|
|
391
|
+
question = fs.readFileSync(questionFile, "utf8").trim();
|
|
392
|
+
if (!question) {
|
|
393
|
+
throw new Error("Question file is empty.");
|
|
394
|
+
}
|
|
395
|
+
shouldUploadQuestionFile = false;
|
|
396
|
+
console.log(
|
|
397
|
+
`Question file is ${questionFileStats.size} bytes (<= ${MAX_INLINE_QUESTION_FILE_BYTES}). Sending as text prompt.`
|
|
398
|
+
);
|
|
399
|
+
}
|
|
400
|
+
}
|
|
261
401
|
let browser;
|
|
262
402
|
try {
|
|
263
403
|
browser = await createBrowser({ headless });
|
|
@@ -270,7 +410,16 @@ async function runChatGpt(chatgptOptions = {}) {
|
|
|
270
410
|
console.error("4. Close any running Chrome instances and try again");
|
|
271
411
|
throw error;
|
|
272
412
|
}
|
|
273
|
-
const
|
|
413
|
+
const allPages = await browser.pages();
|
|
414
|
+
const page = allPages.length > 0 ? allPages[0] : await browser.newPage();
|
|
415
|
+
await page.bringToFront();
|
|
416
|
+
if (allPages.length > 1) {
|
|
417
|
+
for (const p of allPages) {
|
|
418
|
+
if (p !== page) {
|
|
419
|
+
await p.close();
|
|
420
|
+
}
|
|
421
|
+
}
|
|
422
|
+
}
|
|
274
423
|
try {
|
|
275
424
|
const url = "https://chat.openai.com";
|
|
276
425
|
const navigate = await navigatePage(page, url);
|
|
@@ -289,12 +438,15 @@ async function runChatGpt(chatgptOptions = {}) {
|
|
|
289
438
|
}
|
|
290
439
|
if (question) {
|
|
291
440
|
await writeQuestion(page, question);
|
|
292
|
-
await clickSubmitButton(page);
|
|
441
|
+
const didSubmit = await clickSubmitButton(page);
|
|
442
|
+
if (!didSubmit) {
|
|
443
|
+
throw new Error("Prompt was not submitted. The composer button may be disabled or blocked.");
|
|
444
|
+
}
|
|
293
445
|
await navigate.waitForDomIdle(1e3, 3e4);
|
|
294
446
|
await waitForInitialResponse(page);
|
|
295
447
|
await handleStreamingResponse(page, responseFile);
|
|
296
448
|
await saveCookies(page, getCookiePathForUrl(url));
|
|
297
|
-
} else if (questionFile) {
|
|
449
|
+
} else if (shouldUploadQuestionFile && questionFile) {
|
|
298
450
|
await navigate.waitForDomIdle(2e3, 1e4);
|
|
299
451
|
const isUserLoggedIn = await isLoggedIn(page);
|
|
300
452
|
console.log(`Login status: ${isUserLoggedIn ? "Logged in" : "Not logged in"}`);
|
|
@@ -333,7 +485,10 @@ async function runChatGpt(chatgptOptions = {}) {
|
|
|
333
485
|
await fileInput.uploadFile(questionFile);
|
|
334
486
|
await navigate.waitForDomIdle(2e3, 15e3);
|
|
335
487
|
console.log("File uploaded successfully");
|
|
336
|
-
await clickSubmitButton(page);
|
|
488
|
+
const didSubmit = await clickSubmitButton(page);
|
|
489
|
+
if (!didSubmit) {
|
|
490
|
+
throw new Error("Prompt was not submitted after file upload.");
|
|
491
|
+
}
|
|
337
492
|
await navigate.waitForDomIdle(1e3, 3e4);
|
|
338
493
|
await waitForInitialResponse(page);
|
|
339
494
|
await handleStreamingResponse(page, responseFile);
|
|
@@ -353,33 +508,6 @@ async function runChatGpt(chatgptOptions = {}) {
|
|
|
353
508
|
}
|
|
354
509
|
}
|
|
355
510
|
}
|
|
356
|
-
var isMain = false;
|
|
357
|
-
try {
|
|
358
|
-
const mainArg = process.argv[1] && path.resolve(process.argv[1]);
|
|
359
|
-
const currentScript = __filename && path.resolve(__filename);
|
|
360
|
-
if (typeof __require !== "undefined" && typeof module !== "undefined" && __require.main === module) {
|
|
361
|
-
isMain = true;
|
|
362
|
-
}
|
|
363
|
-
console.log("[chatgpt.js][CJS check]", typeof __require, typeof module, __require.main === module);
|
|
364
|
-
console.log("[chatgpt.js][CJS check]", mainArg, currentScript);
|
|
365
|
-
console.log("[chatgpt.js][CJS check]", "isMain:", isMain);
|
|
366
|
-
} catch (_e) {
|
|
367
|
-
}
|
|
368
|
-
try {
|
|
369
|
-
const mainArg = process.argv[1] && path.resolve(process.argv[1]);
|
|
370
|
-
if (mainArg && import.meta.url === pathToFileURL(mainArg).href) {
|
|
371
|
-
isMain = true;
|
|
372
|
-
}
|
|
373
|
-
} catch (_e) {
|
|
374
|
-
}
|
|
375
|
-
if (isMain) {
|
|
376
|
-
(async () => {
|
|
377
|
-
try {
|
|
378
|
-
} catch (error) {
|
|
379
|
-
console.error("Error running ChatGPT:", error);
|
|
380
|
-
}
|
|
381
|
-
})();
|
|
382
|
-
}
|
|
383
511
|
|
|
384
512
|
export {
|
|
385
513
|
runChatGpt
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { createRequire } from 'module'; const require = createRequire(import.meta.url);
|
|
2
|
+
import {
|
|
3
|
+
__commonJS,
|
|
4
|
+
__require,
|
|
5
|
+
init_esm_shims
|
|
6
|
+
} from "./chunk-QQ4A6DLD.mjs";
|
|
7
|
+
|
|
8
|
+
// src/binary-collections-config.cjs
|
|
9
|
+
var require_binary_collections_config = __commonJS({
|
|
10
|
+
"src/binary-collections-config.cjs"(exports, module) {
|
|
11
|
+
init_esm_shims();
|
|
12
|
+
var path = __require("path");
|
|
13
|
+
__require("dotenv").config({ path: path.join(process.cwd(), ".env"), quiet: true });
|
|
14
|
+
function getTempDir() {
|
|
15
|
+
return process.env.TEMP_DIR || path.join(process.cwd(), "tmp");
|
|
16
|
+
}
|
|
17
|
+
function getTempPath(...segments) {
|
|
18
|
+
return path.join(getTempDir(), ...segments);
|
|
19
|
+
}
|
|
20
|
+
var TEMP_BASE_DIR = getTempDir();
|
|
21
|
+
module.exports = {
|
|
22
|
+
getTempDir,
|
|
23
|
+
getTempPath,
|
|
24
|
+
TEMP_BASE_DIR
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
export {
|
|
30
|
+
require_binary_collections_config
|
|
31
|
+
};
|