75 lines
3.4 KiB
JavaScript
75 lines
3.4 KiB
JavaScript
import { readFile } from 'node:fs/promises';
|
|
import path from 'node:path';
|
|
import process from 'node:process';
|
|
import { fileURLToPath, pathToFileURL } from 'node:url';
|
|
|
|
const projectRoot = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..');
|
|
|
|
async function readJson(relativePath) {
|
|
return JSON.parse(await readFile(path.join(projectRoot, relativePath), 'utf8'));
|
|
}
|
|
|
|
function publicationTime() {
|
|
const configured = process.env.PAGES_PUBLICATION_TIME;
|
|
const value = configured ? Date.parse(configured) : Date.now();
|
|
if (!Number.isFinite(value)) throw new Error('PAGES_PUBLICATION_TIME must be a valid ISO-8601 date.');
|
|
return value;
|
|
}
|
|
|
|
const now = publicationTime();
|
|
const policy = await readJson('pages/publication-policy.json');
|
|
const cards = await readJson('src/lib/data/cards-summary.json');
|
|
const boards = await readJson('src/lib/data/boards-summary.json');
|
|
const memory = await readJson('src/lib/data/memory-summary.json');
|
|
const charts = await readJson('src/lib/data/exact-chart-catalog.json');
|
|
const { events } = await import(pathToFileURL(path.join(projectRoot, 'src/lib/data/events.ts')).href);
|
|
|
|
const approvedVersion = policy.approvedMasterDataVersion;
|
|
const versions = new Map([
|
|
['cards-summary.json', cards.masterDataVersion],
|
|
['boards-summary.json', boards.masterDataVersion],
|
|
['memory-summary.json', memory.masterDataVersion]
|
|
]);
|
|
const mismatchedVersions = [...versions].filter(([, version]) => version !== approvedVersion);
|
|
if (mismatchedVersions.length > 0) {
|
|
throw new Error(`Unapproved master data: ${mismatchedVersions.map(([file, version]) => `${file}=${version}`).join(', ')}`);
|
|
}
|
|
|
|
const approvedNotBefore = Date.parse(policy.approvedNotBefore);
|
|
if (!Number.isFinite(approvedNotBefore)) {
|
|
throw new Error('approvedNotBefore must be a valid ISO-8601 date.');
|
|
}
|
|
|
|
const undatedCharts = charts.charts.filter((chart) => !Number.isFinite(chart.releaseTime));
|
|
if (undatedCharts.length > 0) {
|
|
throw new Error(`Pages build contains ${undatedCharts.length} undated charts: ${undatedCharts.map((chart) => `${chart.songId}/${chart.difficulty}`).join(', ')}`);
|
|
}
|
|
|
|
const undatedEvents = events.filter((event) => !Number.isFinite(Date.parse(event.startsAt)));
|
|
if (undatedEvents.length > 0) {
|
|
throw new Error(`Pages build contains undated events: ${undatedEvents.map((event) => event.id).join(', ')}`);
|
|
}
|
|
|
|
const notReadyReasons = [];
|
|
if (now < approvedNotBefore) {
|
|
notReadyReasons.push(`approved master data cannot be published before ${policy.approvedNotBefore}`);
|
|
}
|
|
|
|
const unreleasedCharts = charts.charts.filter((chart) => chart.releaseTime > now);
|
|
if (unreleasedCharts.length > 0) {
|
|
notReadyReasons.push(`${unreleasedCharts.length} charts are not released yet: ${unreleasedCharts.map((chart) => `${chart.songId}/${chart.difficulty}`).join(', ')}`);
|
|
}
|
|
|
|
const unreleasedEvents = events.filter((event) => Date.parse(event.startsAt) > now);
|
|
if (unreleasedEvents.length > 0) {
|
|
notReadyReasons.push(`events are not released yet: ${unreleasedEvents.map((event) => event.id).join(', ')}`);
|
|
}
|
|
|
|
if (notReadyReasons.length > 0) {
|
|
process.stderr.write(`Pages public-data gate is not ready at ${new Date(now).toISOString()}: ${notReadyReasons.join('; ')}.\n`);
|
|
process.exit(78);
|
|
}
|
|
|
|
process.stdout.write(`Pages public-data gate passed at ${new Date(now).toISOString()}.\n`);
|
|
process.stdout.write(`Approved master data: ${approvedVersion}; cards=${cards.cards.length}; charts=${charts.charts.length}; events=${events.length}.\n`);
|