gt 2.11.0 → 2.11.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +10 -0
- package/dist/generated/version.d.ts +1 -1
- package/dist/generated/version.js +1 -1
- package/dist/react/jsx/utils/constants.d.ts +1 -0
- package/dist/react/jsx/utils/constants.js +5 -0
- package/dist/react/jsx/utils/stringParsing/derivation/handleDerivation.d.ts +30 -0
- package/dist/react/jsx/utils/{parseDerive.js → stringParsing/derivation/handleDerivation.js} +99 -66
- package/dist/react/jsx/utils/stringParsing/derivation/index.d.ts +25 -0
- package/dist/react/jsx/utils/stringParsing/derivation/index.js +63 -0
- package/dist/react/jsx/utils/stringParsing/derivation/isDeriveCall.d.ts +11 -0
- package/dist/react/jsx/utils/stringParsing/derivation/isDeriveCall.js +38 -0
- package/dist/react/jsx/utils/stringParsing/processTaggedTemplateCall/handleTaggedTemplateTranslationCall.d.ts +4 -1
- package/dist/react/jsx/utils/stringParsing/processTaggedTemplateCall/handleTaggedTemplateTranslationCall.js +9 -25
- package/dist/react/jsx/utils/stringParsing/processTaggedTemplateCall/index.js +1 -0
- package/dist/react/jsx/utils/stringParsing/processTranslationCall/handleDeriveTranslationCall.js +9 -40
- package/package.json +3 -3
- package/dist/react/jsx/utils/parseDerive.d.ts +0 -15
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,15 @@
|
|
|
1
1
|
# gtx-cli
|
|
2
2
|
|
|
3
|
+
## 2.11.1
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- [#1129](https://github.com/generaltranslation/gt/pull/1129) [`aabe764`](https://github.com/generaltranslation/gt/commit/aabe76422bfbba80ed3453667f82f01b1a195281) Thanks [@ErnestM1234](https://github.com/ErnestM1234)! - feat: derivation support for the t macro
|
|
8
|
+
|
|
9
|
+
- Updated dependencies [[`aabe764`](https://github.com/generaltranslation/gt/commit/aabe76422bfbba80ed3453667f82f01b1a195281), [`84c1443`](https://github.com/generaltranslation/gt/commit/84c1443bda85ccbd8d8dbf56ede341de974db522)]:
|
|
10
|
+
- @generaltranslation/python-extractor@0.1.5
|
|
11
|
+
- generaltranslation@8.1.19
|
|
12
|
+
|
|
3
13
|
## 2.11.0
|
|
4
14
|
|
|
5
15
|
### Minor Changes
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const PACKAGE_VERSION = "2.11.
|
|
1
|
+
export declare const PACKAGE_VERSION = "2.11.1";
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
// This file is auto-generated. Do not edit manually.
|
|
2
|
-
export const PACKAGE_VERSION = '2.11.
|
|
2
|
+
export const PACKAGE_VERSION = '2.11.1';
|
|
@@ -20,6 +20,7 @@ export declare const DERIVE_COMPONENT = "Derive";
|
|
|
20
20
|
export declare const BRANCH_COMPONENT = "Branch";
|
|
21
21
|
export declare const GT_TRANSLATION_FUNCS: string[];
|
|
22
22
|
export declare const STRING_REGISTRATION_FUNCS: readonly ["msg", "t"];
|
|
23
|
+
export declare const GT_DERIVE_STRING_FUNCTIONS: string[];
|
|
23
24
|
export declare const VARIABLE_COMPONENTS: string[];
|
|
24
25
|
export declare const GT_ATTRIBUTES_WITH_SUGAR: readonly ["$id", "$context", "$maxChars"];
|
|
25
26
|
export declare const GT_ATTRIBUTES: readonly ["id", "context", "maxChars", "$id", "$context", "$maxChars"];
|
|
@@ -44,6 +44,11 @@ export const STRING_REGISTRATION_FUNCS = [
|
|
|
44
44
|
MSG_REGISTRATION_FUNCTION,
|
|
45
45
|
T_REGISTRATION_FUNCTION,
|
|
46
46
|
];
|
|
47
|
+
// Derive functions that are imported from GT
|
|
48
|
+
export const GT_DERIVE_STRING_FUNCTIONS = [
|
|
49
|
+
DECLARE_STATIC_FUNCTION,
|
|
50
|
+
DERIVE_FUNCTION,
|
|
51
|
+
];
|
|
47
52
|
// Valid variable components
|
|
48
53
|
export const VARIABLE_COMPONENTS = [
|
|
49
54
|
'Var',
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import * as t from '@babel/types';
|
|
2
|
+
import { NodePath } from '@babel/traverse';
|
|
3
|
+
import { ParsingConfigOptions } from '../../../../../types/parsing.js';
|
|
4
|
+
import { StringNode } from '../../types.js';
|
|
5
|
+
export type StringTree = (string | StringTree)[];
|
|
6
|
+
/**
|
|
7
|
+
* Extracts content if an expression is derivable (statically analyzable) or uses derive()
|
|
8
|
+
* Returns a Node representing the parsed expression
|
|
9
|
+
* @param expr - The expression to check
|
|
10
|
+
* @param tPath - NodePath for scope resolution
|
|
11
|
+
* @param file - Current file path
|
|
12
|
+
* @param parsingOptions - Parsing configuration
|
|
13
|
+
* @param errors - Errors to add to
|
|
14
|
+
* @param runtimeInterpolationState - When provided, non-derive dynamic expressions become {n} placeholders instead of errors. Pass { index: 0 } at the entry point for template macros.
|
|
15
|
+
* @returns Node | null - The parsed node, or null if invalid
|
|
16
|
+
*
|
|
17
|
+
* @note runtimeInterpolationState
|
|
18
|
+
* - Only provide at entry for template macros, otherwise omit
|
|
19
|
+
* - t`Hello {nonDerivableValue}` -> t`Hello {0}`
|
|
20
|
+
*/
|
|
21
|
+
export declare function handleDerivation({ expr, tPath, file, parsingOptions, errors, runtimeInterpolationState, }: {
|
|
22
|
+
expr: t.Expression;
|
|
23
|
+
tPath: NodePath;
|
|
24
|
+
file: string;
|
|
25
|
+
parsingOptions: ParsingConfigOptions;
|
|
26
|
+
errors: string[];
|
|
27
|
+
runtimeInterpolationState?: {
|
|
28
|
+
index: number;
|
|
29
|
+
};
|
|
30
|
+
}): StringNode | null;
|
package/dist/react/jsx/utils/{parseDerive.js → stringParsing/derivation/handleDerivation.js}
RENAMED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import * as t from '@babel/types';
|
|
2
|
-
import { parseStringExpression, nodeToStrings } from '
|
|
3
|
-
import { buildImportMap } from '
|
|
4
|
-
import { resolveImportPath } from '
|
|
2
|
+
import { parseStringExpression, nodeToStrings } from '../../parseString.js';
|
|
3
|
+
import { buildImportMap } from '../../buildImportMap.js';
|
|
4
|
+
import { resolveImportPath } from '../../resolveImportPath.js';
|
|
5
5
|
import { parse } from '@babel/parser';
|
|
6
6
|
import fs from 'node:fs';
|
|
7
|
-
import { warnFunctionNotFoundSync, warnDeriveFunctionNoResultsSync, warnDeriveFunctionNotWrappedSync, } from '
|
|
8
|
-
import { DECLARE_STATIC_FUNCTION, DERIVE_FUNCTION } from './constants.js';
|
|
7
|
+
import { warnFunctionNotFoundSync, warnDeriveFunctionNoResultsSync, warnDeriveFunctionNotWrappedSync, } from '../../../../../console/index.js';
|
|
9
8
|
import traverseModule from '@babel/traverse';
|
|
10
9
|
import generateModule from '@babel/generator';
|
|
10
|
+
import { isDeriveCall } from './isDeriveCall.js';
|
|
11
11
|
// Handle CommonJS/ESM interop
|
|
12
12
|
const traverse = traverseModule.default || traverseModule;
|
|
13
13
|
const generate = generateModule.default || generateModule;
|
|
@@ -30,27 +30,49 @@ const processFunctionCache = new Map();
|
|
|
30
30
|
* @param tPath - NodePath for scope resolution
|
|
31
31
|
* @param file - Current file path
|
|
32
32
|
* @param parsingOptions - Parsing configuration
|
|
33
|
+
* @param errors - Errors to add to
|
|
34
|
+
* @param runtimeInterpolationState - When provided, non-derive dynamic expressions become {n} placeholders instead of errors. Pass { index: 0 } at the entry point for template macros.
|
|
33
35
|
* @returns Node | null - The parsed node, or null if invalid
|
|
36
|
+
*
|
|
37
|
+
* @note runtimeInterpolationState
|
|
38
|
+
* - Only provide at entry for template macros, otherwise omit
|
|
39
|
+
* - t`Hello {nonDerivableValue}` -> t`Hello {0}`
|
|
34
40
|
*/
|
|
35
|
-
export function
|
|
41
|
+
export function handleDerivation({ expr, tPath, file, parsingOptions, errors, runtimeInterpolationState, }) {
|
|
36
42
|
if (!expr) {
|
|
37
43
|
return null;
|
|
38
44
|
}
|
|
39
45
|
// Handle expressions
|
|
40
46
|
if (t.isCallExpression(expr)) {
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
47
|
+
if (isDeriveCall({ expr, tPath })) {
|
|
48
|
+
const variants = getDeriveVariants({
|
|
49
|
+
call: expr,
|
|
50
|
+
tPath,
|
|
51
|
+
file,
|
|
52
|
+
parsingOptions,
|
|
53
|
+
errors,
|
|
54
|
+
});
|
|
55
|
+
if (variants) {
|
|
56
|
+
return {
|
|
57
|
+
type: 'choice',
|
|
58
|
+
nodes: variants.map((v) => ({ type: 'text', text: v })),
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
// derive() had no resolvable results
|
|
62
|
+
const code = expr.arguments.length > 0
|
|
63
|
+
? generate(expr.arguments[0]).code
|
|
64
|
+
: 'no arguments';
|
|
65
|
+
errors.push(warnDeriveFunctionNoResultsSync(file, code, `${expr.loc?.start?.line}:${expr.loc?.start?.column}`));
|
|
66
|
+
return null;
|
|
67
|
+
}
|
|
68
|
+
// Non-derive call
|
|
69
|
+
if (runtimeInterpolationState) {
|
|
70
|
+
return { type: 'text', text: `{${runtimeInterpolationState.index++}}` };
|
|
48
71
|
}
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
errors.push(warnDeriveFunctionNoResultsSync(file, code, `${expr.loc?.start?.line}:${expr.loc?.start?.column}`));
|
|
72
|
+
const calleeName = t.isIdentifier(expr.callee)
|
|
73
|
+
? expr.callee.name
|
|
74
|
+
: generate(expr.callee).code;
|
|
75
|
+
errors.push(warnDeriveFunctionNotWrappedSync(file, calleeName, `${expr.callee.loc?.start?.line}:${expr.callee.loc?.start?.column}`));
|
|
54
76
|
return null;
|
|
55
77
|
}
|
|
56
78
|
// Handle direct string literals
|
|
@@ -68,12 +90,33 @@ export function handleDeriveExpression(expr, tPath, file, parsingOptions, errors
|
|
|
68
90
|
}
|
|
69
91
|
const exprNode = expr.expressions[index];
|
|
70
92
|
if (exprNode && t.isExpression(exprNode)) {
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
93
|
+
if (isDeriveCall({ expr: exprNode, tPath })) {
|
|
94
|
+
// Derive — resolve fully (no runtime interpolation forwarding)
|
|
95
|
+
const result = handleDerivation({
|
|
96
|
+
expr: exprNode,
|
|
97
|
+
tPath,
|
|
98
|
+
file,
|
|
99
|
+
parsingOptions,
|
|
100
|
+
errors,
|
|
101
|
+
});
|
|
102
|
+
if (result === null)
|
|
103
|
+
return null;
|
|
104
|
+
parts.push(result);
|
|
105
|
+
}
|
|
106
|
+
else {
|
|
107
|
+
// Non-derive — recurse with runtime interpolation forwarded
|
|
108
|
+
const result = handleDerivation({
|
|
109
|
+
expr: exprNode,
|
|
110
|
+
tPath,
|
|
111
|
+
file,
|
|
112
|
+
parsingOptions,
|
|
113
|
+
errors,
|
|
114
|
+
runtimeInterpolationState,
|
|
115
|
+
});
|
|
116
|
+
if (result === null)
|
|
117
|
+
return null;
|
|
118
|
+
parts.push(result);
|
|
75
119
|
}
|
|
76
|
-
parts.push(result);
|
|
77
120
|
}
|
|
78
121
|
}
|
|
79
122
|
if (parts.length === 0) {
|
|
@@ -89,8 +132,22 @@ export function handleDeriveExpression(expr, tPath, file, parsingOptions, errors
|
|
|
89
132
|
if (!t.isExpression(expr.left) || !t.isExpression(expr.right)) {
|
|
90
133
|
return null;
|
|
91
134
|
}
|
|
92
|
-
const leftResult =
|
|
93
|
-
|
|
135
|
+
const leftResult = handleDerivation({
|
|
136
|
+
expr: expr.left,
|
|
137
|
+
tPath,
|
|
138
|
+
file,
|
|
139
|
+
parsingOptions,
|
|
140
|
+
errors,
|
|
141
|
+
runtimeInterpolationState,
|
|
142
|
+
});
|
|
143
|
+
const rightResult = handleDerivation({
|
|
144
|
+
expr: expr.right,
|
|
145
|
+
tPath,
|
|
146
|
+
file,
|
|
147
|
+
parsingOptions,
|
|
148
|
+
errors,
|
|
149
|
+
runtimeInterpolationState,
|
|
150
|
+
});
|
|
94
151
|
if (leftResult === null || rightResult === null) {
|
|
95
152
|
return null;
|
|
96
153
|
}
|
|
@@ -98,7 +155,14 @@ export function handleDeriveExpression(expr, tPath, file, parsingOptions, errors
|
|
|
98
155
|
}
|
|
99
156
|
// Handle parenthesized expressions
|
|
100
157
|
if (t.isParenthesizedExpression(expr)) {
|
|
101
|
-
return
|
|
158
|
+
return handleDerivation({
|
|
159
|
+
expr: expr.expression,
|
|
160
|
+
tPath,
|
|
161
|
+
file,
|
|
162
|
+
parsingOptions,
|
|
163
|
+
errors,
|
|
164
|
+
runtimeInterpolationState,
|
|
165
|
+
});
|
|
102
166
|
}
|
|
103
167
|
// Handle numeric literals by converting them to strings
|
|
104
168
|
if (t.isNumericLiteral(expr)) {
|
|
@@ -135,6 +199,9 @@ export function handleDeriveExpression(expr, tPath, file, parsingOptions, errors
|
|
|
135
199
|
return { type: 'text', text: 'null' };
|
|
136
200
|
}
|
|
137
201
|
// Not a derivable expression
|
|
202
|
+
if (runtimeInterpolationState) {
|
|
203
|
+
return { type: 'text', text: `{${runtimeInterpolationState.index++}}` };
|
|
204
|
+
}
|
|
138
205
|
return null;
|
|
139
206
|
}
|
|
140
207
|
/**
|
|
@@ -147,37 +214,13 @@ export function handleDeriveExpression(expr, tPath, file, parsingOptions, errors
|
|
|
147
214
|
*
|
|
148
215
|
* Returns null if it can't be resolved.
|
|
149
216
|
*/
|
|
150
|
-
function getDeriveVariants(call, tPath, file, parsingOptions, errors) {
|
|
217
|
+
function getDeriveVariants({ call, tPath, file, parsingOptions, errors, }) {
|
|
151
218
|
// --- Validate Callee --- //
|
|
152
|
-
// Must be derive(...) or an alias of it
|
|
153
|
-
if (!
|
|
154
|
-
const
|
|
155
|
-
?
|
|
156
|
-
:
|
|
157
|
-
errors.push(warnDeriveFunctionNotWrappedSync(file, code, `${call.callee.loc?.start?.line}:${call.callee.loc?.start?.column}`));
|
|
158
|
-
return null;
|
|
159
|
-
}
|
|
160
|
-
// Check if this is derive by name or by checking the import
|
|
161
|
-
const calleeName = call.callee.name;
|
|
162
|
-
const calleeBinding = tPath.scope.getBinding(calleeName);
|
|
163
|
-
// If it's not literally named 'derive', check if it's imported from GT
|
|
164
|
-
if (!calleeBinding) {
|
|
165
|
-
return null;
|
|
166
|
-
}
|
|
167
|
-
// Check if it's imported from a GT package
|
|
168
|
-
if (calleeBinding.path.isImportSpecifier()) {
|
|
169
|
-
const imported = calleeBinding.path.node.imported;
|
|
170
|
-
const originalName = t.isIdentifier(imported)
|
|
171
|
-
? imported.name
|
|
172
|
-
: imported.value;
|
|
173
|
-
// Only proceed if the original name is 'derive' (or the deprecated 'declareStatic')
|
|
174
|
-
if (originalName !== DECLARE_STATIC_FUNCTION &&
|
|
175
|
-
originalName !== DERIVE_FUNCTION) {
|
|
176
|
-
return null;
|
|
177
|
-
}
|
|
178
|
-
}
|
|
179
|
-
else {
|
|
180
|
-
// Not an import specifier, so it's not derive
|
|
219
|
+
// Must be a derive(...) call or an alias of it
|
|
220
|
+
if (!isDeriveCall({ expr: call, tPath })) {
|
|
221
|
+
const calleeName = t.isIdentifier(call.callee)
|
|
222
|
+
? call.callee.name
|
|
223
|
+
: generate(call.callee).code;
|
|
181
224
|
errors.push(warnDeriveFunctionNotWrappedSync(file, calleeName, `${call.callee.loc?.start?.line}:${call.callee.loc?.start?.column}`));
|
|
182
225
|
return null;
|
|
183
226
|
}
|
|
@@ -507,13 +550,3 @@ function resolveFunctionInFile(filePath, functionName, parsingOptions, errors) {
|
|
|
507
550
|
processFunctionCache.set(cacheKey, result);
|
|
508
551
|
return result;
|
|
509
552
|
}
|
|
510
|
-
/**
|
|
511
|
-
* Handle cond ? "a" : "b"
|
|
512
|
-
* Collects string literals from both branches of a conditional expression
|
|
513
|
-
*/
|
|
514
|
-
function collectConditionalStringVariants(cond, out) {
|
|
515
|
-
if (t.isStringLiteral(cond.consequent))
|
|
516
|
-
out.add(cond.consequent.value);
|
|
517
|
-
if (t.isStringLiteral(cond.alternate))
|
|
518
|
-
out.add(cond.alternate.value);
|
|
519
|
-
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { NodePath } from '@babel/traverse';
|
|
2
|
+
import * as t from '@babel/types';
|
|
3
|
+
import { InlineMetadata } from '../processTranslationCall/extractStringEntryMetadata.js';
|
|
4
|
+
import { ParsingConfig } from '../types.js';
|
|
5
|
+
import { ParsingOutput } from '../types.js';
|
|
6
|
+
/**
|
|
7
|
+
* Registers an expression with support for derive
|
|
8
|
+
* Entry point for string derivation
|
|
9
|
+
*
|
|
10
|
+
* @param tPath - The path to the tag identifier
|
|
11
|
+
* @param expr - The expression to parse
|
|
12
|
+
* @param metadata - Extracted metadata (empty for tagged templates)
|
|
13
|
+
* @param config - Parsing configuration
|
|
14
|
+
* @param output - Parsing output collectors
|
|
15
|
+
* @param enableRuntimeInterpolation - For template macros, enables runtime interpolation for non-derive calls
|
|
16
|
+
*/
|
|
17
|
+
export declare function deriveExpression({ tPath, expr, metadata, config, output, index, enableRuntimeInterpolation, }: {
|
|
18
|
+
tPath: NodePath;
|
|
19
|
+
expr: t.Expression;
|
|
20
|
+
metadata: InlineMetadata;
|
|
21
|
+
config: ParsingConfig;
|
|
22
|
+
output: ParsingOutput;
|
|
23
|
+
index?: number;
|
|
24
|
+
enableRuntimeInterpolation?: boolean;
|
|
25
|
+
}): void;
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { handleDerivation } from './handleDerivation.js';
|
|
2
|
+
import { warnNonStringSync } from '../../../../../console/index.js';
|
|
3
|
+
import { nodeToStrings } from '../../parseString.js';
|
|
4
|
+
import generateModule from '@babel/generator';
|
|
5
|
+
import { indexVars } from 'generaltranslation/internal';
|
|
6
|
+
import { randomUUID } from 'node:crypto';
|
|
7
|
+
import { isValidIcu } from '../../../evaluateJsx.js';
|
|
8
|
+
import { warnInvalidIcuSync } from '../../../../../console/index.js';
|
|
9
|
+
// Handle CommonJS/ESM interop
|
|
10
|
+
const generate = generateModule.default || generateModule;
|
|
11
|
+
/**
|
|
12
|
+
* Registers an expression with support for derive
|
|
13
|
+
* Entry point for string derivation
|
|
14
|
+
*
|
|
15
|
+
* @param tPath - The path to the tag identifier
|
|
16
|
+
* @param expr - The expression to parse
|
|
17
|
+
* @param metadata - Extracted metadata (empty for tagged templates)
|
|
18
|
+
* @param config - Parsing configuration
|
|
19
|
+
* @param output - Parsing output collectors
|
|
20
|
+
* @param enableRuntimeInterpolation - For template macros, enables runtime interpolation for non-derive calls
|
|
21
|
+
*/
|
|
22
|
+
export function deriveExpression({ tPath, expr, metadata, config, output, index, enableRuntimeInterpolation = false, }) {
|
|
23
|
+
// parse derivable expression
|
|
24
|
+
const stringNode = handleDerivation({
|
|
25
|
+
expr,
|
|
26
|
+
tPath,
|
|
27
|
+
file: config.file,
|
|
28
|
+
parsingOptions: config.parsingOptions,
|
|
29
|
+
errors: output.errors,
|
|
30
|
+
runtimeInterpolationState: enableRuntimeInterpolation
|
|
31
|
+
? { index: 0 }
|
|
32
|
+
: undefined,
|
|
33
|
+
});
|
|
34
|
+
// Nothing returned, push error
|
|
35
|
+
if (!stringNode) {
|
|
36
|
+
output.errors.push(warnNonStringSync(config.file, generate(expr).code, `${expr.loc?.start?.line}:${expr.loc?.start?.column}`));
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
// validate ICU
|
|
40
|
+
const strings = nodeToStrings(stringNode).map(indexVars);
|
|
41
|
+
if (!config.ignoreInvalidIcu) {
|
|
42
|
+
for (const string of strings) {
|
|
43
|
+
const { isValid, error } = isValidIcu(string);
|
|
44
|
+
if (!isValid) {
|
|
45
|
+
output.warnings.add(warnInvalidIcuSync(config.file, string, error ?? 'Unknown error', `${expr.loc?.start?.line}:${expr.loc?.start?.column}`));
|
|
46
|
+
return;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
const temporaryDeriveId = `derive-temp-id-${randomUUID()}`;
|
|
51
|
+
for (const string of strings) {
|
|
52
|
+
output.updates.push({
|
|
53
|
+
dataFormat: 'ICU',
|
|
54
|
+
source: string,
|
|
55
|
+
metadata: {
|
|
56
|
+
...metadata,
|
|
57
|
+
// Add the index if an id and index is provided (for handling when registering an array of strings)
|
|
58
|
+
...(metadata.id && index != null && { id: `${metadata.id}.${index}` }),
|
|
59
|
+
staticId: temporaryDeriveId,
|
|
60
|
+
},
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import * as t from '@babel/types';
|
|
2
|
+
import { NodePath } from '@babel/traverse';
|
|
3
|
+
/**
|
|
4
|
+
* Given an expression, determine if it is a derive call
|
|
5
|
+
* @param expr - The expression to check
|
|
6
|
+
* @returns True if the expression is a derive call, false otherwise
|
|
7
|
+
*/
|
|
8
|
+
export declare function isDeriveCall({ expr, tPath, }: {
|
|
9
|
+
expr: t.Expression;
|
|
10
|
+
tPath: NodePath;
|
|
11
|
+
}): boolean;
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import * as t from '@babel/types';
|
|
2
|
+
import { GT_DERIVE_STRING_FUNCTIONS } from '../../constants.js';
|
|
3
|
+
import { GT_LIBRARIES } from '../../../../../types/libraries.js';
|
|
4
|
+
/**
|
|
5
|
+
* Given an expression, determine if it is a derive call
|
|
6
|
+
* @param expr - The expression to check
|
|
7
|
+
* @returns True if the expression is a derive call, false otherwise
|
|
8
|
+
*/
|
|
9
|
+
export function isDeriveCall({ expr, tPath, }) {
|
|
10
|
+
// Check if the expression is a call expression
|
|
11
|
+
if (!t.isCallExpression(expr))
|
|
12
|
+
return false;
|
|
13
|
+
const callee = expr.callee;
|
|
14
|
+
if (!t.isIdentifier(callee))
|
|
15
|
+
return false;
|
|
16
|
+
// Fail if no binding
|
|
17
|
+
const calleeName = callee.name;
|
|
18
|
+
const binding = tPath.scope.getBinding(calleeName);
|
|
19
|
+
if (!binding)
|
|
20
|
+
return false;
|
|
21
|
+
// Check if the callee is imported from GT
|
|
22
|
+
if (!binding.path.isImportSpecifier())
|
|
23
|
+
return false;
|
|
24
|
+
const source = binding.path.parentPath?.isImportDeclaration()
|
|
25
|
+
? binding.path.parentPath?.node.source.value
|
|
26
|
+
: undefined;
|
|
27
|
+
if (!GT_LIBRARIES.includes(source))
|
|
28
|
+
return false;
|
|
29
|
+
// Fail if the original name is not 'derive' (or the deprecated 'declareStatic')
|
|
30
|
+
const imported = binding.path.node.imported;
|
|
31
|
+
const originalName = t.isIdentifier(imported)
|
|
32
|
+
? imported.name
|
|
33
|
+
: imported.value;
|
|
34
|
+
if (!GT_DERIVE_STRING_FUNCTIONS.includes(originalName)) {
|
|
35
|
+
return false;
|
|
36
|
+
}
|
|
37
|
+
return true;
|
|
38
|
+
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import * as t from '@babel/types';
|
|
2
2
|
import { ParsingConfig, ParsingOutput } from '../types.js';
|
|
3
3
|
import { InlineMetadata } from '../processTranslationCall/extractStringEntryMetadata.js';
|
|
4
|
+
import { NodePath } from '@babel/traverse';
|
|
4
5
|
/**
|
|
5
6
|
* Extracts a translatable message from a TaggedTemplateExpression.
|
|
6
7
|
*
|
|
@@ -10,12 +11,14 @@ import { InlineMetadata } from '../processTranslationCall/extractStringEntryMeta
|
|
|
10
11
|
* - Creates numeric placeholders ({0}, {1}, etc.) for each expression
|
|
11
12
|
* - Joins all parts into the final source string
|
|
12
13
|
*
|
|
14
|
+
* @param tPath - The path to the tag identifier
|
|
13
15
|
* @param quasi - The TemplateLiteral from the TaggedTemplateExpression
|
|
14
16
|
* @param metadata - Extracted metadata (empty for tagged templates)
|
|
15
17
|
* @param config - Parsing configuration
|
|
16
18
|
* @param output - Parsing output collectors
|
|
17
19
|
*/
|
|
18
|
-
export declare function handleTaggedTemplateTranslationCall({ quasi, metadata, config, output, }: {
|
|
20
|
+
export declare function handleTaggedTemplateTranslationCall({ tPath, quasi, metadata, config, output, }: {
|
|
21
|
+
tPath: NodePath;
|
|
19
22
|
quasi: t.TemplateLiteral;
|
|
20
23
|
metadata: InlineMetadata;
|
|
21
24
|
config: ParsingConfig;
|
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { warnInvalidIcuSync } from '../../../../../console/index.js';
|
|
1
|
+
import { deriveExpression } from '../derivation/index.js';
|
|
3
2
|
/**
|
|
4
3
|
* Extracts a translatable message from a TaggedTemplateExpression.
|
|
5
4
|
*
|
|
@@ -9,34 +8,19 @@ import { warnInvalidIcuSync } from '../../../../../console/index.js';
|
|
|
9
8
|
* - Creates numeric placeholders ({0}, {1}, etc.) for each expression
|
|
10
9
|
* - Joins all parts into the final source string
|
|
11
10
|
*
|
|
11
|
+
* @param tPath - The path to the tag identifier
|
|
12
12
|
* @param quasi - The TemplateLiteral from the TaggedTemplateExpression
|
|
13
13
|
* @param metadata - Extracted metadata (empty for tagged templates)
|
|
14
14
|
* @param config - Parsing configuration
|
|
15
15
|
* @param output - Parsing output collectors
|
|
16
16
|
*/
|
|
17
|
-
export function handleTaggedTemplateTranslationCall({ quasi, metadata, config, output, }) {
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
parts.push(quasi.quasis[i].value.cooked ?? quasi.quasis[i].value.raw);
|
|
22
|
-
if (i < quasi.expressions.length) {
|
|
23
|
-
const key = varIndex.toString();
|
|
24
|
-
parts.push(`{${key}}`);
|
|
25
|
-
varIndex++;
|
|
26
|
-
}
|
|
27
|
-
}
|
|
28
|
-
const source = parts.join('');
|
|
29
|
-
// Validate ICU format
|
|
30
|
-
if (!config.ignoreInvalidIcu) {
|
|
31
|
-
const { isValid, error } = isValidIcu(source);
|
|
32
|
-
if (!isValid) {
|
|
33
|
-
output.warnings.add(warnInvalidIcuSync(config.file, source, error ?? 'Unknown error', `${quasi.loc?.start?.line}:${quasi.loc?.start?.column}`));
|
|
34
|
-
return;
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
output.updates.push({
|
|
38
|
-
dataFormat: 'ICU',
|
|
39
|
-
source,
|
|
17
|
+
export function handleTaggedTemplateTranslationCall({ tPath, quasi, metadata, config, output, }) {
|
|
18
|
+
deriveExpression({
|
|
19
|
+
tPath,
|
|
20
|
+
expr: quasi,
|
|
40
21
|
metadata,
|
|
22
|
+
config,
|
|
23
|
+
output,
|
|
24
|
+
enableRuntimeInterpolation: true,
|
|
41
25
|
});
|
|
42
26
|
}
|
package/dist/react/jsx/utils/stringParsing/processTranslationCall/handleDeriveTranslationCall.js
CHANGED
|
@@ -1,12 +1,4 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { nodeToStrings } from '../../parseString.js';
|
|
3
|
-
import { indexVars } from 'generaltranslation/internal';
|
|
4
|
-
import { isValidIcu } from '../../../evaluateJsx.js';
|
|
5
|
-
import { warnInvalidIcuSync, warnNonStringSync, } from '../../../../../console/index.js';
|
|
6
|
-
import generateModule from '@babel/generator';
|
|
7
|
-
import { randomUUID } from 'node:crypto';
|
|
8
|
-
// Handle CommonJS/ESM interop
|
|
9
|
-
const generate = generateModule.default || generateModule;
|
|
1
|
+
import { deriveExpression } from '../derivation/index.js';
|
|
10
2
|
/**
|
|
11
3
|
* For the processTranslationCall function, this function handles the case where a string with derive is used.
|
|
12
4
|
* @param arg - The argument to parse
|
|
@@ -17,35 +9,12 @@ const generate = generateModule.default || generateModule;
|
|
|
17
9
|
* @param index - Current index in array of strings being extracted
|
|
18
10
|
*/
|
|
19
11
|
export function handleDeriveTranslationCall({ arg, metadata, tPath, config, output, index, }) {
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
const strings = nodeToStrings(result).map(indexVars);
|
|
29
|
-
if (!config.ignoreInvalidIcu) {
|
|
30
|
-
for (const string of strings) {
|
|
31
|
-
const { isValid, error } = isValidIcu(string);
|
|
32
|
-
if (!isValid) {
|
|
33
|
-
output.warnings.add(warnInvalidIcuSync(config.file, string, error ?? 'Unknown error', `${arg.loc?.start?.line}:${arg.loc?.start?.column}`));
|
|
34
|
-
return;
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
const temporaryDeriveId = `derive-temp-id-${randomUUID()}`;
|
|
39
|
-
for (const string of strings) {
|
|
40
|
-
output.updates.push({
|
|
41
|
-
dataFormat: 'ICU',
|
|
42
|
-
source: string,
|
|
43
|
-
metadata: {
|
|
44
|
-
...metadata,
|
|
45
|
-
// Add the index if an id and index is provided (for handling when registering an array of strings)
|
|
46
|
-
...(metadata.id && index != null && { id: `${metadata.id}.${index}` }),
|
|
47
|
-
staticId: temporaryDeriveId,
|
|
48
|
-
},
|
|
49
|
-
});
|
|
50
|
-
}
|
|
12
|
+
deriveExpression({
|
|
13
|
+
tPath,
|
|
14
|
+
expr: arg,
|
|
15
|
+
metadata,
|
|
16
|
+
config,
|
|
17
|
+
output,
|
|
18
|
+
index,
|
|
19
|
+
});
|
|
51
20
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "gt",
|
|
3
|
-
"version": "2.11.
|
|
3
|
+
"version": "2.11.1",
|
|
4
4
|
"main": "dist/index.js",
|
|
5
5
|
"bin": "dist/main.js",
|
|
6
6
|
"files": [
|
|
@@ -110,8 +110,8 @@
|
|
|
110
110
|
"unified": "^11.0.5",
|
|
111
111
|
"unist-util-visit": "^5.0.0",
|
|
112
112
|
"yaml": "^2.8.0",
|
|
113
|
-
"@generaltranslation/python-extractor": "0.1.
|
|
114
|
-
"generaltranslation": "8.1.
|
|
113
|
+
"@generaltranslation/python-extractor": "0.1.5",
|
|
114
|
+
"generaltranslation": "8.1.19",
|
|
115
115
|
"gt-remark": "1.0.5"
|
|
116
116
|
},
|
|
117
117
|
"devDependencies": {
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
import * as t from '@babel/types';
|
|
2
|
-
import { NodePath } from '@babel/traverse';
|
|
3
|
-
import { ParsingConfigOptions } from '../../../types/parsing.js';
|
|
4
|
-
import { StringNode } from './types.js';
|
|
5
|
-
export type StringTree = (string | StringTree)[];
|
|
6
|
-
/**
|
|
7
|
-
* Extracts content if an expression is derivable (statically analyzable) or uses derive()
|
|
8
|
-
* Returns a Node representing the parsed expression
|
|
9
|
-
* @param expr - The expression to check
|
|
10
|
-
* @param tPath - NodePath for scope resolution
|
|
11
|
-
* @param file - Current file path
|
|
12
|
-
* @param parsingOptions - Parsing configuration
|
|
13
|
-
* @returns Node | null - The parsed node, or null if invalid
|
|
14
|
-
*/
|
|
15
|
-
export declare function handleDeriveExpression(expr: t.Expression, tPath: NodePath, file: string, parsingOptions: ParsingConfigOptions, errors: string[]): StringNode | null;
|