Skip to content

Commit

Permalink
feat: multi locale fallback
Browse files Browse the repository at this point in the history
  • Loading branch information
ST-DDT committed Apr 20, 2022
1 parent b10f00c commit 75ffa2e
Show file tree
Hide file tree
Showing 82 changed files with 188 additions and 201 deletions.
16 changes: 10 additions & 6 deletions scripts/generateLocales.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import { resolve } from 'node:path';
import type { Options } from 'prettier';
import { format } from 'prettier';
import options from '../.prettierrc.cjs';
import { faker } from '../src';
import type { LocaleDefinition } from '../src/definitions';
import { DEFINITIONS } from '../src/definitions';

Expand Down Expand Up @@ -81,19 +82,22 @@ function containsAll(checked?: string[], expected?: string[]): boolean {
}

function generateLocaleFile(locale: string): void {
faker.setLocale(locale);

const localeOrder = faker.localeOrder;

let content = `
${autoGeneratedCommentHeader}
import { Faker } from '../faker';
import ${locale} from '../locales/${locale}';
${locale !== 'en' ? "import en from '../locales/en';" : ''}
${localeOrder
.map((entry) => `import ${entry} from '../locales/${entry}';`)
.join('\n')}
const faker = new Faker({
locale: '${locale}',
localeFallback: 'en',
localeOrder: ${JSON.stringify(localeOrder)},
locales: {
${locale},
${locale !== 'en' ? 'en,' : ''}
${localeOrder.map((entry) => `${entry},`).join('\n')}
},
});
Expand Down
48 changes: 35 additions & 13 deletions src/faker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,14 +38,12 @@ export type UsedLocales = Partial<Record<UsableLocale, LocaleDefinition>>;

export interface FakerOptions {
locales: UsedLocales;
locale?: UsableLocale;
localeFallback?: UsableLocale;
localeOrder?: UsableLocale[];
}

export class Faker {
locales: UsedLocales;
locale: UsableLocale;
localeFallback: UsableLocale;
localeOrder: UsableLocale[];

readonly definitions: LocaleDefinition = this.initDefinitions();

Expand Down Expand Up @@ -95,25 +93,35 @@ export class Faker {
}

this.locales = opts.locales;
this.locale = opts.locale || 'en';
this.localeFallback = opts.localeFallback || 'en';
this.localeOrder = opts.localeOrder ?? ['en'];
}

/**
* Creates a Proxy based LocaleDefinition that virtually merges the locales.
*/
private initDefinitions(): LocaleDefinition {
// Returns the first resolved locale data that aren't undefined
const findFirst = <T>(
resolver: (data: LocaleDefinition) => T | undefined
): T | undefined => {
for (const locale of this.localeOrder) {
const baseData = resolver(this.locales[locale]);
if (baseData != null) {
return baseData;
}
}
return undefined;
};

// Returns the first LocaleDefinition[key] in any locale
const resolveBaseData = (key: keyof LocaleDefinition): unknown =>
this.locales[this.locale][key] ?? this.locales[this.localeFallback][key];
findFirst((data) => data[key]);

// Returns the first LocaleDefinition[module][entry] in any locale
const resolveModuleData = (
module: keyof LocaleDefinition,
entry: string
): unknown =>
this.locales[this.locale][module]?.[entry] ??
this.locales[this.localeFallback][module]?.[entry];
): unknown => findFirst((data) => data[module]?.[entry]);

// Returns a proxy that can return the entries for a module (if it exists)
const moduleLoader = (
Expand Down Expand Up @@ -159,11 +167,25 @@ export class Faker {
}

/**
* Set Faker's locale
* Set Faker's locale using the default fallback strategy.
*
* @param locale The locale to set (e.g. `en` or `en_AU`, `en_AU_ocker`).
* @param fallbacks The fixed fallbacks to use. Defaults to `['en']`.
*/
setLocale(locale: UsableLocale): void {
this.locale = locale;
setLocale(locale: UsableLocale, fallbacks: UsableLocale[] = ['en']): void {
const localeOrder = [];
const parts = locale.split('_');
for (let i = parts.length; i > 0; i--) {
const subLocale = parts.slice(0, i).join('_');
if (this.locales[subLocale] != null) {
localeOrder.push(subLocale);
}
}
for (const fallback of fallbacks) {
if (!localeOrder.includes(fallback) && this.locales[fallback] != null) {
localeOrder.push(fallback);
}
}
this.localeOrder = localeOrder;
}
}
3 changes: 1 addition & 2 deletions src/locale/af_ZA.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,7 @@ import af_ZA from '../locales/af_ZA';
import en from '../locales/en';

const faker = new Faker({
locale: 'af_ZA',
localeFallback: 'en',
localeOrder: ['af_ZA', 'en'],
locales: {
af_ZA,
en,
Expand Down
3 changes: 1 addition & 2 deletions src/locale/ar.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,7 @@ import ar from '../locales/ar';
import en from '../locales/en';

const faker = new Faker({
locale: 'ar',
localeFallback: 'en',
localeOrder: ['ar', 'en'],
locales: {
ar,
en,
Expand Down
3 changes: 1 addition & 2 deletions src/locale/az.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,7 @@ import az from '../locales/az';
import en from '../locales/en';

const faker = new Faker({
locale: 'az',
localeFallback: 'en',
localeOrder: ['az', 'en'],
locales: {
az,
en,
Expand Down
3 changes: 1 addition & 2 deletions src/locale/cz.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,7 @@ import cz from '../locales/cz';
import en from '../locales/en';

const faker = new Faker({
locale: 'cz',
localeFallback: 'en',
localeOrder: ['cz', 'en'],
locales: {
cz,
en,
Expand Down
3 changes: 1 addition & 2 deletions src/locale/de.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,7 @@ import de from '../locales/de';
import en from '../locales/en';

const faker = new Faker({
locale: 'de',
localeFallback: 'en',
localeOrder: ['de', 'en'],
locales: {
de,
en,
Expand Down
5 changes: 3 additions & 2 deletions src/locale/de_AT.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,15 @@
*/

import { Faker } from '../faker';
import de from '../locales/de';
import de_AT from '../locales/de_AT';
import en from '../locales/en';

const faker = new Faker({
locale: 'de_AT',
localeFallback: 'en',
localeOrder: ['de_AT', 'de', 'en'],
locales: {
de_AT,
de,
en,
},
});
Expand Down
5 changes: 3 additions & 2 deletions src/locale/de_CH.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,15 @@
*/

import { Faker } from '../faker';
import de from '../locales/de';
import de_CH from '../locales/de_CH';
import en from '../locales/en';

const faker = new Faker({
locale: 'de_CH',
localeFallback: 'en',
localeOrder: ['de_CH', 'de', 'en'],
locales: {
de_CH,
de,
en,
},
});
Expand Down
3 changes: 1 addition & 2 deletions src/locale/el.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,7 @@ import el from '../locales/el';
import en from '../locales/en';

const faker = new Faker({
locale: 'el',
localeFallback: 'en',
localeOrder: ['el', 'en'],
locales: {
el,
en,
Expand Down
3 changes: 1 addition & 2 deletions src/locale/en.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,7 @@ import { Faker } from '../faker';
import en from '../locales/en';

const faker = new Faker({
locale: 'en',
localeFallback: 'en',
localeOrder: ['en'],
locales: {
en,
},
Expand Down
3 changes: 1 addition & 2 deletions src/locale/en_AU.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,7 @@ import en from '../locales/en';
import en_AU from '../locales/en_AU';

const faker = new Faker({
locale: 'en_AU',
localeFallback: 'en',
localeOrder: ['en_AU', 'en'],
locales: {
en_AU,
en,
Expand Down
5 changes: 3 additions & 2 deletions src/locale/en_AU_ocker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,14 @@

import { Faker } from '../faker';
import en from '../locales/en';
import en_AU from '../locales/en_AU';
import en_AU_ocker from '../locales/en_AU_ocker';

const faker = new Faker({
locale: 'en_AU_ocker',
localeFallback: 'en',
localeOrder: ['en_AU_ocker', 'en_AU', 'en'],
locales: {
en_AU_ocker,
en_AU,
en,
},
});
Expand Down
3 changes: 1 addition & 2 deletions src/locale/en_BORK.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,7 @@ import en from '../locales/en';
import en_BORK from '../locales/en_BORK';

const faker = new Faker({
locale: 'en_BORK',
localeFallback: 'en',
localeOrder: ['en_BORK', 'en'],
locales: {
en_BORK,
en,
Expand Down
3 changes: 1 addition & 2 deletions src/locale/en_CA.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,7 @@ import en from '../locales/en';
import en_CA from '../locales/en_CA';

const faker = new Faker({
locale: 'en_CA',
localeFallback: 'en',
localeOrder: ['en_CA', 'en'],
locales: {
en_CA,
en,
Expand Down
3 changes: 1 addition & 2 deletions src/locale/en_GB.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,7 @@ import en from '../locales/en';
import en_GB from '../locales/en_GB';

const faker = new Faker({
locale: 'en_GB',
localeFallback: 'en',
localeOrder: ['en_GB', 'en'],
locales: {
en_GB,
en,
Expand Down
3 changes: 1 addition & 2 deletions src/locale/en_GH.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,7 @@ import en from '../locales/en';
import en_GH from '../locales/en_GH';

const faker = new Faker({
locale: 'en_GH',
localeFallback: 'en',
localeOrder: ['en_GH', 'en'],
locales: {
en_GH,
en,
Expand Down
3 changes: 1 addition & 2 deletions src/locale/en_IE.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,7 @@ import en from '../locales/en';
import en_IE from '../locales/en_IE';

const faker = new Faker({
locale: 'en_IE',
localeFallback: 'en',
localeOrder: ['en_IE', 'en'],
locales: {
en_IE,
en,
Expand Down
3 changes: 1 addition & 2 deletions src/locale/en_IND.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,7 @@ import en from '../locales/en';
import en_IND from '../locales/en_IND';

const faker = new Faker({
locale: 'en_IND',
localeFallback: 'en',
localeOrder: ['en_IND', 'en'],
locales: {
en_IND,
en,
Expand Down
3 changes: 1 addition & 2 deletions src/locale/en_NG.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,7 @@ import en from '../locales/en';
import en_NG from '../locales/en_NG';

const faker = new Faker({
locale: 'en_NG',
localeFallback: 'en',
localeOrder: ['en_NG', 'en'],
locales: {
en_NG,
en,
Expand Down
3 changes: 1 addition & 2 deletions src/locale/en_US.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,7 @@ import en from '../locales/en';
import en_US from '../locales/en_US';

const faker = new Faker({
locale: 'en_US',
localeFallback: 'en',
localeOrder: ['en_US', 'en'],
locales: {
en_US,
en,
Expand Down
3 changes: 1 addition & 2 deletions src/locale/en_ZA.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,7 @@ import en from '../locales/en';
import en_ZA from '../locales/en_ZA';

const faker = new Faker({
locale: 'en_ZA',
localeFallback: 'en',
localeOrder: ['en_ZA', 'en'],
locales: {
en_ZA,
en,
Expand Down
3 changes: 1 addition & 2 deletions src/locale/es.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,7 @@ import en from '../locales/en';
import es from '../locales/es';

const faker = new Faker({
locale: 'es',
localeFallback: 'en',
localeOrder: ['es', 'en'],
locales: {
es,
en,
Expand Down
5 changes: 3 additions & 2 deletions src/locale/es_MX.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,14 @@

import { Faker } from '../faker';
import en from '../locales/en';
import es from '../locales/es';
import es_MX from '../locales/es_MX';

const faker = new Faker({
locale: 'es_MX',
localeFallback: 'en',
localeOrder: ['es_MX', 'es', 'en'],
locales: {
es_MX,
es,
en,
},
});
Expand Down
3 changes: 1 addition & 2 deletions src/locale/fa.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,7 @@ import en from '../locales/en';
import fa from '../locales/fa';

const faker = new Faker({
locale: 'fa',
localeFallback: 'en',
localeOrder: ['fa', 'en'],
locales: {
fa,
en,
Expand Down
3 changes: 1 addition & 2 deletions src/locale/fi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,7 @@ import en from '../locales/en';
import fi from '../locales/fi';

const faker = new Faker({
locale: 'fi',
localeFallback: 'en',
localeOrder: ['fi', 'en'],
locales: {
fi,
en,
Expand Down
Loading

0 comments on commit 75ffa2e

Please sign in to comment.