@midwayjs/i18n 3.0.0-beta.7 → 3.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,9 +1,175 @@
1
- # midwayjs i18n Component
1
+ # midway i18n Component
2
2
 
3
- Document: [https://midwayjs.org/midway](https://midwayjs.org/midway)
3
+ ## Install
4
+
5
+ ```bash
6
+ $ npm i @midwayjs/i18n --save
7
+ ```
4
8
 
5
9
  ## Usage
6
10
 
11
+ add component in your configuration.
12
+
13
+ ```ts
14
+ import * as koa from '@midwayjs/koa';
15
+ import * as i18n from '@midwayjs/i18n';
16
+
17
+ @Configuratino({
18
+ imports: [
19
+ koa,
20
+ i18n
21
+ ]
22
+ })
23
+ ```
24
+
25
+ You can use `translate` method to translate your message.
26
+
27
+ ```ts
28
+ @Controller('/')
29
+ export class UserController {
30
+
31
+ @Inject()
32
+ i18nService: MidwayI18nService;
33
+
34
+ @Get('/')
35
+ async index(@Query('username') username: string) {
36
+ return this.i18nService.translate('HELLO_MESSAGE', {
37
+ args: {
38
+ username
39
+ },
40
+ });
41
+ }
42
+ }
43
+
44
+ ```
45
+
46
+ ## Default Config
47
+
48
+ ```ts
49
+ // config/config.default.js
50
+ export const i18n = {
51
+ // default locale "en_US"
52
+ defaultLocale: 'en_US',
53
+
54
+ // your can put your translate message here
55
+ localeTable: {
56
+ en_US: {
57
+ // group name
58
+ default: {
59
+ // hello: 'hello'
60
+ }
61
+ },
62
+ zh_CN: {
63
+ // group name
64
+ default: {
65
+ // hello: '你好'
66
+ }
67
+ },
68
+ fallbacks: {
69
+ // 'en_*': 'en_US',
70
+ // pt: 'pt-BR',
71
+ },
72
+ writeCookie: true,
73
+ resolver: {
74
+ // URL parameter,default is "locale"
75
+ queryField: 'locale',
76
+ // Header key, default is "locale"
77
+ headerField: 'locale',
78
+ cookieField: {
79
+ fieldName: 'locale',
80
+ // Cookie domain,default is empty,valid in current domain
81
+ cookieDomain: '',
82
+ // Default validity period, one year.
83
+ cookieMaxAge: FORMAT.MS.ONE_YEAR,
84
+ },
85
+ },
86
+ },
87
+ };
88
+ ```
89
+
90
+ ## Message Format
91
+
92
+ Support Object and Array.
93
+
94
+ **Object**
95
+
96
+ ```ts
97
+ this.i18nService.translate('HELLO_MESSAGE {username}', {
98
+ args: {
99
+ username
100
+ },
101
+ });
102
+ ```
103
+
104
+ **Array**
105
+
106
+ ```ts
107
+ this.i18nService.translate('HELLO_MESSAGE {0} {1}', {
108
+ args: ['harry', 'chen'],
109
+ });
110
+ ```
111
+
112
+ ## Web locale Setting
113
+
114
+ In the egg/koa/express/faas, current locale will be obtained based on query, header, and cookie.
115
+
116
+
117
+ ## Locale Text
118
+
119
+ | locale | locale Text |
120
+ | :--------------- | :------- |
121
+ | 阿拉伯 | ar_EG |
122
+ | 亞美尼亞 | hy_AM |
123
+ | 保加利亚语 | bg_BG |
124
+ | 加泰罗尼亚语 | ca_ES |
125
+ | 捷克语 | cs_CZ |
126
+ | 丹麦语 | da_DK |
127
+ | 德语 | de_DE |
128
+ | 希腊语 | el_GR |
129
+ | 英语 | en_GB |
130
+ | 英语(美式) | en_US |
131
+ | 西班牙语 | es_ES |
132
+ | 爱沙尼亚语 | et_EE |
133
+ | 波斯语 | fa_IR |
134
+ | 芬兰语 | fi_FI |
135
+ | 法语(比利时) | fr_BE |
136
+ | 法语 | fr_FR |
137
+ | 希伯来语 | he_IL |
138
+ | 印地语 | hi_IN |
139
+ | 克罗地亚语 | hr_HR |
140
+ | 匈牙利 | hu_HU |
141
+ | 冰岛语 | is_IS |
142
+ | 印度尼西亚语 | id_ID |
143
+ | 意大利语 | it_IT |
144
+ | 日语 | ja_JP |
145
+ | 格鲁吉亚语 | ka_GE |
146
+ | 卡纳达语 | kn_IN |
147
+ | 韩语/朝鲜语 | ko_KR |
148
+ | 库尔德语 | ku_IQ |
149
+ | 拉脱维亚语 | lv_LV |
150
+ | 马来语 | ms_MY |
151
+ | 蒙古语 | mn_MN |
152
+ | 挪威 | nb_NO |
153
+ | 尼泊尔语 | ne_NP |
154
+ | 荷兰语(比利时) | nl_BE |
155
+ | 荷兰语 | nl_NL |
156
+ | 波兰语 | pl_PL |
157
+ | 葡萄牙语(巴西) | pt_BR |
158
+ | 葡萄牙语 | pt_PT |
159
+ | 斯洛伐克语 | sk_SK |
160
+ | 塞尔维亚 | sr_RS |
161
+ | 斯洛文尼亚 | sl_SI |
162
+ | 瑞典语 | sv_SE |
163
+ | 泰米尔语 | ta_IN |
164
+ | 泰语 | th_TH |
165
+ | 土耳其语 | tr_TR |
166
+ | 罗马尼亚语 | ro_RO |
167
+ | 俄罗斯语 | ru_RU |
168
+ | 乌克兰语 | uk_UA |
169
+ | 越南语 | vi_VN |
170
+ | 简体中文 | zh_CN |
171
+ | 繁体中文 | zh_TW |
172
+
7
173
  ## License
8
174
 
9
175
  [MIT]((http://github.com/midwayjs/midway/blob/master/LICENSE))
@@ -0,0 +1,3 @@
1
+ import { I18nOptions } from '../interface';
2
+ export declare const i18n: I18nOptions;
3
+ //# sourceMappingURL=config.default.d.ts.map
@@ -0,0 +1,24 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.i18n = void 0;
4
+ const decorator_1 = require("@midwayjs/decorator");
5
+ exports.i18n = {
6
+ defaultLocale: 'en_US',
7
+ localeTable: {
8
+ en_US: {},
9
+ },
10
+ fallbacks: {
11
+ // 'en_*': 'en_US',
12
+ // pt: 'pt-BR',
13
+ },
14
+ writeCookie: true,
15
+ resolver: {
16
+ queryField: 'locale',
17
+ cookieField: {
18
+ fieldName: 'locale',
19
+ cookieDomain: '',
20
+ cookieMaxAge: decorator_1.FORMAT.MS.ONE_YEAR,
21
+ },
22
+ },
23
+ };
24
+ //# sourceMappingURL=config.default.js.map
@@ -1,3 +1,6 @@
1
+ import { MidwayApplicationManager } from '@midwayjs/core';
1
2
  export declare class I18nConfiguration {
3
+ applicationManager: MidwayApplicationManager;
4
+ onReady(): Promise<void>;
2
5
  }
3
6
  //# sourceMappingURL=configuration.d.ts.map
@@ -5,12 +5,28 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
5
5
  else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
6
6
  return c > 3 && r && Object.defineProperty(target, key, r), r;
7
7
  };
8
+ var __metadata = (this && this.__metadata) || function (k, v) {
9
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
10
+ };
8
11
  Object.defineProperty(exports, "__esModule", { value: true });
9
12
  exports.I18nConfiguration = void 0;
10
13
  const decorator_1 = require("@midwayjs/decorator");
11
- const DefaultConfig = require("./config.default");
14
+ const DefaultConfig = require("./config/config.default");
15
+ const core_1 = require("@midwayjs/core");
16
+ const middleware_1 = require("./middleware");
12
17
  let I18nConfiguration = class I18nConfiguration {
18
+ async onReady() {
19
+ this.applicationManager
20
+ .getApplications(['koa', 'egg', 'faas', 'express'])
21
+ .forEach(app => {
22
+ app.useMiddleware(middleware_1.I18nMiddleware);
23
+ });
24
+ }
13
25
  };
26
+ __decorate([
27
+ (0, decorator_1.Inject)(),
28
+ __metadata("design:type", core_1.MidwayApplicationManager)
29
+ ], I18nConfiguration.prototype, "applicationManager", void 0);
14
30
  I18nConfiguration = __decorate([
15
31
  (0, decorator_1.Configuration)({
16
32
  namespace: 'i18n',
@@ -1,10 +1,81 @@
1
1
  import { TranslateOptions } from './interface';
2
+ import { IMidwayContext } from '@midwayjs/core';
3
+ export declare class MidwayI18nServiceSingleton {
4
+ private i18nConfig;
5
+ private localeTextMap;
6
+ private defaultLocale;
7
+ private fallbackMatch;
8
+ private localeMatchCache;
9
+ protected init(): Promise<void>;
10
+ /**
11
+ * add a language text mapping
12
+ * @param locale
13
+ * @param localeTextMapping
14
+ */
15
+ addLocale(locale: string, localeTextMapping: Record<string, any>): void;
16
+ /**
17
+ * translate a message
18
+ * @param message
19
+ * @param options
20
+ */
21
+ translate(message: string, options?: TranslateOptions): any;
22
+ /**
23
+ * get locale string by find fallback and default, ignore match message
24
+ * @param locale
25
+ * @param group
26
+ */
27
+ getAvailableLocale(locale: string, group?: string): any;
28
+ /**
29
+ * get available local in locale text map, include fallbacks
30
+ * @param locale
31
+ */
32
+ hasAvailableLocale(locale: string): boolean;
33
+ /**
34
+ * get mapping by locale
35
+ * @param locale
36
+ * @param group
37
+ */
38
+ getLocaleMapping(locale: string, group?: string): any;
39
+ /**
40
+ * get current default language
41
+ */
42
+ getDefaultLocale(): string;
43
+ private getLocaleMappingText;
44
+ }
2
45
  export declare class MidwayI18nService {
3
- i18nConfig: any;
4
- private languageTextMap;
5
- private defaultLanguage;
6
- init(): Promise<void>;
7
- addLanguage(lang: string, langTextMapping: Record<string, string>): void;
46
+ protected i18nServiceSingleton: MidwayI18nServiceSingleton;
47
+ ctx: IMidwayContext;
8
48
  translate(message: string, options?: TranslateOptions): any;
49
+ /**
50
+ * add a language text mapping
51
+ * @param locale
52
+ * @param localeTextMapping
53
+ */
54
+ addLocale(locale: string, localeTextMapping: Record<string, any>): void;
55
+ /**
56
+ * get mapping by lang
57
+ * @param locale
58
+ * @param group
59
+ */
60
+ getLocaleMapping(locale: any, group?: string): any;
61
+ /**
62
+ * get current default language
63
+ */
64
+ getDefaultLocale(): string;
65
+ /**
66
+ * save current context lang to flag, middleware will be set it to cookie
67
+ */
68
+ saveRequestLocale(locale?: string): void;
69
+ /**
70
+ * get locale string by find fallback and default, ignore match message
71
+ * @param locale
72
+ * @param group
73
+ */
74
+ getAvailableLocale(locale: string, group?: string): any;
75
+ /**
76
+ * get available local in locale text map, include fallbacks
77
+ * @param locale
78
+ */
79
+ hasAvailableLocale(locale: string): boolean;
9
80
  }
10
81
  //# sourceMappingURL=i18nService.d.ts.map
@@ -9,67 +9,242 @@ var __metadata = (this && this.__metadata) || function (k, v) {
9
9
  if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
10
10
  };
11
11
  Object.defineProperty(exports, "__esModule", { value: true });
12
- exports.MidwayI18nService = void 0;
12
+ exports.MidwayI18nService = exports.MidwayI18nServiceSingleton = void 0;
13
13
  const decorator_1 = require("@midwayjs/decorator");
14
- const core_1 = require("@midwayjs/core");
14
+ const interface_1 = require("./interface");
15
+ const pm = require("picomatch");
15
16
  const utils_1 = require("./utils");
16
- let MidwayI18nService = class MidwayI18nService {
17
+ let MidwayI18nServiceSingleton = class MidwayI18nServiceSingleton {
17
18
  constructor() {
18
- this.languageTextMap = new Map();
19
+ this.localeTextMap = new Map();
20
+ this.fallbackMatch = [];
21
+ this.localeMatchCache = {};
19
22
  }
20
23
  async init() {
21
- this.defaultLanguage = this.i18nConfig.defaultLanguage;
22
- for (const lang in this.i18nConfig.languageTable) {
23
- this.addLanguage(lang, getES6Object(this.i18nConfig.languageTable[lang]));
24
+ this.defaultLocale = (0, utils_1.formatLocale)(this.i18nConfig.defaultLocale);
25
+ for (const lang in this.i18nConfig.localeTable) {
26
+ this.addLocale(lang, getES6Object(this.i18nConfig.localeTable[lang]));
24
27
  }
25
- }
26
- addLanguage(lang, langTextMapping) {
27
- if (!this.languageTextMap.has(lang)) {
28
- this.languageTextMap.set(lang, {});
28
+ // fallbacks
29
+ for (const rule in this.i18nConfig.fallbacks) {
30
+ this.fallbackMatch.push({
31
+ pattern: pm((0, utils_1.formatLocale)(rule)),
32
+ locale: (0, utils_1.formatLocale)(this.i18nConfig.fallbacks[rule]),
33
+ });
29
34
  }
30
- const currentMap = this.languageTextMap.get(lang);
31
- for (const key in langTextMapping) {
32
- currentMap[key] = langTextMapping[key];
35
+ }
36
+ /**
37
+ * add a language text mapping
38
+ * @param locale
39
+ * @param localeTextMapping
40
+ */
41
+ addLocale(locale, localeTextMapping) {
42
+ const currentLangMap = getMap(this.localeTextMap, locale);
43
+ for (const key in localeTextMapping) {
44
+ if (typeof localeTextMapping[key] === 'string') {
45
+ // set to default
46
+ getMap(currentLangMap, 'default').set(key, localeTextMapping[key]);
47
+ }
48
+ else {
49
+ // set to group
50
+ for (const newKey in localeTextMapping[key]) {
51
+ getMap(currentLangMap, key).set(newKey, localeTextMapping[key][newKey]);
52
+ }
53
+ }
33
54
  }
34
55
  }
56
+ /**
57
+ * translate a message
58
+ * @param message
59
+ * @param options
60
+ */
35
61
  translate(message, options = {}) {
36
- var _a, _b;
37
- const useLang = (_a = options.lang) !== null && _a !== void 0 ? _a : this.defaultLanguage;
62
+ var _a, _b, _c;
63
+ const useLocale = (0, utils_1.formatLocale)((_a = options.locale) !== null && _a !== void 0 ? _a : this.defaultLocale);
38
64
  const args = (_b = options.args) !== null && _b !== void 0 ? _b : [];
39
- const langMap = this.languageTextMap.get(useLang);
40
- if (langMap) {
41
- const msg = (0, core_1.safelyGet)(message, langMap);
42
- if (msg) {
43
- return formatText(msg, args);
65
+ const group = (_c = options.group) !== null && _c !== void 0 ? _c : 'default';
66
+ let msg = this.getLocaleMappingText(useLocale, message, group, args);
67
+ if (!msg && useLocale !== this.defaultLocale) {
68
+ if (this.fallbackMatch.length) {
69
+ const findRule = this.fallbackMatch.find(rule => {
70
+ if (rule.pattern(useLocale)) {
71
+ return true;
72
+ }
73
+ });
74
+ if (findRule) {
75
+ msg = this.getLocaleMappingText(findRule.locale, message, group, args);
76
+ }
44
77
  }
45
- else {
46
- // fallback
47
- const fallbackLanguage = this.i18nConfig.fallbackLanguage;
48
- const fallbackMap = this.languageTextMap.get(fallbackLanguage);
49
- const msg = (0, core_1.safelyGet)(message, fallbackMap);
78
+ if (!msg) {
79
+ msg = this.getLocaleMappingText(this.defaultLocale, message, group, args);
80
+ }
81
+ }
82
+ return msg;
83
+ }
84
+ /**
85
+ * get locale string by find fallback and default, ignore match message
86
+ * @param locale
87
+ * @param group
88
+ */
89
+ getAvailableLocale(locale, group = 'default') {
90
+ locale = (0, utils_1.formatLocale)(locale);
91
+ if (this.localeMatchCache[locale + '_' + group]) {
92
+ return this.localeMatchCache[locale + '_' + group];
93
+ }
94
+ if (this.localeTextMap.has(locale) &&
95
+ this.localeTextMap.get(locale).has(group)) {
96
+ this.localeMatchCache[locale + '_' + group] = locale;
97
+ return locale;
98
+ }
99
+ if (this.fallbackMatch.length) {
100
+ const findRule = this.fallbackMatch.find(rule => {
101
+ if (rule.pattern(locale)) {
102
+ if (this.localeTextMap.has(rule.locale) &&
103
+ this.localeTextMap.get(rule.locale).has(group)) {
104
+ this.localeMatchCache[locale + '_' + group] = rule.locale;
105
+ return true;
106
+ }
107
+ }
108
+ });
109
+ if (findRule) {
110
+ return findRule.locale;
111
+ }
112
+ }
113
+ this.localeMatchCache[locale + '_' + group] = this.defaultLocale;
114
+ return this.defaultLocale;
115
+ }
116
+ /**
117
+ * get available local in locale text map, include fallbacks
118
+ * @param locale
119
+ */
120
+ hasAvailableLocale(locale) {
121
+ locale = (0, utils_1.formatLocale)(locale);
122
+ if (this.localeTextMap.has(locale)) {
123
+ return true;
124
+ }
125
+ if (this.fallbackMatch.length) {
126
+ const findRule = this.fallbackMatch.find(rule => {
127
+ if (rule.pattern(locale)) {
128
+ if (this.localeTextMap.has(rule.locale)) {
129
+ return true;
130
+ }
131
+ }
132
+ });
133
+ if (findRule) {
134
+ return true;
135
+ }
136
+ }
137
+ return false;
138
+ }
139
+ /**
140
+ * get mapping by locale
141
+ * @param locale
142
+ * @param group
143
+ */
144
+ getLocaleMapping(locale, group = 'default') {
145
+ locale = (0, utils_1.formatLocale)(locale);
146
+ const langMap = this.localeTextMap.get(locale);
147
+ if (langMap) {
148
+ return langMap.get(group);
149
+ }
150
+ }
151
+ /**
152
+ * get current default language
153
+ */
154
+ getDefaultLocale() {
155
+ return this.defaultLocale;
156
+ }
157
+ getLocaleMappingText(locale, message, group, args) {
158
+ const langMap = this.localeTextMap.get(locale);
159
+ if (langMap) {
160
+ const textMapping = langMap.get(group);
161
+ if (textMapping) {
162
+ const msg = textMapping.get(message);
50
163
  if (msg) {
51
164
  return formatText(msg, args);
52
165
  }
53
166
  }
54
167
  }
55
- else {
56
- throw new core_1.MidwayCommonError(`Language ${useLang} mapping not found`);
57
- }
58
168
  }
59
169
  };
60
170
  __decorate([
61
171
  (0, decorator_1.Config)('i18n'),
62
172
  __metadata("design:type", Object)
63
- ], MidwayI18nService.prototype, "i18nConfig", void 0);
173
+ ], MidwayI18nServiceSingleton.prototype, "i18nConfig", void 0);
64
174
  __decorate([
65
175
  (0, decorator_1.Init)(),
66
176
  __metadata("design:type", Function),
67
177
  __metadata("design:paramtypes", []),
68
178
  __metadata("design:returntype", Promise)
69
- ], MidwayI18nService.prototype, "init", null);
70
- MidwayI18nService = __decorate([
179
+ ], MidwayI18nServiceSingleton.prototype, "init", null);
180
+ MidwayI18nServiceSingleton = __decorate([
71
181
  (0, decorator_1.Provide)(),
72
182
  (0, decorator_1.Scope)(decorator_1.ScopeEnum.Singleton)
183
+ ], MidwayI18nServiceSingleton);
184
+ exports.MidwayI18nServiceSingleton = MidwayI18nServiceSingleton;
185
+ let MidwayI18nService = class MidwayI18nService {
186
+ translate(message, options = {}) {
187
+ if (!options.locale) {
188
+ options.locale = this.ctx.getAttr && this.ctx.getAttr(interface_1.I18N_ATTR_KEY);
189
+ }
190
+ return this.i18nServiceSingleton.translate(message, options);
191
+ }
192
+ /**
193
+ * add a language text mapping
194
+ * @param locale
195
+ * @param localeTextMapping
196
+ */
197
+ addLocale(locale, localeTextMapping) {
198
+ this.i18nServiceSingleton.addLocale(locale, localeTextMapping);
199
+ }
200
+ /**
201
+ * get mapping by lang
202
+ * @param locale
203
+ * @param group
204
+ */
205
+ getLocaleMapping(locale, group = 'default') {
206
+ return this.i18nServiceSingleton.getLocaleMapping(locale, group);
207
+ }
208
+ /**
209
+ * get current default language
210
+ */
211
+ getDefaultLocale() {
212
+ return this.i18nServiceSingleton.getDefaultLocale();
213
+ }
214
+ /**
215
+ * save current context lang to flag, middleware will be set it to cookie
216
+ */
217
+ saveRequestLocale(locale) {
218
+ var _a, _b;
219
+ const currentLocale = (_a = locale !== null && locale !== void 0 ? locale : this.ctx.getAttr(interface_1.I18N_ATTR_KEY)) !== null && _a !== void 0 ? _a : this.getDefaultLocale();
220
+ (_b = this.ctx) === null || _b === void 0 ? void 0 : _b.setAttr(interface_1.I18N_SAVE_KEY, (0, utils_1.formatLocale)(currentLocale));
221
+ }
222
+ /**
223
+ * get locale string by find fallback and default, ignore match message
224
+ * @param locale
225
+ * @param group
226
+ */
227
+ getAvailableLocale(locale, group = 'default') {
228
+ return this.i18nServiceSingleton.getAvailableLocale(locale, group);
229
+ }
230
+ /**
231
+ * get available local in locale text map, include fallbacks
232
+ * @param locale
233
+ */
234
+ hasAvailableLocale(locale) {
235
+ return this.i18nServiceSingleton.hasAvailableLocale(locale);
236
+ }
237
+ };
238
+ __decorate([
239
+ (0, decorator_1.Inject)(),
240
+ __metadata("design:type", MidwayI18nServiceSingleton)
241
+ ], MidwayI18nService.prototype, "i18nServiceSingleton", void 0);
242
+ __decorate([
243
+ (0, decorator_1.Inject)(),
244
+ __metadata("design:type", Object)
245
+ ], MidwayI18nService.prototype, "ctx", void 0);
246
+ MidwayI18nService = __decorate([
247
+ (0, decorator_1.Provide)()
73
248
  ], MidwayI18nService);
74
249
  exports.MidwayI18nService = MidwayI18nService;
75
250
  function formatText(message, args) {
@@ -88,4 +263,11 @@ function getES6Object(o) {
88
263
  }
89
264
  return o;
90
265
  }
266
+ function getMap(o, key) {
267
+ key = (0, utils_1.formatLocale)(key);
268
+ if (!o.has(key)) {
269
+ o.set(key, new Map());
270
+ }
271
+ return o.get(key);
272
+ }
91
273
  //# sourceMappingURL=i18nService.js.map
package/dist/index.d.ts CHANGED
@@ -1,4 +1,6 @@
1
1
  export { I18nConfiguration as Configuration } from './configuration';
2
2
  export * from './i18nService';
3
+ export * from './middleware';
3
4
  export * from './interface';
5
+ export { formatLocale } from './utils';
4
6
  //# sourceMappingURL=index.d.ts.map
package/dist/index.js CHANGED
@@ -10,9 +10,12 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
10
10
  for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
11
11
  };
12
12
  Object.defineProperty(exports, "__esModule", { value: true });
13
- exports.Configuration = void 0;
13
+ exports.formatLocale = exports.Configuration = void 0;
14
14
  var configuration_1 = require("./configuration");
15
15
  Object.defineProperty(exports, "Configuration", { enumerable: true, get: function () { return configuration_1.I18nConfiguration; } });
16
16
  __exportStar(require("./i18nService"), exports);
17
+ __exportStar(require("./middleware"), exports);
17
18
  __exportStar(require("./interface"), exports);
19
+ var utils_1 = require("./utils");
20
+ Object.defineProperty(exports, "formatLocale", { enumerable: true, get: function () { return utils_1.formatLocale; } });
18
21
  //# sourceMappingURL=index.js.map
@@ -1,11 +1,22 @@
1
- import { i18n } from './config.default';
2
1
  export interface TranslateOptions {
3
- lang?: string;
2
+ locale?: string;
3
+ group?: string;
4
4
  args?: any;
5
5
  }
6
- declare module '@midwayjs/core/dist/interface' {
7
- interface MidwayConfig {
8
- i18n?: typeof i18n;
9
- }
6
+ export interface I18nOptions {
7
+ defaultLocale: string;
8
+ localeTable: Record<string, Record<string, any>>;
9
+ fallbacks: Record<string, any>;
10
+ writeCookie: boolean;
11
+ resolver: {
12
+ queryField: string;
13
+ cookieField: {
14
+ fieldName: string;
15
+ cookieDomain: string;
16
+ cookieMaxAge: number;
17
+ };
18
+ };
10
19
  }
20
+ export declare const I18N_ATTR_KEY = "i18n:locale";
21
+ export declare const I18N_SAVE_KEY = "i18n:need_save_locale";
11
22
  //# sourceMappingURL=interface.d.ts.map
package/dist/interface.js CHANGED
@@ -1,3 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.I18N_SAVE_KEY = exports.I18N_ATTR_KEY = void 0;
4
+ exports.I18N_ATTR_KEY = 'i18n:locale';
5
+ exports.I18N_SAVE_KEY = 'i18n:need_save_locale';
3
6
  //# sourceMappingURL=interface.js.map
@@ -0,0 +1,13 @@
1
+ import { IMiddleware, IMidwayApplication } from '@midwayjs/core';
2
+ import { I18nOptions } from './interface';
3
+ export declare class I18nFilter {
4
+ resolverConfig: I18nOptions['resolver'];
5
+ match(value: any, req: any, res: any): any;
6
+ }
7
+ export declare class I18nMiddleware implements IMiddleware<any, any> {
8
+ resolverConfig: I18nOptions['resolver'];
9
+ i18nConfig: I18nOptions;
10
+ resolve(app: IMidwayApplication): (req: any, res: any, next: any) => Promise<any>;
11
+ static getName(): string;
12
+ }
13
+ //# sourceMappingURL=middleware.d.ts.map
@@ -0,0 +1,156 @@
1
+ "use strict";
2
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
6
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
7
+ };
8
+ var __metadata = (this && this.__metadata) || function (k, v) {
9
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.I18nMiddleware = exports.I18nFilter = void 0;
13
+ const decorator_1 = require("@midwayjs/decorator");
14
+ const interface_1 = require("./interface");
15
+ const i18nService_1 = require("./i18nService");
16
+ const utils_1 = require("./utils");
17
+ let I18nFilter = class I18nFilter {
18
+ match(value, req, res) {
19
+ const saveLocale = req.getAttr(interface_1.I18N_SAVE_KEY);
20
+ if (saveLocale) {
21
+ const cookieOptions = {
22
+ // make sure browser javascript can read the cookie
23
+ httpOnly: false,
24
+ maxAge: this.resolverConfig.cookieField.cookieMaxAge,
25
+ signed: false,
26
+ domain: this.resolverConfig.cookieField.cookieDomain,
27
+ };
28
+ res.cookie(this.resolverConfig.cookieField.fieldName, saveLocale, cookieOptions);
29
+ }
30
+ return value;
31
+ }
32
+ };
33
+ __decorate([
34
+ (0, decorator_1.Config)('i18n.resolver'),
35
+ __metadata("design:type", Object)
36
+ ], I18nFilter.prototype, "resolverConfig", void 0);
37
+ I18nFilter = __decorate([
38
+ (0, decorator_1.Match)()
39
+ ], I18nFilter);
40
+ exports.I18nFilter = I18nFilter;
41
+ let I18nMiddleware = class I18nMiddleware {
42
+ resolve(app) {
43
+ if (app.getFrameworkType() === decorator_1.MidwayFrameworkType.WEB_EXPRESS) {
44
+ // add a filter for i18n cookie
45
+ app.useFilter(I18nFilter);
46
+ return async (req, res, next) => {
47
+ // get request locale from query/header/cookie
48
+ let requestLocale = req.query[this.resolverConfig.queryField] ||
49
+ req.cookies[this.resolverConfig.cookieField.fieldName];
50
+ const i18nService = await req.requestContext.getAsync(i18nService_1.MidwayI18nService);
51
+ if (!requestLocale) {
52
+ // Accept-Language: zh-CN,zh;q=0.5
53
+ // Accept-Language: zh-CN
54
+ let languages = req.acceptsLanguages();
55
+ if (languages) {
56
+ if (Array.isArray(languages)) {
57
+ if (languages[0] === '*') {
58
+ languages = languages.slice(1);
59
+ }
60
+ if (languages.length > 0) {
61
+ for (let i = 0; i < languages.length; i++) {
62
+ const lang = (0, utils_1.formatLocale)(languages[i]);
63
+ if (i18nService.hasAvailableLocale(lang)) {
64
+ requestLocale = lang;
65
+ break;
66
+ }
67
+ }
68
+ }
69
+ }
70
+ else {
71
+ requestLocale = languages;
72
+ }
73
+ }
74
+ }
75
+ // set to current locale
76
+ req.setAttr(interface_1.I18N_ATTR_KEY, requestLocale);
77
+ // auto write locale to cookie
78
+ if (this.i18nConfig.writeCookie) {
79
+ i18nService.saveRequestLocale(requestLocale);
80
+ }
81
+ return next();
82
+ };
83
+ }
84
+ else {
85
+ return async (ctx, next) => {
86
+ // get request locale from query/header/cookie
87
+ let requestLocale = ctx.query[this.resolverConfig.queryField] ||
88
+ ctx.cookies.get(this.resolverConfig.cookieField.fieldName, {
89
+ signed: false,
90
+ });
91
+ const i18nService = await ctx.requestContext.getAsync(i18nService_1.MidwayI18nService);
92
+ if (!requestLocale) {
93
+ // Accept-Language: zh-CN,zh;q=0.5
94
+ // Accept-Language: zh-CN
95
+ let languages = ctx.acceptsLanguages();
96
+ if (languages) {
97
+ if (Array.isArray(languages)) {
98
+ if (languages[0] === '*') {
99
+ languages = languages.slice(1);
100
+ }
101
+ if (languages.length > 0) {
102
+ for (let i = 0; i < languages.length; i++) {
103
+ const lang = (0, utils_1.formatLocale)(languages[i]);
104
+ if (i18nService.hasAvailableLocale(lang)) {
105
+ requestLocale = lang;
106
+ break;
107
+ }
108
+ }
109
+ }
110
+ }
111
+ else {
112
+ requestLocale = languages;
113
+ }
114
+ }
115
+ }
116
+ // set to current locale
117
+ ctx.setAttr(interface_1.I18N_ATTR_KEY, requestLocale);
118
+ // auto write locale to cookie
119
+ if (this.i18nConfig.writeCookie) {
120
+ i18nService.saveRequestLocale(requestLocale);
121
+ }
122
+ // run next middleware and controller
123
+ await next();
124
+ // get need save locale
125
+ const saveLocale = ctx.getAttr(interface_1.I18N_SAVE_KEY);
126
+ if (saveLocale) {
127
+ const cookieOptions = {
128
+ // make sure browser javascript can read the cookie
129
+ httpOnly: false,
130
+ maxAge: this.resolverConfig.cookieField.cookieMaxAge,
131
+ signed: false,
132
+ domain: this.resolverConfig.cookieField.cookieDomain,
133
+ overwrite: true,
134
+ };
135
+ ctx.cookies.set(this.resolverConfig.cookieField.fieldName, saveLocale, cookieOptions);
136
+ }
137
+ };
138
+ }
139
+ }
140
+ static getName() {
141
+ return 'i18n';
142
+ }
143
+ };
144
+ __decorate([
145
+ (0, decorator_1.Config)('i18n.resolver'),
146
+ __metadata("design:type", Object)
147
+ ], I18nMiddleware.prototype, "resolverConfig", void 0);
148
+ __decorate([
149
+ (0, decorator_1.Config)('i18n'),
150
+ __metadata("design:type", Object)
151
+ ], I18nMiddleware.prototype, "i18nConfig", void 0);
152
+ I18nMiddleware = __decorate([
153
+ (0, decorator_1.Middleware)()
154
+ ], I18nMiddleware);
155
+ exports.I18nMiddleware = I18nMiddleware;
156
+ //# sourceMappingURL=middleware.js.map
package/dist/utils.d.ts CHANGED
@@ -1,3 +1,4 @@
1
1
  export declare function formatWithArray(text: any, values: any): any;
2
2
  export declare function formatWithObject(text: any, values: any): any;
3
+ export declare function formatLocale(locale: string): string;
3
4
  //# sourceMappingURL=utils.d.ts.map
package/dist/utils.js CHANGED
@@ -1,28 +1,33 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.formatWithObject = exports.formatWithArray = void 0;
3
+ exports.formatLocale = exports.formatWithObject = exports.formatWithArray = void 0;
4
4
  const ARRAY_INDEX_RE = /\{(\d+)\}/g;
5
5
  function formatWithArray(text, values) {
6
- return text.replace(ARRAY_INDEX_RE, (orignal, matched) => {
6
+ return text.replace(ARRAY_INDEX_RE, (original, matched) => {
7
7
  const index = parseInt(matched);
8
8
  if (index < values.length) {
9
9
  return values[index];
10
10
  }
11
11
  // not match index, return original text
12
- return orignal;
12
+ return original;
13
13
  });
14
14
  }
15
15
  exports.formatWithArray = formatWithArray;
16
16
  const Object_INDEX_RE = /\{(.+?)\}/g;
17
17
  function formatWithObject(text, values) {
18
- return text.replace(Object_INDEX_RE, (orignal, matched) => {
18
+ return text.replace(Object_INDEX_RE, (original, matched) => {
19
19
  const value = values[matched];
20
20
  if (value) {
21
21
  return value;
22
22
  }
23
23
  // not match index, return original text
24
- return orignal;
24
+ return original;
25
25
  });
26
26
  }
27
27
  exports.formatWithObject = formatWithObject;
28
+ function formatLocale(locale) {
29
+ // support zh_CN, en_US => zh-CN, en-US
30
+ return locale.replace('_', '-').toLowerCase();
31
+ }
32
+ exports.formatLocale = formatLocale;
28
33
  //# sourceMappingURL=utils.js.map
package/index.d.ts ADDED
@@ -0,0 +1,9 @@
1
+ import { I18nOptions } from './dist/';
2
+
3
+ export * from './dist/index';
4
+
5
+ declare module '@midwayjs/core/dist/interface' {
6
+ interface MidwayConfig {
7
+ i18n?: PowerPartial<I18nOptions>;
8
+ }
9
+ }
package/package.json CHANGED
@@ -1,17 +1,23 @@
1
1
  {
2
2
  "name": "@midwayjs/i18n",
3
- "description": "midway i18n compoennet",
4
- "version": "3.0.0-beta.7",
3
+ "description": "midway i18n component",
4
+ "version": "3.0.1",
5
5
  "main": "dist/index",
6
- "typings": "dist/index.d.ts",
6
+ "typings": "index.d.ts",
7
7
  "files": [
8
8
  "dist/**/*.js",
9
- "dist/**/*.d.ts"
9
+ "dist/**/*.d.ts",
10
+ "index.d.ts"
10
11
  ],
12
+ "dependencies": {
13
+ "picomatch": "2.3.1"
14
+ },
11
15
  "devDependencies": {
12
- "@midwayjs/core": "^3.0.0-beta.7",
13
- "@midwayjs/decorator": "^3.0.0-beta.7",
14
- "@midwayjs/mock": "^3.0.0-beta.7"
16
+ "@midwayjs/core": "^3.0.1",
17
+ "@midwayjs/decorator": "^3.0.0",
18
+ "@midwayjs/express": "^3.0.1",
19
+ "@midwayjs/koa": "^3.0.1",
20
+ "@midwayjs/mock": "^3.0.1"
15
21
  },
16
22
  "keywords": [
17
23
  "midway",
@@ -21,8 +27,8 @@
21
27
  "license": "MIT",
22
28
  "scripts": {
23
29
  "build": "tsc",
24
- "test": "node --require=ts-node/register ../../node_modules/.bin/jest",
25
- "cov": "node --require=ts-node/register ../../node_modules/.bin/jest --coverage --forceExit",
30
+ "test": "node --require=ts-node/register ../../node_modules/.bin/jest --runInBand",
31
+ "cov": "node --require=ts-node/register ../../node_modules/.bin/jest --runInBand --coverage --forceExit",
26
32
  "ci": "npm run test",
27
33
  "lint": "mwts check"
28
34
  },
@@ -33,5 +39,5 @@
33
39
  "type": "git",
34
40
  "url": "https://github.com/midwayjs/midway.git"
35
41
  },
36
- "gitHead": "24590729121d9110e2d960db5b5e587cf55a1efc"
42
+ "gitHead": "f345b4ed0392e5c3b9e815438ef0a377ad6da076"
37
43
  }
package/CHANGELOG.md DELETED
@@ -1,62 +0,0 @@
1
- # Change Log
2
-
3
- All notable changes to this project will be documented in this file.
4
- See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
5
-
6
- # [3.0.0-beta.7](https://github.com/midwayjs/midway/compare/v3.0.0-beta.6...v3.0.0-beta.7) (2021-12-03)
7
-
8
- **Note:** Version bump only for package @midwayjs/i18n
9
-
10
-
11
-
12
-
13
-
14
- # [3.0.0-beta.6](https://github.com/midwayjs/midway/compare/v3.0.0-beta.5...v3.0.0-beta.6) (2021-11-26)
15
-
16
- **Note:** Version bump only for package @midwayjs/i18n
17
-
18
-
19
-
20
-
21
-
22
- # [3.0.0-beta.5](https://github.com/midwayjs/midway/compare/v3.0.0-beta.4...v3.0.0-beta.5) (2021-11-25)
23
-
24
- **Note:** Version bump only for package @midwayjs/i18n
25
-
26
-
27
-
28
-
29
-
30
- # [3.0.0-beta.4](https://github.com/midwayjs/midway/compare/v3.0.0-beta.3...v3.0.0-beta.4) (2021-11-24)
31
-
32
-
33
- ### Features
34
-
35
- * add i18n ([#1375](https://github.com/midwayjs/midway/issues/1375)) ([bffefe0](https://github.com/midwayjs/midway/commit/bffefe07afe45777d49b5a76b9ab17fc2b9d9a55))
36
-
37
-
38
-
39
-
40
-
41
- # [3.0.0-beta.3](https://github.com/midwayjs/midway/compare/v3.0.0-beta.2...v3.0.0-beta.3) (2021-11-18)
42
-
43
-
44
- ### Features
45
-
46
- * add component and framework config definition ([#1367](https://github.com/midwayjs/midway/issues/1367)) ([b2fe615](https://github.com/midwayjs/midway/commit/b2fe6157f99659471ff1333eca0b86bb889f61a3))
47
-
48
-
49
-
50
-
51
-
52
- # [3.0.0-beta.2](https://github.com/midwayjs/midway/compare/v3.0.0-beta.1...v3.0.0-beta.2) (2021-11-16)
53
-
54
- **Note:** Version bump only for package @midwayjs/info
55
-
56
-
57
-
58
-
59
-
60
- # [3.0.0-beta.1](https://github.com/midwayjs/midway/compare/v2.12.4...v3.0.0-beta.1) (2021-11-14)
61
-
62
- **Note:** Version bump only for package @midwayjs/info
@@ -1,9 +0,0 @@
1
- export declare const i18n: {
2
- defaultLanguage: string;
3
- languageTable: {
4
- en: {};
5
- };
6
- fallbackLanguage: string;
7
- fallbacks: {};
8
- };
9
- //# sourceMappingURL=config.default.d.ts.map
@@ -1,17 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.i18n = void 0;
4
- exports.i18n = {
5
- defaultLanguage: 'en',
6
- languageTable: {
7
- en: {},
8
- },
9
- fallbackLanguage: 'en',
10
- fallbacks: {
11
- // 'en-CA': 'fr',
12
- // 'en-*': 'en',
13
- // 'fr-*': 'fr',
14
- // pt: 'pt-BR',
15
- },
16
- };
17
- //# sourceMappingURL=config.default.js.map