rsshub
Version:
Make RSS Great Again!
97 lines (95 loc) • 3.47 kB
JavaScript
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 };