← back to Dw Fleet Registry
audit-search-discovery.mjs
45 lines
#!/usr/bin/env node
import fs from 'node:fs/promises';
const configUrl = new URL('./data/search-properties.json', import.meta.url);
const outputDir = new URL('./tmp/', import.meta.url);
const outputUrl = new URL('./tmp/search-discovery-report.json', import.meta.url);
const config = JSON.parse(await fs.readFile(configUrl, 'utf8'));
const results = [];
for (const property of config.properties) {
if (property.kind !== 'public-site') {
results.push({ id: property.id, kind: property.kind, status: 'not-probed', reason: property.startPolicy || 'not a public search surface' });
continue;
}
const checks = [];
for (const endpoint of property.discovery) {
const url = new URL(endpoint, property.localUrl).href;
try {
const response = await fetch(url, { signal: AbortSignal.timeout(5000) });
const contentType = response.headers.get('content-type') || '';
const text = await response.text();
checks.push({ endpoint, status: response.status, ok: response.ok, contentType, bytes: Buffer.byteLength(text) });
} catch (error) {
checks.push({ endpoint, status: null, ok: false, error: error.message });
}
}
results.push({ id: property.id, kind: property.kind, status: checks.every(c => c.ok) ? 'ready' : 'incomplete', checks });
}
const report = {
$schema: 'search-discovery-report/v1',
generatedAt: new Date().toISOString(),
summary: {
ready: results.filter(r => r.status === 'ready').length,
incomplete: results.filter(r => r.status === 'incomplete').length,
gatedOrInternal: results.filter(r => r.status === 'not-probed').length
},
results
};
await fs.mkdir(outputDir, { recursive: true });
await fs.writeFile(outputUrl, JSON.stringify(report, null, 2) + '\n');
console.log(JSON.stringify(report.summary));
for (const result of results) console.log(`${result.id}: ${result.status}`);
if (report.summary.incomplete) process.exitCode = 1;