@intlify/vue-i18n-extensions 6.0.4 → 6.0.5

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.
@@ -0,0 +1,95 @@
1
+ import { DirectiveTransform } from '@vue/compiler-dom';
2
+ import { I18n, I18nMode } from 'vue-i18n';
3
+
4
+ /**
5
+ * Transform options for `v-t` custom directive
6
+ *
7
+ * @public
8
+ */
9
+ interface TransformVTDirectiveOptions<Messages extends Record<string, unknown> = {}, // eslint-disable-line @typescript-eslint/ban-types -- TODO: fix this
10
+ DateTimeFormats extends Record<string, unknown> = {}, // eslint-disable-line @typescript-eslint/ban-types -- TODO: fix this
11
+ NumberFormats extends Record<string, unknown> = {}, // eslint-disable-line @typescript-eslint/ban-types -- TODO: fix this
12
+ Legacy extends boolean = true> {
13
+ /**
14
+ * I18n instance
15
+ *
16
+ * @remarks
17
+ * If this option is specified, `v-t` custom directive transform uses an I18n instance to pre-translate.
18
+ * The translation will use the global resources registered in the I18n instance,
19
+ * that is, `v-t` directive transform is also a limitation that the resources of each component cannot be used.
20
+ */
21
+ i18n?: I18n<Messages, DateTimeFormats, NumberFormats, Legacy>;
22
+ /**
23
+ * I18n Mode
24
+ *
25
+ * @remarks
26
+ * Specify the API style of vue-i18n. If you use legacy API style (e.g. `$t`) at vue-i18n, you need to specify `legacy`.
27
+ *
28
+ * @default 'composition'
29
+ */
30
+ mode?: I18nMode;
31
+ /**
32
+ * Translation function signatures
33
+ *
34
+ * @remarks
35
+ * You can specify the signature of the translation function attached to the binding context when it is codegen in the Vue Compiler.
36
+ * If you have changed the signature to a non `t` signature in the `setup` hook or `<script setup>`, you can safely SSR it.
37
+ * If each Vue component has a different signature for the translation function, you can specify several in an array for safe SSR.
38
+ * This option value is `undefined` and the signature attached to the binding context is `t`.
39
+ */
40
+ translationSignatures?: string | string[];
41
+ }
42
+ /**
43
+ * Transform `v-t` custom directive
44
+ *
45
+ * @remarks
46
+ * Transform that `v-t` custom directive is optimized vue-i18n code by Vue compiler.
47
+ * This transform can improve the performance by pre-translating, and it does support SSR.
48
+ *
49
+ * @param options - `v-t` custom directive transform options, see {@link TransformVTDirectiveOptions}
50
+ * @returns Directive transform
51
+ *
52
+ * @example
53
+ * ```js
54
+ * import { compile } from '@vue/compiler-dom'
55
+ * import { createI18n } from 'vue-i18n'
56
+ * import { transformVTDirective } from '@intlify/vue-i18n-extensions'
57
+ *
58
+ * // create i18n instance
59
+ * const i18n = createI18n({
60
+ * locale: 'ja',
61
+ * messages: {
62
+ * en: {
63
+ * hello: 'hello'
64
+ * },
65
+ * ja: {
66
+ * hello: 'こんにちは'
67
+ * }
68
+ * }
69
+ * })
70
+ *
71
+ * // get transform from `transformVTDirective` function, with `i18n` option
72
+ * const transformVT = transformVTDirective({ i18n })
73
+ *
74
+ * const { code } = compile(`<p v-t="'hello'"></p>`, {
75
+ * mode: 'function',
76
+ * hoistStatic: true,
77
+ * prefixIdentifiers: true,
78
+ * directiveTransforms: { t: transformVT } // <- you need to specify to `directiveTransforms` option!
79
+ * })
80
+ *
81
+ * console.log(code)
82
+ * // output ->
83
+ * // const { createVNode: _createVNode, openBlock: _openBlock, createBlock: _createBlock } = Vue
84
+ * // return function render(_ctx, _cache) {
85
+ * // return (_openBlock(), _createBlock(\\"div\\", null, \\"こんにちは!\\"))
86
+ * // }
87
+ * ```
88
+ * @public
89
+ */
90
+ declare function transformVTDirective<Messages extends Record<string, unknown> = {}, // eslint-disable-line @typescript-eslint/ban-types -- TODO: fix this
91
+ DateTimeFormats extends Record<string, unknown> = {}, // eslint-disable-line @typescript-eslint/ban-types -- TODO: fix this
92
+ NumberFormats extends Record<string, unknown> = {}, // eslint-disable-line @typescript-eslint/ban-types -- TODO: fix this
93
+ Legacy extends boolean = true>(options?: TransformVTDirectiveOptions<Messages, DateTimeFormats, NumberFormats, Legacy>): DirectiveTransform;
94
+
95
+ export { type TransformVTDirectiveOptions, transformVTDirective };
@@ -0,0 +1,95 @@
1
+ import { DirectiveTransform } from '@vue/compiler-dom';
2
+ import { I18n, I18nMode } from 'vue-i18n';
3
+
4
+ /**
5
+ * Transform options for `v-t` custom directive
6
+ *
7
+ * @public
8
+ */
9
+ interface TransformVTDirectiveOptions<Messages extends Record<string, unknown> = {}, // eslint-disable-line @typescript-eslint/ban-types -- TODO: fix this
10
+ DateTimeFormats extends Record<string, unknown> = {}, // eslint-disable-line @typescript-eslint/ban-types -- TODO: fix this
11
+ NumberFormats extends Record<string, unknown> = {}, // eslint-disable-line @typescript-eslint/ban-types -- TODO: fix this
12
+ Legacy extends boolean = true> {
13
+ /**
14
+ * I18n instance
15
+ *
16
+ * @remarks
17
+ * If this option is specified, `v-t` custom directive transform uses an I18n instance to pre-translate.
18
+ * The translation will use the global resources registered in the I18n instance,
19
+ * that is, `v-t` directive transform is also a limitation that the resources of each component cannot be used.
20
+ */
21
+ i18n?: I18n<Messages, DateTimeFormats, NumberFormats, Legacy>;
22
+ /**
23
+ * I18n Mode
24
+ *
25
+ * @remarks
26
+ * Specify the API style of vue-i18n. If you use legacy API style (e.g. `$t`) at vue-i18n, you need to specify `legacy`.
27
+ *
28
+ * @default 'composition'
29
+ */
30
+ mode?: I18nMode;
31
+ /**
32
+ * Translation function signatures
33
+ *
34
+ * @remarks
35
+ * You can specify the signature of the translation function attached to the binding context when it is codegen in the Vue Compiler.
36
+ * If you have changed the signature to a non `t` signature in the `setup` hook or `<script setup>`, you can safely SSR it.
37
+ * If each Vue component has a different signature for the translation function, you can specify several in an array for safe SSR.
38
+ * This option value is `undefined` and the signature attached to the binding context is `t`.
39
+ */
40
+ translationSignatures?: string | string[];
41
+ }
42
+ /**
43
+ * Transform `v-t` custom directive
44
+ *
45
+ * @remarks
46
+ * Transform that `v-t` custom directive is optimized vue-i18n code by Vue compiler.
47
+ * This transform can improve the performance by pre-translating, and it does support SSR.
48
+ *
49
+ * @param options - `v-t` custom directive transform options, see {@link TransformVTDirectiveOptions}
50
+ * @returns Directive transform
51
+ *
52
+ * @example
53
+ * ```js
54
+ * import { compile } from '@vue/compiler-dom'
55
+ * import { createI18n } from 'vue-i18n'
56
+ * import { transformVTDirective } from '@intlify/vue-i18n-extensions'
57
+ *
58
+ * // create i18n instance
59
+ * const i18n = createI18n({
60
+ * locale: 'ja',
61
+ * messages: {
62
+ * en: {
63
+ * hello: 'hello'
64
+ * },
65
+ * ja: {
66
+ * hello: 'こんにちは'
67
+ * }
68
+ * }
69
+ * })
70
+ *
71
+ * // get transform from `transformVTDirective` function, with `i18n` option
72
+ * const transformVT = transformVTDirective({ i18n })
73
+ *
74
+ * const { code } = compile(`<p v-t="'hello'"></p>`, {
75
+ * mode: 'function',
76
+ * hoistStatic: true,
77
+ * prefixIdentifiers: true,
78
+ * directiveTransforms: { t: transformVT } // <- you need to specify to `directiveTransforms` option!
79
+ * })
80
+ *
81
+ * console.log(code)
82
+ * // output ->
83
+ * // const { createVNode: _createVNode, openBlock: _openBlock, createBlock: _createBlock } = Vue
84
+ * // return function render(_ctx, _cache) {
85
+ * // return (_openBlock(), _createBlock(\\"div\\", null, \\"こんにちは!\\"))
86
+ * // }
87
+ * ```
88
+ * @public
89
+ */
90
+ declare function transformVTDirective<Messages extends Record<string, unknown> = {}, // eslint-disable-line @typescript-eslint/ban-types -- TODO: fix this
91
+ DateTimeFormats extends Record<string, unknown> = {}, // eslint-disable-line @typescript-eslint/ban-types -- TODO: fix this
92
+ NumberFormats extends Record<string, unknown> = {}, // eslint-disable-line @typescript-eslint/ban-types -- TODO: fix this
93
+ Legacy extends boolean = true>(options?: TransformVTDirectiveOptions<Messages, DateTimeFormats, NumberFormats, Legacy>): DirectiveTransform;
94
+
95
+ export { type TransformVTDirectiveOptions, transformVTDirective };
package/dist/index.mjs ADDED
@@ -0,0 +1,465 @@
1
+ import { NodeTypes, TO_DISPLAY_STRING, createCompoundExpression, createSimpleExpression, isText, BindingTypes } from '@vue/compiler-dom';
2
+ import { isString, format, isNumber, isArray, isSymbol, isObject, toDisplayString, hasOwn } from '@intlify/shared';
3
+ import { parse } from '@babel/parser';
4
+
5
+ function evaluateValue(expression) {
6
+ const ret = { status: "ng", value: void 0 };
7
+ try {
8
+ const ast = parse(`const a = ${expression.trim()}`);
9
+ if (ast.program.body.length >= 1 && ast.program.body[0].type === "VariableDeclaration" && ast.program.body[0].declarations.length >= 1) {
10
+ const node = ast.program.body[0].declarations[0].init;
11
+ if (node != null && (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
+ }
19
+ return ret;
20
+ }
21
+ function parseVTExpression(expression) {
22
+ const ret = {
23
+ path: "",
24
+ named: {},
25
+ options: {}
26
+ };
27
+ try {
28
+ const ast = parse(`const a = ${expression.trim()}`);
29
+ if (ast.program.body.length >= 1 && ast.program.body[0].type === "VariableDeclaration" && ast.program.body[0].declarations.length >= 1) {
30
+ const node = ast.program.body[0].declarations[0].init;
31
+ if (node != null) {
32
+ if (node.type === "StringLiteral" && node.extra) {
33
+ ret.path = node.extra.raw;
34
+ } else if (node.type === "Identifier") {
35
+ ret.path = node.name;
36
+ } else if (node.type === "MemberExpression") {
37
+ ret.path = getObjectMemberValue(node);
38
+ } else if (node.type === "ObjectExpression") {
39
+ node.properties.forEach((propNode) => {
40
+ if (propNode.type === "ObjectProperty") {
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
+ if (propValueNode.type === "ObjectExpression") {
59
+ traverseObjectMember(propValueNode, ret.named);
60
+ }
61
+ break;
62
+ default:
63
+ break;
64
+ }
65
+ }
66
+ });
67
+ }
68
+ }
69
+ }
70
+ } catch (_e) {
71
+ }
72
+ return ret;
73
+ }
74
+ function getObjectMemberValue(node) {
75
+ if ((node.type === "StringLiteral" || node.type === "NumericLiteral") && node.extra) {
76
+ return node.extra.raw;
77
+ } else if (node.type === "Identifier") {
78
+ return node.name;
79
+ } else if (node.type === "MemberExpression") {
80
+ const paths = [];
81
+ collectMemberPath(node, paths);
82
+ paths.reverse();
83
+ return paths.join(".");
84
+ } else {
85
+ return "";
86
+ }
87
+ }
88
+ function traverseObjectMember(node, target) {
89
+ node.properties.forEach((propNode) => {
90
+ if (propNode.type === "ObjectProperty") {
91
+ const propKeyNode = propNode.key;
92
+ if (propKeyNode.type !== "Identifier") {
93
+ return;
94
+ }
95
+ if (!(propKeyNode.name in target)) {
96
+ target[propKeyNode.name] = {};
97
+ }
98
+ const propValueNode = propNode.value;
99
+ if (propValueNode.type === "ObjectExpression") {
100
+ traverseObjectMember(propValueNode, target[propKeyNode.name]);
101
+ } else {
102
+ target[propKeyNode.name] = getObjectMemberValue(propValueNode);
103
+ }
104
+ }
105
+ });
106
+ }
107
+ function collectMemberPath(node, paths) {
108
+ if (node.type === "Identifier") {
109
+ paths.push(node.name);
110
+ return;
111
+ } else if (node.type === "MemberExpression" && node.property.type === "Identifier") {
112
+ paths.push(node.property.name);
113
+ return collectMemberPath(node.object, paths);
114
+ }
115
+ }
116
+
117
+ var ReportCodes = /* @__PURE__ */ ((ReportCodes2) => {
118
+ ReportCodes2[ReportCodes2["SUCCESS"] = 0] = "SUCCESS";
119
+ ReportCodes2[ReportCodes2["UNEXPECTED_DIRECTIVE_EXPRESSION"] = 1] = "UNEXPECTED_DIRECTIVE_EXPRESSION";
120
+ ReportCodes2[ReportCodes2["NOT_SUPPORTED"] = 2] = "NOT_SUPPORTED";
121
+ ReportCodes2[ReportCodes2["FAILED_VALUE_EVALUATION"] = 3] = "FAILED_VALUE_EVALUATION";
122
+ ReportCodes2[ReportCodes2["REQUIRED_PARAMETER"] = 4] = "REQUIRED_PARAMETER";
123
+ ReportCodes2[ReportCodes2["INVALID_PARAMETER_TYPE"] = 5] = "INVALID_PARAMETER_TYPE";
124
+ ReportCodes2[ReportCodes2["OVERRIDE_ELEMENT_CHILDREN"] = 6] = "OVERRIDE_ELEMENT_CHILDREN";
125
+ ReportCodes2[ReportCodes2["NOT_RESOLVED_COMPOSER"] = 7] = "NOT_RESOLVED_COMPOSER";
126
+ ReportCodes2[ReportCodes2["UNEXPECTED_ERROR"] = 8] = "UNEXPECTED_ERROR";
127
+ ReportCodes2[ReportCodes2["__EXTEND_POINT__"] = 9] = "__EXTEND_POINT__";
128
+ return ReportCodes2;
129
+ })(ReportCodes || {});
130
+ const ReportMessages = {
131
+ [1 /* UNEXPECTED_DIRECTIVE_EXPRESSION */]: `Unexpected directive expression: {0}`,
132
+ [2 /* NOT_SUPPORTED */]: `Not supported transform: {0}`,
133
+ [3 /* FAILED_VALUE_EVALUATION */]: `Failed value evaluation: {0}`,
134
+ [4 /* REQUIRED_PARAMETER */]: `Required parameter: {0}`,
135
+ [5 /* INVALID_PARAMETER_TYPE */]: `Required parameter: {0}`,
136
+ [6 /* OVERRIDE_ELEMENT_CHILDREN */]: `v-t will override element children: {0}`,
137
+ [7 /* NOT_RESOLVED_COMPOSER */]: `Not resolved vue-i18n composer: {0}`,
138
+ [8 /* UNEXPECTED_ERROR */]: `Unexpected error: {0}`
139
+ };
140
+ function getReportMessage(code, ...args) {
141
+ return format(ReportMessages[code], ...args);
142
+ }
143
+ function createExtensionsError(code, msg, loc) {
144
+ const error = new SyntaxError(msg);
145
+ error.code = code;
146
+ if (loc) {
147
+ error.loc = loc;
148
+ }
149
+ return error;
150
+ }
151
+ function report(code, options = {}) {
152
+ const mode = options.mode && isString(options.mode) && ["warn", "error"].includes(options.mode) ? options.mode : "warn";
153
+ const msg = getReportMessage(code, options.args);
154
+ if (mode === "warn") {
155
+ console.warn("[vue-i18n-extensions] " + msg);
156
+ } else {
157
+ throw createExtensionsError(code, msg, options.loc);
158
+ }
159
+ }
160
+
161
+ function createContentBuilder(options = {}) {
162
+ let _indentLevel = options.indentLevel != null && isNumber(options.indentLevel) ? options.indentLevel : 0;
163
+ let _content = "";
164
+ function push(content) {
165
+ _content += content;
166
+ }
167
+ function _newline(n) {
168
+ push("\n" + ` `.repeat(n));
169
+ }
170
+ function newline() {
171
+ _newline(_indentLevel);
172
+ }
173
+ function pushline(content) {
174
+ push(content);
175
+ newline();
176
+ }
177
+ function indent(withoutNewLine) {
178
+ if (withoutNewLine) {
179
+ ++_indentLevel;
180
+ } else {
181
+ _newline(++_indentLevel);
182
+ }
183
+ }
184
+ function deindent(withoutNewLine) {
185
+ if (withoutNewLine) {
186
+ --_indentLevel;
187
+ } else {
188
+ _newline(--_indentLevel);
189
+ }
190
+ }
191
+ return {
192
+ get indentLevel() {
193
+ return _indentLevel;
194
+ },
195
+ get content() {
196
+ return String(_content);
197
+ },
198
+ push,
199
+ newline,
200
+ pushline,
201
+ indent,
202
+ deindent
203
+ };
204
+ }
205
+
206
+ function transformVTDirective(options = {}) {
207
+ const i18nInstance = options.i18n;
208
+ const mode = isString(options.mode) && ["composition", "legacy"].includes(options.mode) ? options.mode : "composition";
209
+ const translationSignatures = isString(options.translationSignatures) ? [options.translationSignatures] : isArray(options.translationSignatures) ? options.translationSignatures : ["t"];
210
+ translationSignatures.push(`$t`);
211
+ return (dir, node, context) => {
212
+ const { exp, loc } = dir;
213
+ if (!exp) {
214
+ report(ReportCodes.UNEXPECTED_DIRECTIVE_EXPRESSION, {
215
+ mode: "error",
216
+ args: [node.loc.source || ""],
217
+ loc: node.loc
218
+ });
219
+ }
220
+ if (node.children.length > 0) {
221
+ report(ReportCodes.OVERRIDE_ELEMENT_CHILDREN, {
222
+ mode: "error",
223
+ args: [node.loc.source || ""],
224
+ loc: node.loc
225
+ });
226
+ node.children.length = 0;
227
+ }
228
+ if (isSimpleExpressionNode(exp)) {
229
+ if (isConstant(exp) && i18nInstance) {
230
+ const { status, value } = evaluateValue(exp.content);
231
+ if (status === "ng") {
232
+ report(ReportCodes.FAILED_VALUE_EVALUATION, {
233
+ args: [node.loc.source || ""],
234
+ loc: node.loc
235
+ });
236
+ return { props: [] };
237
+ }
238
+ const [parsedValue, parseStatus] = parseValue(value);
239
+ if (parseStatus !== ReportCodes.SUCCESS) {
240
+ report(parseStatus, { args: [node.loc.source || ""], loc: node.loc });
241
+ return { props: [] };
242
+ }
243
+ if (parsedValue == null) {
244
+ report(ReportCodes.UNEXPECTED_ERROR, {
245
+ args: [node.loc.source || ""],
246
+ loc: node.loc
247
+ });
248
+ return { props: [] };
249
+ }
250
+ const global = getComposer(i18nInstance);
251
+ if (global == null) {
252
+ report(ReportCodes.NOT_RESOLVED_COMPOSER, {
253
+ args: [node.loc.source || ""],
254
+ loc: node.loc
255
+ });
256
+ return { props: [] };
257
+ }
258
+ const content = global.t(...makeParams(parsedValue));
259
+ node.children.push({
260
+ type: NodeTypes.TEXT,
261
+ content
262
+ });
263
+ return { props: [] };
264
+ } else {
265
+ const translationParams = parseVTExpression(exp.content);
266
+ const code = generateTranslationCode(
267
+ context,
268
+ mode,
269
+ translationParams,
270
+ translationSignatures
271
+ );
272
+ context.helper(TO_DISPLAY_STRING);
273
+ node.children.push({
274
+ type: NodeTypes.INTERPOLATION,
275
+ content: createCompoundExpression([
276
+ createSimpleExpression(code, false, loc, 0 /* NOT_CONSTANT */)
277
+ ])
278
+ });
279
+ return { props: [] };
280
+ }
281
+ } else if (isCompoundExpressionNode(exp)) {
282
+ const content = exp.children.map(mapNodeContentHandler).join("");
283
+ const code = generateTranslationCode(
284
+ context,
285
+ mode,
286
+ parseVTExpression(content),
287
+ translationSignatures
288
+ );
289
+ context.helper(TO_DISPLAY_STRING);
290
+ node.children.push({
291
+ type: NodeTypes.INTERPOLATION,
292
+ content: createCompoundExpression([
293
+ createSimpleExpression(code, false, loc, 0 /* NOT_CONSTANT */)
294
+ ])
295
+ });
296
+ return { props: [] };
297
+ } else {
298
+ report(ReportCodes.NOT_SUPPORTED, {
299
+ args: [node.loc.source || ""],
300
+ loc: node.loc
301
+ });
302
+ return { props: [] };
303
+ }
304
+ };
305
+ }
306
+ function getComposer(i18n) {
307
+ return isI18nInstance(i18n) ? getComposerInternal(i18n) : null;
308
+ }
309
+ function isI18nInstance(i18n) {
310
+ return i18n != null && "global" in i18n && "mode" in i18n;
311
+ }
312
+ function getComposerInternal(i18n) {
313
+ if (i18n.mode === "composition") {
314
+ return isComposer(i18n.global) ? i18n.global : null;
315
+ } else {
316
+ return isVueI18n(i18n.global) ? i18n.global.__composer : null;
317
+ }
318
+ }
319
+ function isComposer(target) {
320
+ return target != null && !("__composer" in target);
321
+ }
322
+ function isVueI18n(target) {
323
+ return target != null && "__composer" in target;
324
+ }
325
+ function isSimpleExpressionNode(node) {
326
+ return node != null && node.type === NodeTypes.SIMPLE_EXPRESSION;
327
+ }
328
+ function isCompoundExpressionNode(node) {
329
+ return node != null && node.type === NodeTypes.COMPOUND_EXPRESSION;
330
+ }
331
+ function isConstant(node) {
332
+ if ("isConstant" in node) {
333
+ return node.isConstant;
334
+ } else if ("constType" in node) {
335
+ return node.constType <= 3 /* CAN_STRINGIFY */;
336
+ } else {
337
+ throw Error("unexpected error in Vue SimpleExpressionNode");
338
+ }
339
+ }
340
+ function mapNodeContentHandler(value) {
341
+ if (isString(value)) {
342
+ return value;
343
+ } else if (isSymbol(value)) {
344
+ return value.description || "";
345
+ } else if (isSimpleExpressionNode(value)) {
346
+ return value.content;
347
+ } else if (isCompoundExpressionNode(value)) {
348
+ return value.children.map(mapNodeContentHandler).join("");
349
+ } else if (isText(value)) {
350
+ if (isString(value.content)) {
351
+ return value.content;
352
+ } else if (isSimpleExpressionNode(value.content)) {
353
+ return value.content.content;
354
+ } else if (isCompoundExpressionNode(value.content)) {
355
+ return value.content.children.map(mapNodeContentHandler).join("");
356
+ } else {
357
+ return "";
358
+ }
359
+ } else {
360
+ return "";
361
+ }
362
+ }
363
+ function parseValue(value) {
364
+ if (isString(value)) {
365
+ return [{ path: value }, ReportCodes.SUCCESS];
366
+ } else if (isObject(value)) {
367
+ if (!("path" in value)) {
368
+ return [null, ReportCodes.REQUIRED_PARAMETER];
369
+ }
370
+ return [value, ReportCodes.SUCCESS];
371
+ } else {
372
+ return [null, ReportCodes.INVALID_PARAMETER_TYPE];
373
+ }
374
+ }
375
+ function makeParams(value) {
376
+ const { path, locale, args, choice, plural } = value;
377
+ const options = {};
378
+ const named = args || {};
379
+ if (isString(locale)) {
380
+ options.locale = locale;
381
+ }
382
+ if (isNumber(choice)) {
383
+ options.plural = choice;
384
+ }
385
+ if (isNumber(plural)) {
386
+ options.plural = plural;
387
+ }
388
+ return [path, named, options];
389
+ }
390
+ function generateTranslationCode(context, mode, params, translationSignatures) {
391
+ return mode === "composition" ? generateComposableCode(context, params, translationSignatures) : generateLegacyCode(context, params);
392
+ }
393
+ function generateTranslationCallableSignatures(context, translationSignatures) {
394
+ const { prefixIdentifiers, bindingMetadata } = context;
395
+ return translationSignatures.map((signature) => {
396
+ const type = hasOwn(bindingMetadata, signature) && bindingMetadata[signature];
397
+ const bindingContext = prefixIdentifiers ? type && type.startsWith("setup") || type === BindingTypes.LITERAL_CONST ? "$setup." : "_ctx." : "";
398
+ return `${bindingContext}${signature}`;
399
+ }).join(" || ");
400
+ }
401
+ function generateComposableCode(context, params, translationSignatures) {
402
+ const baseCode = `(${generateTranslationCallableSignatures(context, translationSignatures)})`;
403
+ const builder = createContentBuilder();
404
+ builder.push(`${baseCode}(`);
405
+ builder.push(`${toDisplayString(params.path)}`);
406
+ builder.push(`, { `);
407
+ generateNamedCode(builder, params.named);
408
+ builder.push(` }`);
409
+ builder.push(`, { `);
410
+ if (params.options.locale) {
411
+ builder.push(`locale: ${toDisplayString(params.options.locale)}`);
412
+ }
413
+ if (params.options.plural) {
414
+ if (params.options.locale) {
415
+ builder.push(", ");
416
+ }
417
+ builder.push(`plural: ${toDisplayString(params.options.plural)}`);
418
+ }
419
+ builder.push(` }`);
420
+ builder.push(`)`);
421
+ const content = builder.content;
422
+ return content;
423
+ }
424
+ function generateNamedCode(builder, named) {
425
+ const keys = Object.keys(named);
426
+ keys.forEach((k) => {
427
+ const v = named[k];
428
+ if (isObject(v)) {
429
+ builder.push(`${k}: { `);
430
+ generateNamedCode(builder, v);
431
+ builder.push(` }`);
432
+ } else {
433
+ builder.push(`${k}: ${toDisplayString(v)}`);
434
+ }
435
+ });
436
+ }
437
+ function generateLegacyCode(context, params) {
438
+ const mode = !params.options.plural ? "basic" : "plural";
439
+ const baseCode = `${context.prefixIdentifiers ? "_ctx." : ""}${mode === "basic" ? "$t" : "$tc"}`;
440
+ const builder = createContentBuilder();
441
+ builder.push(`${baseCode}(`);
442
+ builder.push(`${toDisplayString(params.path)}`);
443
+ if (mode === "basic") {
444
+ if (isString(params.options.locale)) {
445
+ builder.push(`, ${toDisplayString(params.options.locale)}`);
446
+ }
447
+ builder.push(`, { `);
448
+ generateNamedCode(builder, params.named);
449
+ builder.push(` }`);
450
+ } else {
451
+ builder.push(`, ${toDisplayString(params.options.plural)}`);
452
+ if (isString(params.options.locale)) {
453
+ builder.push(`, ${toDisplayString(params.options.locale)}`);
454
+ } else {
455
+ builder.push(`, { `);
456
+ generateNamedCode(builder, params.named);
457
+ builder.push(` }`);
458
+ }
459
+ }
460
+ builder.push(`)`);
461
+ const content = builder.content;
462
+ return content;
463
+ }
464
+
465
+ export { transformVTDirective };