build-browser-detector.js

 1#!/usr/bin/env node
 2
 3/**
 4 * Generates cli/engine/detect-antipatterns-browser.js
 5 * by concatenating the browser-safe detector modules and wrapping them in an IIFE.
 6 *
 7 * Run: node scripts/build-browser-detector.js
 8 */
 9
10import fs from 'fs';
11import path from 'path';
12import { fileURLToPath } from 'url';
13
14const __dirname = path.dirname(fileURLToPath(import.meta.url));
15const ROOT = path.resolve(__dirname, '..');
16
17const MODULES = [
18  'cli/engine/shared/constants.mjs',
19  'cli/engine/registry/antipatterns.mjs',
20  'cli/engine/shared/color.mjs',
21  'cli/engine/rules/checks.mjs',
22  'cli/engine/browser/injected/index.mjs',
23];
24const OUTPUT = path.join(ROOT, 'cli/engine/detect-antipatterns-browser.js');
25const SITE_OUTPUT = path.join(ROOT, 'site/public/js/detect-antipatterns-browser.js');
26
27function browserSafeModule(relPath) {
28  let code = fs.readFileSync(path.join(ROOT, relPath), 'utf-8');
29  if (relPath === 'cli/engine/registry/antipatterns.mjs') {
30    const match = code.match(/const ANTIPATTERNS = \[[\s\S]*?\n\];/);
31    if (!match) throw new Error('Could not extract browser antipattern registry');
32    code = match[0];
33  }
34  code = code.replace(/^import[\s\S]*?;\n/gm, '');
35  code = code.replace(/^export\s+\{[\s\S]*?^};\n?/gm, '');
36  return `// --- ${relPath} ---\n${code.trim()}\n`;
37}
38
39const code = MODULES.map(browserSafeModule).join('\n');
40
41const output = `/**
42 * Anti-Pattern Browser Detector for Impeccable
43 * Copyright (c) 2026 Paul Bakaus
44 * SPDX-License-Identifier: Apache-2.0
45 *
46 * GENERATED -- do not edit. Source: cli/engine/browser/injected/index.mjs
47 * Rebuild: node scripts/build-browser-detector.js
48 *
49 * Usage: <script src="detect-antipatterns-browser.js"></script>
50 * Re-scan: window.impeccableScan()
51 */
52(function () {
53if (typeof window === 'undefined') return;
54${code}
55})();
56`;
57
58fs.writeFileSync(OUTPUT, output);
59fs.mkdirSync(path.dirname(SITE_OUTPUT), { recursive: true });
60fs.writeFileSync(SITE_OUTPUT, output);
61console.log(`Generated ${path.relative(ROOT, OUTPUT)} (${(output.length / 1024).toFixed(1)} KB)`);
62console.log(`Generated ${path.relative(ROOT, SITE_OUTPUT)} (${(output.length / 1024).toFixed(1)} KB)`);