lazy-apply 0.1.2 → 0.1.3

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/cli.js CHANGED
@@ -6,7 +6,7 @@ import { existsSync, mkdirSync, readFileSync, rmSync, writeFileSync } from "node
6
6
  import { homedir, hostname, platform, tmpdir, userInfo } from "node:os";
7
7
  import { dirname, join } from "node:path";
8
8
  import { createInterface } from "node:readline/promises";
9
- var VERSION = true ? "0.1.2" : "dev";
9
+ var VERSION = true ? "0.1.3" : "dev";
10
10
  var DEFAULT_APP = "https://lazyapply.online";
11
11
  var HOME = join(homedir(), ".lazy-apply");
12
12
  var CONFIG = join(HOME, "config.json");
package/dist/runner.js CHANGED
@@ -144,7 +144,33 @@ var pick = (opts, ...prefer) => {
144
144
  };
145
145
  var or = (v, fallback) => v && v.trim() || fallback;
146
146
  var links = (s) => [s.website, s.linkedin, s.github].filter(Boolean).join(" | ");
147
+ var yesNo = (o, yes) => o?.length ? pick(o, yes ? /^yes\b/i : /^no\b/i) : yes ? "Yes" : "No";
148
+ var countriesIn = (text) => {
149
+ const out = /* @__PURE__ */ new Set();
150
+ for (const part of text.split(/,|\bor\b|\band\b|\//i)) {
151
+ const c = countryOf(part) ?? (/\bpoland\b/i.test(part) ? "Poland" : void 0);
152
+ if (c) out.add(c);
153
+ }
154
+ return out;
155
+ };
147
156
  var RULES = [
157
+ // Screening questions that sound like other rules but are not: answered before the broad rules below see them.
158
+ { test: /employment agreements?|post[- ]employment restrictions?|non[- ]?compete|non[- ]?solicit|restrictive covenants?/i, answer: (_s, o) => yesNo(o, false) },
159
+ { test: /(previously|ever|before) (worked|been employed|consulted|interned)( at| for| with)|former (employee|contractor) (of|at)/i, answer: (_s, o) => yesNo(o, false) },
160
+ // "...sponsorship to remain in your current location": about where the person lives, not where the job is.
161
+ { test: /sponsor[^?]*(current(ly)? (location|country)|where you (currently )?(live|reside|are based))/i, answer: (s, o) => {
162
+ const home = countryOf(s.location);
163
+ if (!home) return void 0;
164
+ const ok = s.workAuthorizedCountries.split(",").some((c) => c.trim().toLowerCase() === home.toLowerCase());
165
+ return yesNo(o, !ok);
166
+ } },
167
+ // "Are you currently located in either Canada, UK or Poland?"
168
+ { test: /(currently |presently )?(locat(ed|ion)|living|based|residing|reside) in (either )?[A-Z][^?]*\b(or|and)\b/i, answer: (s, o, _c, label) => {
169
+ const home = countryOf(s.location);
170
+ if (!home || !label) return void 0;
171
+ const listed = countriesIn(label.replace(/^.*?\b(?:in|either)\b/i, ""));
172
+ return listed.size ? yesNo(o, listed.has(home)) : void 0;
173
+ } },
148
174
  { test: /^first\s*name/i, answer: (s) => or(s.firstName) },
149
175
  { test: /^last\s*name|surname|family name/i, answer: (s) => or(s.lastName) },
150
176
  { test: /^(full |legal )?name$/i, answer: (s) => or(`${s.firstName} ${s.lastName}`.trim()) },
@@ -397,14 +423,16 @@ function findEmptyRequired() {
397
423
  if (!box) continue;
398
424
  const required = /\*|✱/.test(raw) || /required/i.test(lab.className) || !!(ctl && (ctl.hasAttribute("required") || ctl.getAttribute("aria-required") === "true")) || !!box.querySelector("[required], [aria-required=true]");
399
425
  if (!required) continue;
400
- const scope = ctl && !/radio|checkbox/.test(ctl.type || "") ? ctl.parentElement || box : box;
426
+ const combo = !!ctl && (ctl.getAttribute("role") === "combobox" || !!ctl.closest("[class*=select__], [class*=-container]"));
427
+ const scope = ctl && !combo && !/radio|checkbox/.test(ctl.type || "") ? ctl.parentElement || box : box;
401
428
  const texts = Array.from(scope.querySelectorAll("input:not([type=hidden]):not([type=radio]):not([type=checkbox]):not([type=file]):not([type=submit]), textarea, select"));
402
429
  const files = Array.from(scope.querySelectorAll("input[type=file]"));
403
430
  const checks = Array.from(scope.querySelectorAll("input[type=radio], input[type=checkbox]"));
404
431
  const buttons = Array.from(scope.querySelectorAll("button, [role=radio], [role=checkbox]")).filter((b) => b.type !== "submit");
405
432
  if (!texts.length && !files.length && !checks.length && !buttons.length) continue;
406
433
  const scopeText = scope.textContent || "";
407
- const filled = texts.some((t) => t.value?.trim()) || files.some((f) => (f.files?.length || 0) > 0) || files.length > 0 && /\.(pdf|docx?|rtf|txt)\b/i.test(scopeText) || checks.some((c) => c.checked) || buttons.some((b) => b.getAttribute("aria-pressed") === "true" || b.getAttribute("aria-checked") === "true" || /selected|active|checked/i.test(b.className) && !/unselected/i.test(b.className));
434
+ const chosen = !!Array.from(scope.querySelectorAll("[class*=single-value], [class*=multi-value], [class*=singleValue], [class*=multiValue]")).some((e) => (e.textContent || "").trim()) || !!scope.querySelector("[class*=value-container--has-value]") || Array.from(scope.querySelectorAll("input[type=hidden]")).some((h) => h.value.trim() && /question|answer|select|value/i.test(h.name || h.id || ""));
435
+ const filled = chosen || texts.some((t) => t.value?.trim()) || files.some((f) => (f.files?.length || 0) > 0) || files.length > 0 && /\.(pdf|docx?|rtf|txt)\b/i.test(scopeText) || checks.some((c) => c.checked) || buttons.some((b) => b.getAttribute("aria-pressed") === "true" || b.getAttribute("aria-checked") === "true" || /selected|active|checked/i.test(b.className) && !/unselected/i.test(b.className));
408
436
  const label = clean(raw).replace(/(ATTACH RESUME|No location found|Couldn't auto-read|Analyzing resume|Loading).*$/i, "").trim();
409
437
  if (!filled && label && !seen.has(label)) {
410
438
  seen.add(label);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lazy-apply",
3
- "version": "0.1.2",
3
+ "version": "0.1.3",
4
4
  "description": "The Lazy Apply runner: fills your approved job applications in Chrome on your own computer. Run `npx lazy-apply`.",
5
5
  "type": "module",
6
6
  "bin": { "lazy-apply": "dist/cli.js" },