Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: auto generate/update locale files #252

Merged
merged 13 commits into from Feb 1, 2022
1 change: 1 addition & 0 deletions CONTRIBUTING.md
Expand Up @@ -13,6 +13,7 @@ If you want to make `Faker` a better, please read the following contribution gui
Make sure you **build** the project before running the docs, cause some files depend on `dist`.
Use `pnpm run docs:dev` to edit them in live mode.
- The tests are executing `vitest` against `test/**/*.spec.ts`
- If you update the locales, make sure to run `pnpm run generate:locales` to generate/update the related files.
ST-DDT marked this conversation as resolved.
Show resolved Hide resolved

## Architecture

Expand Down
6 changes: 6 additions & 0 deletions docs/api/localization.md
Expand Up @@ -13,6 +13,10 @@ faker.setLocale('de');
faker.locale = 'de';
```

<!-- LOCALES-AUTO-GENERATED-START -->

<!-- Run 'pnpm run generate:locales' to update. -->

| Locale | Name |
| :---------- | :------------------------ |
| af_ZA | Afrikaans |
Expand Down Expand Up @@ -72,6 +76,8 @@ faker.locale = 'de';
| zh_TW | Chinese (Taiwan) |
| zu_ZA | Zulu (South Africa) |

<!-- LOCALES-AUTO-GENERATED-END -->

## Individual Localization Packages

As of version `v3.0.0` Faker supports incremental loading of locales.
Expand Down
4 changes: 3 additions & 1 deletion package.json
Expand Up @@ -56,7 +56,8 @@
"build:code": "esno ./scripts/bundle.ts",
"build:types": "tsc --emitDeclarationOnly --outDir dist/types",
"build": "run-s build:clean build:code build:types",
"generate:api-docs": "esno scripts/apidoc.ts",
"generate:api-docs": "esno ./scripts/apidoc.ts",
"generate:locales": "esno ./scripts/generateLocales.ts",
"docs:build": "run-s docs:prepare docs:build:run",
"docs:build:run": "vitepress build docs",
"docs:build:ci": "run-s build docs:build",
Expand Down Expand Up @@ -89,6 +90,7 @@
"@types/node": "~16.11.21",
"@typescript-eslint/eslint-plugin": "~5.10.1",
"@typescript-eslint/parser": "~5.10.1",
"@types/prettier": "~2.4.3",
"@types/validator": "~13.7.1",
"@vitest/ui": "~0.2.5",
"c8": "~7.11.0",
Expand Down
6 changes: 6 additions & 0 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

101 changes: 101 additions & 0 deletions scripts/generateLocales.ts
@@ -0,0 +1,101 @@
import { readdirSync, readFileSync, writeFileSync } from 'node:fs';
import { resolve } from 'node:path';
import type { Options } from 'prettier';
import { format } from 'prettier';
import options from '../.prettierrc.cjs';
import type { LocaleDefinition } from '../src';

const pathRoot = resolve(__dirname, '..');
const pathLocale = resolve(pathRoot, 'src', 'locale');
const pathLocales = resolve(pathRoot, 'src', 'locales');
const pathLocalesIndex = resolve(pathLocales, 'index.ts');
const pathDocsApiLocalization = resolve(
pathRoot,
'docs',
'api',
'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 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;

localeIndexImports += `import ${locale} from './${locale}';\n`;
localeIndexType += ` | '${locale}'\n`;
localeIndexLocales += ` ${locale},\n`;
localizationLocales += `| ${locale} | ${localeTitle} |\n`;

// src/locale/<locale>.ts
let content = `
${autoGeneratedCommentHeader}

import { Faker } from '..';
import ${locale} from '../locales/${locale}';
${locale !== 'en' ? "import en from '../locales/en';" : ''}

const faker = new Faker({
locale: '${locale}',
localeFallback: 'en',
locales: {
${locale},
${locale !== 'en' ? 'en,' : ''}
},
});

export = faker;
`;

content = format(content, prettierTsOptions);
writeFileSync(resolve(pathLocale, locale + '.ts'), content);
}

// src/locales/index.ts

let indexContent = `
${autoGeneratedCommentHeader}

${localeIndexImports}

${localeIndexType};

export type KnownLocales = Record<KnownLocale, LocaleDefinition>;

${localeIndexLocales}};

export default locales;
`;

indexContent = format(indexContent, prettierTsOptions);

writeFileSync(pathLocalesIndex, indexContent);

// docs/api/localization.md

localizationLocales = format(localizationLocales, prettierMdOptions);

let localizationContent = readFileSync(pathDocsApiLocalization, 'utf-8');
localizationContent = localizationContent.replace(
/(^<!-- LOCALES-AUTO-GENERATED-START -->$).*(^<!-- LOCALES-AUTO-GENERATED-END -->$)/gms,
`$1\n\n<!-- Run '${scriptCommand}' to update. -->\n\n${localizationLocales}\n$2`
);
writeFileSync(pathDocsApiLocalization, localizationContent);
5 changes: 5 additions & 0 deletions src/locale/af_ZA.ts
@@ -1,3 +1,8 @@
/*
* This file is automatically generated.
* Run 'pnpm run generate:locales' to update.
*/

import { Faker } from '..';
import af_ZA from '../locales/af_ZA';
import en from '../locales/en';
Expand Down
5 changes: 5 additions & 0 deletions src/locale/ar.ts
@@ -1,3 +1,8 @@
/*
* This file is automatically generated.
* Run 'pnpm run generate:locales' to update.
*/

import { Faker } from '..';
import ar from '../locales/ar';
import en from '../locales/en';
Expand Down
5 changes: 5 additions & 0 deletions src/locale/az.ts
@@ -1,3 +1,8 @@
/*
* This file is automatically generated.
* Run 'pnpm run generate:locales' to update.
*/

import { Faker } from '..';
import az from '../locales/az';
import en from '../locales/en';
Expand Down
5 changes: 5 additions & 0 deletions src/locale/cz.ts
@@ -1,3 +1,8 @@
/*
* This file is automatically generated.
* Run 'pnpm run generate:locales' to update.
*/

import { Faker } from '..';
import cz from '../locales/cz';
import en from '../locales/en';
Expand Down
5 changes: 5 additions & 0 deletions src/locale/de.ts
@@ -1,3 +1,8 @@
/*
* This file is automatically generated.
* Run 'pnpm run generate:locales' to update.
*/

import { Faker } from '..';
import de from '../locales/de';
import en from '../locales/en';
Expand Down
5 changes: 5 additions & 0 deletions src/locale/de_AT.ts
@@ -1,3 +1,8 @@
/*
* This file is automatically generated.
* Run 'pnpm run generate:locales' to update.
*/

import { Faker } from '..';
import de_AT from '../locales/de_AT';
import en from '../locales/en';
Expand Down
5 changes: 5 additions & 0 deletions src/locale/de_CH.ts
@@ -1,3 +1,8 @@
/*
* This file is automatically generated.
* Run 'pnpm run generate:locales' to update.
*/

import { Faker } from '..';
import de_CH from '../locales/de_CH';
import en from '../locales/en';
Expand Down
5 changes: 5 additions & 0 deletions src/locale/el.ts
@@ -1,3 +1,8 @@
/*
* This file is automatically generated.
* Run 'pnpm run generate:locales' to update.
*/

import { Faker } from '..';
import el from '../locales/el';
import en from '../locales/en';
Expand Down
5 changes: 5 additions & 0 deletions src/locale/en.ts
@@ -1,3 +1,8 @@
/*
* This file is automatically generated.
* Run 'pnpm run generate:locales' to update.
*/

import { Faker } from '..';
import en from '../locales/en';

Expand Down
5 changes: 5 additions & 0 deletions src/locale/en_AU.ts
@@ -1,3 +1,8 @@
/*
* This file is automatically generated.
* Run 'pnpm run generate:locales' to update.
*/

import { Faker } from '..';
import en_AU from '../locales/en_AU';
import en from '../locales/en';
Expand Down
5 changes: 5 additions & 0 deletions src/locale/en_AU_ocker.ts
@@ -1,3 +1,8 @@
/*
* This file is automatically generated.
* Run 'pnpm run generate:locales' to update.
*/

import { Faker } from '..';
import en_AU_ocker from '../locales/en_AU_ocker';
import en from '../locales/en';
Expand Down
5 changes: 5 additions & 0 deletions src/locale/en_BORK.ts
@@ -1,3 +1,8 @@
/*
* This file is automatically generated.
* Run 'pnpm run generate:locales' to update.
*/

import { Faker } from '..';
import en_BORK from '../locales/en_BORK';
import en from '../locales/en';
Expand Down
5 changes: 5 additions & 0 deletions src/locale/en_CA.ts
@@ -1,3 +1,8 @@
/*
* This file is automatically generated.
* Run 'pnpm run generate:locales' to update.
*/

import { Faker } from '..';
import en_CA from '../locales/en_CA';
import en from '../locales/en';
Expand Down
5 changes: 5 additions & 0 deletions src/locale/en_GB.ts
@@ -1,3 +1,8 @@
/*
* This file is automatically generated.
* Run 'pnpm run generate:locales' to update.
*/

import { Faker } from '..';
import en_GB from '../locales/en_GB';
import en from '../locales/en';
Expand Down
5 changes: 5 additions & 0 deletions src/locale/en_GH.ts
@@ -1,3 +1,8 @@
/*
* This file is automatically generated.
* Run 'pnpm run generate:locales' to update.
*/

import { Faker } from '..';
import en_GH from '../locales/en_GH';
import en from '../locales/en';
Expand Down
5 changes: 5 additions & 0 deletions src/locale/en_IE.ts
@@ -1,3 +1,8 @@
/*
* This file is automatically generated.
* Run 'pnpm run generate:locales' to update.
*/

import { Faker } from '..';
import en_IE from '../locales/en_IE';
import en from '../locales/en';
Expand Down
5 changes: 5 additions & 0 deletions src/locale/en_IND.ts
@@ -1,3 +1,8 @@
/*
* This file is automatically generated.
* Run 'pnpm run generate:locales' to update.
*/

import { Faker } from '..';
import en_IND from '../locales/en_IND';
import en from '../locales/en';
Expand Down
5 changes: 5 additions & 0 deletions src/locale/en_NG.ts
@@ -1,3 +1,8 @@
/*
* This file is automatically generated.
* Run 'pnpm run generate:locales' to update.
*/

import { Faker } from '..';
import en_NG from '../locales/en_NG';
import en from '../locales/en';
Expand Down
5 changes: 5 additions & 0 deletions src/locale/en_US.ts
@@ -1,3 +1,8 @@
/*
* This file is automatically generated.
* Run 'pnpm run generate:locales' to update.
*/

import { Faker } from '..';
import en_US from '../locales/en_US';
import en from '../locales/en';
Expand Down
5 changes: 5 additions & 0 deletions src/locale/en_ZA.ts
@@ -1,3 +1,8 @@
/*
* This file is automatically generated.
* Run 'pnpm run generate:locales' to update.
*/

import { Faker } from '..';
import en_ZA from '../locales/en_ZA';
import en from '../locales/en';
Expand Down
5 changes: 5 additions & 0 deletions src/locale/es.ts
@@ -1,3 +1,8 @@
/*
* This file is automatically generated.
* Run 'pnpm run generate:locales' to update.
*/

import { Faker } from '..';
import es from '../locales/es';
import en from '../locales/en';
Expand Down
5 changes: 5 additions & 0 deletions src/locale/es_MX.ts
@@ -1,3 +1,8 @@
/*
* This file is automatically generated.
* Run 'pnpm run generate:locales' to update.
*/

import { Faker } from '..';
import es_MX from '../locales/es_MX';
import en from '../locales/en';
Expand Down
5 changes: 5 additions & 0 deletions src/locale/fa.ts
@@ -1,3 +1,8 @@
/*
* This file is automatically generated.
* Run 'pnpm run generate:locales' to update.
*/

import { Faker } from '..';
import fa from '../locales/fa';
import en from '../locales/en';
Expand Down
5 changes: 5 additions & 0 deletions src/locale/fi.ts
@@ -1,3 +1,8 @@
/*
* This file is automatically generated.
* Run 'pnpm run generate:locales' to update.
*/

import { Faker } from '..';
import fi from '../locales/fi';
import en from '../locales/en';
Expand Down
5 changes: 5 additions & 0 deletions src/locale/fr.ts
@@ -1,3 +1,8 @@
/*
* This file is automatically generated.
* Run 'pnpm run generate:locales' to update.
*/

import { Faker } from '..';
import fr from '../locales/fr';
import en from '../locales/en';
Expand Down