feat(core): add built-in locale packs and lazy loadLocale (#1590)

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Sam Potts
2026-06-18 12:16:47 -07:00
committed by GitHub
co-authored by Cursor
parent 768bf09da0
commit 9170a5879e
171 changed files with 3416 additions and 6 deletions
+85
View File
@@ -11,6 +11,7 @@
* 4. Package metadata — non-private packages have required fields
* 5. Release-please config — every versioned package is registered
* 6. Define imports — no bare side-effect imports from relative paths
* 7. i18n locales — tag lists match locale files and generated stubs
*/
import { existsSync, readdirSync, readFileSync } from 'node:fs';
import { dirname, join, resolve } from 'node:path';
@@ -324,6 +325,89 @@ function checkDefineImports() {
return { ok: warnings.length === 0, warnings };
}
// ── Check 7: i18n locale consistency ─────────────────────────────────────────
const GENERATED_I18N_HEADER = '/** Generated by packages/core/scripts/generate-i18n-locales.ts — do not edit. */';
function parseLocaleTagArray(source, exportName) {
const match = source.match(new RegExp(`export const ${exportName} = \\[([\\s\\S]*?)\\] as const`));
if (!match) {
throw new Error(`Could not parse ${exportName} from built-in-locales.ts`);
}
return [...match[1].matchAll(/'([^']+)'/g)].map((m) => m[1]);
}
function checkI18nLocales() {
const warnings = [];
const builtInPath = join(PACKAGES_DIR, 'core/src/core/i18n/built-in-locales.ts');
const builtInSource = readText(builtInPath);
const builtInLocales = parseLocaleTagArray(builtInSource, 'BUILT_IN_LOCALES');
const aliasTags = parseLocaleTagArray(builtInSource, 'LOCALE_ALIAS_TAGS');
const shippedTags = [...builtInLocales, ...aliasTags];
const coreLocalesDir = join(PACKAGES_DIR, 'core/src/core/i18n/locales');
const coreFiles = readdirSync(coreLocalesDir)
.filter((file) => file.endsWith('.ts'))
.map((file) => file.slice(0, -3));
const expectedCore = new Set(['all', 'en', ...builtInLocales, ...aliasTags]);
for (const tag of builtInLocales) {
if (!coreFiles.includes(tag)) {
warnings.push(`BUILT_IN_LOCALES tag "${tag}" has no packages/core/src/core/i18n/locales/${tag}.ts`);
}
}
for (const tag of aliasTags) {
if (!coreFiles.includes(tag)) {
warnings.push(`LOCALE_ALIAS_TAGS tag "${tag}" has no packages/core/src/core/i18n/locales/${tag}.ts`);
}
}
for (const file of coreFiles) {
if (!expectedCore.has(file)) {
warnings.push(
`Unexpected locale file packages/core/src/core/i18n/locales/${file}.ts (not in built-in-locales.ts)`
);
}
}
const allPath = join(coreLocalesDir, 'all.ts');
if (!readText(allPath).startsWith(GENERATED_I18N_HEADER)) {
warnings.push(
'packages/core/src/core/i18n/locales/all.ts is not generated — run pnpm -F @videojs/core generate:locales'
);
}
for (const pkg of ['html', 'react']) {
const localesDir = join(PACKAGES_DIR, `${pkg}/src/i18n/locales`);
const expectedPlatform = new Set(['all', 'en', ...shippedTags]);
for (const tag of expectedPlatform) {
const filePath = join(localesDir, `${tag}.ts`);
if (!existsSync(filePath)) {
warnings.push(`Missing generated re-export packages/${pkg}/src/i18n/locales/${tag}.ts`);
continue;
}
if (!readText(filePath).startsWith(GENERATED_I18N_HEADER)) {
warnings.push(
`packages/${pkg}/src/i18n/locales/${tag}.ts is not generated — run pnpm -F @videojs/core generate:locales`
);
}
}
for (const file of readdirSync(localesDir)) {
if (!file.endsWith('.ts')) continue;
const tag = file.slice(0, -3);
if (!expectedPlatform.has(tag)) {
warnings.push(`Unexpected locale re-export packages/${pkg}/src/i18n/locales/${file}`);
}
}
}
return { ok: warnings.length === 0, warnings };
}
// ── Main ────────────────────────────────────────────────────────────────────
const checks = [
@@ -334,6 +418,7 @@ const checks = [
{ name: 'Release-please config', fn: checkReleasePleaseConfig },
{ name: 'Bundled docs publishing', fn: checkBundledDocs },
{ name: 'Define imports', fn: checkDefineImports },
{ name: 'i18n locales', fn: checkI18nLocales },
];
let failed = 0;