diff --git a/src/client/includes/flatObj.ts b/src/client/includes/flatObj.ts new file mode 100644 index 0000000..7265394 --- /dev/null +++ b/src/client/includes/flatObj.ts @@ -0,0 +1,14 @@ +// could use a reduce, but a simple for-in has less footprint +export const flatObj = (obj: Record, prefix = '') => { + const flatted: Record = {} + for (const key in obj) { + const flatKey = prefix + key + // we want plain objects and arrays + if (typeof obj[key] === 'object') { + Object.assign(flatted, flatObj(obj[key], `${flatKey}.`)) + } else { + flatted[flatKey] = obj[key] + } + } + return flatted +} diff --git a/src/client/includes/getClientLocale.ts b/src/client/includes/getClientLocale.ts new file mode 100644 index 0000000..a131e0d --- /dev/null +++ b/src/client/includes/getClientLocale.ts @@ -0,0 +1,59 @@ +import { GetClientLocaleOptions } from '../types' + +const getFromQueryString = (queryString: string, key: string) => { + const keyVal = queryString.split('&').find(i => i.indexOf(`${key}=`) === 0) + + if (keyVal) { + return keyVal.split('=').pop() + } + return null +} + +const getFirstMatch = (base: string, pattern: RegExp) => { + const match = pattern.exec(base) + // istanbul ignore if + if (!match) return null + // istanbul ignore else + return match[1] || null +} + +export const getClientLocale = ({ + navigator, + hash, + search, + pathname, + hostname, +}: GetClientLocaleOptions) => { + let locale + + // istanbul ignore next + if (typeof window === 'undefined') return null + + if (hostname) { + locale = getFirstMatch(window.location.hostname, hostname) + if (locale) return locale + } + + if (pathname) { + locale = getFirstMatch(window.location.pathname, pathname) + if (locale) return locale + } + + if (navigator) { + // istanbul ignore else + locale = window.navigator.language || window.navigator.languages[0] + if (locale) return locale + } + + if (search) { + locale = getFromQueryString(window.location.search.substr(1), search) + if (locale) return locale + } + + if (hash) { + locale = getFromQueryString(window.location.hash.substr(1), hash) + if (locale) return locale + } + + return null +} diff --git a/src/runtime/configs.ts b/src/runtime/configs.ts index d15a0d8..a3603f7 100644 --- a/src/runtime/configs.ts +++ b/src/runtime/configs.ts @@ -1,4 +1,4 @@ -import { getClientLocale } from './includes/utils' +import { getClientLocale } from './includes/getClientLocale' import { ConfigureOptions } from './types' import { $locale } from './stores/locale' diff --git a/src/runtime/includes/utils.ts b/src/runtime/includes/utils.ts index 5b70ea6..a131e0d 100644 --- a/src/runtime/includes/utils.ts +++ b/src/runtime/includes/utils.ts @@ -1,20 +1,5 @@ import { GetClientLocaleOptions } from '../types' -// could use a reduce, but a simple for-in has less footprint -export const flatObj = (obj: Record, prefix = '') => { - const flatted: Record = {} - for (const key in obj) { - const flatKey = prefix + key - // we want plain objects and arrays - if (typeof obj[key] === 'object') { - Object.assign(flatted, flatObj(obj[key], `${flatKey}.`)) - } else { - flatted[flatKey] = obj[key] - } - } - return flatted -} - const getFromQueryString = (queryString: string, key: string) => { const keyVal = queryString.split('&').find(i => i.indexOf(`${key}=`) === 0) diff --git a/src/runtime/stores/dictionary.ts b/src/runtime/stores/dictionary.ts index a4c5127..80bd669 100644 --- a/src/runtime/stores/dictionary.ts +++ b/src/runtime/stores/dictionary.ts @@ -1,7 +1,7 @@ import { writable, derived } from 'svelte/store' -import { LocaleDictionary, DeepDictionary, Dictionary } from '../types' -import { flatObj } from '../includes/utils' +import { LocaleDictionary, DeepDictionary, Dictionary } from '../types/index' +import { flatObj } from '../includes/flatObj' import { getFallbackOf } from './locale' diff --git a/test/runtime/includes/utils.test.ts b/test/runtime/includes/utils.test.ts index a5b45c2..8adfc1e 100644 --- a/test/runtime/includes/utils.test.ts +++ b/test/runtime/includes/utils.test.ts @@ -1,11 +1,5 @@ -import { - getClientLocale, - capital, - title, - upper, - lower, - flatObj, -} from '../../../src/runtime/includes/utils' +import { getClientLocale } from '../../../src/client/includes/getClientLocale' +import { flatObj } from '../../../src/client/includes/flatObj' describe('getting client locale', () => { beforeEach(() => { @@ -113,24 +107,6 @@ describe('getting client locale', () => { }) }) -describe('string utilities', () => { - test('transforms a string into capital case', () => { - expect(capital('lowercase string')).toMatch('Lowercase string') - }) - - test('transforms a string into title case', () => { - expect(title('lowercase string')).toMatch('Lowercase String') - }) - - test('transforms a string into uppercase', () => { - expect(upper('lowercase string')).toMatch('LOWERCASE STRING') - }) - - test('transforms a string into lowercase', () => { - expect(lower('UPPERCASE STRING')).toMatch('uppercase string') - }) -}) - describe('deep object handling', () => { test('flattens a deep object', () => { const obj = {