job-pro 1.0.3 → 1.0.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/apply.js +49 -10
- package/dist/index.js +1 -1
- package/package.json +1 -1
package/dist/apply.js
CHANGED
|
@@ -437,21 +437,16 @@ export async function submitApplication(staged, target, options = {}) {
|
|
|
437
437
|
if (options.extraHeaders) {
|
|
438
438
|
Object.assign(headers, options.extraHeaders);
|
|
439
439
|
}
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
response = await fetch(url, {
|
|
443
|
-
method: staged.submit_method ?? "POST",
|
|
444
|
-
headers,
|
|
445
|
-
body: fd,
|
|
446
|
-
});
|
|
447
|
-
}
|
|
448
|
-
catch (err) {
|
|
440
|
+
const r = await fetchWithRetry(url, { method: staged.submit_method ?? "POST", headers, body: fd }, "submit");
|
|
441
|
+
if (!r.ok) {
|
|
449
442
|
return {
|
|
450
443
|
ok: false,
|
|
451
444
|
posted_to: url,
|
|
452
|
-
|
|
445
|
+
status: r.status,
|
|
446
|
+
message: r.message,
|
|
453
447
|
};
|
|
454
448
|
}
|
|
449
|
+
const response = r.response;
|
|
455
450
|
let preview = "";
|
|
456
451
|
try {
|
|
457
452
|
preview = (await response.text()).slice(0, 4000);
|
|
@@ -709,6 +704,50 @@ export async function executeFeishu3Step(staged, session, target) {
|
|
|
709
704
|
steps,
|
|
710
705
|
};
|
|
711
706
|
}
|
|
707
|
+
async function fetchWithRetry(url, init, label, log) {
|
|
708
|
+
const maxRetries = Math.max(0, Math.min(5, Number.parseInt(process.env.JOB_PRO_RETRY ?? "2", 10) || 2));
|
|
709
|
+
let lastErr = "";
|
|
710
|
+
for (let attempt = 0; attempt <= maxRetries; attempt++) {
|
|
711
|
+
let response = null;
|
|
712
|
+
try {
|
|
713
|
+
response = await fetch(url, init);
|
|
714
|
+
}
|
|
715
|
+
catch (err) {
|
|
716
|
+
lastErr = `network error: ${err instanceof Error ? err.message : String(err)}`;
|
|
717
|
+
log?.push({ attempt: attempt + 1, ok: false, message: `${label}: ${lastErr}` });
|
|
718
|
+
// Network errors are retryable. Back off and try again.
|
|
719
|
+
if (attempt < maxRetries) {
|
|
720
|
+
await sleep(retryDelayMs(attempt));
|
|
721
|
+
continue;
|
|
722
|
+
}
|
|
723
|
+
return { ok: false, message: lastErr };
|
|
724
|
+
}
|
|
725
|
+
// 4xx → user error, don't retry.
|
|
726
|
+
if (response.status >= 400 && response.status < 500) {
|
|
727
|
+
log?.push({ attempt: attempt + 1, ok: false, status: response.status, message: `${label}: HTTP ${response.status} (no retry — 4xx)` });
|
|
728
|
+
return { ok: false, status: response.status, message: `HTTP ${response.status}: ${response.statusText}` };
|
|
729
|
+
}
|
|
730
|
+
// 5xx → server error, retry.
|
|
731
|
+
if (response.status >= 500 && attempt < maxRetries) {
|
|
732
|
+
lastErr = `HTTP ${response.status}: ${response.statusText}`;
|
|
733
|
+
log?.push({ attempt: attempt + 1, ok: false, status: response.status, message: `${label}: ${lastErr} (will retry)` });
|
|
734
|
+
await sleep(retryDelayMs(attempt));
|
|
735
|
+
continue;
|
|
736
|
+
}
|
|
737
|
+
log?.push({ attempt: attempt + 1, ok: response.ok, status: response.status, message: `${label}: HTTP ${response.status}` });
|
|
738
|
+
return { ok: true, response };
|
|
739
|
+
}
|
|
740
|
+
return { ok: false, message: lastErr || "exhausted retries" };
|
|
741
|
+
}
|
|
742
|
+
function retryDelayMs(attempt) {
|
|
743
|
+
// Exponential backoff with jitter: 250ms / 500ms / 1s / 2s / 4s, ±25%.
|
|
744
|
+
const base = 250 * Math.pow(2, attempt);
|
|
745
|
+
const jitter = base * (Math.random() * 0.5 - 0.25);
|
|
746
|
+
return Math.round(base + jitter);
|
|
747
|
+
}
|
|
748
|
+
function sleep(ms) {
|
|
749
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
750
|
+
}
|
|
712
751
|
/** Build the headers bag used by every Feishu/Beisen/Moka step. */
|
|
713
752
|
function sessionHeaderBag(session, targetHost) {
|
|
714
753
|
const out = {
|
package/dist/index.js
CHANGED
|
@@ -60,7 +60,7 @@ import { createRequire as require_createRequire } from "node:module";
|
|
|
60
60
|
function require_module() {
|
|
61
61
|
return { createRequire: require_createRequire };
|
|
62
62
|
}
|
|
63
|
-
const VERSION = "1.0.
|
|
63
|
+
const VERSION = "1.0.5";
|
|
64
64
|
const COMPANIES = [
|
|
65
65
|
{ key: "tencent", family: "Bespoke", source: "join.qq.com", label: "Tencent / 腾讯" },
|
|
66
66
|
{ key: "bytedance", family: "Bespoke", source: "jobs.bytedance.com", label: "ByteDance / 字节跳动" },
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "job-pro",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.5",
|
|
4
4
|
"description": "Query Chinese big-tech campus recruiting from your terminal. 50 companies, all 50 live. 46 via each company's own API; the 4 with no public canonical feed (Hikvision, CICC, Cainiao, WeBank) surfaced via Liepin as a clearly-labeled third-party fallback. No signup, no token, no server.",
|
|
5
5
|
"homepage": "https://job.ha7ch.com",
|
|
6
6
|
"repository": "https://github.com/HA7CH/job-pro",
|