job-pro 1.0.89 → 1.0.91

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 CHANGED
@@ -1208,11 +1208,6 @@ export async function executeCdpRealBrowser(staged, session, target) {
1208
1208
  if (!existsSync(resumeField.value)) {
1209
1209
  return { ok: false, posted_to: targetUrl, message: `resume file not found: ${resumeField.value}`, steps };
1210
1210
  }
1211
- const applicant = {};
1212
- for (const f of staged.staged) {
1213
- if (f.name === "name" || f.name === "email" || f.name === "phone")
1214
- applicant[f.name] = f.value;
1215
- }
1216
1211
  const r = await withPage(async (page) => {
1217
1212
  await page.goto(targetUrl, { waitUntil: "networkidle2", timeout: 30000 });
1218
1213
  steps.push({
@@ -1268,18 +1263,29 @@ export async function executeCdpRealBrowser(staged, session, target) {
1268
1263
  return { kind: "no-form" };
1269
1264
  }
1270
1265
  steps.push({ step: "wait-form", url: page.url(), status: 200, ok: true, message: "modal rendered" });
1271
- // Fill name/email/phone if matching inputs exist.
1272
- for (const [key, value] of Object.entries(applicant)) {
1273
- if (!value)
1266
+ // Fill every staged non-file field. The schema layer normalises field
1267
+ // names to whatever the upstream API expects (first_name, last_name,
1268
+ // email, phone, question_XXX for Greenhouse custom questions, name/
1269
+ // email/phone for Feishu, etc.) — so input[name="<f.name>"] usually
1270
+ // matches. Falls back to placeholder / aria-label / id contains-match.
1271
+ let filled = 0, missed = 0;
1272
+ for (const f of staged.staged) {
1273
+ if (f.type === "input_file")
1274
+ continue;
1275
+ if (!f.value)
1274
1276
  continue;
1275
1277
  try {
1276
- const sel = `input[name="${key}"], input[placeholder*="${key}"], input[aria-label*="${key}"]`;
1277
- await page.type(sel, value, { delay: 30 });
1278
+ const sel = `input[name="${f.name}"], textarea[name="${f.name}"], ` +
1279
+ `input[id="${f.name}"], textarea[id="${f.name}"], ` +
1280
+ `input[placeholder*="${f.name}"], input[aria-label*="${f.name}"]`;
1281
+ await page.type(sel, f.value, { delay: 20 });
1282
+ filled++;
1278
1283
  }
1279
1284
  catch {
1280
- steps.push({ step: `fill-${key}`, url: page.url(), status: 0, ok: false, message: "selector not found" });
1285
+ missed++;
1281
1286
  }
1282
1287
  }
1288
+ steps.push({ step: "fill-fields", url: page.url(), status: 200, ok: filled > 0, message: `filled ${filled}, missed ${missed}` });
1283
1289
  // Upload resume.
1284
1290
  try {
1285
1291
  const fileInput = await page.$('input[type=file]');
package/dist/index.js CHANGED
@@ -700,16 +700,20 @@ async function runCompany(adapter, company, rawArgs) {
700
700
  if (debugUrl) {
701
701
  // Route through the family-specific executor where appropriate so the
702
702
  // user can verify each step's wire format against their echo server.
703
+ // --via-cdp forces the puppeteer DOM path even in debug mode (CDP's
704
+ // debug mode just navigates the apply_url and pauses for 3s without
705
+ // submitting — useful to verify the SPA loads correctly).
703
706
  const kindForDebug = sr.schema.submit_kind ?? "multipart-anon";
704
- const debugExecutor = kindForDebug === "feishu-3-step" ? executeFeishu3Step :
705
- kindForDebug === "moka-aes" ? executeMokaApply :
706
- kindForDebug === "beisen-wecruit" ? executeBeisenWecruit :
707
- kindForDebug === "beisen-italent" ? executeBeisenITalent :
708
- kindForDebug === "cdp-real-browser" ? executeCdpRealBrowser :
709
- null;
707
+ const debugExecutor = viaCdp ? executeCdpRealBrowser :
708
+ kindForDebug === "feishu-3-step" ? executeFeishu3Step :
709
+ kindForDebug === "moka-aes" ? executeMokaApply :
710
+ kindForDebug === "beisen-wecruit" ? executeBeisenWecruit :
711
+ kindForDebug === "beisen-italent" ? executeBeisenITalent :
712
+ kindForDebug === "cdp-real-browser" ? executeCdpRealBrowser :
713
+ null;
710
714
  if (debugExecutor) {
711
715
  const result = await debugExecutor(staged, session, { kind: "debug", url: debugUrl });
712
- return emit({ mode: "debug-submit", staged, submit_kind: kindForDebug, result }, compact);
716
+ return emit({ mode: "debug-submit", staged, submit_kind: kindForDebug, via_cdp: viaCdp, result }, compact);
713
717
  }
714
718
  const result = await submitApplication(staged, { kind: "debug", url: debugUrl });
715
719
  return emit({ mode: "debug-submit", staged, submit_kind: kindForDebug, result }, compact);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "job-pro",
3
- "version": "1.0.89",
3
+ "version": "1.0.91",
4
4
  "description": "Query Chinese big-tech campus recruiting + auto-apply from your terminal. 50 companies, all 50 live (46 via official APIs, 4 via Liepin third-party fallback). 45/50 with end-to-end verified apply endpoints; 5 structurally-external (Liepin IM × 4 + Unitree WeChat). No signup, no token, no server.",
5
5
  "homepage": "https://job.ha7ch.com",
6
6
  "repository": "https://github.com/HA7CH/job-pro",