@intlify/vue-i18n-extensions 5.0.0 → 6.0.0

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
@@ -2,13 +2,11 @@
2
2
 
3
3
  [![npm](https://img.shields.io/npm/v/@intlify/vue-i18n-extensions/next.svg)](https://www.npmjs.com/package/@intlify/vue-i18n-extensions)
4
4
  [![npm](https://img.shields.io/npm/v/@intlify/vue-i18n-extensions.svg)](https://www.npmjs.com/package/@intlify/vue-i18n-extensions)
5
- [![vue-i18n-extensions Dev Token](https://badge.devtoken.rocks/vue-i18n-extensions)](https://devtoken.rocks/package/vue-i18n-extensions)
6
5
 
7
6
  Extensions for vue-i18n
8
7
 
9
- ## ⚠️ Notice
10
- This `next` branch is development branch for Vue 3! The version for Vue 2 is now in [`master`](https://github.com/intlify/vue-i18n-extensions/tree/master) branch!
11
-
8
+ > [!IMPORTANT]
9
+ > This `next` branch is development branch for Vue 3! The version for Vue 2 is now in [`master`](https://github.com/intlify/vue-i18n-extensions/tree/master) branch!
12
10
 
13
11
  This library exports the following extensions:
14
12
 
@@ -17,13 +15,18 @@ This library exports the following extensions:
17
15
  - Server-side rendering for `v-t` custom directive
18
16
  - Pre-Translation
19
17
 
20
-
21
18
  ## 💿 Installation
22
19
 
23
20
  ```sh
24
- $ npm i --save-dev @intlify/vue-i18n-extensions@next
25
- ```
21
+ # npm
22
+ npm i --save-dev @intlify/vue-i18n-extensions@next
26
23
 
24
+ # pnpm
25
+ pnpm add -D @intlify/vue-i18n-extensions@next
26
+
27
+ # yarn
28
+ yarn add -D @intlify/vue-i18n-extensions@next
29
+ ```
27
30
 
28
31
  ## 🚀 Extensions
29
32
 
@@ -89,14 +92,15 @@ console.log(await renderToString(app))
89
92
  // output -> <div>I eat 2 bananas!</div>`
90
93
  ```
91
94
 
92
-
93
95
  ### Pre-Translation with using `v-t` custom directive
94
96
 
95
- You can pre-translation i18n locale messsages of vue-i18n.
97
+ You can pre-translation i18n locale messages of vue-i18n.
96
98
 
97
- > :warning: NOTE: Only the scope of global i18n locale messages can be pre-translated !!
99
+ > [!WARNING]
100
+ > Only the global scope i18n locale messages can be pre-translated !!
98
101
 
99
- > :warning: NOTE: Currently only `v-t` custom directive is supported !!
102
+ > [!WARNING]
103
+ > only `v-t` custom directive is supported !!
100
104
 
101
105
  In order to use this feature, you need to specify to Vue compiler option.
102
106
  The following example that use `compile` of `@vue/compiler-dom`:
@@ -139,7 +143,7 @@ console.log(code)
139
143
  */
140
144
  ```
141
145
 
142
- The following configration example of `vue-loader`:
146
+ The following configuration example of `vue-loader`:
143
147
 
144
148
  ```js
145
149
  const { VueLoaderPlugin } = require('vue-loader')
@@ -175,7 +179,7 @@ module.exports = {
175
179
  }
176
180
  }
177
181
  ]
178
- },
182
+ }
179
183
  // ...
180
184
  ]
181
185
  },
@@ -194,12 +198,10 @@ You can specify the transform resulting from `transformVTDirective` in the compi
194
198
  - `rollup-plugin-vue` (`compilerOptions` at [`Options`](https://github.com/vuejs/rollup-plugin-vue/blob/next/src/index.ts#L50))
195
199
  - `vite` (`vueCompilerOptions` at [`CoreOptions`](https://github.com/vitejs/vite/blob/master/src/node/config.ts#L154))
196
200
 
197
-
198
201
  ## 🤝 API
199
202
 
200
203
  About details, See [docs](./docs/@intlify/vue-i18n-extensions-api.md)
201
204
 
202
-
203
205
  ## ©️ License
204
206
 
205
207
  [MIT](http://opensource.org/licenses/MIT)
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@intlify/vue-i18n-extensions",
3
3
  "description": "vue-i18n extensions",
4
- "version": "5.0.0",
4
+ "version": "6.0.0",
5
5
  "author": {
6
6
  "name": "kazuya kawaguchi",
7
7
  "email": "kawakazu80@gmail.com"
@@ -9,72 +9,50 @@
9
9
  "bugs": {
10
10
  "url": "https://github.com/intlify/vue-i18n-extensions/issues"
11
11
  },
12
- "changelog": {
13
- "labels": {
14
- "Type: Feature": ":star: Features",
15
- "Type: Bug": ":bug: Bug Fixes",
16
- "Type: Security": ":lock: Security Fixes",
17
- "Type: Performance": ":chart_with_upwards_trend: Performance Fixes",
18
- "Type: Improvement": ":zap: Improvement Features",
19
- "Type: Breaking": ":boom: Breaking Change",
20
- "Type: Deprecated": ":warning: Deprecated Features",
21
- "Type: I18n": ":globe_with_meridians: Internationalization",
22
- "Type: A11y": ":wheelchair: Accessibility",
23
- "Type: Documentation": ":pencil: Documentation"
24
- }
25
- },
26
12
  "dependencies": {
27
- "@babel/parser": "^7.20.0",
13
+ "@babel/parser": "^7.24.6",
28
14
  "@intlify/shared": "^9.0.0",
29
15
  "@vue/compiler-dom": "^3.2.45",
30
16
  "vue-i18n": "^9.0.0"
31
17
  },
32
18
  "devDependencies": {
33
- "@kazupon/lerna-changelog": "^4.3.0",
19
+ "@babel/types": "^7.24.6",
20
+ "@eslint/js": "^9.2.0",
34
21
  "@microsoft/api-extractor": "^7.18.4",
35
- "@secretlint/secretlint-rule-preset-recommend": "^3.3.0",
36
- "@types/jest": "^26.0.24",
37
- "@types/node": "^18.11.17",
38
- "@typescript-eslint/eslint-plugin": "^5.46.1",
39
- "@typescript-eslint/parser": "^5.46.1",
22
+ "@types/eslint": "^8.56.10",
23
+ "@types/node": "^20.13.0",
24
+ "@vitest/coverage-v8": "^1.6.0",
25
+ "@vue/compiler-core": "^3.2.45",
40
26
  "@vue/compiler-sfc": "^3.2.45",
41
27
  "@vue/compiler-ssr": "^3.2.45",
42
28
  "@vue/runtime-dom": "^3.2.45",
43
29
  "@vue/server-renderer": "^3.2.45",
44
30
  "api-docs-gen": "^0.4.0",
45
- "babel-loader": "^8.2.0",
46
- "eslint": "^8.30.0",
47
- "eslint-config-prettier": "^8.5.0",
48
- "eslint-plugin-prettier": "^4.2.1",
49
- "jest": "^27.0.6",
50
- "jest-puppeteer": "^6.0.0",
51
- "jest-watch-typeahead": "^1.0.0",
52
- "lint-staged": "^11.0.0",
53
- "npm-run-all": "^4.1.5",
31
+ "bumpp": "^9.4.1",
32
+ "eslint": "^9.2.0",
33
+ "get-port-please": "^3.1.2",
34
+ "gh-changelogen": "^0.2.8",
35
+ "globals": "^15.0.0",
36
+ "jsdom": "^24.0.0",
37
+ "lint-staged": "^15.2.5",
38
+ "npm-run-all2": "^6.0.0",
54
39
  "opener": "^1.5.2",
55
- "prettier": "^2.8.1",
56
- "puppeteer": "^12.0.0",
57
- "secretlint": "^3.3.0",
58
- "shipjs": "^0.24.0",
59
- "ts-jest": "^27.0.4",
60
- "typescript": "^4.9.1",
61
- "vue": "^3.2.45",
62
- "vue-loader": "^16.2.0",
63
- "webpack": "^5.49.0",
64
- "webpack-cli": "^4.7.2",
65
- "webpack-dev-server": "^3.11.2",
66
- "yorkie": "^2.0.0"
40
+ "pkg-types": "^1.1.1",
41
+ "playwright": "^1.44.0",
42
+ "prettier": "^3.2.5",
43
+ "tsx": "^4.11.0",
44
+ "typescript": "^5.4.5",
45
+ "typescript-eslint": "^7.9.0",
46
+ "vitest": "^1.6.0",
47
+ "vue": "^3.2.45"
67
48
  },
68
49
  "engines": {
69
- "node": ">= 14.18"
50
+ "node": ">= 18"
70
51
  },
71
52
  "files": [
72
53
  "lib/*.js",
73
54
  "dist/*.d.ts"
74
55
  ],
75
- "gitHooks": {
76
- "pre-commit": "lint-staged"
77
- },
78
56
  "homepage": "https://github.com/intlify/vue-i18n-extensions#readme",
79
57
  "keywords": [
80
58
  "extensions",
@@ -86,14 +64,16 @@
86
64
  ],
87
65
  "license": "MIT",
88
66
  "lint-staged": {
89
- "*.js": [
67
+ "*.{json,md,yml}": [
90
68
  "prettier --write"
91
69
  ],
92
- "*.ts?(x)": [
93
- "prettier --parser=typescript --write"
70
+ "*.{js,mjs,cjs}": [
71
+ "prettier --write",
72
+ "eslint --fix"
94
73
  ],
95
- "*": [
96
- "secretlint"
74
+ "*.ts?(x)": [
75
+ "prettier --parser=typescript --write",
76
+ "eslint --fix"
97
77
  ]
98
78
  },
99
79
  "main": "lib/index.js",
@@ -105,33 +85,30 @@
105
85
  "type": "git",
106
86
  "url": "git+https://github.com/intlify/vue-i18n-extensions.git"
107
87
  },
88
+ "types": "dist/vue-i18n-extensions.d.ts",
108
89
  "scripts": {
109
- "build": "yarn build:transpile && yarn build:extract && yarn build:docs",
90
+ "changelog": "gh-changelogen --repo=intlify/vue-i18n-extensions",
91
+ "release": "bumpp --commit \"release: v%s\" --push --tag",
92
+ "build": "pnpm build:transpile && pnpm build:extract && pnpm build:docs",
93
+ "build:nightly": "pnpm build:transpile && pnpm build:extract",
110
94
  "build:docs": "api-docs-gen ./temp/vue-i18n-extensions.api.json -c ./docsgen.config.js -o ./docs",
111
- "build:extract": "api-extractor run -l -c ./api-extractor.json",
112
- "build:transpile": "tsc -p .",
113
- "clean": "npm-run-all clean:*",
114
- "clean:cache:jest": "jest --clearCache",
115
- "clean:coverage": "rm -rf ./coverage",
116
- "clean:extract": "rm -rf ./temp/*.* ./dist/*.* ./etc/*.*",
117
- "clean:lib": "rm -rf ./lib/*.*",
95
+ "build:extract": "api-extractor run -l -c ./api-extractor.json --typescript-compiler-folder node_modules/typescript",
96
+ "build:transpile": "tsc -p tsconfig.build.json",
97
+ "check-install": "tsx scripts/playwright.ts",
98
+ "clean": "git clean -fdx",
118
99
  "coverage": "opener coverage/lcov-report/index.html",
119
100
  "example": "webpack serve --config example/webpack.config.js --inline --hot",
120
- "fix": "npm-run-all --parallel lint:eslint:fix format:fix",
121
- "format": "prettier --config .prettierrc --ignore-path .prettierignore --list-different '**/*.{js,json,html}'",
122
- "format:fix": "yarn format --write",
123
- "lint": "npm-run-all --parallel lint:eslint lint:secret",
124
- "lint:eslint": "eslint ./src ./test --ext .ts",
125
- "lint:eslint:fix": "yarn lint:eslint --fix",
126
- "lint:secret": "npx secretlint \"**/*\"",
127
- "release:prepare": "shipjs prepare",
128
- "release:trigger": "shipjs trigger",
129
- "test": "yarn lint && yarn test:cover && yarn test:e2e",
130
- "test:cover": "yarn clean:cache:jest && yarn test:unit --coverage",
131
- "test:e2e": "jest --runInBand --config ./jest.e2e.config.js",
132
- "test:unit": "yarn clean:cache:jest && jest --env node",
133
- "test:watch": "yarn clean:cache:jest && jest --env node --watch",
134
- "watch": "tsc -p . --watch"
135
- },
136
- "types": "dist/vue-i18n-extensions.d.ts"
137
- }
101
+ "lint": "run-p \"lint:* {@}\" --",
102
+ "lint:prettier": "prettier . --check",
103
+ "lint:eslint": "eslint .",
104
+ "fix": "run-p \"fix:* {@}\" --",
105
+ "fix:prettier": "prettier . --write",
106
+ "fix:eslint": "eslint . --fix",
107
+ "test": "pnpm test:cover && pnpm check-install && pnpm test:e2e",
108
+ "test:cover": "pnpm test:unit --coverage --coverage.include=src",
109
+ "test:e2e": "vitest -c ./vitest.e2e.config.ts run",
110
+ "test:unit": "vitest run",
111
+ "test:watch": "vitest --no-cache --watch",
112
+ "watch": "tsc -p tsconfig.build.json --watch"
113
+ }
114
+ }
@@ -1,81 +0,0 @@
1
- import { DirectiveTransform } from '@vue/compiler-dom';
2
- import { I18n } from 'vue-i18n';
3
- import { I18nMode } from 'vue-i18n';
4
-
5
- /**
6
- * Transform `v-t` custom directive
7
- *
8
- * @remarks
9
- * Transform that `v-t` custom directive is optimized vue-i18n code by Vue compiler.
10
- * This transform can improve the performance by pre-translating, and it does support SSR.
11
- *
12
- * @param options - `v-t` custom directive transform options, see {@link TransformVTDirectiveOptions}
13
- * @returns Directive transform
14
- *
15
- * @example
16
- * ```js
17
- * import { compile } from '@vue/compiler-dom'
18
- * import { createI18n } from 'vue-i18n'
19
- * import { transformVTDirective } from '@intlify/vue-i18n-extensions'
20
- *
21
- * // create i18n instance
22
- * const i18n = createI18n({
23
- * locale: 'ja',
24
- * messages: {
25
- * en: {
26
- * hello: 'hello'
27
- * },
28
- * ja: {
29
- * hello: 'こんにちは'
30
- * }
31
- * }
32
- * })
33
- *
34
- * // get transform from `transformVTDirective` function, with `i18n` option
35
- * const transformVT = transformVTDirective({ i18n })
36
- *
37
- * const { code } = compile(`<p v-t="'hello'"></p>`, {
38
- * mode: 'function',
39
- * hoistStatic: true,
40
- * prefixIdentifiers: true,
41
- * directiveTransforms: { t: transformVT } // <- you need to specify to `directiveTransforms` option!
42
- * })
43
- *
44
- * console.log(code)
45
- * // output ->
46
- * // const { createVNode: _createVNode, openBlock: _openBlock, createBlock: _createBlock } = Vue
47
- * // return function render(_ctx, _cache) {
48
- * // return (_openBlock(), _createBlock(\\"div\\", null, \\"こんにちは!\\"))
49
- * // }
50
- * ```
51
- * @public
52
- */
53
- export declare function transformVTDirective<Messages = {}, DateTimeFormats = {}, NumberFormats = {}, Legacy extends boolean = true>(options?: TransformVTDirectiveOptions<Messages, DateTimeFormats, NumberFormats, Legacy>): DirectiveTransform;
54
-
55
- /**
56
- * Transform options for `v-t` custom directive
57
- *
58
- * @public
59
- */
60
- export declare interface TransformVTDirectiveOptions<Messages = {}, DateTimeFormats = {}, NumberFormats = {}, Legacy extends boolean = true> {
61
- /**
62
- * I18n instance
63
- *
64
- * @remarks
65
- * If this option is specified, `v-t` custom diretive transform uses an I18n instance to pre-translate.
66
- * The translation will use the global resources registered in the I18n instance,
67
- * that is, `v-t` diretive transform is also a limitation that the resources of each component cannot be used.
68
- */
69
- i18n?: I18n<Messages, DateTimeFormats, NumberFormats, Legacy>;
70
- /**
71
- * I18n Mode
72
- *
73
- * @remarks
74
- * Specify the API style of vue-i18n. If you use legacy API style (e.g. `$t`) at vue-i18n, you need to specify `legacy`.
75
- *
76
- * @default 'composition'
77
- */
78
- mode?: I18nMode;
79
- }
80
-
81
- export { }
package/lib/builder.js DELETED
@@ -1,62 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.createContentBuilder = void 0;
4
- const shared_1 = require("@intlify/shared");
5
- /**
6
- * Create a Content Builder
7
- *
8
- * @param options - Content Builder options
9
- *
10
- * @returns A {@link ContentBuilder} instance
11
- *
12
- * @public
13
- */
14
- function createContentBuilder(options = {}) {
15
- let _indentLevel = options.indentLevel != null && (0, shared_1.isNumber)(options.indentLevel)
16
- ? options.indentLevel
17
- : 0;
18
- let _content = '';
19
- function push(content) {
20
- _content += content;
21
- }
22
- function _newline(n) {
23
- push('\n' + ` `.repeat(n));
24
- }
25
- function newline() {
26
- _newline(_indentLevel);
27
- }
28
- function pushline(content) {
29
- push(content);
30
- newline();
31
- }
32
- function indent(withoutNewLine) {
33
- if (withoutNewLine) {
34
- ++_indentLevel;
35
- }
36
- else {
37
- _newline(++_indentLevel);
38
- }
39
- }
40
- function deindent(withoutNewLine) {
41
- if (withoutNewLine) {
42
- --_indentLevel;
43
- }
44
- else {
45
- _newline(--_indentLevel);
46
- }
47
- }
48
- return {
49
- get indentLevel() {
50
- return _indentLevel;
51
- },
52
- get content() {
53
- return String(_content);
54
- },
55
- push,
56
- newline,
57
- pushline,
58
- indent,
59
- deindent
60
- };
61
- }
62
- exports.createContentBuilder = createContentBuilder;
package/lib/index.js DELETED
@@ -1,5 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.transformVTDirective = void 0;
4
- var transform_1 = require("./transform");
5
- Object.defineProperty(exports, "transformVTDirective", { enumerable: true, get: function () { return transform_1.transformVTDirective; } });
package/lib/report.js DELETED
@@ -1,42 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.report = exports.getReportMessage = void 0;
4
- const shared_1 = require("@intlify/shared");
5
- // TODO: should be extracted as i18n resources (intlify project self hosting!)
6
- const ReportMessages = {
7
- [1 /* ReportCodes.UNEXPECTED_DIRECTIVE_EXPRESSION */]: `Unexpected directive expression: {0}`,
8
- [2 /* ReportCodes.NOT_SUPPORTED */]: `Not supported transform: {0}`,
9
- [3 /* ReportCodes.FAILED_VALUE_EVALUATION */]: `Failed valu evaluation: {0}`,
10
- [4 /* ReportCodes.REQUIRED_PARAMETER */]: `Required parameter: {0}`,
11
- [5 /* ReportCodes.INVALID_PARAMETER_TYPE */]: `Required parameter: {0}`,
12
- [6 /* ReportCodes.NOT_SUPPORTED_PRESERVE */]: `Not supportted 'preserve': {0}`,
13
- [7 /* ReportCodes.ORVERRIDE_ELEMENT_CHILDREN */]: `v-t will override element children: {0}`
14
- };
15
- function getReportMessage(code, ...args) {
16
- return (0, shared_1.format)(ReportMessages[code], ...args);
17
- }
18
- exports.getReportMessage = getReportMessage;
19
- function createExtensionsError(code, msg, loc) {
20
- const error = new SyntaxError(msg);
21
- error.code = code;
22
- if (loc) {
23
- error.loc = loc;
24
- }
25
- return error;
26
- }
27
- function report(code, optinos = {}) {
28
- const mode = optinos.mode &&
29
- (0, shared_1.isString)(optinos.mode) &&
30
- ['warn', 'error'].includes(optinos.mode)
31
- ? optinos.mode
32
- : 'warn';
33
- const msg = getReportMessage(code, optinos.args);
34
- if (mode === 'warn') {
35
- console.warn('[vue-i18n-extensions] ' + msg);
36
- }
37
- else {
38
- // error
39
- throw createExtensionsError(code, msg, optinos.loc);
40
- }
41
- }
42
- exports.report = report;
package/lib/transform.js DELETED
@@ -1,319 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.transformVTDirective = void 0;
4
- const compiler_dom_1 = require("@vue/compiler-dom");
5
- const shared_1 = require("@intlify/shared");
6
- const transpiler_1 = require("./transpiler");
7
- const report_1 = require("./report");
8
- const builder_1 = require("./builder");
9
- /**
10
- * Transform `v-t` custom directive
11
- *
12
- * @remarks
13
- * Transform that `v-t` custom directive is optimized vue-i18n code by Vue compiler.
14
- * This transform can improve the performance by pre-translating, and it does support SSR.
15
- *
16
- * @param options - `v-t` custom directive transform options, see {@link TransformVTDirectiveOptions}
17
- * @returns Directive transform
18
- *
19
- * @example
20
- * ```js
21
- * import { compile } from '@vue/compiler-dom'
22
- * import { createI18n } from 'vue-i18n'
23
- * import { transformVTDirective } from '@intlify/vue-i18n-extensions'
24
- *
25
- * // create i18n instance
26
- * const i18n = createI18n({
27
- * locale: 'ja',
28
- * messages: {
29
- * en: {
30
- * hello: 'hello'
31
- * },
32
- * ja: {
33
- * hello: 'こんにちは'
34
- * }
35
- * }
36
- * })
37
- *
38
- * // get transform from `transformVTDirective` function, with `i18n` option
39
- * const transformVT = transformVTDirective({ i18n })
40
- *
41
- * const { code } = compile(`<p v-t="'hello'"></p>`, {
42
- * mode: 'function',
43
- * hoistStatic: true,
44
- * prefixIdentifiers: true,
45
- * directiveTransforms: { t: transformVT } // <- you need to specify to `directiveTransforms` option!
46
- * })
47
- *
48
- * console.log(code)
49
- * // output ->
50
- * // const { createVNode: _createVNode, openBlock: _openBlock, createBlock: _createBlock } = Vue
51
- * // return function render(_ctx, _cache) {
52
- * // return (_openBlock(), _createBlock(\\"div\\", null, \\"こんにちは!\\"))
53
- * // }
54
- * ```
55
- * @public
56
- */
57
- function transformVTDirective(options = {}) {
58
- const i18nInstance = options.i18n;
59
- const mode = (0, shared_1.isString)(options.mode) && ['composition', 'legacy'].includes(options.mode)
60
- ? options.mode
61
- : 'composition';
62
- return (dir, node, context) => {
63
- const { exp, loc } = dir;
64
- // console.log('v-t dir', dir)
65
- // console.log('v-t node', node)
66
- if (!exp) {
67
- // TODO: throw error with context.OnError
68
- // NOTE: We need to support from @vue/compiler-core
69
- // https://github.com/vuejs/vue-next/issues/1147
70
- (0, report_1.report)(1 /* ReportCodes.UNEXPECTED_DIRECTIVE_EXPRESSION */, {
71
- mode: 'error',
72
- args: [node.loc.source || ''],
73
- loc: node.loc
74
- });
75
- }
76
- if (node.children.length > 0) {
77
- // TODO: throw error with context.OnError
78
- // NOTE: We need to support from @vue/compiler-core
79
- // https://github.com/vuejs/vue-next/issues/1147
80
- (0, report_1.report)(7 /* ReportCodes.ORVERRIDE_ELEMENT_CHILDREN */, {
81
- mode: 'error',
82
- args: [node.loc.source || ''],
83
- loc: node.loc
84
- });
85
- node.children.length = 0;
86
- }
87
- if (dir.modifiers.includes('preserve')) {
88
- (0, report_1.report)(6 /* ReportCodes.NOT_SUPPORTED_PRESERVE */, {
89
- args: [node.loc.source || ''],
90
- loc: node.loc
91
- });
92
- }
93
- if (isSimpleExpressionNode(exp)) {
94
- if (isConstant(exp) && i18nInstance) {
95
- const { status, value } = (0, transpiler_1.evaluateValue)(exp.content);
96
- if (status === 'ng') {
97
- (0, report_1.report)(3 /* ReportCodes.FAILED_VALUE_EVALUATION */, {
98
- args: [node.loc.source || ''],
99
- loc: node.loc
100
- });
101
- return { props: [] };
102
- }
103
- const [parsedValue, parseStatus] = parseValue(value);
104
- if (parseStatus !== 0 /* ReportCodes.SUCCESS */) {
105
- (0, report_1.report)(parseStatus, { args: [node.loc.source || ''], loc: node.loc });
106
- return { props: [] };
107
- }
108
- const global = i18nInstance.mode === 'composition'
109
- ? i18nInstance.global // eslint-disable-line @typescript-eslint/no-explicit-any
110
- : i18nInstance.global.__composer; // eslint-disable-line @typescript-eslint/no-explicit-any
111
- const content = global.t(...makeParams(parsedValue));
112
- node.children.push({
113
- type: 2 /* NodeTypes.TEXT */,
114
- content
115
- });
116
- return { props: [] };
117
- }
118
- else {
119
- const translationParams = (0, transpiler_1.parseVTExpression)(exp.content);
120
- const code = generateTranslationCode(context, mode, translationParams);
121
- context.helper(compiler_dom_1.TO_DISPLAY_STRING);
122
- node.children.push({
123
- type: 5 /* NodeTypes.INTERPOLATION */,
124
- content: (0, compiler_dom_1.createCompoundExpression)([
125
- (0, compiler_dom_1.createSimpleExpression)(code, false, loc,
126
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
127
- 0 /* ConstantTypes.NOT_CONSTANT */)
128
- ])
129
- });
130
- return { props: [] };
131
- }
132
- }
133
- else if (isCompoundExpressionNode(exp)) {
134
- const content = exp.children.map(mapNodeContentHanlder).join('');
135
- const code = generateTranslationCode(context, mode, (0, transpiler_1.parseVTExpression)(content));
136
- context.helper(compiler_dom_1.TO_DISPLAY_STRING);
137
- node.children.push({
138
- type: 5 /* NodeTypes.INTERPOLATION */,
139
- content: (0, compiler_dom_1.createCompoundExpression)([
140
- (0, compiler_dom_1.createSimpleExpression)(code, false, loc,
141
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
142
- 0 /* ConstantTypes.NOT_CONSTANT */)
143
- ])
144
- });
145
- return { props: [] };
146
- }
147
- else {
148
- (0, report_1.report)(2 /* ReportCodes.NOT_SUPPORTED */, {
149
- args: [node.loc.source || ''],
150
- loc: node.loc
151
- });
152
- return { props: [] };
153
- }
154
- };
155
- }
156
- exports.transformVTDirective = transformVTDirective;
157
- function isSimpleExpressionNode(node) {
158
- return node != null && node.type === 4 /* NodeTypes.SIMPLE_EXPRESSION */;
159
- }
160
- function isCompoundExpressionNode(node) {
161
- return node != null && node.type === 8 /* NodeTypes.COMPOUND_EXPRESSION */;
162
- }
163
- function isConstant(node) {
164
- if ('isConstant' in node) {
165
- // for v3.0.3 earlier
166
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
167
- return node.isConstant;
168
- }
169
- else if ('constType' in node) {
170
- // for v3.0.3 or later
171
- return node.constType <= 3 /* ConstantTypes.CAN_STRINGIFY */;
172
- }
173
- else {
174
- throw Error('unexpected error');
175
- }
176
- }
177
- function mapNodeContentHanlder(value) {
178
- if ((0, shared_1.isString)(value)) {
179
- return value;
180
- }
181
- else if ((0, shared_1.isSymbol)(value)) {
182
- return value.description || '';
183
- }
184
- else if (isSimpleExpressionNode(value)) {
185
- return value.content;
186
- }
187
- else if (isCompoundExpressionNode(value)) {
188
- return value.children.map(mapNodeContentHanlder).join('');
189
- }
190
- else if ((0, compiler_dom_1.isText)(value)) {
191
- if ((0, shared_1.isString)(value.content)) {
192
- return value.content;
193
- }
194
- else if (isSimpleExpressionNode(value.content)) {
195
- return value.content.content;
196
- }
197
- else if (isCompoundExpressionNode(value.content)) {
198
- return value.content.children.map(mapNodeContentHanlder).join('');
199
- }
200
- else {
201
- return '';
202
- }
203
- }
204
- else {
205
- return '';
206
- }
207
- }
208
- function parseValue(value) {
209
- if ((0, shared_1.isString)(value)) {
210
- return [{ path: value }, 0 /* ReportCodes.SUCCESS */];
211
- }
212
- else if ((0, shared_1.isObject)(value)) {
213
- if (!('path' in value)) {
214
- return [null, 4 /* ReportCodes.REQUIRED_PARAMETER */];
215
- }
216
- return [value, 0 /* ReportCodes.SUCCESS */];
217
- }
218
- else {
219
- return [null, 5 /* ReportCodes.INVALID_PARAMETER_TYPE */];
220
- }
221
- }
222
- function makeParams(value) {
223
- const { path, locale, args, choice, plural } = value;
224
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
225
- const options = {};
226
- const named = args || {};
227
- if ((0, shared_1.isString)(locale)) {
228
- options.locale = locale;
229
- }
230
- if ((0, shared_1.isNumber)(choice)) {
231
- options.plural = choice;
232
- }
233
- if ((0, shared_1.isNumber)(plural)) {
234
- options.plural = plural;
235
- }
236
- return [path, named, options];
237
- }
238
- function generateTranslationCode(context, mode, params) {
239
- return mode === 'composition'
240
- ? generateComposableCode(context, params)
241
- : generateLegacyCode(context, params);
242
- }
243
- function generateComposableCode(context, params) {
244
- const baseCode = `${context.prefixIdentifiers ? '_ctx.' : ''}t`;
245
- const builder = (0, builder_1.createContentBuilder)();
246
- builder.push(`${baseCode}(`);
247
- // generate path
248
- builder.push(`${(0, shared_1.toDisplayString)(params.path)}`);
249
- // generate named
250
- builder.push(`, { `);
251
- generateNamedCode(builder, params.named);
252
- builder.push(` }`);
253
- // generate options
254
- builder.push(`, { `);
255
- if (params.options.locale) {
256
- builder.push(`locale: ${(0, shared_1.toDisplayString)(params.options.locale)}`);
257
- }
258
- if (params.options.plural) {
259
- if (params.options.locale) {
260
- builder.push(', ');
261
- }
262
- builder.push(`plural: ${(0, shared_1.toDisplayString)(params.options.plural)}`);
263
- }
264
- builder.push(` }`);
265
- builder.push(`)`);
266
- const content = builder.content;
267
- return content;
268
- }
269
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
270
- function generateNamedCode(builder, named) {
271
- const keys = Object.keys(named);
272
- keys.forEach(k => {
273
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
274
- const v = named[k];
275
- if ((0, shared_1.isObject)(v)) {
276
- builder.push(`${k}: { `);
277
- generateNamedCode(builder, v);
278
- builder.push(` }`);
279
- }
280
- else {
281
- builder.push(`${k}: ${(0, shared_1.toDisplayString)(v)}`);
282
- }
283
- });
284
- }
285
- function generateLegacyCode(context, params) {
286
- const mode = !params.options.plural ? 'basic' : 'plural';
287
- const baseCode = `${context.prefixIdentifiers ? '_ctx.' : ''}${mode === 'basic' ? '$t' : '$tc'}`;
288
- const builder = (0, builder_1.createContentBuilder)();
289
- builder.push(`${baseCode}(`);
290
- // generate path
291
- builder.push(`${(0, shared_1.toDisplayString)(params.path)}`);
292
- if (mode === 'basic') {
293
- // generate locale
294
- if ((0, shared_1.isString)(params.options.locale)) {
295
- builder.push(`, ${(0, shared_1.toDisplayString)(params.options.locale)}`);
296
- }
297
- // generate named
298
- builder.push(`, { `);
299
- generateNamedCode(builder, params.named);
300
- builder.push(` }`);
301
- }
302
- else {
303
- // generaete plural
304
- builder.push(`, ${(0, shared_1.toDisplayString)(params.options.plural)}`);
305
- if ((0, shared_1.isString)(params.options.locale)) {
306
- // generate locale
307
- builder.push(`, ${(0, shared_1.toDisplayString)(params.options.locale)}`);
308
- }
309
- else {
310
- // generate named
311
- builder.push(`, { `);
312
- generateNamedCode(builder, params.named);
313
- builder.push(` }`);
314
- }
315
- }
316
- builder.push(`)`);
317
- const content = builder.content;
318
- return content;
319
- }
package/lib/transpiler.js DELETED
@@ -1,117 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.parseVTExpression = exports.evaluateValue = void 0;
4
- /* eslint-disable @typescript-eslint/no-explicit-any */
5
- const parser_1 = require("@babel/parser");
6
- function evaluateValue(expression) {
7
- const ret = { status: 'ng', value: undefined };
8
- try {
9
- const ast = (0, parser_1.parse)(`const a = ${expression.trim()}`);
10
- const node = ast.program.body[0].declarations[0].init;
11
- if (node.type === 'StringLiteral' || node.type === 'ObjectExpression') {
12
- const val = new Function(`return ${expression.trim()}`)();
13
- ret.status = 'ok';
14
- ret.value = val;
15
- }
16
- }
17
- catch (e) { }
18
- return ret;
19
- }
20
- exports.evaluateValue = evaluateValue;
21
- function parseVTExpression(expression) {
22
- const ret = {
23
- path: '',
24
- named: {},
25
- options: {}
26
- };
27
- try {
28
- const ast = (0, parser_1.parse)(`const a = ${expression.trim()}`);
29
- const node = ast.program.body[0].declarations[0].init;
30
- if (node.type === 'StringLiteral') {
31
- ret.path = node.extra.raw;
32
- }
33
- else if (node.type === 'Identifier') {
34
- ret.path = node.name;
35
- }
36
- else if (node.type === 'MemberExpression') {
37
- ret.path = getObjectMemberValue(node);
38
- }
39
- else if (node.type === 'ObjectExpression') {
40
- node.properties.forEach((propNode) => {
41
- const propKeyNode = propNode.key;
42
- if (propKeyNode.type !== 'Identifier') {
43
- return;
44
- }
45
- const propValueNode = propNode.value;
46
- switch (propKeyNode.name) {
47
- case 'path':
48
- ret.path = getObjectMemberValue(propValueNode);
49
- break;
50
- case 'locale':
51
- ret.options.locale = getObjectMemberValue(propValueNode);
52
- break;
53
- case 'choice':
54
- case 'plural':
55
- ret.options.plural = getObjectMemberValue(propValueNode);
56
- break;
57
- case 'args':
58
- // console.log('args', propValueNode)
59
- traverseObjectMember(propValueNode, ret.named);
60
- break;
61
- default:
62
- break;
63
- }
64
- });
65
- }
66
- }
67
- catch (e) { }
68
- return ret;
69
- }
70
- exports.parseVTExpression = parseVTExpression;
71
- function getObjectMemberValue(node) {
72
- if (node.type === 'StringLiteral' || node.type === 'NumericLiteral') {
73
- return node.extra.raw;
74
- }
75
- else if (node.type === 'Identifier') {
76
- return node.name;
77
- }
78
- else if (node.type === 'MemberExpression') {
79
- const paths = [];
80
- collectMermberPath(node, paths);
81
- paths.reverse();
82
- return paths.join('.');
83
- }
84
- else {
85
- return '';
86
- }
87
- }
88
- function traverseObjectMember(node, target) {
89
- node.properties.forEach((propNode) => {
90
- const propKeyNode = propNode.key;
91
- if (propKeyNode.type !== 'Identifier') {
92
- return;
93
- }
94
- if (!(propKeyNode.name in target)) {
95
- target[propKeyNode.name] = {};
96
- }
97
- // console.log('propNode', propNode)
98
- const propValueNode = propNode.value;
99
- if (propValueNode.type === 'ObjectExpression') {
100
- traverseObjectMember(propValueNode, target[propKeyNode.name]);
101
- }
102
- else {
103
- target[propKeyNode.name] = getObjectMemberValue(propValueNode);
104
- }
105
- });
106
- }
107
- function collectMermberPath(node, paths) {
108
- if (node.type === 'Identifier') {
109
- paths.push(node.name);
110
- return;
111
- }
112
- if (node.property.type === 'Identifier') {
113
- paths.push(node.property.name);
114
- return collectMermberPath(node.object, paths);
115
- }
116
- }
117
- /* eslint-enable @typescript-eslint/no-explicit-any */