job-pro 1.0.12 → 1.0.14
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/index.js +55 -5
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -127,7 +127,8 @@ USAGE
|
|
|
127
127
|
job-pro profile show print the loaded profile
|
|
128
128
|
job-pro find <keyword> search ALL 50 companies in parallel
|
|
129
129
|
[--limit N] [--companies a,b,c]
|
|
130
|
-
[--timeout ms] [--
|
|
130
|
+
[--timeout ms] [--apply-ready]
|
|
131
|
+
[--compact | --text]
|
|
131
132
|
job-pro --version
|
|
132
133
|
job-pro help
|
|
133
134
|
|
|
@@ -1087,10 +1088,23 @@ async function main() {
|
|
|
1087
1088
|
}
|
|
1088
1089
|
if (cmd === "find") {
|
|
1089
1090
|
const compact = args.includes("--compact");
|
|
1091
|
+
const textMode = args.includes("--text");
|
|
1092
|
+
const applyReadyOnly = args.includes("--apply-ready");
|
|
1090
1093
|
const keyword = args[1];
|
|
1091
1094
|
if (!keyword || keyword.startsWith("--")) {
|
|
1092
|
-
die(`usage: job-pro find <keyword> [--limit N] [--companies a,b,c] [--timeout ms] [--compact]`);
|
|
1095
|
+
die(`usage: job-pro find <keyword> [--limit N] [--companies a,b,c] [--timeout ms] [--apply-ready] [--compact | --text]`);
|
|
1093
1096
|
}
|
|
1097
|
+
// Static apply-readiness map. Source of truth for what kind of submission
|
|
1098
|
+
// each adapter supports — kept in sync with apply-smoke's submit_kind tally.
|
|
1099
|
+
const ANON_ADAPTERS = new Set(["xpeng", "weride", "hoyoverse"]);
|
|
1100
|
+
const EXTERNAL_ADAPTERS = new Set(["hikvision", "cicc", "cainiao", "webank", "unitree"]);
|
|
1101
|
+
const applyStatusFor = (adapterKey) => {
|
|
1102
|
+
if (EXTERNAL_ADAPTERS.has(adapterKey))
|
|
1103
|
+
return "external";
|
|
1104
|
+
if (ANON_ADAPTERS.has(adapterKey))
|
|
1105
|
+
return "anon";
|
|
1106
|
+
return loadSession(adapterKey) ? "session" : "missing-session";
|
|
1107
|
+
};
|
|
1094
1108
|
const { args: aLimit, value: limitStr } = popFlagValue(args, "--limit");
|
|
1095
1109
|
const { args: aCompanies, value: companiesStr } = popFlagValue(aLimit, "--companies");
|
|
1096
1110
|
const { args: aTimeout, value: timeoutStr } = popFlagValue(aCompanies, "--timeout");
|
|
@@ -1125,7 +1139,7 @@ async function main() {
|
|
|
1125
1139
|
return { company, ok: false, count: 0, positions: [], message: r.message ?? "search failed", elapsed_ms: elapsed };
|
|
1126
1140
|
}
|
|
1127
1141
|
const positions = Array.isArray(r?.positions) ? r.positions.slice(0, limit) : [];
|
|
1128
|
-
return { company, ok: true, count: positions.length, positions, elapsed_ms: elapsed };
|
|
1142
|
+
return { company, ok: true, count: positions.length, positions, apply_status: applyStatusFor(company), elapsed_ms: elapsed };
|
|
1129
1143
|
}
|
|
1130
1144
|
catch (err) {
|
|
1131
1145
|
const elapsed = Date.now() - t0;
|
|
@@ -1138,8 +1152,44 @@ async function main() {
|
|
|
1138
1152
|
}
|
|
1139
1153
|
}));
|
|
1140
1154
|
const totalMs = Date.now() - startedAt;
|
|
1141
|
-
const
|
|
1155
|
+
const allHits = settled.filter((r) => r.count > 0);
|
|
1156
|
+
const withHits = applyReadyOnly
|
|
1157
|
+
? allHits.filter((r) => r.apply_status === "anon" || r.apply_status === "session")
|
|
1158
|
+
: allHits;
|
|
1142
1159
|
const total = withHits.reduce((s, r) => s + r.count, 0);
|
|
1160
|
+
const failed = settled.filter((r) => !r.ok).map((r) => ({ company: r.company, message: r.message }));
|
|
1161
|
+
if (textMode) {
|
|
1162
|
+
const STATUS_ICON = {
|
|
1163
|
+
anon: "✅",
|
|
1164
|
+
session: "🟢",
|
|
1165
|
+
"missing-session": "🟡",
|
|
1166
|
+
external: "⛔",
|
|
1167
|
+
};
|
|
1168
|
+
const filterNote = applyReadyOnly ? " [apply-ready only]" : "";
|
|
1169
|
+
console.log(`\nfind "${keyword}" — ${total} hit(s) across ${withHits.length}/${scope.length} companies (${totalMs}ms)${filterNote}\n`);
|
|
1170
|
+
for (const r of withHits) {
|
|
1171
|
+
const icon = STATUS_ICON[r.apply_status ?? ""] ?? "?";
|
|
1172
|
+
console.log(`${icon} ${r.company} (${r.count}) — ${r.apply_status}`);
|
|
1173
|
+
for (const p of r.positions) {
|
|
1174
|
+
const title = (p.title ?? "").trim().replace(/\s+/g, " ");
|
|
1175
|
+
const loc = (p.work_cities ?? "").trim();
|
|
1176
|
+
console.log(` ${p.post_id ?? "?"} ${title}${loc ? ` — ${loc}` : ""}`);
|
|
1177
|
+
if (p.apply_url)
|
|
1178
|
+
console.log(` ${p.apply_url}`);
|
|
1179
|
+
}
|
|
1180
|
+
console.log("");
|
|
1181
|
+
}
|
|
1182
|
+
const hiddenCount = allHits.length - withHits.length;
|
|
1183
|
+
if (applyReadyOnly && hiddenCount > 0) {
|
|
1184
|
+
console.log(`(${hiddenCount} company-bucket(s) hidden — missing-session / external)\n`);
|
|
1185
|
+
}
|
|
1186
|
+
if (failed.length > 0) {
|
|
1187
|
+
console.log(`Failed (${failed.length}):`);
|
|
1188
|
+
for (const f of failed)
|
|
1189
|
+
console.log(` ${f.company}: ${f.message}`);
|
|
1190
|
+
}
|
|
1191
|
+
return;
|
|
1192
|
+
}
|
|
1143
1193
|
emit({
|
|
1144
1194
|
ok: true,
|
|
1145
1195
|
keyword,
|
|
@@ -1148,7 +1198,7 @@ async function main() {
|
|
|
1148
1198
|
scanned_companies: scope.length,
|
|
1149
1199
|
elapsed_ms: totalMs,
|
|
1150
1200
|
results: withHits,
|
|
1151
|
-
failed
|
|
1201
|
+
failed,
|
|
1152
1202
|
}, compact);
|
|
1153
1203
|
return;
|
|
1154
1204
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "job-pro",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.14",
|
|
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",
|