Improve videos
This commit is contained in:
parent
4012e4e047
commit
d3418c67cc
11 changed files with 988 additions and 869 deletions
|
|
@ -59,9 +59,79 @@ function emitScript(storyboard: Storyboard): string {
|
|||
return path;
|
||||
}
|
||||
|
||||
function main(): void {
|
||||
/**
|
||||
* Validate every stubbed/initial filter name and travel-destination slug
|
||||
* against the LIVE API. Wrong names don't error in the app — they silently
|
||||
* no-op, the map never changes, and you only find out after a full render.
|
||||
* Fails hard on a mismatch; soft-warns if the API is unreachable (render.sh
|
||||
* has already health-checked it by the time preflight runs).
|
||||
*/
|
||||
async function validateAgainstLiveApi(): Promise<void> {
|
||||
const apiBase = process.env.API_URL ?? process.env.APP_URL;
|
||||
if (!apiBase) {
|
||||
console.warn('[preflight] no API_URL/APP_URL set — skipping live filter validation');
|
||||
return;
|
||||
}
|
||||
|
||||
let featureNames: Set<string>;
|
||||
try {
|
||||
const res = await fetch(`${apiBase}/api/features`);
|
||||
if (!res.ok) throw new Error(`HTTP ${res.status}`);
|
||||
const body = (await res.json()) as {
|
||||
groups: { features: { name: string }[] }[];
|
||||
};
|
||||
featureNames = new Set(body.groups.flatMap((g) => g.features.map((f) => f.name)));
|
||||
} catch (err) {
|
||||
console.warn(`[preflight] could not fetch ${apiBase}/api/features (${err}) — skipping validation`);
|
||||
return;
|
||||
}
|
||||
|
||||
const problems: string[] = [];
|
||||
for (const sb of storyboards) {
|
||||
const filterNames = [
|
||||
...Object.keys(sb.content.stubbedFilters),
|
||||
...Object.keys(sb.content.initialFilters ?? {}),
|
||||
];
|
||||
for (const name of filterNames) {
|
||||
if (!featureNames.has(name)) {
|
||||
problems.push(`[${sb.name}] filter "${name}" is not a live /api/features name`);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const modes = new Set(
|
||||
storyboards.flatMap((sb) => sb.content.stubbedTravelTimeFilters.map((tt) => tt.mode))
|
||||
);
|
||||
for (const mode of modes) {
|
||||
try {
|
||||
const res = await fetch(`${apiBase}/api/travel-destinations?mode=${mode}`);
|
||||
if (!res.ok) throw new Error(`HTTP ${res.status}`);
|
||||
const body = (await res.json()) as { destinations: { slug: string }[] };
|
||||
const slugs = new Set(body.destinations.map((d) => d.slug));
|
||||
for (const sb of storyboards) {
|
||||
for (const tt of sb.content.stubbedTravelTimeFilters) {
|
||||
if (tt.mode === mode && !slugs.has(tt.slug)) {
|
||||
problems.push(`[${sb.name}] travel destination "${tt.slug}" (${mode}) not on live API`);
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (err) {
|
||||
console.warn(`[preflight] could not validate travel destinations for ${mode}: ${err}`);
|
||||
}
|
||||
}
|
||||
|
||||
if (problems.length > 0) {
|
||||
for (const p of problems) console.error(`[preflight] FAIL: ${p}`);
|
||||
process.exit(1);
|
||||
}
|
||||
console.log('[preflight] all stubbed filter names and travel slugs match the live API');
|
||||
}
|
||||
|
||||
async function main(): Promise<void> {
|
||||
if (!existsSync(OUTPUT_DIR)) mkdirSync(OUTPUT_DIR, { recursive: true });
|
||||
|
||||
await validateAgainstLiveApi();
|
||||
|
||||
for (const sb of storyboards) emitScript(sb);
|
||||
|
||||
// Index for shell loops — each entry has every field render.sh needs to
|
||||
|
|
@ -84,4 +154,7 @@ function main(): void {
|
|||
console.log(`[preflight] wrote storyboard index → ${indexPath}`);
|
||||
}
|
||||
|
||||
main();
|
||||
main().catch((err) => {
|
||||
console.error(err);
|
||||
process.exit(1);
|
||||
});
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue