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(locales): add mergeLocales utility #1707

Merged
merged 13 commits into from
Jan 13, 2023
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 'src';

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

for (const locale of locales) {
for (const key in locale) {
if (merged[key] === undefined) {
if (typeof locale[key] === 'object') {
ST-DDT marked this conversation as resolved.
Show resolved Hide resolved
merged[key] = { ...locale[key] };
} else {
merged[key] = locale[key];
}
} else {
if (typeof locale[key] === 'object') {
merged[key] = { ...locale[key], ...merged[key] };
} else {
// Do nothing
ST-DDT marked this conversation as resolved.
Show resolved Hide resolved
}
}
}
}

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

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

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

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

it('should extend locales', () => {
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'] },
});
});
});
ST-DDT marked this conversation as resolved.
Show resolved Hide resolved