import { readFileSync, existsSync } from 'node:fs'; import { dirname, join } from 'node:path'; import { fileURLToPath } from 'node:url'; export interface Fingerprint { cats?: number[]; html?: string | string[]; text?: string | string[]; css?: string | string[]; headers?: Record; meta?: Record; cookies?: Record; scriptSrc?: string | string[]; scripts?: string | string[]; url?: string | string[]; js?: Record; dns?: Record; certIssuer?: string; implies?: string | string[]; requires?: string | string[]; excludes?: string | string[]; website?: string; icon?: string; description?: string; } export interface Categoria { name: string; priority: number; } export interface Dataset { tecnologias: Record; categorias: Record; meta: { versao?: string; atualizadoEm?: string }; } let cache: Dataset | undefined; function acharPastaDados(): string { const candidatos: string[] = []; let dir = dirname(fileURLToPath(import.meta.url)); for (let i = 0; i < 6; i++) { candidatos.push(join(dir, 'data', 'fingerprints')); dir = dirname(dir); } candidatos.push(join(process.cwd(), 'data', 'fingerprints')); for (const c of candidatos) { if (existsSync(join(c, 'technologies.json'))) return c; } throw new Error('Não encontrei o dataset de fingerprints (data/fingerprints/technologies.json).'); } export function carregarDataset(): Dataset { if (cache) return cache; const pasta = acharPastaDados(); const tecnologias = lerJson>(join(pasta, 'technologies.json')); const categorias = lerJson>(join(pasta, 'categories.json')); const meta = existsSync(join(pasta, 'meta.json')) ? lerJson<{ versao?: string; atualizadoEm?: string }>(join(pasta, 'meta.json')) : {}; cache = { tecnologias, categorias, meta }; return cache; } function lerJson(caminho: string): T { return JSON.parse(readFileSync(caminho, 'utf8')) as T; }