Skip to content

Commit f50a7ab

Browse files
committed
fix: Add failsafe if there is no php files or json files.
1 parent 69c5def commit f50a7ab

File tree

6 files changed

+76
-15
lines changed

6 files changed

+76
-15
lines changed

src/index.ts

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import { LanguageInterface } from './interfaces/language'
44
import { LanguageJsonFileInterface } from './interfaces/language-json-file'
55
import { ReplacementsInterface } from './interfaces/replacements'
66
import { choose } from './pluralization'
7+
import { avoidExceptionOnPromise, avoidException } from './utils/avoid-exceptions';
78

89
const isServer = typeof window === 'undefined'
910

@@ -139,12 +140,13 @@ function setLanguage({ lang, messages }: LanguageInterface): string {
139140
*/
140141
async function resolveLang(callable: Function, lang: string): Promise<LanguageJsonFileInterface> {
141142
const hasPhpTranslations = typeof process !== 'undefined' && process.env ? process.env.LARAVEL_VUE_I18N_HAS_PHP : false;
142-
const data = callable(lang)
143+
144+
let data = avoidException(callable, lang);
143145

144146
if (data instanceof Promise) {
145147
if (hasPhpTranslations) {
146-
const phpLang = await callable(`php_${lang}`);
147-
const jsonLang = await data;
148+
const phpLang = await avoidExceptionOnPromise(callable(`php_${lang}`));
149+
const jsonLang = await avoidExceptionOnPromise(data);
148150

149151
return new Promise((resolve) => resolve({
150152
default: {
@@ -154,14 +156,16 @@ async function resolveLang(callable: Function, lang: string): Promise<LanguageJs
154156
}));
155157
}
156158

157-
return data;
159+
return new Promise(async resolve => resolve({
160+
default: await avoidExceptionOnPromise(data),
161+
}));
158162
}
159163

160164
if (hasPhpTranslations) {
161165
return new Promise((resolve) => resolve({
162166
default: {
163167
...data,
164-
...(callable(`php_${lang}`)),
168+
...(avoidException(callable, `php_${lang}`)),
165169
}
166170
}));
167171
}

src/utils/avoid-exceptions.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
export const avoidException = (callback: Function, param, defaults = {}) => {
2+
try {
3+
return callback(param);
4+
} catch {
5+
return defaults;
6+
}
7+
}
8+
9+
export const avoidExceptionOnPromise = async (promise, defaults = {}) => {
10+
try {
11+
return (await promise).default || defaults;
12+
} catch (e) {
13+
return defaults;
14+
}
15+
}

test/fixtures/lang/es.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
"Welcome!": "Bienvenido!"
3+
}

test/fixtures/lang/fr/auth.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
<?php
2+
3+
return [
4+
'failed' => 'Ces identifiants ne correspondent pas à nos enregistrements.',
5+
];

test/setup.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,21 @@ global.mountPlugin = async (template = '<div />', lang = 'pt') => {
1717
return wrapper;
1818
}
1919

20+
global.mountPluginWithRequire = async (template = '<div />', lang = 'pt') => {
21+
const wrapper = mount({ template }, {
22+
global: {
23+
plugins: [[i18nVue, {
24+
lang,
25+
resolve: (lang) => require(`./fixtures/lang/${lang}.json`),
26+
}]]
27+
}
28+
});
29+
30+
await new Promise(resolve => setTimeout(resolve))
31+
32+
return wrapper;
33+
}
34+
2035
global.mixLoader = () => {
2136
parseAll(__dirname + '/fixtures/lang/');
2237

test/translate.test.ts

Lines changed: 29 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -125,16 +125,7 @@ it('resolves translated data without Promise', async () => {
125125
});
126126

127127
it('resolves translated data with require', async () => {
128-
const wrapper = mount({ template: `<h1>{{ $t('Welcome!') }}</h1>` }, {
129-
global: {
130-
plugins: [[i18nVue, {
131-
lang: 'pt',
132-
resolve: (lang) => require(`./fixtures/lang/${lang}.json`),
133-
}]]
134-
}
135-
});
136-
137-
await new Promise(resolve => setTimeout(resolve));
128+
const wrapper = await global.mountPluginWithRequire(`<h1>{{ $t('Welcome!') }}</h1>`);
138129

139130
expect(trans('Welcome!')).toBe('Bem-vindo!');
140131
});
@@ -145,3 +136,31 @@ it('resolves translated data from .php files', async () => {
145136

146137
expect(wrapper.html()).toBe('<h1>As credenciais indicadas não coincidem com as registadas no sistema.</h1>')
147138
});
139+
140+
it('resolves translated data with loader if there is no .php files for that lang', async () => {
141+
global.mixLoader();
142+
const wrapper = await global.mountPlugin(`<h1 v-text="$t('Welcome!')" />`, 'es');
143+
144+
expect(wrapper.html()).toBe('<h1>Bienvenido!</h1>')
145+
})
146+
147+
it('resolves translated data with loader if there is no .php files for that lang with require', async () => {
148+
global.mixLoader();
149+
const wrapper = await global.mountPluginWithRequire(`<h1 v-text="$t('Welcome!')" />`, 'es');
150+
151+
expect(wrapper.html()).toBe('<h1>Bienvenido!</h1>')
152+
});
153+
154+
it('resolves translated data with loader if there is only .php files for that lang', async () => {
155+
global.mixLoader();
156+
const wrapper = await global.mountPlugin(`<h1 v-text="$t('auth.failed')" />`, 'fr');
157+
158+
expect(wrapper.html()).toBe('<h1>Ces identifiants ne correspondent pas à nos enregistrements.</h1>')
159+
})
160+
161+
it('resolves translated data with loader if there is only .php files for that lang with require', async () => {
162+
global.mixLoader();
163+
const wrapper = await global.mountPluginWithRequire(`<h1 v-text="$t('auth.failed')" />`, 'fr');
164+
165+
expect(wrapper.html()).toBe('<h1>Ces identifiants ne correspondent pas à nos enregistrements.</h1>')
166+
})

0 commit comments

Comments
 (0)