#!/usr/bin/env node /** Read one original Himalayas posting through its documented public API. * Publisher evidence only: never clears employer/application/profile gates. * No account, browser, retries, cache, model, or user-layer writes. * Contract: https://himalayas.app/docs/remote-jobs-api#how-do-i-check-a-job-is-still-open */ import fs from 'node:fs/promises'; import { isMainModule } from './lib/is-main-module.mjs'; const MAX_BODY = 1024 * 1024; const TIMEOUT_MS = 15_000; const TRACKING = /^utm_[a-z_]+$/; const CHALLENGE = /cf-chl-|\/cdn-cgi\/challenge-platform|enable javascript and cookies|\s*just a moment/i; const object = value => value !== null && typeof value === 'object' && !Array.isArray(value); const text = (value, max) => typeof value === 'string' && value.trim().length > 0 && value.length <= max; const epoch = value => Number.isSafeInteger(value) && value > 0; export function resolveHimalayasPosting(originalUrl) { if (typeof originalUrl !== 'string' || originalUrl.length > 8192 || originalUrl.trim() !== originalUrl || /[\\\u0000-\u0020]/.test(originalUrl) || /\/\.{1,2}(?:\/|[?#]|$)/.test(originalUrl)) return null; let url; try { url = new URL(originalUrl); } catch { return null; } if (url.protocol !== 'https:' || url.hostname !== 'himalayas.app' || url.port || url.username || url.password) return null; const match = url.pathname.match(/^\/companies\/([a-z0-9][a-z0-9-]{0,255})\/jobs\/([a-z0-9][a-z0-9-]{0,255})\/?$/); if (!match || [...url.searchParams.keys()].some(key => !TRACKING.test(key))) return null; const guid = `https://himalayas.app/companies/${match[1]}/jobs/${match[2]}`; return { originalUrl, companySlug: match[1], jobSlug: match[2], guid, apiUrl: guid.replace('https://himalayas.app/', 'https://himalayas.app/jobs/api/') }; } function evidence(identity, status, metadata) { return { ...identity, httpStatus: status, retrievedAt: metadata.retrievedAt, cache: { documentedMaxAgeSeconds: 600, ageSeconds: metadata.ageSeconds ?? null, cacheControl: metadata.cacheControl ?? null }, employerVerified: false, applicationVerified: false, evaluationAllowed: false }; } /** The 200 means publisher-open, never verified employer/application liveness. */ export function classifyHimalayasPosting(originalUrl, status, body, metadata = {}) { const identity = resolveHimalayasPosting(originalUrl); if (!identity) return { publisherStatus: 'unknown', code: 'unsupported_url', evaluationAllowed: false }; const observed = metadata.retrievedAt ?? new Date().toISOString(); const base = evidence(identity, status, { ...metadata, retrievedAt: observed }); const unknown = code => ({ ...base, publisherStatus: 'unknown', code }); if (!Number.isFinite(Date.parse(observed))) return unknown('invalid_retrieval_time'); if (metadata.ageSeconds != null && (!Number.isSafeInteger(metadata.ageSeconds) || metadata.ageSeconds < 0 || metadata.ageSeconds > 600)) return unknown('publisher_cache_age_unconfirmed'); // The API's 404 means no record at this path, not confirmed closure. if (status === 404) return unknown('himalayas_not_found'); if (status === 410) { if (!object(body) || body.ok !== false || body.expired !== true || !epoch(body.expiryDate) || body.expiryDate > Date.parse(observed) / 1000 || body.job || body.guid) return unknown('invalid_closed_payload'); return { ...base, publisherStatus: 'closed', code: 'himalayas_closed', expiryDate: body.expiryDate }; } if (status !== 200) return unknown('himalayas_http_unconfirmed'); const job = body?.job; if (!object(body) || !object(job) || job.guid !== identity.guid || job.companySlug !== identity.companySlug || resolveHimalayasPosting(job.applicationLink)?.guid !== identity.guid) return unknown('identity_mismatch'); if (!text(job.title, 240) || !text(job.companyName, 240) || !text(job.description, MAX_BODY) || !Array.isArray(job.locationRestrictions) || !Array.isArray(job.timezoneRestrictions) || !epoch(job.pubDate) || !epoch(job.expiryDate)) return unknown('partial_job'); if (CHALLENGE.test(job.description) || /^(?:just a moment|access denied|sign in|log in|forbidden)\b/i.test(job.title)) return unknown('challenge_or_login_wall'); const plain = job.description.replace(/<(script|style)\b[^>]*>[\s\S]*?<\/\1>/gi, ' ') .replace(/<[^>]*>|&(?:#\w+|\w+);/g, ' ').replace(/\s+/g, ' ').trim(); if (plain.length < 500) return unknown('insufficient_description'); // An inconsistent expiry is uncertainty; only the documented 410 closes it. if (job.expiryDate <= Date.parse(observed) / 1000) return unknown('inconsistent_expiry'); return { ...base, publisherStatus: 'open', code: 'himalayas_publisher_open', job: { title: job.title, companyName: job.companyName, companySlug: job.companySlug, guid: job.guid, applicationLink: job.applicationLink, description: job.description, locationRestrictions: job.locationRestrictions, timezoneRestrictions: job.timezoneRestrictions, pubDate: job.pubDate, expiryDate: job.expiryDate } }; } /** One anonymous GET; callers must treat every returned string as job data. */ export async function retrieveHimalayasPosting(originalUrl, { fetchFn = globalThis.fetch, now = Date.now } = {}) { const identity = resolveHimalayasPosting(originalUrl); if (!identity) return classifyHimalayasPosting(originalUrl, null, null); const metadata = { retrievedAt: new Date(now()).toISOString() }; const fail = code => ({ ...evidence(identity, null, metadata), publisherStatus: 'unknown', code }); try { const response = await fetchFn(identity.apiUrl, { method: 'GET', redirect: 'error', headers: { Accept: 'application/json' }, signal: AbortSignal.timeout(TIMEOUT_MS) }); if (response.url && response.url !== identity.apiUrl) { await response.body?.cancel(); return fail('response_url_mismatch'); } metadata.cacheControl = response.headers.get('cache-control'); const age = response.headers.get('age'); if (age !== null) metadata.ageSeconds = /^\d+$/.test(age) ? Number(age) : NaN; if (response.status === 404 || ![200, 410].includes(response.status)) { await response.body?.cancel(); return classifyHimalayasPosting(originalUrl, response.status, null, metadata); } if (!/^application\/(?:[a-z0-9.+-]+\+)?json(?:\s*;|$)/i.test(response.headers.get('content-type') ?? '')) { await response.body?.cancel(); return fail('non_json_response'); } const chunks = []; let size = 0; for await (const chunk of response.body ?? []) { size += chunk.byteLength; if (size > MAX_BODY) return fail('response_too_large'); chunks.push(chunk); } const body = JSON.parse(new TextDecoder('utf-8', { fatal: true }).decode(Buffer.concat(chunks))); return classifyHimalayasPosting(originalUrl, response.status, body, metadata); } catch { return fail('transport_or_json_unconfirmed'); } } async function main() { const args = process.argv.slice(2); if (args.length === 1 && (args[0] === '--help' || args[0] === '-h')) { console.log('Usage: node himalayas-posting.mjs --request <file|->\nRead bounded {"url":"original-posting-url"} JSON from stdin (-) or an existing file.\nOptions:\n --request <file|-> Read one original posting through the public API\n --help, -h Print usage without reading input or making a request'); return; } if (args.length !== 2 || args[0] !== '--request') throw new Error('Use --request - with JSON on stdin (or an existing request file)'); let request; if (args[1] === '-') { const chunks = []; let size = 0; for await (const chunk of process.stdin) { size += chunk.byteLength; if (size > 16 * 1024) throw new Error('Request too large'); chunks.push(chunk); } request = new TextDecoder('utf-8', { fatal: true }).decode(Buffer.concat(chunks)); } else { const info = await fs.stat(args[1]); if (!info.isFile() || info.size > 16 * 1024) throw new Error('Invalid request file'); request = await fs.readFile(args[1], 'utf8'); } const input = JSON.parse(request); if (!object(input) || Object.keys(input).join(',') !== 'url' || typeof input.url !== 'string') throw new Error('Expected {"url":"original-posting-url"}'); const result = await retrieveHimalayasPosting(input.url); console.log(JSON.stringify(result)); process.exitCode = result.publisherStatus === 'unknown' ? 2 : 0; } if (isMainModule(import.meta.url)) { main().catch(() => { console.error('Himalayas retrieval failed: invalid request or unavailable public data.'); process.exitCode = 2; }); }