39639-vm/backend/src/services/firecrawl.js
2026-04-15 01:46:21 +00:00

64 lines
1.9 KiB
JavaScript

const FIRECRAWL_DEFAULT_BASE_URL = 'https://api.firecrawl.dev/v1';
function toBoolean(value, defaultValue = false) {
if (value === undefined || value === null || value === '') {
return defaultValue;
}
if (typeof value === 'boolean') {
return value;
}
const normalizedValue = String(value).trim().toLowerCase();
if (['1', 'true', 'yes', 'on'].includes(normalizedValue)) {
return true;
}
if (['0', 'false', 'no', 'off'].includes(normalizedValue)) {
return false;
}
return defaultValue;
}
function getFirecrawlRuntime() {
const apiKey = String(process.env.FIRECRAWL_API_KEY || '').trim();
const baseUrl = String(
process.env.FIRECRAWL_BASE_URL || FIRECRAWL_DEFAULT_BASE_URL,
).trim();
const enabled = toBoolean(process.env.FIRECRAWL_ENABLED, true);
return {
provider: 'firecrawl',
baseUrl,
enabled,
configured: Boolean(apiKey),
hasApiKey: Boolean(apiKey),
mode: 'scaffold_only',
};
}
function getFirecrawlScaffold({ requestedPages, entitlements } = {}) {
const runtime = getFirecrawlRuntime();
const wantsAdvancedCrawl = Number(requestedPages || 1) > 1;
const advancedCrawlUnlocked = Boolean(entitlements?.canAdvancedCrawl);
const shouldUseFirecrawlLater = runtime.enabled && (wantsAdvancedCrawl || advancedCrawlUnlocked);
return {
...runtime,
status: runtime.configured ? 'ready_for_activation' : 'awaiting_api_key',
wouldHandleJavascript: true,
wouldHandleSitemapDiscovery: true,
shouldUseFirecrawlLater,
message: runtime.configured
? 'Firecrawl scaffold is wired and ready for the next activation step, but this analyzer still uses the built-in crawler today.'
: 'Firecrawl scaffold is wired, but FIRECRAWL_API_KEY is not set yet. The analyzer still uses the built-in crawler for now.',
};
}
module.exports = {
getFirecrawlRuntime,
getFirecrawlScaffold,
};