job-pro 1.0.42 → 1.0.43

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.
Files changed (2) hide show
  1. package/dist/index.js +23 -10
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -1235,7 +1235,20 @@ async function main() {
1235
1235
  // 401/403/200-with-error-body/405/4xx-with-business-error = real route
1236
1236
  return "verified-real";
1237
1237
  }
1238
+ function withTimeout(p, ms) {
1239
+ return Promise.race([
1240
+ p,
1241
+ new Promise((resolve) => setTimeout(() => resolve(null), ms)),
1242
+ ]);
1243
+ }
1238
1244
  const results = await Promise.all(scope.map(async (company) => {
1245
+ // lilith uses CDP (puppeteer launches Chrome) — its withTimeout
1246
+ // returns but the browser handle keeps the event loop alive, so
1247
+ // the process never exits. Skip it explicitly; users who want to
1248
+ // recon lilith can scope --companies=lilith and accept the hang.
1249
+ if (company === "lilith") {
1250
+ return { company, classification: "probe-error", detail: "skipped — CDP adapter (puppeteer); pass --companies=lilith explicitly to probe" };
1251
+ }
1239
1252
  const adapter = ADAPTERS[company];
1240
1253
  if (!adapter)
1241
1254
  return { company, classification: "probe-error", detail: "unknown adapter" };
@@ -1243,23 +1256,21 @@ async function main() {
1243
1256
  return { company, classification: "probe-error", detail: "no fetchApplicationSchema" };
1244
1257
  }
1245
1258
  // Use a placeholder post_id so we don't have to search.
1259
+ // Per-step timeout protects against slow / hung adapters.
1246
1260
  let schema = null;
1247
1261
  try {
1248
- const r = (await adapter.fetchApplicationSchema("recon-probe"));
1249
- if (r.ok && r.schema)
1262
+ const r = await withTimeout(adapter.fetchApplicationSchema("recon-probe"), 10000);
1263
+ if (r?.ok && r.schema)
1250
1264
  schema = r.schema;
1251
1265
  }
1252
1266
  catch { }
1253
- // Most bespoke adapters return a valid schema even on bogus id,
1254
- // because they build it from the id alone. The ones that need a
1255
- // real id (mihoyo etc.) fall through to "fetch a real id".
1256
1267
  if (!schema) {
1257
1268
  try {
1258
- const list = (await adapter.searchPositions({ pageSize: 1 }));
1259
- const pid = list.positions?.[0]?.post_id;
1269
+ const list = await withTimeout(adapter.searchPositions({ pageSize: 1 }), 10000);
1270
+ const pid = list?.positions?.[0]?.post_id;
1260
1271
  if (pid) {
1261
- const r = (await adapter.fetchApplicationSchema(pid));
1262
- if (r.ok && r.schema)
1272
+ const r = await withTimeout(adapter.fetchApplicationSchema(pid), 10000);
1273
+ if (r?.ok && r.schema)
1263
1274
  schema = r.schema;
1264
1275
  }
1265
1276
  }
@@ -1318,7 +1329,9 @@ async function main() {
1318
1329
  for (const [k, v] of [...tally.entries()].sort()) {
1319
1330
  console.log(` ${k.padEnd(20)} ${v}`);
1320
1331
  }
1321
- return;
1332
+ // Some adapters (cdp/lilith via puppeteer) keep the event loop alive
1333
+ // after their probe resolves. Explicit exit guarantees the CLI returns.
1334
+ process.exit(0);
1322
1335
  }
1323
1336
  if (cmd === "selftest") {
1324
1337
  // Three end-to-end checks against the easiest adapter (xpeng, anon-submit):
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "job-pro",
3
- "version": "1.0.42",
3
+ "version": "1.0.43",
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",