Files
career-ops-vbleroy/providers/lever.mjs
T
redlineo d295c7f139
Release Please / release-please (push) Failing after 4m2s
Web CI / web typecheck + build (push) Successful in 3m39s
CodeQL Analysis / Analyze (javascript-typescript) (push) Failing after 1h1m49s
CodeQL Analysis / Analyze (go) (push) Failing after 1h1m49s
init
2026-07-13 10:14:00 +03:00

40 lines
1.3 KiB
JavaScript

// @ts-check
/** @typedef {import('./_types.js').Provider} Provider */
// Lever provider — hits the public postings endpoint.
// Auto-detects from careers_url pattern `https://jobs.lever.co/<slug>`.
function resolveApiUrl(entry) {
const url = entry.careers_url || '';
const match = url.match(/jobs\.lever\.co\/([^/?#]+)/);
if (!match) return null;
return `https://api.lever.co/v0/postings/${match[1]}`;
}
/** @type {Provider} */
export default {
id: 'lever',
detect(entry) {
const apiUrl = resolveApiUrl(entry);
return apiUrl ? { url: apiUrl } : null;
},
async fetch(entry, ctx) {
const apiUrl = resolveApiUrl(entry);
if (!apiUrl) throw new Error(`lever: cannot derive API URL for ${entry.name}`);
const json = await ctx.fetchJson(apiUrl, { redirect: 'error' });
if (!Array.isArray(json)) return [];
return json.map(j => ({
title: j.text || '',
url: j.hostedUrl || '',
company: entry.name,
location: j.categories?.location || '',
// Lever's v0 postings list ships the full description for free (same
// payload, no per-job request) — enables scan.mjs content_filter.
description: typeof j.descriptionPlain === 'string' ? j.descriptionPlain : '',
postedAt: typeof j.createdAt === 'number' ? j.createdAt : undefined,
}));
},
};