gtx-cli 2.5.0-alpha.3 → 2.5.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/CHANGELOG.md +23 -0
- package/dist/config/generateSettings.js +8 -1
- package/dist/console/colors.d.ts +1 -0
- package/dist/console/colors.js +3 -0
- package/dist/console/index.d.ts +8 -0
- package/dist/console/index.js +15 -2
- package/dist/react/jsx/evaluateJsx.d.ts +9 -6
- package/dist/react/jsx/evaluateJsx.js +33 -5
- package/dist/react/jsx/utils/buildImportMap.d.ts +9 -0
- package/dist/react/jsx/utils/buildImportMap.js +30 -0
- package/dist/react/jsx/utils/constants.d.ts +2 -0
- package/dist/react/jsx/utils/constants.js +11 -2
- package/dist/react/jsx/utils/getPathsAndAliases.d.ts +17 -0
- package/dist/react/jsx/utils/getPathsAndAliases.js +89 -0
- package/dist/react/{data-_gt → jsx/utils/jsxParsing}/addGTIdentifierToSyntaxTree.d.ts +2 -1
- package/dist/react/{data-_gt → jsx/utils/jsxParsing}/addGTIdentifierToSyntaxTree.js +30 -6
- package/dist/react/jsx/utils/jsxParsing/handleChildrenWhitespace.d.ts +6 -0
- package/dist/react/jsx/utils/jsxParsing/handleChildrenWhitespace.js +199 -0
- package/dist/react/jsx/utils/jsxParsing/multiplication/findMultiplicationNode.d.ts +13 -0
- package/dist/react/jsx/utils/jsxParsing/multiplication/findMultiplicationNode.js +42 -0
- package/dist/react/jsx/utils/jsxParsing/multiplication/multiplyJsxTree.d.ts +5 -0
- package/dist/react/jsx/utils/jsxParsing/multiplication/multiplyJsxTree.js +69 -0
- package/dist/react/jsx/utils/jsxParsing/parseJsx.d.ts +61 -0
- package/dist/react/jsx/utils/jsxParsing/parseJsx.js +1005 -0
- package/dist/react/jsx/utils/jsxParsing/parseTProps.d.ts +8 -0
- package/dist/react/jsx/utils/jsxParsing/parseTProps.js +47 -0
- package/dist/react/jsx/utils/jsxParsing/types.d.ts +48 -0
- package/dist/react/jsx/utils/jsxParsing/types.js +34 -0
- package/dist/react/jsx/utils/parseStringFunction.js +4 -141
- package/dist/react/jsx/utils/resolveImportPath.d.ts +11 -0
- package/dist/react/jsx/utils/resolveImportPath.js +111 -0
- package/dist/react/parse/createInlineUpdates.js +19 -70
- package/package.json +2 -2
- package/dist/react/jsx/trimJsxStringChildren.d.ts +0 -7
- package/dist/react/jsx/trimJsxStringChildren.js +0 -122
- package/dist/react/jsx/utils/parseJsx.d.ts +0 -21
- package/dist/react/jsx/utils/parseJsx.js +0 -259
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,28 @@
|
|
|
1
1
|
# gtx-cli
|
|
2
2
|
|
|
3
|
+
## 2.5.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- [#788](https://github.com/generaltranslation/gt/pull/788) [`99e4648`](https://github.com/generaltranslation/gt/commit/99e46486ae2046c689e0045372d63c4eb3dc5d48) Thanks [@ErnestM1234](https://github.com/ErnestM1234)! - More information: https://https://generaltranslation.com/en-US/blog/gt-next_v6_8_0
|
|
8
|
+
|
|
9
|
+
feat: static component
|
|
10
|
+
|
|
11
|
+
- [#791](https://github.com/generaltranslation/gt/pull/791) [`fee5d4a`](https://github.com/generaltranslation/gt/commit/fee5d4a3d0fd20e0928eebb83201a87289265719) Thanks [@brian-lou](https://github.com/brian-lou)! - Update Notes:
|
|
12
|
+
https://generaltranslation.com/blog/generaltranslation_v8
|
|
13
|
+
|
|
14
|
+
Please update the following packages to the latest version:
|
|
15
|
+
- generaltranslation: `7.9.1` or later
|
|
16
|
+
- gtx-cli: `2.4.15` or later
|
|
17
|
+
- gt-sanity: `1.0.11` or later
|
|
18
|
+
|
|
19
|
+
Older versions of these packages may not be compatible with the latest version of the General Translation API and may require updating.
|
|
20
|
+
|
|
21
|
+
### Patch Changes
|
|
22
|
+
|
|
23
|
+
- Updated dependencies [[`fee5d4a`](https://github.com/generaltranslation/gt/commit/fee5d4a3d0fd20e0928eebb83201a87289265719)]:
|
|
24
|
+
- generaltranslation@8.0.0
|
|
25
|
+
|
|
3
26
|
## 2.4.15
|
|
4
27
|
|
|
5
28
|
### Patch Changes
|
|
@@ -158,7 +158,14 @@ export async function generateSettings(flags, cwd = process.cwd()) {
|
|
|
158
158
|
// Add parsing options if not provided
|
|
159
159
|
mergedOptions.parsingOptions = mergedOptions.parsingOptions || {};
|
|
160
160
|
mergedOptions.parsingOptions.conditionNames = mergedOptions.parsingOptions
|
|
161
|
-
.conditionNames || [
|
|
161
|
+
.conditionNames || [
|
|
162
|
+
'development',
|
|
163
|
+
'browser',
|
|
164
|
+
'module',
|
|
165
|
+
'import',
|
|
166
|
+
'require',
|
|
167
|
+
'default',
|
|
168
|
+
];
|
|
162
169
|
// Add branch options if not provided
|
|
163
170
|
const branchOptions = mergedOptions.branchOptions || {};
|
|
164
171
|
branchOptions.enabled = flags.enableBranching ?? false;
|
package/dist/console/colors.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
export declare function colorizeFilepath(filepath: string): string;
|
|
2
2
|
export declare function colorizeComponent(component: string): string;
|
|
3
|
+
export declare function colorizeFunctionName(functionName: string): string;
|
|
3
4
|
export declare function colorizeIdString(id: string): string;
|
|
4
5
|
export declare function colorizeContent(content: string): string;
|
|
5
6
|
export declare function colorizeLine(line: string): string;
|
package/dist/console/colors.js
CHANGED
|
@@ -5,6 +5,9 @@ export function colorizeFilepath(filepath) {
|
|
|
5
5
|
export function colorizeComponent(component) {
|
|
6
6
|
return chalk.yellow(component);
|
|
7
7
|
}
|
|
8
|
+
export function colorizeFunctionName(functionName) {
|
|
9
|
+
return chalk.yellow(functionName);
|
|
10
|
+
}
|
|
8
11
|
export function colorizeIdString(id) {
|
|
9
12
|
return chalk.yellow(id);
|
|
10
13
|
}
|
package/dist/console/index.d.ts
CHANGED
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
export declare const warnApiKeyInConfigSync: (optionsFilepath: string) => string;
|
|
2
2
|
export declare const warnVariablePropSync: (file: string, attrName: string, value: string, location?: string) => string;
|
|
3
|
+
export declare const warnInvalidReturnSync: (file: string, functionName: string, expression: string, location?: string) => string;
|
|
4
|
+
export declare const warnMissingReturnSync: (file: string, functionName: string, location?: string) => string;
|
|
3
5
|
export declare const warnHasUnwrappedExpressionSync: (file: string, unwrappedExpressions: string[], id?: string, location?: string) => string;
|
|
6
|
+
export declare const warnFailedToConstructJsxTreeSync: (file: string, code: string, location?: string) => string;
|
|
4
7
|
export declare const warnNestedTComponent: (file: string, location?: string) => string;
|
|
5
8
|
export declare const warnNonStaticExpressionSync: (file: string, attrName: string, value: string, location?: string) => string;
|
|
6
9
|
export declare const warnInvalidIcuSync: (file: string, value: string, error: string, location?: string) => string;
|
|
@@ -10,6 +13,11 @@ export declare const warnAsyncUseGT: (file: string, location?: string) => string
|
|
|
10
13
|
export declare const warnSyncGetGT: (file: string, location?: string) => string;
|
|
11
14
|
export declare const warnTernarySync: (file: string, location?: string) => string;
|
|
12
15
|
export declare const withLocation: (file: string, message: string, location?: string) => string;
|
|
16
|
+
export declare const warnInvalidStaticChildSync: (file: string, location?: string) => string;
|
|
17
|
+
export declare const warnFunctionNotFoundSync: (file: string, functionName: string, location?: string) => string;
|
|
18
|
+
export declare const warnDuplicateFunctionDefinitionSync: (file: string, functionName: string, location?: string) => string;
|
|
19
|
+
export declare const warnInvalidStaticInitSync: (file: string, functionName: string, location?: string) => string;
|
|
20
|
+
export declare const warnRecursiveFunctionCallSync: (file: string, functionName: string, location?: string) => string;
|
|
13
21
|
export declare const noLocalesError = "No locales found! Please provide a list of locales to translate to, or specify them in your gt.config.json file.";
|
|
14
22
|
export declare const noDefaultLocaleError = "No default locale found! Please provide a default locale, or specify it in your gt.config.json file.";
|
|
15
23
|
export declare const noFilesError = "Incorrect or missing files configuration! Please make sure your files are configured correctly in your gt.config.json file.";
|
package/dist/console/index.js
CHANGED
|
@@ -1,8 +1,15 @@
|
|
|
1
|
-
import { colorizeFilepath, colorizeComponent, colorizeIdString, colorizeContent, colorizeLine, } from './colors.js';
|
|
1
|
+
import { colorizeFilepath, colorizeComponent, colorizeIdString, colorizeContent, colorizeLine, colorizeFunctionName, } from './colors.js';
|
|
2
|
+
const withWillErrorInNextVersion = (message) => `${message} (This will become an error in the next major version of the CLI.)`;
|
|
3
|
+
// Static function related errors
|
|
4
|
+
const withStaticError = (message) => `<Static> rules violation: ${message}`;
|
|
2
5
|
// Synchronous wrappers for backward compatibility
|
|
3
6
|
export const warnApiKeyInConfigSync = (optionsFilepath) => `${colorizeFilepath(optionsFilepath)}: Your API key is exposed! Please remove it from the file and include it as an environment variable.`;
|
|
4
7
|
export const warnVariablePropSync = (file, attrName, value, location) => withLocation(file, `${colorizeComponent('<T>')} component has dynamic attribute ${colorizeIdString(attrName)} with value: ${colorizeContent(value)}. Change ${colorizeIdString(attrName)} to ensure this content is translated.`, location);
|
|
8
|
+
export const warnInvalidReturnSync = (file, functionName, expression, location) => withLocation(file, withStaticError(`Function ${colorizeFunctionName(functionName)} does not return a static expression. ${colorizeFunctionName(functionName)} must return either (1) a static string literal, (2) another static function invocation, (3) static JSX content, or (4) a ternary expression. Instead got:\n${colorizeContent(expression)}`), location);
|
|
9
|
+
// TODO: this is temporary until we handle implicit returns
|
|
10
|
+
export const warnMissingReturnSync = (file, functionName, location) => withLocation(file, `Function ${colorizeFunctionName(functionName)} is wrapped in ${colorizeComponent('<Static>')} tags but does have an explicit return statement. Static functions must have an explicit return statment.`, location);
|
|
5
11
|
export const warnHasUnwrappedExpressionSync = (file, unwrappedExpressions, id, location) => withLocation(file, `${colorizeComponent('<T>')} component${id ? ` with id ${colorizeIdString(id)}` : ''} has children that could change at runtime. Use a variable component like ${colorizeComponent('<Var>')} to ensure this content is translated.\n${colorizeContent(unwrappedExpressions.join('\n'))}`, location);
|
|
12
|
+
export const warnFailedToConstructJsxTreeSync = (file, code, location) => withLocation(file, `Failed to construct JsxTree! Call expression is not a valid createElement call: ${colorizeContent(code)}`, location);
|
|
6
13
|
export const warnNestedTComponent = (file, location) => withLocation(file, `Found nested <T> component. <T> components cannot be directly nested.`, location);
|
|
7
14
|
export const warnNonStaticExpressionSync = (file, attrName, value, location) => withLocation(file, `Found non-static expression for attribute ${colorizeIdString(attrName)}: ${colorizeContent(value)}. Change "${colorizeIdString(attrName)}" to ensure this content is translated.`, location);
|
|
8
15
|
export const warnInvalidIcuSync = (file, value, error, location) => withWillErrorInNextVersion(withLocation(file, `Found invalid ICU string: ${colorizeContent(value)}. Change the value to a valid ICU to ensure this content is translated. Error message: ${error}.`, location));
|
|
@@ -12,7 +19,13 @@ export const warnAsyncUseGT = (file, location) => withLocation(file, `Found useG
|
|
|
12
19
|
export const warnSyncGetGT = (file, location) => withLocation(file, `Found getGT() in a synchronous function. Use useGT() instead, or make the function async.`, location);
|
|
13
20
|
export const warnTernarySync = (file, location) => withLocation(file, 'Found ternary expression. A Branch component may be more appropriate here.', location);
|
|
14
21
|
export const withLocation = (file, message, location) => `${colorizeFilepath(file)}${location ? ` (${colorizeLine(location)})` : ''}: ${message}`;
|
|
15
|
-
const
|
|
22
|
+
export const warnInvalidStaticChildSync = (file, location) => withLocation(file, 'Found invalid <Static> invocation. Children must be an expression container with a function invocation. Callee must be a single identifier. (Example: <T> <Static> {getSubject()} </Static> </T>)', location);
|
|
23
|
+
export const warnFunctionNotFoundSync = (file, functionName, location) => withLocation(file, `Function ${colorizeFunctionName(functionName)} definition could not be resolved. This might affect translation resolution for this ${colorizeComponent('<T>')} component.`, location);
|
|
24
|
+
export const warnDuplicateFunctionDefinitionSync = (file, functionName, location) => withLocation(file, `Function ${colorizeFunctionName(functionName)} is defined multiple times. Only the first definition will be used.`, location);
|
|
25
|
+
export const warnInvalidStaticInitSync = (file, functionName, location) => withLocation(file, withStaticError(`The definition for ${colorizeFunctionName(functionName)} could not be resolved. When using arrow syntax to define a static function, the right hand side or the assignment MUST only contain the arrow function itself and no other expressions.
|
|
26
|
+
Example: ${colorizeContent(`const ${colorizeFunctionName(functionName)} = () => { ... }`)}
|
|
27
|
+
Invalid: ${colorizeContent(`const ${colorizeFunctionName(functionName)} = [() => { ... }][0]`)}`), location);
|
|
28
|
+
export const warnRecursiveFunctionCallSync = (file, functionName, location) => withLocation(file, withStaticError(`Recursive function call detected: ${colorizeFunctionName(functionName)}. A static function use recursive calls to construct its result.`), location);
|
|
16
29
|
// Re-export error messages
|
|
17
30
|
export const noLocalesError = `No locales found! Please provide a list of locales to translate to, or specify them in your gt.config.json file.`;
|
|
18
31
|
export const noDefaultLocaleError = `No default locale found! Please provide a default locale, or specify it in your gt.config.json file.`;
|
|
@@ -5,15 +5,18 @@ import * as t from '@babel/types';
|
|
|
5
5
|
* @returns Whether the node is meaningful
|
|
6
6
|
*/
|
|
7
7
|
export declare function isMeaningful(node: t.Node): boolean;
|
|
8
|
-
|
|
9
|
-
* Checks if an expression is static (does not contain any variables which could change at runtime).
|
|
10
|
-
* @param expr - The expression to check
|
|
11
|
-
* @returns An object containing the result of the static check
|
|
12
|
-
*/
|
|
13
|
-
export declare function isStaticExpression(expr: t.Expression | t.JSXEmptyExpression): {
|
|
8
|
+
export declare function isStaticExpression(expr: t.Expression | t.JSXEmptyExpression, jsxStatic?: false): {
|
|
14
9
|
isStatic: boolean;
|
|
15
10
|
value?: string;
|
|
16
11
|
};
|
|
12
|
+
export declare function isStaticExpression(expr: t.Expression | t.JSXEmptyExpression, jsxStatic?: true): {
|
|
13
|
+
isStatic: boolean;
|
|
14
|
+
value?: string | boolean | null;
|
|
15
|
+
};
|
|
16
|
+
export declare function isStaticExpression(expr: t.Expression | t.JSXEmptyExpression, jsxStatic?: boolean): {
|
|
17
|
+
isStatic: boolean;
|
|
18
|
+
value?: string | boolean | null;
|
|
19
|
+
};
|
|
17
20
|
export declare function isStaticValue(expr: t.Expression | t.JSXEmptyExpression): boolean;
|
|
18
21
|
export declare function isValidIcu(string: string): {
|
|
19
22
|
isValid: boolean;
|
|
@@ -33,9 +33,10 @@ export function isMeaningful(node) {
|
|
|
33
33
|
/**
|
|
34
34
|
* Checks if an expression is static (does not contain any variables which could change at runtime).
|
|
35
35
|
* @param expr - The expression to check
|
|
36
|
+
* @param ignoreStaticFunction - Whether to ignore static functions
|
|
36
37
|
* @returns An object containing the result of the static check
|
|
37
38
|
*/
|
|
38
|
-
export function isStaticExpression(expr) {
|
|
39
|
+
export function isStaticExpression(expr, jsxStatic = false) {
|
|
39
40
|
// Handle empty expressions
|
|
40
41
|
if (t.isJSXEmptyExpression(expr)) {
|
|
41
42
|
return { isStatic: true, value: '' };
|
|
@@ -46,7 +47,10 @@ export function isStaticExpression(expr) {
|
|
|
46
47
|
}
|
|
47
48
|
// Handle template literals without expressions
|
|
48
49
|
if (t.isTemplateLiteral(expr) && expr.expressions.length === 0) {
|
|
49
|
-
return {
|
|
50
|
+
return {
|
|
51
|
+
isStatic: true,
|
|
52
|
+
value: jsxStatic ? expr.quasis[0].value.cooked : expr.quasis[0].value.raw,
|
|
53
|
+
};
|
|
50
54
|
}
|
|
51
55
|
// Binary expressions are not static
|
|
52
56
|
if (t.isBinaryExpression(expr)) {
|
|
@@ -55,19 +59,43 @@ export function isStaticExpression(expr) {
|
|
|
55
59
|
}
|
|
56
60
|
// Handle parenthesized expressions
|
|
57
61
|
if (t.isParenthesizedExpression(expr)) {
|
|
58
|
-
return isStaticExpression(expr.expression);
|
|
62
|
+
return isStaticExpression(expr.expression, jsxStatic);
|
|
59
63
|
}
|
|
60
64
|
// Handle numeric literals by converting them to strings
|
|
61
65
|
if (t.isNumericLiteral(expr)) {
|
|
62
66
|
return { isStatic: true, value: String(expr.value) };
|
|
63
67
|
}
|
|
68
|
+
// Handle unary expressions by converting them to strings
|
|
69
|
+
if (t.isUnaryExpression(expr)) {
|
|
70
|
+
let value;
|
|
71
|
+
let operator = '';
|
|
72
|
+
if (expr.operator === '-') {
|
|
73
|
+
operator = expr.operator;
|
|
74
|
+
}
|
|
75
|
+
if (t.isNumericLiteral(expr.argument)) {
|
|
76
|
+
if (expr.argument.value === 0) {
|
|
77
|
+
value = '0';
|
|
78
|
+
}
|
|
79
|
+
else {
|
|
80
|
+
value = operator + expr.argument.value.toString();
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
else {
|
|
84
|
+
// invalid
|
|
85
|
+
return { isStatic: false };
|
|
86
|
+
}
|
|
87
|
+
return { isStatic: true, value };
|
|
88
|
+
}
|
|
64
89
|
// Handle boolean literals by converting them to strings
|
|
65
90
|
if (t.isBooleanLiteral(expr)) {
|
|
66
|
-
return {
|
|
91
|
+
return {
|
|
92
|
+
isStatic: true,
|
|
93
|
+
value: jsxStatic ? expr.value : String(expr.value),
|
|
94
|
+
};
|
|
67
95
|
}
|
|
68
96
|
// Handle null literal
|
|
69
97
|
if (t.isNullLiteral(expr)) {
|
|
70
|
-
return { isStatic: true, value: 'null' };
|
|
98
|
+
return { isStatic: true, value: jsxStatic ? null : 'null' };
|
|
71
99
|
}
|
|
72
100
|
// Not a static expression
|
|
73
101
|
return { isStatic: false };
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { NodePath } from '@babel/traverse';
|
|
2
|
+
/**
|
|
3
|
+
* Builds a map of imported function names to their import paths from a given program path.
|
|
4
|
+
* Handles both named imports and default imports.
|
|
5
|
+
*
|
|
6
|
+
* Example: import { getInfo } from './constants' -> Map { 'getInfo' => './constants' }
|
|
7
|
+
* Example: import utils from './utils' -> Map { 'utils' => './utils' }
|
|
8
|
+
*/
|
|
9
|
+
export declare function buildImportMap(programPath: NodePath): Map<string, string>;
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import * as t from '@babel/types';
|
|
2
|
+
/**
|
|
3
|
+
* Builds a map of imported function names to their import paths from a given program path.
|
|
4
|
+
* Handles both named imports and default imports.
|
|
5
|
+
*
|
|
6
|
+
* Example: import { getInfo } from './constants' -> Map { 'getInfo' => './constants' }
|
|
7
|
+
* Example: import utils from './utils' -> Map { 'utils' => './utils' }
|
|
8
|
+
*/
|
|
9
|
+
export function buildImportMap(programPath) {
|
|
10
|
+
const importMap = new Map();
|
|
11
|
+
programPath.traverse({
|
|
12
|
+
ImportDeclaration(importPath) {
|
|
13
|
+
if (t.isStringLiteral(importPath.node.source)) {
|
|
14
|
+
const importSource = importPath.node.source.value;
|
|
15
|
+
importPath.node.specifiers.forEach((spec) => {
|
|
16
|
+
if (t.isImportSpecifier(spec) &&
|
|
17
|
+
t.isIdentifier(spec.imported) &&
|
|
18
|
+
t.isIdentifier(spec.local)) {
|
|
19
|
+
importMap.set(spec.local.name, importSource);
|
|
20
|
+
}
|
|
21
|
+
else if (t.isImportDefaultSpecifier(spec) &&
|
|
22
|
+
t.isIdentifier(spec.local)) {
|
|
23
|
+
importMap.set(spec.local.name, importSource);
|
|
24
|
+
}
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
},
|
|
28
|
+
});
|
|
29
|
+
return importMap;
|
|
30
|
+
}
|
|
@@ -3,6 +3,8 @@ export declare const INLINE_TRANSLATION_HOOK = "useGT";
|
|
|
3
3
|
export declare const INLINE_TRANSLATION_HOOK_ASYNC = "getGT";
|
|
4
4
|
export declare const INLINE_MESSAGE_HOOK = "useMessages";
|
|
5
5
|
export declare const INLINE_MESSAGE_HOOK_ASYNC = "getMessages";
|
|
6
|
+
export declare const TRANSLATION_COMPONENT = "T";
|
|
7
|
+
export declare const STATIC_COMPONENT = "Static";
|
|
6
8
|
export declare const GT_TRANSLATION_FUNCS: string[];
|
|
7
9
|
export declare const VARIABLE_COMPONENTS: string[];
|
|
8
10
|
export declare const GT_ATTRIBUTES_WITH_SUGAR: string[];
|
|
@@ -3,6 +3,8 @@ export const INLINE_TRANSLATION_HOOK = 'useGT';
|
|
|
3
3
|
export const INLINE_TRANSLATION_HOOK_ASYNC = 'getGT';
|
|
4
4
|
export const INLINE_MESSAGE_HOOK = 'useMessages';
|
|
5
5
|
export const INLINE_MESSAGE_HOOK_ASYNC = 'getMessages';
|
|
6
|
+
export const TRANSLATION_COMPONENT = 'T';
|
|
7
|
+
export const STATIC_COMPONENT = 'Static';
|
|
6
8
|
// GT translation functions
|
|
7
9
|
export const GT_TRANSLATION_FUNCS = [
|
|
8
10
|
INLINE_TRANSLATION_HOOK,
|
|
@@ -10,7 +12,8 @@ export const GT_TRANSLATION_FUNCS = [
|
|
|
10
12
|
INLINE_MESSAGE_HOOK,
|
|
11
13
|
INLINE_MESSAGE_HOOK_ASYNC,
|
|
12
14
|
MSG_TRANSLATION_HOOK,
|
|
13
|
-
|
|
15
|
+
TRANSLATION_COMPONENT,
|
|
16
|
+
STATIC_COMPONENT,
|
|
14
17
|
'Var',
|
|
15
18
|
'DateTime',
|
|
16
19
|
'Currency',
|
|
@@ -19,7 +22,13 @@ export const GT_TRANSLATION_FUNCS = [
|
|
|
19
22
|
'Plural',
|
|
20
23
|
];
|
|
21
24
|
// Valid variable components
|
|
22
|
-
export const VARIABLE_COMPONENTS = [
|
|
25
|
+
export const VARIABLE_COMPONENTS = [
|
|
26
|
+
'Var',
|
|
27
|
+
'DateTime',
|
|
28
|
+
'Currency',
|
|
29
|
+
'Num',
|
|
30
|
+
STATIC_COMPONENT,
|
|
31
|
+
];
|
|
23
32
|
export const GT_ATTRIBUTES_WITH_SUGAR = ['$id', '$context'];
|
|
24
33
|
export const GT_ATTRIBUTES = ['id', 'context', ...GT_ATTRIBUTES_WITH_SUGAR];
|
|
25
34
|
export function mapAttributeName(attrName) {
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { NodePath } from '@babel/traverse';
|
|
2
|
+
/**
|
|
3
|
+
*
|
|
4
|
+
*/
|
|
5
|
+
export declare function getPathsAndAliases(ast: any, pkg: 'gt-react' | 'gt-next'): {
|
|
6
|
+
importAliases: Record<string, string>;
|
|
7
|
+
inlineTranslationPaths: Array<{
|
|
8
|
+
localName: string;
|
|
9
|
+
path: NodePath;
|
|
10
|
+
originalName: string;
|
|
11
|
+
}>;
|
|
12
|
+
translationComponentPaths: Array<{
|
|
13
|
+
localName: string;
|
|
14
|
+
path: NodePath;
|
|
15
|
+
originalName: string;
|
|
16
|
+
}>;
|
|
17
|
+
};
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import traverseModule from '@babel/traverse';
|
|
2
|
+
import { GT_TRANSLATION_FUNCS, INLINE_TRANSLATION_HOOK, INLINE_TRANSLATION_HOOK_ASYNC, INLINE_MESSAGE_HOOK, INLINE_MESSAGE_HOOK_ASYNC, MSG_TRANSLATION_HOOK, TRANSLATION_COMPONENT, } from '../../jsx/utils/constants.js';
|
|
3
|
+
import { extractImportName } from './parseAst.js';
|
|
4
|
+
// Handle CommonJS/ESM interop
|
|
5
|
+
const traverse = traverseModule.default || traverseModule;
|
|
6
|
+
/**
|
|
7
|
+
*
|
|
8
|
+
*/
|
|
9
|
+
export function getPathsAndAliases(ast, pkg) {
|
|
10
|
+
// First pass: collect imports and process translation functions
|
|
11
|
+
const importAliases = {};
|
|
12
|
+
const inlineTranslationPaths = [];
|
|
13
|
+
const translationComponentPaths = [];
|
|
14
|
+
traverse(ast, {
|
|
15
|
+
ImportDeclaration(path) {
|
|
16
|
+
if (path.node.source.value.startsWith(pkg)) {
|
|
17
|
+
const importName = extractImportName(path.node, pkg, GT_TRANSLATION_FUNCS);
|
|
18
|
+
for (const name of importName) {
|
|
19
|
+
if (name.original === INLINE_TRANSLATION_HOOK ||
|
|
20
|
+
name.original === INLINE_TRANSLATION_HOOK_ASYNC ||
|
|
21
|
+
name.original === INLINE_MESSAGE_HOOK ||
|
|
22
|
+
name.original === INLINE_MESSAGE_HOOK_ASYNC ||
|
|
23
|
+
name.original === MSG_TRANSLATION_HOOK) {
|
|
24
|
+
inlineTranslationPaths.push({
|
|
25
|
+
localName: name.local,
|
|
26
|
+
path,
|
|
27
|
+
originalName: name.original,
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
else if (name.original === TRANSLATION_COMPONENT) {
|
|
31
|
+
translationComponentPaths.push({
|
|
32
|
+
localName: name.local,
|
|
33
|
+
path,
|
|
34
|
+
originalName: name.original,
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
else {
|
|
38
|
+
importAliases[name.local] = name.original;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
},
|
|
43
|
+
VariableDeclarator(path) {
|
|
44
|
+
// Check if the init is a require call
|
|
45
|
+
if (path.node.init?.type === 'CallExpression' &&
|
|
46
|
+
path.node.init.callee.type === 'Identifier' &&
|
|
47
|
+
path.node.init.callee.name === 'require') {
|
|
48
|
+
// Check if it's requiring our package
|
|
49
|
+
const args = path.node.init.arguments;
|
|
50
|
+
if (args.length === 1 &&
|
|
51
|
+
args[0].type === 'StringLiteral' &&
|
|
52
|
+
args[0].value.startsWith(pkg)) {
|
|
53
|
+
const parentPath = path.parentPath;
|
|
54
|
+
if (parentPath.isVariableDeclaration()) {
|
|
55
|
+
const importName = extractImportName(parentPath.node, pkg, GT_TRANSLATION_FUNCS);
|
|
56
|
+
for (const name of importName) {
|
|
57
|
+
if (name.original === INLINE_TRANSLATION_HOOK ||
|
|
58
|
+
name.original === INLINE_TRANSLATION_HOOK_ASYNC ||
|
|
59
|
+
name.original === INLINE_MESSAGE_HOOK ||
|
|
60
|
+
name.original === INLINE_MESSAGE_HOOK_ASYNC ||
|
|
61
|
+
name.original === MSG_TRANSLATION_HOOK) {
|
|
62
|
+
inlineTranslationPaths.push({
|
|
63
|
+
localName: name.local,
|
|
64
|
+
path: parentPath,
|
|
65
|
+
originalName: name.original,
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
else if (name.original === TRANSLATION_COMPONENT) {
|
|
69
|
+
translationComponentPaths.push({
|
|
70
|
+
localName: name.local,
|
|
71
|
+
path: parentPath,
|
|
72
|
+
originalName: name.original,
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
else {
|
|
76
|
+
importAliases[name.local] = name.original;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
},
|
|
83
|
+
});
|
|
84
|
+
return {
|
|
85
|
+
importAliases,
|
|
86
|
+
inlineTranslationPaths,
|
|
87
|
+
translationComponentPaths,
|
|
88
|
+
};
|
|
89
|
+
}
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import { JsxChildren } from 'generaltranslation/types';
|
|
2
|
+
import { MultipliedTreeNode } from './types.js';
|
|
2
3
|
/**
|
|
3
4
|
* Add GT Identifier and minify the tree (recreates addGTIdentifier and writeChildrenAsObjects)
|
|
4
5
|
* @param tree - The tree to add GT identifiers to
|
|
5
6
|
* @param startingIndex - The starting index for GT IDs
|
|
6
7
|
* @returns The tree with GT identifiers added
|
|
7
8
|
*/
|
|
8
|
-
export default function addGTIdentifierToSyntaxTree(tree:
|
|
9
|
+
export default function addGTIdentifierToSyntaxTree(tree: MultipliedTreeNode, startingIndex?: number): JsxChildren;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { HTML_CONTENT_PROPS, } from 'generaltranslation/types';
|
|
2
|
-
import { defaultVariableNames, getVariableName, minifyVariableType, } from '
|
|
2
|
+
import { defaultVariableNames, getVariableName, minifyVariableType, } from '../../../utils/getVariableName.js';
|
|
3
3
|
import { isAcceptedPluralForm } from 'generaltranslation/internal';
|
|
4
4
|
/**
|
|
5
5
|
* Construct the data-_gt prop
|
|
@@ -55,6 +55,10 @@ function constructGTProp(type, props, id) {
|
|
|
55
55
|
* @returns The tree with GT identifiers added
|
|
56
56
|
*/
|
|
57
57
|
export default function addGTIdentifierToSyntaxTree(tree, startingIndex = 0) {
|
|
58
|
+
// Edge case: boolean or null, just return the tree
|
|
59
|
+
if (typeof tree === 'boolean' || tree === null) {
|
|
60
|
+
return tree;
|
|
61
|
+
}
|
|
58
62
|
// Object to keep track of the current index for GT IDs
|
|
59
63
|
const indexObject = { index: startingIndex };
|
|
60
64
|
/**
|
|
@@ -83,12 +87,23 @@ export default function addGTIdentifierToSyntaxTree(tree, startingIndex = 0) {
|
|
|
83
87
|
};
|
|
84
88
|
}
|
|
85
89
|
// Construct the data-_gt prop
|
|
86
|
-
const generaltranslation = constructGTProp(type, props, indexObject.index);
|
|
90
|
+
const generaltranslation = constructGTProp(type, (props || {}), indexObject.index);
|
|
91
|
+
// Save current index and recurse
|
|
92
|
+
const currentIndex = indexObject.index;
|
|
93
|
+
const children = handleChildren(props?.children === undefined ? null : props?.children);
|
|
94
|
+
// Enforce boolean rendering behavior
|
|
95
|
+
// <T>{true}</T> -> true <- this is a boolean value, not a string
|
|
96
|
+
// <T>{false}</T> -> nothing
|
|
97
|
+
let includeChildren = true;
|
|
98
|
+
if (typeof children === 'boolean') {
|
|
99
|
+
// So, technically JsxChildren do include boolean values, but the type is incorrect
|
|
100
|
+
includeChildren = children !== false;
|
|
101
|
+
}
|
|
87
102
|
// Return the result
|
|
88
103
|
return {
|
|
89
|
-
t: type || `C${
|
|
90
|
-
i:
|
|
91
|
-
c:
|
|
104
|
+
t: type || `C${currentIndex}`,
|
|
105
|
+
i: currentIndex,
|
|
106
|
+
...(includeChildren && { c: children }),
|
|
92
107
|
...(generaltranslation && { d: generaltranslation }),
|
|
93
108
|
};
|
|
94
109
|
}
|
|
@@ -104,7 +119,16 @@ export default function addGTIdentifierToSyntaxTree(tree, startingIndex = 0) {
|
|
|
104
119
|
*/
|
|
105
120
|
const handleChildren = (children) => {
|
|
106
121
|
return Array.isArray(children)
|
|
107
|
-
? children.map(handleSingleChild)
|
|
122
|
+
? children.map(handleSingleChild).filter((child) => {
|
|
123
|
+
// Enforce boolean rendering behavior
|
|
124
|
+
// <T>{true}{false}{null}</T> -> []
|
|
125
|
+
if (typeof child === 'boolean' ||
|
|
126
|
+
child === null ||
|
|
127
|
+
child === undefined) {
|
|
128
|
+
return false;
|
|
129
|
+
}
|
|
130
|
+
return true;
|
|
131
|
+
})
|
|
108
132
|
: handleSingleChild(children);
|
|
109
133
|
};
|
|
110
134
|
return handleChildren(tree);
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { JsxTree, MultiplicationNode, WhitespaceJsxTreeResult, WhitespaceMultiplicationNode } from './types.js';
|
|
2
|
+
export declare function trimJsxStringChild(child: string): string;
|
|
3
|
+
export declare function handleChildrenWhitespace(currentTree: MultiplicationNode['branches'], parentNodeType: 'multiplication'): (WhitespaceJsxTreeResult | WhitespaceMultiplicationNode)[];
|
|
4
|
+
export declare function handleChildrenWhitespace(currentTree: MultiplicationNode['branches'], parentNodeType?: 'element' | 'expression' | undefined): WhitespaceJsxTreeResult | WhitespaceMultiplicationNode | (WhitespaceJsxTreeResult | WhitespaceMultiplicationNode)[];
|
|
5
|
+
export declare function handleChildrenWhitespace(currentTree: MultiplicationNode | JsxTree, parentNodeType?: 'multiplication' | 'element' | 'expression' | undefined): null | WhitespaceJsxTreeResult | WhitespaceMultiplicationNode;
|
|
6
|
+
export declare function handleChildrenWhitespace(currentTree: JsxTree | JsxTree[]): null | WhitespaceJsxTreeResult | WhitespaceJsxTreeResult[];
|