UNPKG

rsshub

Version:
97 lines (95 loc) 3.47 kB
import { n as init_esm_shims, t as __dirname } from "./esm-shims-CzJ_djXG.mjs"; import "./config-C37vj7VH.mjs"; import "./dist-BInvbO1W.mjs"; import "./logger-Czu8UMNd.mjs"; import { t as ofetch_default } from "./ofetch-BIyrKU3Y.mjs"; import { t as art } from "./render-BQo6B4tL.mjs"; import path from "node:path"; //#region lib/routes/hiring.cafe/jobs.ts init_esm_shims(); const CONFIG = { DEFAULT_PAGE_SIZE: 20, MAX_PAGE_SIZE: 100 }; const API = { BASE_URL: "https://hiring.cafe/api/search-jobs", HEADERS: { "Content-Type": "application/json" } }; const validateSearchParams = ({ keywords, page = 0, size = CONFIG.DEFAULT_PAGE_SIZE }) => ({ keywords: keywords.trim(), page: Math.max(0, Math.floor(Number(page))), size: Math.min(Math.max(1, Math.floor(Number(size))), CONFIG.MAX_PAGE_SIZE) }); const fetchJobs = async (searchParams) => { const payload = { size: searchParams.size || 20, page: searchParams.page || 0, searchState: { searchQuery: searchParams.keywords, sortBy: searchParams.sortBy || "date" } }; return await ofetch_default(API.BASE_URL, { method: "POST", body: payload, headers: API.HEADERS }); }; const renderJobDescription = (jobInfo, processedData) => art(path.join(__dirname, "templates/jobs-71f48c16.art"), { company_name: processedData.company_name, location: processedData.formatted_workplace_location ?? "Remote/Unspecified", is_compensation_transparent: Boolean(processedData.is_compensation_transparent && processedData.yearly_min_compensation && processedData.yearly_max_compensation), yearly_min_compensation_formatted: processedData.yearly_min_compensation?.toLocaleString() ?? "", yearly_max_compensation_formatted: processedData.yearly_max_compensation?.toLocaleString() ?? "", workplace_type: processedData.workplace_type ?? "Not specified", requirements_summary: processedData.requirements_summary ?? "No requirements specified", job_description: jobInfo.description ?? "" }); const transformJobItem = (item) => { const { job_information: jobInfo, v5_processed_job_data: processedData, apply_url, id } = item; return { title: `${jobInfo.title} - ${processedData.company_name}`, description: renderJobDescription(jobInfo, processedData), link: apply_url, pubDate: new Date(processedData.estimated_publish_date_millis).toUTCString(), category: [ processedData.job_category, ...processedData.role_activities, processedData.workplace_type ].filter((x) => !!x), author: processedData.company_name, guid: id }; }; async function handler(ctx) { const searchParams = validateSearchParams({ keywords: ctx.req.param("keywords") }); const response = await fetchJobs(searchParams); const items = response.results.map((item) => transformJobItem(item)); return { title: `HiringCafe Jobs: ${searchParams.keywords}`, description: `Job search results for "${searchParams.keywords}" on HiringCafe`, link: `https://hiring.cafe/jobs?q=${encodeURIComponent(searchParams.keywords)}`, item: items, total: response.total }; } const route = { path: "/jobs/:keywords", categories: ["other"], example: "/hiring.cafe/jobs/sustainability", parameters: { keywords: "Keywords to search for" }, features: { requireConfig: false, requirePuppeteer: false, antiCrawler: false, supportBT: false, supportPodcast: false, supportScihub: false }, radar: [{ source: ["hiring.cafe"] }], name: "Jobs", maintainers: ["mintyfrankie"], handler }; //#endregion export { route };