/** * Direct company career pages — auto-detect ATS backends and pull public job feeds. */ import type { ExtractorManifest, ExtractorRunResult, } from "@shared/types/extractors"; import type { CreateJobInput } from "@shared/types/jobs"; import { detectAtsTargets, fetchCareersPage, fetchJobsForTarget, readUrlList, } from "./src/resolve-ats.js"; function matchesTerm(job: CreateJobInput, term: string): boolean { const lower = term.toLowerCase(); if (job.title.toLowerCase().includes(lower)) return true; if (job.employer.toLowerCase().includes(lower)) return true; if (job.jobDescription?.toLowerCase().includes(lower)) return true; return false; } export const manifest: ExtractorManifest = { id: "careerspages", displayName: "Career Pages", providesSources: ["careerspages"], async run(context): Promise { if (context.shouldCancel?.()) return { success: true, jobs: [] }; const pageUrls = readUrlList(context.settings.careersPageUrls); if (pageUrls.length === 0) { return { success: true, jobs: [], error: "No career page URLs configured. Set CAREERS_PAGE_URLS or careersPageUrls (JSON array or comma/newline-separated URLs).", }; } const terms = context.searchTerms.length > 0 ? context.searchTerms : []; const seen = new Set(); const out: CreateJobInput[] = []; try { for (let i = 0; i < pageUrls.length; i += 1) { if (context.shouldCancel?.()) break; const pageUrl = pageUrls[i]; context.onProgress?.({ phase: "list", termsProcessed: i, termsTotal: pageUrls.length, currentUrl: pageUrl, detail: `Career pages: resolving ATS for ${pageUrl}`, }); const html = await fetchCareersPage(pageUrl); const targets = detectAtsTargets(html, pageUrl); if (targets.length === 0) continue; for (const target of targets) { if (context.shouldCancel?.()) break; const jobs = await fetchJobsForTarget(target); for (const job of jobs) { if ( terms.length > 0 && !terms.some((term) => matchesTerm(job, term)) ) { continue; } const key = job.jobUrl; if (seen.has(key)) continue; seen.add(key); out.push(job); } } } return { success: true, jobs: out }; } catch (error) { const message = error instanceof Error ? error.message : "Unknown error"; return { success: false, jobs: out, error: message }; } }, }; export default manifest;