diff options
| author | ST-DDT <[email protected]> | 2022-02-11 19:58:56 +0100 |
|---|---|---|
| committer | GitHub <[email protected]> | 2022-02-11 19:58:56 +0100 |
| commit | 419e9e20a570b44909faf24c9019bf7f232ee7a9 (patch) | |
| tree | b4a5399d9033d281fa4b018adc5f448a23a998a4 /scripts | |
| parent | 6afa92b7471cf3e4170c8063e7b01ee68321e546 (diff) | |
| download | faker-419e9e20a570b44909faf24c9019bf7f232ee7a9.tar.xz faker-419e9e20a570b44909faf24c9019bf7f232ee7a9.zip | |
feat(types): provide strong typing for locales 2 (#398)
Diffstat (limited to 'scripts')
| -rw-r--r-- | scripts/generateLocales.ts | 164 |
1 files changed, 144 insertions, 20 deletions
diff --git a/scripts/generateLocales.ts b/scripts/generateLocales.ts index 0d3d2fd2..4419e523 100644 --- a/scripts/generateLocales.ts +++ b/scripts/generateLocales.ts @@ -4,6 +4,9 @@ import type { Options } from 'prettier'; import { format } from 'prettier'; import options from '../.prettierrc.cjs'; import type { LocaleDefinition } from '../src'; +import { DEFINITIONS } from '../src/definitions'; + +// Constants const pathRoot = resolve(__dirname, '..'); const pathLocale = resolve(pathRoot, 'src', 'locale'); @@ -16,36 +19,58 @@ const pathDocsApiLocalization = resolve( 'localization.md' ); -const scriptCommand = 'pnpm run generate:locales'; const prettierTsOptions: Options = { ...options, parser: 'typescript' }; const prettierMdOptions: Options = { ...options, parser: 'markdown' }; -const locales = readdirSync(pathLocales); -locales.splice(locales.indexOf('index.ts'), 1); - -let localeIndexImports = "import type { LocaleDefinition } from '..';\n"; -let localeIndexType = 'export type KnownLocale =\n'; -let localeIndexLocales = 'const locales: KnownLocales = {\n'; - -let localizationLocales = '| Locale | Name |\n| :--- | :--- |\n'; +const scriptCommand = 'pnpm run generate:locales'; const autoGeneratedCommentHeader = `/* * This file is automatically generated. * Run '${scriptCommand}' to update. */`; -for (const locale of locales) { - // eslint-disable-next-line @typescript-eslint/no-var-requires - const localeDef: LocaleDefinition = require('../src/locales/' + - locale).default; - const localeTitle = localeDef.title; +// Helper functions - localeIndexImports += `import ${locale} from './${locale}';\n`; - localeIndexType += ` | '${locale}'\n`; - localeIndexLocales += ` ${locale},\n`; - localizationLocales += `| ${locale} | ${localeTitle} |\n`; +function removeIndexTs(files: string[]): string[] { + const index = files.indexOf('index.ts'); + if (index !== -1) { + files.splice(index, 1); + } + return files; +} - // src/locale/<locale>.ts +function removeTsSuffix(files: string[]): string[] { + return files.map((file) => file.replace('.ts', '')); +} + +function escapeImport(module: string): string { + if (module === 'name') { + return 'name_'; + } else if (module === 'type') { + return 'type_'; + } else { + return module; + } +} + +function escapeField(module: string): string { + if (module === 'name') { + return 'name: name_'; + } else if (module === 'type') { + return 'type: type_'; + } else { + return module; + } +} + +function containsAll(checked?: string[], expected?: string[]): boolean { + if (typeof expected === 'undefined' || typeof checked === 'undefined') { + return true; + } + return expected.every((c) => checked.includes(c)); +} + +function generateLocaleFile(locale: string) { let content = ` ${autoGeneratedCommentHeader} @@ -69,6 +94,106 @@ for (const locale of locales) { writeFileSync(resolve(pathLocale, locale + '.ts'), content); } +function generateLocalesIndexFile( + path: string, + name: string, + type: string, + depth: number, + extra: string = '', + expected?: string[] +) { + let modules = readdirSync(path); + modules = removeIndexTs(modules); + modules = removeTsSuffix(modules); + const importType = type; + if (!containsAll(modules, expected)) { + type = `Partial<${type}>`; + } + let fieldType = ''; + let asType = ''; + if (!containsAll(expected, modules)) { + asType = ` as ${type}`; + } else { + fieldType = `: ${type}`; + } + let content = `${autoGeneratedCommentHeader} + import type { ${importType} } from '..${'/..'.repeat(depth)}'; + ${modules + .map((module) => `import ${escapeImport(module)} from './${module}';`) + .join('\n')} + + const ${name}${fieldType} = { + ${extra} + ${modules.map((module) => `${escapeField(module)},`).join('\n')} + }${asType}; + + export default ${name}; + `; + content = format(content, prettierTsOptions); + writeFileSync(resolve(path, 'index.ts'), content); +} + +// Start of actual logic + +const locales = readdirSync(pathLocales); +removeIndexTs(locales); + +let localeIndexImports = "import type { LocaleDefinition } from '..';\n"; +let localeIndexType = 'export type KnownLocale =\n'; +let localeIndexLocales = 'const locales: KnownLocales = {\n'; + +let localizationLocales = '| Locale | Name |\n| :--- | :--- |\n'; + +for (const locale of locales) { + // eslint-disable-next-line @typescript-eslint/no-var-requires + const localeDef: LocaleDefinition = require('../src/locales/' + + locale).default; + const localeTitle = localeDef.title; + const localeSeparator = localeDef.separator; + + localeIndexImports += `import ${locale} from './${locale}';\n`; + localeIndexType += ` | '${locale}'\n`; + localeIndexLocales += ` ${locale},\n`; + localizationLocales += `| ${locale} | ${localeTitle} |\n`; + + // src/locale/<locale>.ts + generateLocaleFile(locale); + + // src/locales/<locale>/index.ts + const pathModules = resolve(pathLocales, locale); + generateLocalesIndexFile( + pathModules, + locale, + 'LocaleDefinition', + 1, + `title: '${localeTitle}',` + + (localeSeparator ? `\nseparator: '${localeSeparator}',` : ''), + undefined + ); + + let modules = readdirSync(pathModules); + modules = removeIndexTs(modules); + modules = removeTsSuffix(modules); + for (const module of modules) { + // src/locales/<locale>/<module>/index.ts + const pathModule = resolve(pathModules, module); + const moduleFiles: string[] = DEFINITIONS[module]; + if (typeof moduleFiles === 'undefined') { + continue; + } + generateLocalesIndexFile( + pathModule, + module, + `${module.replace(/(^|_)([a-z])/g, (s) => + s.replace('_', '').toUpperCase() + )}Definitions`, + 2, + '', + moduleFiles + ); + } +} + // src/locales/index.ts let indexContent = ` @@ -86,7 +211,6 @@ let indexContent = ` `; indexContent = format(indexContent, prettierTsOptions); - writeFileSync(pathLocalesIndex, indexContent); // docs/api/localization.md |
