import { resolveSearchCities } from "@shared/search-cities.js"; import type { ExtractorManifest, ExtractorProgressEvent, } from "@shared/types/extractors"; import { runHiringCafe } from "./src/run"; function toProgress(event: { type: string; termIndex: number; termTotal: number; searchTerm: string; pageNo?: number; totalCollected?: number; }): ExtractorProgressEvent { if (event.type === "term_start") { return { phase: "list", termsProcessed: Math.max(event.termIndex - 1, 0), termsTotal: event.termTotal, currentUrl: event.searchTerm, detail: `Hiring Cafe: term ${event.termIndex}/${event.termTotal} (${event.searchTerm})`, }; } if (event.type === "page_fetched") { const pageNo = (event.pageNo ?? 0) + 1; const totalCollected = event.totalCollected ?? 0; return { phase: "list", termsProcessed: Math.max(event.termIndex - 1, 0), termsTotal: event.termTotal, listPagesProcessed: pageNo, jobPagesEnqueued: totalCollected, jobPagesProcessed: totalCollected, currentUrl: `page ${pageNo}`, detail: `Hiring Cafe: term ${event.termIndex}/${event.termTotal}, page ${pageNo} (${totalCollected} collected)`, }; } return { phase: "list", termsProcessed: event.termIndex, termsTotal: event.termTotal, currentUrl: event.searchTerm, detail: `Hiring Cafe: completed term ${event.termIndex}/${event.termTotal} (${event.searchTerm})`, }; } export const manifest: ExtractorManifest = { id: "hiringcafe", displayName: "Hiring Cafe", providesSources: ["hiringcafe"], async run(context) { if (context.shouldCancel?.()) { return { success: true, jobs: [] }; } const maxJobsPerTerm = context.settings.jobspyResultsWanted ? parseInt(context.settings.jobspyResultsWanted, 10) : 200; const result = await runHiringCafe({ country: context.selectedCountry, countryKey: context.selectedCountry, searchTerms: context.searchTerms, locations: resolveSearchCities({ single: context.settings.searchCities ?? context.settings.jobspyLocation, }), workplaceTypes: context.settings.workplaceTypes ? JSON.parse(context.settings.workplaceTypes) : undefined, maxJobsPerTerm, onProgress: (event) => { if (context.shouldCancel?.()) return; context.onProgress?.(toProgress(event)); }, }); if (!result.success) { return { success: false, jobs: [], error: result.error, }; } return { success: true, jobs: result.jobs, }; }, }; export default manifest;