← 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;