src/detection/dataset.ts (view raw)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 |
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<string, string>;
meta?: Record<string, string | string[]>;
cookies?: Record<string, string>;
scriptSrc?: string | string[];
scripts?: string | string[];
url?: string | string[];
js?: Record<string, string>;
dns?: Record<string, string | string[]>;
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<string, Fingerprint>;
categorias: Record<string, Categoria>;
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<Record<string, Fingerprint>>(join(pasta, 'technologies.json'));
const categorias = lerJson<Record<string, Categoria>>(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<T>(caminho: string): T {
return JSON.parse(readFileSync(caminho, 'utf8')) as T;
}
|