@eggjs/i18n 3.0.1 → 4.0.0-beta.17

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.
Files changed (60) hide show
  1. package/README.md +10 -18
  2. package/dist/app/extend/application.d.ts +12 -0
  3. package/dist/app/extend/application.js +48 -0
  4. package/dist/app/extend/context.d.ts +76 -0
  5. package/dist/app/extend/context.js +152 -0
  6. package/dist/{commonjs/app.d.ts → app.d.ts} +10 -8
  7. package/dist/app.js +96 -0
  8. package/{src/types.ts → dist/config/config.default.d.ts} +7 -33
  9. package/dist/config/config.default.js +15 -0
  10. package/dist/index.d.ts +1 -0
  11. package/dist/index.js +4 -0
  12. package/dist/locales.d.ts +7 -0
  13. package/dist/locales.js +53 -0
  14. package/dist/types.d.ts +29 -0
  15. package/dist/types.js +1 -0
  16. package/dist/utils.d.ts +5 -0
  17. package/dist/utils.js +10 -0
  18. package/package.json +54 -73
  19. package/dist/commonjs/app/extend/application.d.ts +0 -8
  20. package/dist/commonjs/app/extend/application.js +0 -80
  21. package/dist/commonjs/app/extend/context.d.ts +0 -72
  22. package/dist/commonjs/app/extend/context.js +0 -177
  23. package/dist/commonjs/app.js +0 -103
  24. package/dist/commonjs/config/config.default.d.ts +0 -5
  25. package/dist/commonjs/config/config.default.js +0 -16
  26. package/dist/commonjs/index.d.ts +0 -1
  27. package/dist/commonjs/index.js +0 -4
  28. package/dist/commonjs/locales.d.ts +0 -3
  29. package/dist/commonjs/locales.js +0 -71
  30. package/dist/commonjs/package.json +0 -3
  31. package/dist/commonjs/types.d.ts +0 -74
  32. package/dist/commonjs/types.js +0 -3
  33. package/dist/commonjs/utils.d.ts +0 -2
  34. package/dist/commonjs/utils.js +0 -12
  35. package/dist/esm/app/extend/application.d.ts +0 -8
  36. package/dist/esm/app/extend/application.js +0 -76
  37. package/dist/esm/app/extend/context.d.ts +0 -72
  38. package/dist/esm/app/extend/context.js +0 -174
  39. package/dist/esm/app.d.ts +0 -56
  40. package/dist/esm/app.js +0 -97
  41. package/dist/esm/config/config.default.d.ts +0 -5
  42. package/dist/esm/config/config.default.js +0 -14
  43. package/dist/esm/index.d.ts +0 -1
  44. package/dist/esm/index.js +0 -2
  45. package/dist/esm/locales.d.ts +0 -3
  46. package/dist/esm/locales.js +0 -65
  47. package/dist/esm/package.json +0 -3
  48. package/dist/esm/types.d.ts +0 -74
  49. package/dist/esm/types.js +0 -2
  50. package/dist/esm/utils.d.ts +0 -2
  51. package/dist/esm/utils.js +0 -8
  52. package/dist/package.json +0 -4
  53. package/src/app/extend/application.ts +0 -91
  54. package/src/app/extend/context.ts +0 -192
  55. package/src/app.ts +0 -107
  56. package/src/config/config.default.ts +0 -15
  57. package/src/index.ts +0 -1
  58. package/src/locales.ts +0 -73
  59. package/src/typings/index.d.ts +0 -4
  60. package/src/utils.ts +0 -8
package/src/app.ts DELETED
@@ -1,107 +0,0 @@
1
- import path from 'node:path';
2
- import { debuglog } from 'node:util';
3
- import { loadLocaleResources } from './locales.js';
4
- import { exists } from 'utility';
5
- import { ms } from 'humanize-ms';
6
- import type { ILifecycleBoot } from '@eggjs/core';
7
- import type I18nApplication from './app/extend/application.js';
8
- import { formatLocale } from './utils.js';
9
-
10
- const debug = debuglog('@eggjs/i18n/app');
11
-
12
- /**
13
- * I18n 国际化
14
- *
15
- * 通过设置 Plugin 配置 `i18n: true`,开启多语言支持。
16
- *
17
- * #### 语言文件存储路径
18
- *
19
- * 统一存放在 `config/locale/*.js` 下( 兼容`config/locales/*.js` ),如包含英文,简体中文,繁体中文的语言文件:
20
- *
21
- * ```
22
- * - config/locale/
23
- * - en-US.js
24
- * - zh-CN.js
25
- * - zh-TW.js
26
- * ```
27
- * @class I18n
28
- * @param {App} app Application object.
29
- * @example
30
- *
31
- * #### I18n 文件内容
32
- *
33
- * ```js
34
- * // config/locale/zh-CN.js
35
- * module.exports = {
36
- * "Email": "邮箱",
37
- * "Welcome back, %s!": "欢迎回来, %s!",
38
- * "Hello %s, how are you today?": "你好 %s, 今天过得咋样?",
39
- * };
40
- * ```
41
- *
42
- * ```js
43
- * // config/locale/en-US.js
44
- * module.exports = {
45
- * "Email": "Email",
46
- * };
47
- * ```
48
- * 或者也可以用 JSON 格式的文件:
49
- *
50
- * ```js
51
- * // config/locale/zh-CN.json
52
- * {
53
- * "email": "邮箱",
54
- * "login": "帐号",
55
- * "createdAt": "注册时间"
56
- * }
57
- * ```
58
- */
59
-
60
- export default class I18n implements ILifecycleBoot {
61
- private readonly app;
62
-
63
- constructor(app: I18nApplication & { locals: Record<string, any> }) {
64
- this.app = app;
65
- }
66
-
67
- async didLoad() {
68
- const i18nConfig = this.app.config.i18n;
69
- i18nConfig.defaultLocale = formatLocale(i18nConfig.defaultLocale);
70
- i18nConfig.cookieMaxAge = ms(i18nConfig.cookieMaxAge);
71
-
72
- i18nConfig.dirs = Array.isArray(i18nConfig.dirs) ? i18nConfig.dirs : [];
73
- // 按 egg > 插件 > 框架 > 应用的顺序遍历 config/locale(config/locales) 目录,加载所有配置文件
74
- for (const unit of this.app.loader.getLoadUnits()) {
75
- let localePath = path.join(unit.path, 'config/locale');
76
- /**
77
- * 优先选择 `config/locale` 目录下的多语言文件,不存在时再选择 `config/locales` 目录
78
- * 避免 2 个目录同时存在时可能导致的冲突
79
- */
80
- if (!(await exists(localePath))) {
81
- localePath = path.join(unit.path, 'config/locales');
82
- }
83
- i18nConfig.dirs.push(localePath);
84
- }
85
-
86
- debug('app.config.i18n.dirs:', i18nConfig.dirs);
87
-
88
- await loadLocaleResources(this.app, i18nConfig);
89
-
90
- const app = this.app;
91
- function gettextInContext(key: string, ...args: any[]) {
92
- const ctx = app.ctxStorage.getStore()!;
93
- return ctx.gettext(key, ...args);
94
- }
95
- // 在 view 中使用 `__(key, value, ...args)`
96
- Object.defineProperties(app.locals, {
97
- __: {
98
- value: gettextInContext,
99
- enumerable: true,
100
- },
101
- gettext: {
102
- value: gettextInContext,
103
- enumerable: true,
104
- },
105
- });
106
- }
107
- }
@@ -1,15 +0,0 @@
1
- import type { I18nConfig } from '../types.js';
2
-
3
- export default {
4
- i18n: {
5
- defaultLocale: 'en_US',
6
- dirs: [],
7
- queryField: 'locale',
8
- cookieField: 'locale',
9
- cookieDomain: '',
10
- cookieMaxAge: '1y',
11
- localeAlias: {},
12
- writeCookie: true,
13
- dir: undefined,
14
- } as I18nConfig,
15
- };
package/src/index.ts DELETED
@@ -1 +0,0 @@
1
- import './types.js';
package/src/locales.ts DELETED
@@ -1,73 +0,0 @@
1
- import { debuglog } from 'node:util';
2
- import fs from 'node:fs/promises';
3
- import path from 'node:path';
4
- import ini from 'ini';
5
- import yaml from 'js-yaml';
6
- import { exists, readJSON } from 'utility';
7
- import { importModule } from '@eggjs/utils';
8
- import type { I18nConfig } from './types.js';
9
- import I18nApplication, { I18N_RESOURCES } from './app/extend/application.js';
10
- import { formatLocale, isObject } from './utils.js';
11
-
12
- const debug = debuglog('@eggjs/i18n/locales');
13
-
14
- export async function loadLocaleResources(app: I18nApplication, options: I18nConfig) {
15
- const localeDirs = options.dirs;
16
- const resources: Record<string, Record<string, string>> = {};
17
-
18
- if (options.dir && !localeDirs.includes(options.dir)) {
19
- localeDirs.push(options.dir);
20
- }
21
-
22
- for (const dir of localeDirs) {
23
- if (!(await exists(dir))) {
24
- continue;
25
- }
26
-
27
- const names = await fs.readdir(dir);
28
- for (const name of names) {
29
- const filepath = path.join(dir, name);
30
- // support en_US.js => en-US.js
31
- const locale = formatLocale(name.split('.')[0]);
32
- let resource: Record<string, string> = {};
33
-
34
- if (name.endsWith('.js') || name.endsWith('.ts')) {
35
- resource = flattening(await importModule(filepath, {
36
- importDefaultOnly: true,
37
- }));
38
- } else if (name.endsWith('.json')) {
39
- resource = flattening(await readJSON(filepath));
40
- } else if (name.endsWith('.properties')) {
41
- resource = ini.parse(await fs.readFile(filepath, 'utf8'));
42
- } else if (name.endsWith('.yml') || name.endsWith('.yaml')) {
43
- resource = flattening(yaml.load(await fs.readFile(filepath, 'utf8')));
44
- }
45
-
46
- resources[locale] = resources[locale] || {};
47
- Object.assign(resources[locale], resource);
48
- }
49
- }
50
-
51
- debug('Init locales with %j, got %j resources', options, Object.keys(resources));
52
- app[I18N_RESOURCES] = resources;
53
- }
54
-
55
- function flattening(data: any) {
56
- const result: Record<string, string> = {};
57
-
58
- function deepFlat(data: any, prefix: string) {
59
- for (const key in data) {
60
- const value = data[key];
61
- const k = prefix ? prefix + '.' + key : key;
62
- if (isObject(value)) {
63
- deepFlat(value, k);
64
- } else {
65
- result[k] = String(value);
66
- }
67
- }
68
- }
69
-
70
- deepFlat(data, '');
71
-
72
- return result;
73
- }
@@ -1,4 +0,0 @@
1
- // make sure to import egg typings and let typescript know about it
2
- // @see https://github.com/whxaxes/blog/issues/11
3
- // and https://www.typescriptlang.org/docs/handbook/declaration-merging.html
4
- import 'egg';
package/src/utils.ts DELETED
@@ -1,8 +0,0 @@
1
- export function isObject(obj: any) {
2
- return Object.prototype.toString.call(obj) === '[object Object]';
3
- }
4
-
5
- export function formatLocale(locale: string) {
6
- // support zh_CN, en_US => zh-CN, en-US
7
- return locale.replace('_', '-').toLowerCase();
8
- }