aboutsummaryrefslogtreecommitdiffstats
path: root/tools/feature-registry-check.js
blob: 5d0adc3ae32e30c2ba440038d2beb137a96695f6 (plain) (blame)
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
// Guard: src/features/index.js and build.js's featureIndexSource must agree.
// They drifted once (nwc was added to index.js only, so its i18n strings
// shipped but its code never did — the settings card silently never rendered,
// because build.js SWAPS OUT features/index.js for a generated module).
//
// The strongest form of agreement is equality: the checked-in module must be
// code-identical (comments and whitespace aside) to what featureIndexSource
// generates for the full feature set — imports, construction order, deferred
// placeholder slots, and the deferred loader all included.
//   bun tools/feature-registry-check.js
import { readFileSync } from 'node:fs';
import { featureIndexSource, enabledFeatures } from '../build.js';

const strip = (s) => s
  .replace(/\/\/[^\n]*/g, '')       // line comments
  .replace(/\s+/g, ' ')             // whitespace runs
  .replace(/,\s*([}\]])/g, '$1')   // optional trailing commas
  .replace(/, /g, ',').replace(/ ,/g, ',')
  .trim();

const idx = readFileSync(new URL('../src/features/index.js', import.meta.url), 'utf8');
const gen = featureIndexSource(enabledFeatures(undefined));

if (strip(idx) !== strip(gen)) {
  console.log('x src/features/index.js does not match build.js featureIndexSource (full set)');
  console.log('\n--- generated (normalized) ---\n' + strip(gen));
  console.log('\n--- checked in (normalized) ---\n' + strip(idx));
  process.exit(1);
}
console.log(`ok features/index.js matches the generator (${enabledFeatures(undefined).length} features, deferred slots included)`);