Skip to content

Commit

Permalink
feat: add useEmptyString option to generate empty string as a value f…
Browse files Browse the repository at this point in the history
…or new keys
  • Loading branch information
felixmosh committed Jun 1, 2021
1 parent 8f07edd commit 22ce291
Show file tree
Hide file tree
Showing 7 changed files with 113 additions and 11 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ syncLocales({
| localesFolder | `string` | |
| outputFolder | `string?` | `localesFolder` |
| overridePluralRules | `(pluralResolver: PluralResolver)? => PluralResolver` | |
| useEmptyString | `boolean` | `false` |


Currently, the lib supports only `.json` locale files, PRs are welcome :].
Expand Down
9 changes: 9 additions & 0 deletions src/cli.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,14 @@ const options = yargs.usage('i18next-locales-sync -p en -s de ja he -l ./path/to
type: 'string',
normalize: true,
},
useEmptyString: {
alias: 'e',
description: 'Use empty string as a value for new keys',
type: 'boolean',
normalize: true,
default: false,
defaultDescription: '`false`',
},
}).argv;

if (options.config) {
Expand Down Expand Up @@ -74,4 +82,5 @@ syncLocales({
localesFolder: options.localesFolder,
outputFolder: options.outputFolder,
overridePluralRules: options.overridePluralRules as any,
useEmptyString: options.useEmptyString,
});
3 changes: 3 additions & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ interface SyncLocalesOptions {
outputFolder?: string;
fileExtension?: string;
overridePluralRules?: (pluralResolver: PluralResolver) => PluralResolver;
useEmptyString?: boolean;
}

export function syncLocales({
Expand All @@ -21,6 +22,7 @@ export function syncLocales({
outputFolder = localesFolder,
overridePluralRules,
fileExtension = '.json',
useEmptyString = false,
}: SyncLocalesOptions) {
const pluralResolver = new PluralResolver();

Expand All @@ -40,6 +42,7 @@ export function syncLocales({
primaryLanguage,
otherLanguages,
pluralResolver,
useEmptyString,
});

writeToDisk({
Expand Down
45 changes: 34 additions & 11 deletions src/syncJson.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,26 +18,38 @@ function generatePluralForms(
targetObject: JSONObject;
newTargetObject: JSONObject;
sourceKey: string;
sourceValue: JSONValue;
targetValue: JSONValue;
sourceLng: string;
targetLng: string;
},
pluralResolver: PluralResolver
pluralResolver: PluralResolver,
useEmptyString = false
) {
const singularSourceKey = pluralResolver.getSingularFormOfKey(sourceKey, sourceLng);

const pluralForms = pluralResolver.getPluralFormsOfKey(singularSourceKey, targetLng);
const fallbackValue = useEmptyString ? '' : sourceObject[sourceKey];

pluralForms.forEach((key) => {
newTargetObject[key] =
(targetObject && targetObject[key] && !isObject(targetObject[key])
? targetObject[key]
: sourceObject[key]) || sourceObject[sourceKey];
: useEmptyString
? ''
: sourceObject[key]) || fallbackValue;
});
}

function syncEntry(sourceLng: string, targetLng: string, pluralResolver: PluralResolver) {
function syncEntry({
sourceLng,
targetLng,
pluralResolver,
useEmptyString,
}: {
sourceLng: string;
targetLng: string;
pluralResolver: PluralResolver;
useEmptyString?: boolean;
}) {
const sourceSuffixes = pluralResolver.getPluralFormsOfKey('', sourceLng).filter(Boolean);
const targetSuffixes = pluralResolver.getPluralFormsOfKey('', targetLng).filter(Boolean);

Expand All @@ -62,17 +74,16 @@ function syncEntry(sourceLng: string, targetLng: string, pluralResolver: PluralR
sourceObject,
targetObject,
newTargetObject,
sourceValue,
targetValue,
sourceKey,
sourceLng,
targetLng,
},
pluralResolver
pluralResolver,
useEmptyString
);
} else {
newTargetObject[sourceKey] =
targetValue && !isObject(targetValue) ? targetValue : sourceValue;
targetValue && !isObject(targetValue) ? targetValue : useEmptyString ? '' : sourceValue;

// keeps existing plural forms
targetSuffixes.forEach((suffix) => {
Expand All @@ -91,13 +102,25 @@ interface SyncJsonOptions {
target: LocaleObject;
pluralResolver: PluralResolver;
depth?: number;
useEmptyString?: boolean;
}

export function syncJson({ source, target, pluralResolver, depth = MAX_DEPTH }: SyncJsonOptions) {
export function syncJson({
source,
target,
pluralResolver,
depth = MAX_DEPTH,
useEmptyString = false,
}: SyncJsonOptions) {
target.data = traverse(
source.data,
target.data,
syncEntry(source.language, target.language, pluralResolver),
syncEntry({
sourceLng: source.language,
targetLng: target.language,
pluralResolver,
useEmptyString,
}),
depth
);

Expand Down
3 changes: 3 additions & 0 deletions src/syncLocaleFiles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,15 @@ interface Options {
primaryLanguage: string;
otherLanguages: string[];
pluralResolver: PluralResolver;
useEmptyString?: boolean;
}

export function syncLocaleFiles({
localeFiles,
primaryLanguage,
otherLanguages,
pluralResolver,
useEmptyString,
}: Options): LocalesFiles {
const primaryLocaleFiles = localeFiles[primaryLanguage];
otherLanguages.forEach((currentLanguage) => {
Expand All @@ -24,6 +26,7 @@ export function syncLocaleFiles({
source: { data: primaryLocaleFiles[primaryNamespace].data, language: primaryLanguage },
target: { data: currentNamespaces[primaryNamespace].data, language: currentLanguage },
pluralResolver,
useEmptyString,
});

currentNamespaces[primaryNamespace].data = data;
Expand Down
21 changes: 21 additions & 0 deletions test/syncJson/basicKeys.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -140,4 +140,25 @@ describe('syncJson: basic keys', () => {
);
});
});

describe('useEmptyString = true', () => {
it('should add missing keys in json and use empty string', () => {
const source = {
data: { foo: 'foo', nested: { bar: 'bar', array: [1, 2] } },
language: 'en',
};
const actual = syncJson({
source,
target: { data: { foo: 'he foo' }, language: 'he' },
pluralResolver,
useEmptyString: true,
});

expect(actual.data).toStrictEqual({
foo: 'he foo',
nested: { bar: '', array: ['', ''] },
});
expect(source).toStrictEqual(source);
});
});
});
42 changes: 42 additions & 0 deletions test/syncJson/plurals.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,27 @@ describe('syncJson: plurals', () => {
});
});

it('should add plural form with empty string as a value', () => {
const source = {
data: { book: 'book en', book_plural: 'books en' },
language: 'en',
};
const actual = syncJson({
source,
target: { data: { book_0: 'book he 0' }, language: 'he' },
pluralResolver,
useEmptyString: true,
});

expect(actual.data).toStrictEqual({
book: '',
book_0: 'book he 0',
book_1: '',
book_2: '',
book_3: '',
});
});

it('should add plural form only if the target language needs it', () => {
const source = {
data: { book: 'book en', book_plural: 'books en' },
Expand Down Expand Up @@ -67,6 +88,27 @@ describe('syncJson: plurals', () => {
});
});

it('should not override existing values', () => {
const source = {
data: { book: 'book en', book_plural: 'books en' },
language: 'en',
};
const actual = syncJson({
source,
target: {
data: { book: 'book de' },
language: 'de',
},
pluralResolver,
useEmptyString: true,
});

expect(actual.data).toStrictEqual({
book: 'book de',
book_plural: '',
});
});

it('should handle plural of none standard plural form as a source (he)', () => {
const source = {
data: {
Expand Down

0 comments on commit 22ce291

Please sign in to comment.