Files
heros_web/scripts/verify-flow-segment-data.mjs

64 lines
2.5 KiB
JavaScript

import { readFile } from 'node:fs/promises';
import { readCampaignFlowSegments } from './campaign-flow-segments.mjs';
const { routes, segments, manifestHash } = await readCampaignFlowSegments();
const flowSource = await readFile(new URL('./verify-flow.mjs', import.meta.url), 'utf8');
const packageJson = JSON.parse(await readFile(new URL('../package.json', import.meta.url), 'utf8'));
assert(segments.length === 12, `Expected 12 campaign flow segments, received ${segments.length}.`);
assert(routes.length === 66, `Expected 66 campaign battle routes, received ${routes.length}.`);
assert(/^[a-f0-9]{64}$/.test(manifestHash), `Expected a SHA-256 flow manifest hash, received ${manifestHash}.`);
const flattenedBattleIds = segments.flatMap(({ battleIds }) => battleIds);
assert(
JSON.stringify(flattenedBattleIds) === JSON.stringify(routes.map(({ battleId }) => battleId)),
'Campaign flow segments must preserve the canonical 66-battle route order.'
);
const specialCheckpointSteps = {
'hanzhong-shuhan': 'shu-han-foundation-camp',
'yiling-baidi': 'baidi-entrustment-camp',
nanzhong: 'northern-campaign-prep-camp',
northern: 'ending-complete'
};
for (const segment of segments) {
assert(segment.index === segments.indexOf(segment), `Flow segment ${segment.id} has an invalid index.`);
assert(
countOccurrences(flowSource, `shouldRunFlowSegment('${segment.id}')`) === 1,
`Flow segment ${segment.id} must have exactly one executable body boundary.`
);
assert(
countOccurrences(flowSource, `completeFlowSegment(page, '${segment.id}')`) === 1,
`Flow segment ${segment.id} must have exactly one completion checkpoint.`
);
const specialStep = specialCheckpointSteps[segment.id];
if (specialStep) {
assert(
segment.checkpointStep === specialStep,
`Flow segment ${segment.id} must end at ${specialStep}, received ${segment.checkpointStep}.`
);
}
}
assert(
packageJson.scripts?.['verify:flow'] === 'node scripts/verify-flow-segments.mjs',
'The default verify:flow command must use the segmented orchestrator.'
);
assert(
packageJson.scripts?.['verify:flow:monolith'] === 'node scripts/verify-flow.mjs',
'The legacy monolith flow command must remain available for comparison.'
);
console.log(`Verified ${segments.length} campaign flow segments across ${routes.length} ordered battles (${manifestHash.slice(0, 12)}).`);
function countOccurrences(source, needle) {
return source.split(needle).length - 1;
}
function assert(condition, message) {
if (!condition) {
throw new Error(message);
}
}