@eggjs/i18n 4.0.0-beta.18 → 4.0.0-beta.20

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.
@@ -1,12 +1,2 @@
1
- import { Application } from "egg";
2
-
3
- //#region src/app/extend/application.d.ts
4
- declare const I18N_RESOURCES: unique symbol;
5
- declare class I18nApplication extends Application {
6
- [I18N_RESOURCES]: Record<string, Record<string, string>>;
7
- isSupportLocale(locale: string): boolean;
8
- gettext(locale: string, key: string, value?: any, ...args: any[]): string;
9
- __(locale: string, key: string, value?: any, ...args: any[]): string;
10
- }
11
- //#endregion
1
+ import { I18N_RESOURCES, I18nApplication } from "../../application-CY4eNoP8.js";
12
2
  export { I18N_RESOURCES, I18nApplication as default };
@@ -1,48 +1,4 @@
1
- import { isObject } from "../../utils.js";
2
- import { debuglog, format } from "node:util";
3
- import { Application } from "egg";
1
+ import "../../utils-D06av2P8.js";
2
+ import { I18N_RESOURCES, I18nApplication } from "../../application-BzyHiDpF.js";
4
3
 
5
- //#region src/app/extend/application.ts
6
- const debug = debuglog("egg/i18n/app/extend/application");
7
- const I18N_RESOURCES = Symbol("Application i18n resources");
8
- var I18nApplication = class extends Application {
9
- isSupportLocale(locale) {
10
- return !!this[I18N_RESOURCES][locale];
11
- }
12
- gettext(locale, key, value, ...args) {
13
- if (!locale || !key) return "";
14
- let text = (this[I18N_RESOURCES][locale] || {})[key];
15
- if (text === void 0) text = key;
16
- debug("%s: %j => %j", locale, key, text);
17
- if (!text) return "";
18
- if (value === void 0) return text;
19
- if (args.length === 0) {
20
- if (isObject(value)) return formatWithObject(text, value);
21
- if (Array.isArray(value)) return formatWithArray(text, value);
22
- return format(text, value);
23
- }
24
- return format(text, value, ...args);
25
- }
26
- __(locale, key, value, ...args) {
27
- return this.gettext(locale, key, value, ...args);
28
- }
29
- };
30
- const ARRAY_INDEX_RE = /\{(\d+)\}/g;
31
- function formatWithArray(text, values) {
32
- return text.replace(ARRAY_INDEX_RE, (original, matched) => {
33
- const index = parseInt(matched);
34
- if (index < values.length) return values[index];
35
- return original;
36
- });
37
- }
38
- const Object_INDEX_RE = /\{(.+?)\}/g;
39
- function formatWithObject(text, values) {
40
- return text.replace(Object_INDEX_RE, (original, matched) => {
41
- const value = values[matched];
42
- if (value) return value;
43
- return original;
44
- });
45
- }
46
-
47
- //#endregion
48
4
  export { I18N_RESOURCES, I18nApplication as default };
@@ -1,76 +1,2 @@
1
- import { Context } from "egg";
2
-
3
- //#region src/app/extend/context.d.ts
4
- declare class I18nContext extends Context {
5
- /**
6
- * get current request locale
7
- * @member Context#locale
8
- * @return {String} lower case locale string, e.g.: 'zh-cn', 'en-us'
9
- */
10
- get locale(): string;
11
- set locale(l: string);
12
- /**
13
- * `ctx.__` 的别名。
14
- * @see {@link Context#__}
15
- * @function Context#gettext
16
- */
17
- gettext(key: string, value?: any, ...args: any[]): string;
18
- /**
19
- * 如果开启了 I18n 多语言功能,那么会出现此 API,通过它可以获取到当前请求对应的本地化数据。
20
- *
21
- * 详细使用说明,请查看 {@link I18n}
22
- * - `ctx.__ = function (key, value[, value2, ...])`: 类似 `util.format` 接口
23
- * - `ctx.__ = function (key, values)`: 支持数组下标占位符方式,如
24
- * - `__` 的别名是 `gettext(key, value)`
25
- *
26
- * > NOTE: __ 是两个下划线哦!
27
- * @function Context#__
28
- * @example
29
- * ```js
30
- * ctx.__('{0} {0} {1} {1}'), ['foo', 'bar'])
31
- * ctx.gettext('{0} {0} {1} {1}'), ['foo', 'bar'])
32
- * =>
33
- * foo foo bar bar
34
- * ```
35
- * ##### Controller 下的使用示例
36
- *
37
- * ```js
38
- * module.exports = function* () {
39
- * this.body = {
40
- * message: this.__('Welcome back, %s!', this.user.name),
41
- * // 或者使用 gettext,如果觉得 __ 不好看的话
42
- * // message: this.gettext('Welcome back, %s!', this.user.name),
43
- * user: this.user,
44
- * };
45
- * };
46
- * ```
47
- *
48
- * ##### View 文件下的使用示例
49
- *
50
- * ```html
51
- * <li>{{ __('Email') }}: {{ user.email }}</li>
52
- * <li>
53
- * {{ __('Hello %s, how are you today?', user.name) }}
54
- * </li>
55
- * <li>
56
- * {{ __('{0} {0} {1} {1}'), ['foo', 'bar']) }}
57
- * </li>
58
- * ```
59
- *
60
- * ##### locale 参数获取途径
61
- *
62
- * 优先级从上到下:
63
- *
64
- * - query: `/?locale=en-US`
65
- * - cookie: `locale=zh-TW`
66
- * - header: `Accept-Language: zh-CN,zh;q=0.5`
67
- */
68
- __(key: string, value?: any, ...args: any[]): string;
69
- __locale: string;
70
- __getLocale(): string;
71
- __localeOrigin: string;
72
- __getLocaleOrigin(): string;
73
- __setLocale(locale: string): void;
74
- }
75
- //#endregion
1
+ import { I18nContext } from "../../context-0NWdtfPn.js";
76
2
  export { I18nContext as default };
@@ -1,152 +1,4 @@
1
- import { formatLocale } from "../../utils.js";
2
- import { debuglog } from "node:util";
3
- import { Context } from "egg";
1
+ import "../../utils-D06av2P8.js";
2
+ import { I18nContext } from "../../context-BP8fJWAn.js";
4
3
 
5
- //#region src/app/extend/context.ts
6
- const debug = debuglog("egg/i18n/app/extend/context");
7
- var I18nContext = class extends Context {
8
- /**
9
- * get current request locale
10
- * @member Context#locale
11
- * @return {String} lower case locale string, e.g.: 'zh-cn', 'en-us'
12
- */
13
- get locale() {
14
- return this.__getLocale();
15
- }
16
- set locale(l) {
17
- this.__setLocale(l);
18
- }
19
- /**
20
- * `ctx.__` 的别名。
21
- * @see {@link Context#__}
22
- * @function Context#gettext
23
- */
24
- gettext(key, value, ...args) {
25
- return this.app.gettext(this.locale, key, value, ...args);
26
- }
27
- /**
28
- * 如果开启了 I18n 多语言功能,那么会出现此 API,通过它可以获取到当前请求对应的本地化数据。
29
- *
30
- * 详细使用说明,请查看 {@link I18n}
31
- * - `ctx.__ = function (key, value[, value2, ...])`: 类似 `util.format` 接口
32
- * - `ctx.__ = function (key, values)`: 支持数组下标占位符方式,如
33
- * - `__` 的别名是 `gettext(key, value)`
34
- *
35
- * > NOTE: __ 是两个下划线哦!
36
- * @function Context#__
37
- * @example
38
- * ```js
39
- * ctx.__('{0} {0} {1} {1}'), ['foo', 'bar'])
40
- * ctx.gettext('{0} {0} {1} {1}'), ['foo', 'bar'])
41
- * =>
42
- * foo foo bar bar
43
- * ```
44
- * ##### Controller 下的使用示例
45
- *
46
- * ```js
47
- * module.exports = function* () {
48
- * this.body = {
49
- * message: this.__('Welcome back, %s!', this.user.name),
50
- * // 或者使用 gettext,如果觉得 __ 不好看的话
51
- * // message: this.gettext('Welcome back, %s!', this.user.name),
52
- * user: this.user,
53
- * };
54
- * };
55
- * ```
56
- *
57
- * ##### View 文件下的使用示例
58
- *
59
- * ```html
60
- * <li>{{ __('Email') }}: {{ user.email }}</li>
61
- * <li>
62
- * {{ __('Hello %s, how are you today?', user.name) }}
63
- * </li>
64
- * <li>
65
- * {{ __('{0} {0} {1} {1}'), ['foo', 'bar']) }}
66
- * </li>
67
- * ```
68
- *
69
- * ##### locale 参数获取途径
70
- *
71
- * 优先级从上到下:
72
- *
73
- * - query: `/?locale=en-US`
74
- * - cookie: `locale=zh-TW`
75
- * - header: `Accept-Language: zh-CN,zh;q=0.5`
76
- */
77
- __(key, value, ...args) {
78
- return this.gettext(key, value, ...args);
79
- }
80
- __getLocale() {
81
- if (this.__locale) return this.__locale;
82
- const { localeAlias, defaultLocale, cookieField, queryField, writeCookie } = this.app.config.i18n;
83
- const cookieLocale = this.cookies.get(cookieField, { signed: false });
84
- let locale = this.query[queryField];
85
- let localeOrigin = "query";
86
- if (!locale && cookieLocale) {
87
- locale = cookieLocale;
88
- localeOrigin = "cookie";
89
- }
90
- if (!locale) {
91
- let languages = this.acceptsLanguages();
92
- if (languages) if (Array.isArray(languages)) {
93
- if (languages[0] === "*") languages = languages.slice(1);
94
- if (languages.length > 0) for (const l of languages) {
95
- const lang = formatLocale(l);
96
- if (this.app.isSupportLocale(lang) || localeAlias[lang]) {
97
- locale = lang;
98
- localeOrigin = "header";
99
- break;
100
- }
101
- }
102
- } else {
103
- locale = languages;
104
- localeOrigin = "header";
105
- }
106
- if (!locale) {
107
- locale = defaultLocale;
108
- localeOrigin = "default";
109
- }
110
- }
111
- if (locale in localeAlias) {
112
- const originalLocale = locale;
113
- locale = localeAlias[locale];
114
- debug("Used alias, received %s but using %s", originalLocale, locale);
115
- }
116
- locale = formatLocale(locale);
117
- if (!this.app.isSupportLocale(locale)) {
118
- debug("Locale %s is not supported. Using default (%s)", locale, defaultLocale);
119
- locale = defaultLocale;
120
- }
121
- if (writeCookie && cookieLocale !== locale && !this.headerSent) updateCookie(this, locale);
122
- debug("Locale: %s from %s", locale, localeOrigin);
123
- this.__locale = locale;
124
- this.__localeOrigin = localeOrigin;
125
- return locale;
126
- }
127
- __getLocaleOrigin() {
128
- if (this.__localeOrigin) return this.__localeOrigin;
129
- this.__getLocale();
130
- return this.__localeOrigin;
131
- }
132
- __setLocale(locale) {
133
- this.__locale = locale;
134
- this.__localeOrigin = "set";
135
- if (this.app.config.i18n.writeCookie && !this.headerSent) updateCookie(this, locale);
136
- }
137
- };
138
- function updateCookie(ctx, locale) {
139
- const { cookieMaxAge, cookieField, cookieDomain } = ctx.app.config.i18n;
140
- const cookieOptions = {
141
- httpOnly: false,
142
- maxAge: cookieMaxAge,
143
- signed: false,
144
- domain: cookieDomain,
145
- overwrite: true
146
- };
147
- ctx.cookies.set(cookieField, locale, cookieOptions);
148
- debug("Saved cookie with locale %s, options: %j", locale, cookieOptions);
149
- }
150
-
151
- //#endregion
152
4
  export { I18nContext as default };
package/dist/app.js CHANGED
@@ -1,5 +1,6 @@
1
- import { formatLocale } from "./utils.js";
2
- import { loadLocaleResources } from "./locales.js";
1
+ import { formatLocale } from "./utils-D06av2P8.js";
2
+ import "./application-BzyHiDpF.js";
3
+ import { loadLocaleResources } from "./locales-BA2I-wwk.js";
3
4
  import path from "node:path";
4
5
  import { debuglog } from "node:util";
5
6
  import { exists } from "utility";
@@ -0,0 +1,48 @@
1
+ import { isObject } from "./utils-D06av2P8.js";
2
+ import { debuglog, format } from "node:util";
3
+ import { Application } from "egg";
4
+
5
+ //#region src/app/extend/application.ts
6
+ const debug = debuglog("egg/i18n/app/extend/application");
7
+ const I18N_RESOURCES = Symbol("Application i18n resources");
8
+ var I18nApplication = class extends Application {
9
+ isSupportLocale(locale) {
10
+ return !!this[I18N_RESOURCES][locale];
11
+ }
12
+ gettext(locale, key, value, ...args) {
13
+ if (!locale || !key) return "";
14
+ let text = (this[I18N_RESOURCES][locale] || {})[key];
15
+ if (text === void 0) text = key;
16
+ debug("%s: %j => %j", locale, key, text);
17
+ if (!text) return "";
18
+ if (value === void 0) return text;
19
+ if (args.length === 0) {
20
+ if (isObject(value)) return formatWithObject(text, value);
21
+ if (Array.isArray(value)) return formatWithArray(text, value);
22
+ return format(text, value);
23
+ }
24
+ return format(text, value, ...args);
25
+ }
26
+ __(locale, key, value, ...args) {
27
+ return this.gettext(locale, key, value, ...args);
28
+ }
29
+ };
30
+ const ARRAY_INDEX_RE = /\{(\d+)\}/g;
31
+ function formatWithArray(text, values) {
32
+ return text.replace(ARRAY_INDEX_RE, (original, matched) => {
33
+ const index = parseInt(matched);
34
+ if (index < values.length) return values[index];
35
+ return original;
36
+ });
37
+ }
38
+ const Object_INDEX_RE = /\{(.+?)\}/g;
39
+ function formatWithObject(text, values) {
40
+ return text.replace(Object_INDEX_RE, (original, matched) => {
41
+ const value = values[matched];
42
+ if (value) return value;
43
+ return original;
44
+ });
45
+ }
46
+
47
+ //#endregion
48
+ export { I18N_RESOURCES, I18nApplication };
@@ -0,0 +1,12 @@
1
+ import { Application } from "egg";
2
+
3
+ //#region src/app/extend/application.d.ts
4
+ declare const I18N_RESOURCES: unique symbol;
5
+ declare class I18nApplication extends Application {
6
+ [I18N_RESOURCES]: Record<string, Record<string, string>>;
7
+ isSupportLocale(locale: string): boolean;
8
+ gettext(locale: string, key: string, value?: any, ...args: any[]): string;
9
+ __(locale: string, key: string, value?: any, ...args: any[]): string;
10
+ }
11
+ //#endregion
12
+ export { I18N_RESOURCES, I18nApplication };
@@ -1,54 +1,2 @@
1
- //#region src/config/config.default.d.ts
2
- interface I18nConfig {
3
- /**
4
- * 默认语言是美式英语,毕竟支持多语言,基本都是以英语为母板
5
- * 默认值是 `en_US`
6
- */
7
- defaultLocale: string;
8
- /**
9
- * 多语言资源文件存放路径,不建议修改
10
- * 默认值是 `[]`
11
- */
12
- dirs: string[];
13
- /**
14
- * @deprecated please use `dirs` instead
15
- */
16
- dir?: string;
17
- /**
18
- * 设置当前语言的 query 参数字段名,默认通过 `query.locale` 获取
19
- * 如果你想修改为 `query.lang`,那么请通过修改此配置实现
20
- * 默认值是 `locale`
21
- */
22
- queryField: string;
23
- /**
24
- * 如果当前请求用户语言有变化,都会设置到 cookie 中保持着,
25
- * 默认是存储在key 为 locale 的 cookie 中
26
- * 默认值是 `locale`
27
- */
28
- cookieField: string;
29
- /**
30
- * 存储 locale 的 cookie domain 配置,默认不设置,为当前域名才有效
31
- * 默认值是 `''`
32
- */
33
- cookieDomain: string;
34
- /**
35
- * cookie 默认一年后过期,如果设置为 Number,则单位为 ms
36
- * 默认值是 `'1y'`
37
- */
38
- cookieMaxAge: string | number;
39
- /**
40
- * locale 别名,比如 zh_CN => cn
41
- * 默认值是 `{}`
42
- */
43
- localeAlias: Record<string, string>;
44
- /**
45
- * 是否写入 cookie
46
- * 默认值是 `true`
47
- */
48
- writeCookie: boolean;
49
- }
50
- declare const _default: {
51
- i18n: I18nConfig;
52
- };
53
- //#endregion
1
+ import { I18nConfig, _default } from "../config.default-zrkP0tMD.js";
54
2
  export { I18nConfig, _default as default };
@@ -1,15 +1,3 @@
1
- //#region src/config/config.default.ts
2
- var config_default_default = { i18n: {
3
- defaultLocale: "en_US",
4
- dirs: [],
5
- queryField: "locale",
6
- cookieField: "locale",
7
- cookieDomain: "",
8
- cookieMaxAge: "1y",
9
- localeAlias: {},
10
- writeCookie: true,
11
- dir: void 0
12
- } };
1
+ import { config_default_default } from "../config.default-pQAjrMmI.js";
13
2
 
14
- //#endregion
15
3
  export { config_default_default as default };
@@ -0,0 +1,15 @@
1
+ //#region src/config/config.default.ts
2
+ var config_default_default = { i18n: {
3
+ defaultLocale: "en_US",
4
+ dirs: [],
5
+ queryField: "locale",
6
+ cookieField: "locale",
7
+ cookieDomain: "",
8
+ cookieMaxAge: "1y",
9
+ localeAlias: {},
10
+ writeCookie: true,
11
+ dir: void 0
12
+ } };
13
+
14
+ //#endregion
15
+ export { config_default_default };
@@ -0,0 +1,54 @@
1
+ //#region src/config/config.default.d.ts
2
+ interface I18nConfig {
3
+ /**
4
+ * 默认语言是美式英语,毕竟支持多语言,基本都是以英语为母板
5
+ * 默认值是 `en_US`
6
+ */
7
+ defaultLocale: string;
8
+ /**
9
+ * 多语言资源文件存放路径,不建议修改
10
+ * 默认值是 `[]`
11
+ */
12
+ dirs: string[];
13
+ /**
14
+ * @deprecated please use `dirs` instead
15
+ */
16
+ dir?: string;
17
+ /**
18
+ * 设置当前语言的 query 参数字段名,默认通过 `query.locale` 获取
19
+ * 如果你想修改为 `query.lang`,那么请通过修改此配置实现
20
+ * 默认值是 `locale`
21
+ */
22
+ queryField: string;
23
+ /**
24
+ * 如果当前请求用户语言有变化,都会设置到 cookie 中保持着,
25
+ * 默认是存储在key 为 locale 的 cookie 中
26
+ * 默认值是 `locale`
27
+ */
28
+ cookieField: string;
29
+ /**
30
+ * 存储 locale 的 cookie domain 配置,默认不设置,为当前域名才有效
31
+ * 默认值是 `''`
32
+ */
33
+ cookieDomain: string;
34
+ /**
35
+ * cookie 默认一年后过期,如果设置为 Number,则单位为 ms
36
+ * 默认值是 `'1y'`
37
+ */
38
+ cookieMaxAge: string | number;
39
+ /**
40
+ * locale 别名,比如 zh_CN => cn
41
+ * 默认值是 `{}`
42
+ */
43
+ localeAlias: Record<string, string>;
44
+ /**
45
+ * 是否写入 cookie
46
+ * 默认值是 `true`
47
+ */
48
+ writeCookie: boolean;
49
+ }
50
+ declare const _default: {
51
+ i18n: I18nConfig;
52
+ };
53
+ //#endregion
54
+ export { I18nConfig, _default };
@@ -0,0 +1,76 @@
1
+ import { Context } from "egg";
2
+
3
+ //#region src/app/extend/context.d.ts
4
+ declare class I18nContext extends Context {
5
+ /**
6
+ * get current request locale
7
+ * @member Context#locale
8
+ * @return {String} lower case locale string, e.g.: 'zh-cn', 'en-us'
9
+ */
10
+ get locale(): string;
11
+ set locale(l: string);
12
+ /**
13
+ * `ctx.__` 的别名。
14
+ * @see {@link Context#__}
15
+ * @function Context#gettext
16
+ */
17
+ gettext(key: string, value?: any, ...args: any[]): string;
18
+ /**
19
+ * 如果开启了 I18n 多语言功能,那么会出现此 API,通过它可以获取到当前请求对应的本地化数据。
20
+ *
21
+ * 详细使用说明,请查看 {@link I18n}
22
+ * - `ctx.__ = function (key, value[, value2, ...])`: 类似 `util.format` 接口
23
+ * - `ctx.__ = function (key, values)`: 支持数组下标占位符方式,如
24
+ * - `__` 的别名是 `gettext(key, value)`
25
+ *
26
+ * > NOTE: __ 是两个下划线哦!
27
+ * @function Context#__
28
+ * @example
29
+ * ```js
30
+ * ctx.__('{0} {0} {1} {1}'), ['foo', 'bar'])
31
+ * ctx.gettext('{0} {0} {1} {1}'), ['foo', 'bar'])
32
+ * =>
33
+ * foo foo bar bar
34
+ * ```
35
+ * ##### Controller 下的使用示例
36
+ *
37
+ * ```js
38
+ * module.exports = function* () {
39
+ * this.body = {
40
+ * message: this.__('Welcome back, %s!', this.user.name),
41
+ * // 或者使用 gettext,如果觉得 __ 不好看的话
42
+ * // message: this.gettext('Welcome back, %s!', this.user.name),
43
+ * user: this.user,
44
+ * };
45
+ * };
46
+ * ```
47
+ *
48
+ * ##### View 文件下的使用示例
49
+ *
50
+ * ```html
51
+ * <li>{{ __('Email') }}: {{ user.email }}</li>
52
+ * <li>
53
+ * {{ __('Hello %s, how are you today?', user.name) }}
54
+ * </li>
55
+ * <li>
56
+ * {{ __('{0} {0} {1} {1}'), ['foo', 'bar']) }}
57
+ * </li>
58
+ * ```
59
+ *
60
+ * ##### locale 参数获取途径
61
+ *
62
+ * 优先级从上到下:
63
+ *
64
+ * - query: `/?locale=en-US`
65
+ * - cookie: `locale=zh-TW`
66
+ * - header: `Accept-Language: zh-CN,zh;q=0.5`
67
+ */
68
+ __(key: string, value?: any, ...args: any[]): string;
69
+ __locale: string;
70
+ __getLocale(): string;
71
+ __localeOrigin: string;
72
+ __getLocaleOrigin(): string;
73
+ __setLocale(locale: string): void;
74
+ }
75
+ //#endregion
76
+ export { I18nContext };
@@ -0,0 +1,152 @@
1
+ import { formatLocale } from "./utils-D06av2P8.js";
2
+ import { debuglog } from "node:util";
3
+ import { Context } from "egg";
4
+
5
+ //#region src/app/extend/context.ts
6
+ const debug = debuglog("egg/i18n/app/extend/context");
7
+ var I18nContext = class extends Context {
8
+ /**
9
+ * get current request locale
10
+ * @member Context#locale
11
+ * @return {String} lower case locale string, e.g.: 'zh-cn', 'en-us'
12
+ */
13
+ get locale() {
14
+ return this.__getLocale();
15
+ }
16
+ set locale(l) {
17
+ this.__setLocale(l);
18
+ }
19
+ /**
20
+ * `ctx.__` 的别名。
21
+ * @see {@link Context#__}
22
+ * @function Context#gettext
23
+ */
24
+ gettext(key, value, ...args) {
25
+ return this.app.gettext(this.locale, key, value, ...args);
26
+ }
27
+ /**
28
+ * 如果开启了 I18n 多语言功能,那么会出现此 API,通过它可以获取到当前请求对应的本地化数据。
29
+ *
30
+ * 详细使用说明,请查看 {@link I18n}
31
+ * - `ctx.__ = function (key, value[, value2, ...])`: 类似 `util.format` 接口
32
+ * - `ctx.__ = function (key, values)`: 支持数组下标占位符方式,如
33
+ * - `__` 的别名是 `gettext(key, value)`
34
+ *
35
+ * > NOTE: __ 是两个下划线哦!
36
+ * @function Context#__
37
+ * @example
38
+ * ```js
39
+ * ctx.__('{0} {0} {1} {1}'), ['foo', 'bar'])
40
+ * ctx.gettext('{0} {0} {1} {1}'), ['foo', 'bar'])
41
+ * =>
42
+ * foo foo bar bar
43
+ * ```
44
+ * ##### Controller 下的使用示例
45
+ *
46
+ * ```js
47
+ * module.exports = function* () {
48
+ * this.body = {
49
+ * message: this.__('Welcome back, %s!', this.user.name),
50
+ * // 或者使用 gettext,如果觉得 __ 不好看的话
51
+ * // message: this.gettext('Welcome back, %s!', this.user.name),
52
+ * user: this.user,
53
+ * };
54
+ * };
55
+ * ```
56
+ *
57
+ * ##### View 文件下的使用示例
58
+ *
59
+ * ```html
60
+ * <li>{{ __('Email') }}: {{ user.email }}</li>
61
+ * <li>
62
+ * {{ __('Hello %s, how are you today?', user.name) }}
63
+ * </li>
64
+ * <li>
65
+ * {{ __('{0} {0} {1} {1}'), ['foo', 'bar']) }}
66
+ * </li>
67
+ * ```
68
+ *
69
+ * ##### locale 参数获取途径
70
+ *
71
+ * 优先级从上到下:
72
+ *
73
+ * - query: `/?locale=en-US`
74
+ * - cookie: `locale=zh-TW`
75
+ * - header: `Accept-Language: zh-CN,zh;q=0.5`
76
+ */
77
+ __(key, value, ...args) {
78
+ return this.gettext(key, value, ...args);
79
+ }
80
+ __getLocale() {
81
+ if (this.__locale) return this.__locale;
82
+ const { localeAlias, defaultLocale, cookieField, queryField, writeCookie } = this.app.config.i18n;
83
+ const cookieLocale = this.cookies.get(cookieField, { signed: false });
84
+ let locale = this.query[queryField];
85
+ let localeOrigin = "query";
86
+ if (!locale && cookieLocale) {
87
+ locale = cookieLocale;
88
+ localeOrigin = "cookie";
89
+ }
90
+ if (!locale) {
91
+ let languages = this.acceptsLanguages();
92
+ if (languages) if (Array.isArray(languages)) {
93
+ if (languages[0] === "*") languages = languages.slice(1);
94
+ if (languages.length > 0) for (const l of languages) {
95
+ const lang = formatLocale(l);
96
+ if (this.app.isSupportLocale(lang) || localeAlias[lang]) {
97
+ locale = lang;
98
+ localeOrigin = "header";
99
+ break;
100
+ }
101
+ }
102
+ } else {
103
+ locale = languages;
104
+ localeOrigin = "header";
105
+ }
106
+ if (!locale) {
107
+ locale = defaultLocale;
108
+ localeOrigin = "default";
109
+ }
110
+ }
111
+ if (locale in localeAlias) {
112
+ const originalLocale = locale;
113
+ locale = localeAlias[locale];
114
+ debug("Used alias, received %s but using %s", originalLocale, locale);
115
+ }
116
+ locale = formatLocale(locale);
117
+ if (!this.app.isSupportLocale(locale)) {
118
+ debug("Locale %s is not supported. Using default (%s)", locale, defaultLocale);
119
+ locale = defaultLocale;
120
+ }
121
+ if (writeCookie && cookieLocale !== locale && !this.headerSent) updateCookie(this, locale);
122
+ debug("Locale: %s from %s", locale, localeOrigin);
123
+ this.__locale = locale;
124
+ this.__localeOrigin = localeOrigin;
125
+ return locale;
126
+ }
127
+ __getLocaleOrigin() {
128
+ if (this.__localeOrigin) return this.__localeOrigin;
129
+ this.__getLocale();
130
+ return this.__localeOrigin;
131
+ }
132
+ __setLocale(locale) {
133
+ this.__locale = locale;
134
+ this.__localeOrigin = "set";
135
+ if (this.app.config.i18n.writeCookie && !this.headerSent) updateCookie(this, locale);
136
+ }
137
+ };
138
+ function updateCookie(ctx, locale) {
139
+ const { cookieMaxAge, cookieField, cookieDomain } = ctx.app.config.i18n;
140
+ const cookieOptions = {
141
+ httpOnly: false,
142
+ maxAge: cookieMaxAge,
143
+ signed: false,
144
+ domain: cookieDomain,
145
+ overwrite: true
146
+ };
147
+ ctx.cookies.set(cookieField, locale, cookieOptions);
148
+ debug("Saved cookie with locale %s, options: %j", locale, cookieOptions);
149
+ }
150
+
151
+ //#endregion
152
+ export { I18nContext };
package/dist/index.d.ts CHANGED
@@ -1 +1,4 @@
1
- export { };
1
+ import "./application-CY4eNoP8.js";
2
+ import "./context-0NWdtfPn.js";
3
+ import "./config.default-zrkP0tMD.js";
4
+ import "./types-DoabcMjn.js";
package/dist/index.js CHANGED
@@ -1,4 +1,7 @@
1
- import "./app/extend/application.js";
2
- import "./app/extend/context.js";
1
+ import "./utils-D06av2P8.js";
2
+ import "./application-BzyHiDpF.js";
3
+ import "./config.default-pQAjrMmI.js";
4
+ import "./context-BP8fJWAn.js";
5
+ import "./types-BsuPrIpu.js";
3
6
 
4
7
  export { };
@@ -0,0 +1,53 @@
1
+ import { formatLocale, isObject } from "./utils-D06av2P8.js";
2
+ import { I18N_RESOURCES } from "./application-BzyHiDpF.js";
3
+ import path from "node:path";
4
+ import { debuglog } from "node:util";
5
+ import { exists, readJSON } from "utility";
6
+ import fs from "node:fs/promises";
7
+ import ini from "ini";
8
+ import yaml from "js-yaml";
9
+ import { importModule } from "@eggjs/utils";
10
+
11
+ //#region src/locales.ts
12
+ const debug = debuglog("egg/i18n/locales");
13
+ async function loadLocaleResources(app, options) {
14
+ const localeDirs = options.dirs;
15
+ const resources = {};
16
+ if (options.dir && !localeDirs.includes(options.dir)) {
17
+ app.deprecate("[@eggjs/i18n] `config.i18n.dir` is deprecated, please use `config.i18n.dirs` instead");
18
+ localeDirs.push(options.dir);
19
+ }
20
+ for (const dir of localeDirs) {
21
+ if (!await exists(dir)) continue;
22
+ const names = await fs.readdir(dir);
23
+ for (const name of names) {
24
+ const filepath = path.join(dir, name);
25
+ const locale = formatLocale(name.split(".")[0]);
26
+ let resource = {};
27
+ if (name.endsWith(".js") || name.endsWith(".ts")) resource = flattening(await importModule(filepath, { importDefaultOnly: true }));
28
+ else if (name.endsWith(".json")) resource = flattening(await readJSON(filepath));
29
+ else if (name.endsWith(".properties")) resource = ini.parse(await fs.readFile(filepath, "utf8"));
30
+ else if (name.endsWith(".yml") || name.endsWith(".yaml")) resource = flattening(yaml.load(await fs.readFile(filepath, "utf8")));
31
+ resources[locale] = resources[locale] || {};
32
+ Object.assign(resources[locale], resource);
33
+ }
34
+ }
35
+ debug("Init locales with %j, got %j resources", options, Object.keys(resources));
36
+ app[I18N_RESOURCES] = resources;
37
+ }
38
+ function flattening(data) {
39
+ const result = {};
40
+ function deepFlat(data$1, prefix) {
41
+ for (const key in data$1) {
42
+ const value = data$1[key];
43
+ const k = prefix ? prefix + "." + key : key;
44
+ if (isObject(value)) deepFlat(value, k);
45
+ else result[k] = String(value);
46
+ }
47
+ }
48
+ deepFlat(data, "");
49
+ return result;
50
+ }
51
+
52
+ //#endregion
53
+ export { loadLocaleResources };
package/dist/locales.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { I18nConfig } from "./config/config.default.js";
1
+ import { I18nConfig } from "./config.default-zrkP0tMD.js";
2
2
  import { Application } from "egg";
3
3
 
4
4
  //#region src/locales.d.ts
package/dist/locales.js CHANGED
@@ -1,53 +1,5 @@
1
- import { formatLocale, isObject } from "./utils.js";
2
- import { I18N_RESOURCES } from "./app/extend/application.js";
3
- import path from "node:path";
4
- import { debuglog } from "node:util";
5
- import { exists, readJSON } from "utility";
6
- import fs from "node:fs/promises";
7
- import ini from "ini";
8
- import yaml from "js-yaml";
9
- import { importModule } from "@eggjs/utils";
1
+ import "./utils-D06av2P8.js";
2
+ import "./application-BzyHiDpF.js";
3
+ import { loadLocaleResources } from "./locales-BA2I-wwk.js";
10
4
 
11
- //#region src/locales.ts
12
- const debug = debuglog("egg/i18n/locales");
13
- async function loadLocaleResources(app, options) {
14
- const localeDirs = options.dirs;
15
- const resources = {};
16
- if (options.dir && !localeDirs.includes(options.dir)) {
17
- app.deprecate("[@eggjs/i18n] `config.i18n.dir` is deprecated, please use `config.i18n.dirs` instead");
18
- localeDirs.push(options.dir);
19
- }
20
- for (const dir of localeDirs) {
21
- if (!await exists(dir)) continue;
22
- const names = await fs.readdir(dir);
23
- for (const name of names) {
24
- const filepath = path.join(dir, name);
25
- const locale = formatLocale(name.split(".")[0]);
26
- let resource = {};
27
- if (name.endsWith(".js") || name.endsWith(".ts")) resource = flattening(await importModule(filepath, { importDefaultOnly: true }));
28
- else if (name.endsWith(".json")) resource = flattening(await readJSON(filepath));
29
- else if (name.endsWith(".properties")) resource = ini.parse(await fs.readFile(filepath, "utf8"));
30
- else if (name.endsWith(".yml") || name.endsWith(".yaml")) resource = flattening(yaml.load(await fs.readFile(filepath, "utf8")));
31
- resources[locale] = resources[locale] || {};
32
- Object.assign(resources[locale], resource);
33
- }
34
- }
35
- debug("Init locales with %j, got %j resources", options, Object.keys(resources));
36
- app[I18N_RESOURCES] = resources;
37
- }
38
- function flattening(data) {
39
- const result = {};
40
- function deepFlat(data$1, prefix) {
41
- for (const key in data$1) {
42
- const value = data$1[key];
43
- const k = prefix ? prefix + "." + key : key;
44
- if (isObject(value)) deepFlat(value, k);
45
- else result[k] = String(value);
46
- }
47
- }
48
- deepFlat(data, "");
49
- return result;
50
- }
51
-
52
- //#endregion
53
5
  export { loadLocaleResources };
@@ -0,0 +1 @@
1
+ export { };
@@ -0,0 +1,29 @@
1
+ import { I18nConfig } from "./config.default-zrkP0tMD.js";
2
+
3
+ //#region src/types.d.ts
4
+ declare module 'egg' {
5
+ interface EggAppConfig {
6
+ /**
7
+ * I18n options
8
+ * @member Config#i18n
9
+ */
10
+ i18n: I18nConfig;
11
+ }
12
+ interface Application {
13
+ isSupportLocale(locale: string): boolean;
14
+ gettext(locale: string, key: string, value?: any, ...args: any[]): string;
15
+ __(locale: string, key: string, value?: any, ...args: any[]): string;
16
+ }
17
+ interface Context {
18
+ /**
19
+ * get and set current request locale
20
+ * @member Context#locale
21
+ * @return {String} lower case locale string, e.g.: 'zh-cn', 'en-us'
22
+ */
23
+ locale: string;
24
+ gettext(key: string, value?: any, ...args: any[]): string;
25
+ __(key: string, value?: any, ...args: any[]): string;
26
+ __getLocale(): string;
27
+ __setLocale(l: string): void;
28
+ }
29
+ }
package/dist/types.d.ts CHANGED
@@ -1,29 +1,2 @@
1
- import { I18nConfig } from "./config/config.default.js";
2
-
3
- //#region src/types.d.ts
4
- declare module 'egg' {
5
- interface EggAppConfig {
6
- /**
7
- * I18n options
8
- * @member Config#i18n
9
- */
10
- i18n: I18nConfig;
11
- }
12
- interface Application {
13
- isSupportLocale(locale: string): boolean;
14
- gettext(locale: string, key: string, value?: any, ...args: any[]): string;
15
- __(locale: string, key: string, value?: any, ...args: any[]): string;
16
- }
17
- interface Context {
18
- /**
19
- * get and set current request locale
20
- * @member Context#locale
21
- * @return {String} lower case locale string, e.g.: 'zh-cn', 'en-us'
22
- */
23
- locale: string;
24
- gettext(key: string, value?: any, ...args: any[]): string;
25
- __(key: string, value?: any, ...args: any[]): string;
26
- __getLocale(): string;
27
- __setLocale(l: string): void;
28
- }
29
- }
1
+ import "./config.default-zrkP0tMD.js";
2
+ import "./types-DoabcMjn.js";
package/dist/types.js CHANGED
@@ -1 +1,3 @@
1
+ import "./types-BsuPrIpu.js";
2
+
1
3
  export { };
@@ -0,0 +1,10 @@
1
+ //#region src/utils.ts
2
+ function isObject(obj) {
3
+ return Object.prototype.toString.call(obj) === "[object Object]";
4
+ }
5
+ function formatLocale(locale) {
6
+ return locale.replaceAll("_", "-").toLowerCase();
7
+ }
8
+
9
+ //#endregion
10
+ export { formatLocale, isObject };
package/dist/utils.js CHANGED
@@ -1,10 +1,3 @@
1
- //#region src/utils.ts
2
- function isObject(obj) {
3
- return Object.prototype.toString.call(obj) === "[object Object]";
4
- }
5
- function formatLocale(locale) {
6
- return locale.replaceAll("_", "-").toLowerCase();
7
- }
1
+ import { formatLocale, isObject } from "./utils-D06av2P8.js";
8
2
 
9
- //#endregion
10
3
  export { formatLocale, isObject };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@eggjs/i18n",
3
- "version": "4.0.0-beta.18",
3
+ "version": "4.0.0-beta.20",
4
4
  "description": "i18n plugin for egg",
5
5
  "eggPlugin": {
6
6
  "name": "i18n"
@@ -45,21 +45,21 @@
45
45
  "ini": "^5.0.0",
46
46
  "js-yaml": "^4.1.0",
47
47
  "utility": "^2.5.0",
48
- "@eggjs/utils": "5.0.0-beta.18"
48
+ "@eggjs/utils": "5.0.0-beta.20"
49
49
  },
50
50
  "peerDependencies": {
51
- "egg": "4.1.0-beta.18"
51
+ "egg": "4.1.0-beta.20"
52
52
  },
53
53
  "devDependencies": {
54
54
  "@types/ini": "^4.1.1",
55
55
  "@types/js-yaml": "4",
56
- "@types/node": "24.5.2",
56
+ "@types/node": "^24.6.2",
57
57
  "egg-view-nunjucks": "^2.3.0",
58
58
  "tsdown": "^0.15.4",
59
- "typescript": "5.9.2",
60
- "vitest": "4.0.0-beta.13",
61
- "@eggjs/mock": "7.0.0-beta.18",
62
- "@eggjs/tsconfig": "3.1.0-beta.18"
59
+ "typescript": "^5.9.3",
60
+ "vitest": "4.0.0-beta.16",
61
+ "@eggjs/tsconfig": "3.1.0-beta.20",
62
+ "@eggjs/mock": "7.0.0-beta.20"
63
63
  },
64
64
  "files": [
65
65
  "dist"