#!/usr/bin/env bun import { KEYWORDS } from "../config.ts"; import { fetchJobs, isEnglishContent } from "../fetch.ts"; import type { SearchConfig } from "../config.ts"; const CSV = "./jobs.csv"; const existingLinks = new Set(); try { const text = await Bun.file(CSV).text(); for (const line of text.split("\n").slice(1)) { const url = line.match(/"(https?:\/\/[^"]+)"/)?.[1]; if (url) existingLinks.add(url); } } catch {} const searches: SearchConfig[] = [ { label: "Switzerland remote (by name)", keywords: KEYWORDS, location: "Switzerland", workType: ["remote"], timePosted: "month" }, { label: "Basel remote", keywords: KEYWORDS, geoId: "103383283", location: "Basel", workType: ["remote"], timePosted: "month" }, { label: "Basel Metro remote", keywords: KEYWORDS, geoId: "90009885", location: "Basel Metropolitan Area", workType: ["remote"], timePosted: "month" }, { label: "Zürich remote", keywords: KEYWORDS, geoId: "102436504", location: "Zürich, Switzerland", workType: ["remote"], timePosted: "month" }, { label: "Zürich Metro remote", keywords: KEYWORDS, geoId: "107814425", location: "Zürich Metropolitan Area", workType: ["remote"], timePosted: "month" }, { label: "Zürich Area remote", keywords: KEYWORDS, geoId: "90009888", location: "Zürich Area", workType: ["remote"], timePosted: "month" }, { label: "Bern remote", keywords: KEYWORDS, location: "Bern, Switzerland", workType: ["remote"], timePosted: "month" }, // seniority-filtered pass for mid-senior+ { label: "Switzerland remote (mid-senior)", keywords: KEYWORDS, location: "Switzerland", workType: ["remote"], seniority: ["mid-senior", "director"], timePosted: "month" }, ]; type Job = { id: string; title: string; company: string; link: string; search: string }; const results: Job[] = []; const seen = new Set(); for (const config of searches) { console.log(`\n[${config.label}]`); const jobs = await fetchJobs(config); if (jobs.length === 0) { console.log(" no jobs found"); continue; } let added = 0; for (const job of jobs) { if (seen.has(job.id) || existingLinks.has(job.link)) continue; seen.add(job.id); process.stdout.write(` ${job.title} @ ${job.company} … `); const english = await isEnglishContent(job.id); if (!english) { console.log("dropped"); continue; } console.log("ok"); results.push({ ...job, search: config.label }); added++; } console.log(` => ${added} new`); } console.log(`\n=== TOTAL: ${results.length} remote jobs ===\n`); for (const j of results) { console.log(`[${j.search}] ${j.title} | ${j.company} | ${j.id} | ${j.link}`); }