init project
This commit is contained in:
@@ -0,0 +1,50 @@
|
||||
import { readFile, stat } from 'node:fs/promises';
|
||||
import path from 'node:path';
|
||||
import { fail, pass, repositoryRoot } from './lib.mjs';
|
||||
|
||||
const manifest = JSON.parse(
|
||||
await readFile(
|
||||
path.join(repositoryRoot, 'src', 'contracts', 'phase9', 'route-manifest.json'),
|
||||
'utf8',
|
||||
),
|
||||
);
|
||||
const errors = [];
|
||||
const requiredLocales = ['en', 'fr', 'ar'];
|
||||
const ids = new Set();
|
||||
|
||||
if (JSON.stringify(manifest.locales) !== JSON.stringify(requiredLocales)) {
|
||||
errors.push('Route locales must remain exactly en, fr, ar.');
|
||||
}
|
||||
for (const route of manifest.routes) {
|
||||
if (ids.has(route.id)) errors.push(`Duplicate route ID: ${route.id}`);
|
||||
ids.add(route.id);
|
||||
for (const locale of requiredLocales) {
|
||||
if (typeof route.slugs[locale] !== 'string') errors.push(`${route.id} has no ${locale} slug.`);
|
||||
}
|
||||
}
|
||||
for (const locale of requiredLocales) {
|
||||
if (!manifest.hreflang.values.includes(locale)) errors.push(`hreflang omits ${locale}.`);
|
||||
}
|
||||
if (manifest.hreflang.xDefaultLocale !== 'en') errors.push('x-default must resolve to English.');
|
||||
if (manifest.switching.dropUnknownQuery !== true) {
|
||||
errors.push('Unknown query parameters must be dropped.');
|
||||
}
|
||||
|
||||
for (const routeFile of [
|
||||
'src/app/[locale]/page.tsx',
|
||||
'src/app/[locale]/[slug]/page.tsx',
|
||||
'src/app/[locale]/not-found.tsx',
|
||||
]) {
|
||||
try {
|
||||
await stat(path.join(repositoryRoot, routeFile));
|
||||
} catch {
|
||||
errors.push(`Runtime route implementation missing: ${routeFile}`);
|
||||
}
|
||||
}
|
||||
|
||||
if (errors.length > 0) fail(errors);
|
||||
else
|
||||
pass(
|
||||
`${manifest.routes.length} route IDs have complete locale, runtime, hash, query, ` +
|
||||
'and hreflang contracts.',
|
||||
);
|
||||
Reference in New Issue
Block a user