Skip to content

Commit

Permalink
feat(locales): add mergeLocales utility (#1707)
Browse files Browse the repository at this point in the history
  • Loading branch information
ST-DDT authored Jan 13, 2023
1 parent 47b2cfc commit 788fce0
Show file tree
Hide file tree
Showing 2 changed files with 96 additions and 0 deletions.
37 changes: 37 additions & 0 deletions src/utils/merge-locales.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import type { LocaleDefinition } from '..';

/**
* Merges the given locales into one locale.
* The locales are merged in the order they are given.
* The first locale that provides an entry for a category will be used for that.
* Mutating the category entries in the returned locale will also mutate the entries in the respective source locale.
*
* @param locales The locales to merge.
* @returns The newly merged locale.
*
* @example
* const de_CH_with_fallbacks = mergeLocales([ de_CH, de, en ]);
*/
export function mergeLocales(locales: LocaleDefinition[]): LocaleDefinition {
const merged: LocaleDefinition = {} as LocaleDefinition;

for (const locale of locales) {
for (const key in locale) {
if (merged[key] === undefined) {
if (typeof locale[key] === 'object') {
merged[key] = { ...locale[key] };
} else {
merged[key] = locale[key];
}
} else {
if (typeof locale[key] === 'object') {
merged[key] = { ...locale[key], ...merged[key] };
} else {
// Primitive values cannot be merged
}
}
}
}

return merged;
}
59 changes: 59 additions & 0 deletions test/utils/merge-locales.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
import { describe, expect, it } from 'vitest';
import type { LocaleDefinition } from '../../src';
import { mergeLocales } from '../../src/utils/merge-locales';

describe('mergeLocales', () => {
it('should not overwrite entries', () => {
const locale1: LocaleDefinition = {
title: 'a',
person: { firstName: ['a'] },
finance: { credit_card: { visa: ['a'] } },
};
const locale2: LocaleDefinition = {
title: 'b',
person: { firstName: ['b'] },
finance: { credit_card: { mastercard: ['b'] } },
};
const locale3: LocaleDefinition = {
title: 'c',
person: { firstName: ['c'] },
finance: { credit_card: {} },
};

const merged = mergeLocales([locale1, locale2, locale3]);

expect(merged).toEqual({
title: 'a',
person: { firstName: ['a'] },
finance: { credit_card: { visa: ['a'] } },
});
});

it('should extend categories', () => {
const locale1: LocaleDefinition = {
title: 'a',
location: { city: ['a'] },
person: { first_name: ['a'] },
};
const locale2: LocaleDefinition = {
title: 'b',
animal: { cat: ['b'] },
person: { last_name: ['b'] },
};
const locale3: LocaleDefinition = {
title: 'c',
color: { human: ['c'] },
person: {},
};

const merged = mergeLocales([locale1, locale2, locale3]);

expect(merged).toEqual({
title: 'a',
animal: { cat: ['b'] },
color: { human: ['c'] },
location: { city: ['a'] },
person: { first_name: ['a'], last_name: ['b'] },
});
});
});

0 comments on commit 788fce0

Please sign in to comment.