mirror of
https://github.com/zoriya/v10.git
synced 2026-08-16 02:45:09 +00:00
feat(core): add built-in locale packs and lazy loadLocale (#1590)
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user