gtx-cli 2.3.6-alpha.2 → 2.3.6-alpha.3
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/dist/api/checkFileTranslations.d.ts +23 -0
- package/dist/api/checkFileTranslations.js +236 -0
- package/dist/api/downloadFileBatch.d.ts +20 -0
- package/dist/api/downloadFileBatch.js +113 -0
- package/dist/api/sendFiles.d.ts +17 -0
- package/dist/api/sendFiles.js +115 -0
- package/dist/api/uploadFiles.d.ts +27 -0
- package/dist/api/uploadFiles.js +40 -0
- package/dist/cli/base.d.ts +32 -0
- package/dist/cli/base.js +335 -0
- package/dist/cli/commands/stage.d.ts +5 -0
- package/dist/cli/commands/stage.js +100 -0
- package/dist/cli/commands/translate.d.ts +6 -0
- package/dist/cli/commands/translate.js +63 -0
- package/dist/cli/flags.d.ts +3 -0
- package/dist/cli/flags.js +38 -0
- package/dist/cli/next.d.ts +11 -0
- package/dist/cli/next.js +20 -0
- package/dist/cli/react.d.ts +18 -0
- package/dist/cli/react.js +175 -0
- package/dist/config/generateSettings.d.ts +9 -0
- package/dist/config/generateSettings.js +176 -0
- package/dist/config/optionPresets.d.ts +2 -0
- package/dist/config/optionPresets.js +56 -0
- package/dist/config/resolveConfig.d.ts +4 -0
- package/dist/config/resolveConfig.js +19 -0
- package/dist/config/utils.d.ts +2 -0
- package/dist/config/utils.js +4 -0
- package/dist/config/validateSettings.d.ts +3 -0
- package/dist/config/validateSettings.js +32 -0
- package/dist/console/colors.d.ts +5 -0
- package/dist/console/colors.js +16 -0
- package/dist/console/index.d.ts +21 -0
- package/dist/console/index.js +24 -0
- package/dist/console/logging.d.ts +53 -0
- package/dist/console/logging.js +185 -0
- package/dist/formats/files/fileMapping.d.ts +11 -0
- package/dist/formats/files/fileMapping.js +82 -0
- package/dist/formats/files/save.d.ts +5 -0
- package/dist/formats/files/save.js +17 -0
- package/dist/formats/files/supportedFiles.d.ts +10 -0
- package/dist/formats/files/supportedFiles.js +18 -0
- package/dist/formats/files/translate.d.ts +4 -0
- package/dist/formats/files/translate.js +119 -0
- package/dist/formats/files/upload.d.ts +13 -0
- package/dist/formats/files/upload.js +136 -0
- package/dist/formats/gt/save.d.ts +9 -0
- package/dist/formats/gt/save.js +26 -0
- package/dist/formats/json/flattenJson.d.ts +14 -0
- package/dist/formats/json/flattenJson.js +64 -0
- package/dist/formats/json/mergeJson.d.ts +13 -0
- package/dist/formats/json/mergeJson.js +257 -0
- package/dist/formats/json/parseJson.d.ts +2 -0
- package/dist/formats/json/parseJson.js +108 -0
- package/dist/formats/json/utils.d.ts +47 -0
- package/dist/formats/json/utils.js +149 -0
- package/dist/formats/utils.d.ts +2 -0
- package/dist/formats/utils.js +24 -0
- package/dist/formats/yaml/mergeYaml.d.ts +5 -0
- package/dist/formats/yaml/mergeYaml.js +55 -0
- package/dist/formats/yaml/parseYaml.d.ts +5 -0
- package/dist/formats/yaml/parseYaml.js +23 -0
- package/dist/formats/yaml/utils.d.ts +2 -0
- package/dist/formats/yaml/utils.js +22 -0
- package/dist/fs/config/loadConfig.d.ts +1 -0
- package/dist/fs/config/loadConfig.js +9 -0
- package/dist/fs/config/parseFilesConfig.d.ts +27 -0
- package/dist/fs/config/parseFilesConfig.js +129 -0
- package/dist/fs/config/setupConfig.d.ts +17 -0
- package/dist/fs/config/setupConfig.js +50 -0
- package/dist/fs/config/updateConfig.d.ts +10 -0
- package/dist/fs/config/updateConfig.js +36 -0
- package/dist/fs/config/updateVersions.d.ts +10 -0
- package/dist/fs/config/updateVersions.js +30 -0
- package/dist/fs/copyFile.d.ts +7 -0
- package/dist/fs/copyFile.js +39 -0
- package/dist/fs/createLoadTranslationsFile.d.ts +1 -0
- package/dist/fs/createLoadTranslationsFile.js +36 -0
- package/dist/fs/determineFramework.d.ts +5 -0
- package/dist/fs/determineFramework.js +46 -0
- package/dist/fs/findFilepath.d.ts +36 -0
- package/dist/fs/findFilepath.js +89 -0
- package/dist/fs/getPackageResource.d.ts +1 -0
- package/dist/fs/getPackageResource.js +6 -0
- package/dist/fs/index.d.ts +1 -0
- package/dist/fs/index.js +1 -0
- package/dist/fs/loadJSON.d.ts +6 -0
- package/dist/fs/loadJSON.js +17 -0
- package/dist/fs/matchFiles.d.ts +1 -0
- package/dist/fs/matchFiles.js +8 -0
- package/dist/fs/saveJSON.d.ts +1 -0
- package/dist/fs/saveJSON.js +7 -0
- package/dist/fs/utils.d.ts +1 -0
- package/dist/fs/utils.js +16 -0
- package/dist/hooks/postProcess.d.ts +4 -0
- package/dist/hooks/postProcess.js +110 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.js +20 -0
- package/dist/main.d.ts +2 -0
- package/dist/main.js +9 -0
- package/dist/next/config/parseNextConfig.d.ts +10 -0
- package/dist/next/config/parseNextConfig.js +53 -0
- package/dist/next/jsx/utils.d.ts +7 -0
- package/dist/next/jsx/utils.js +42 -0
- package/dist/next/parse/handleInitGT.d.ts +7 -0
- package/dist/next/parse/handleInitGT.js +208 -0
- package/dist/next/parse/wrapContent.d.ts +11 -0
- package/dist/next/parse/wrapContent.js +163 -0
- package/dist/react/config/createESBuildConfig.d.ts +2 -0
- package/dist/react/config/createESBuildConfig.js +119 -0
- package/dist/react/data-_gt/addGTIdentifierToSyntaxTree.d.ts +8 -0
- package/dist/react/data-_gt/addGTIdentifierToSyntaxTree.js +111 -0
- package/dist/react/jsx/evaluateJsx.d.ts +17 -0
- package/dist/react/jsx/evaluateJsx.js +85 -0
- package/dist/react/jsx/trimJsxStringChildren.d.ts +7 -0
- package/dist/react/jsx/trimJsxStringChildren.js +95 -0
- package/dist/react/jsx/utils/constants.d.ts +10 -0
- package/dist/react/jsx/utils/constants.js +31 -0
- package/dist/react/jsx/utils/parseAst.d.ts +30 -0
- package/dist/react/jsx/utils/parseAst.js +277 -0
- package/dist/react/jsx/utils/parseJsx.d.ts +21 -0
- package/dist/react/jsx/utils/parseJsx.js +244 -0
- package/dist/react/jsx/utils/parseStringFunction.d.ts +16 -0
- package/dist/react/jsx/utils/parseStringFunction.js +411 -0
- package/dist/react/jsx/utils/validateStringFunction.d.ts +7 -0
- package/dist/react/jsx/utils/validateStringFunction.js +31 -0
- package/dist/react/jsx/wrapJsx.d.ts +51 -0
- package/dist/react/jsx/wrapJsx.js +387 -0
- package/dist/react/parse/createDictionaryUpdates.d.ts +3 -0
- package/dist/react/parse/createDictionaryUpdates.js +169 -0
- package/dist/react/parse/createInlineUpdates.d.ts +6 -0
- package/dist/react/parse/createInlineUpdates.js +122 -0
- package/dist/react/parse/wrapContent.d.ts +11 -0
- package/dist/react/parse/wrapContent.js +162 -0
- package/dist/react/utils/flattenDictionary.d.ts +20 -0
- package/dist/react/utils/flattenDictionary.js +75 -0
- package/dist/react/utils/getEntryAndMetadata.d.ts +5 -0
- package/dist/react/utils/getEntryAndMetadata.js +11 -0
- package/dist/react/utils/getVariableName.d.ts +25 -0
- package/dist/react/utils/getVariableName.js +37 -0
- package/dist/setup/userInput.d.ts +4 -0
- package/dist/setup/userInput.js +29 -0
- package/dist/setup/wizard.d.ts +2 -0
- package/dist/setup/wizard.js +127 -0
- package/dist/translation/parse.d.ts +15 -0
- package/dist/translation/parse.js +76 -0
- package/dist/translation/stage.d.ts +2 -0
- package/dist/translation/stage.js +44 -0
- package/dist/translation/validate.d.ts +2 -0
- package/dist/translation/validate.js +50 -0
- package/dist/types/data/json.d.ts +6 -0
- package/dist/types/data/json.js +1 -0
- package/dist/types/data.d.ts +30 -0
- package/dist/types/data.js +1 -0
- package/dist/types/files.d.ts +1 -0
- package/dist/types/files.js +1 -0
- package/dist/types/index.d.ts +173 -0
- package/dist/types/index.js +1 -0
- package/dist/utils/addExplicitAnchorIds.d.ts +24 -0
- package/dist/utils/addExplicitAnchorIds.js +260 -0
- package/dist/utils/constants.d.ts +2 -0
- package/dist/utils/constants.js +2 -0
- package/dist/utils/credentials.d.ts +12 -0
- package/dist/utils/credentials.js +119 -0
- package/dist/utils/flattenJsonFiles.d.ts +2 -0
- package/dist/utils/flattenJsonFiles.js +36 -0
- package/dist/utils/gt.d.ts +2 -0
- package/dist/utils/gt.js +2 -0
- package/dist/utils/hash.d.ts +6 -0
- package/dist/utils/hash.js +11 -0
- package/dist/utils/headers.d.ts +1 -0
- package/dist/utils/headers.js +14 -0
- package/dist/utils/installPackage.d.ts +3 -0
- package/dist/utils/installPackage.js +77 -0
- package/dist/utils/localizeStaticImports.d.ts +15 -0
- package/dist/utils/localizeStaticImports.js +341 -0
- package/dist/utils/localizeStaticUrls.d.ts +19 -0
- package/dist/utils/localizeStaticUrls.js +432 -0
- package/dist/utils/packageInfo.d.ts +3 -0
- package/dist/utils/packageInfo.js +17 -0
- package/dist/utils/packageJson.d.ts +6 -0
- package/dist/utils/packageJson.js +76 -0
- package/dist/utils/packageManager.d.ts +28 -0
- package/dist/utils/packageManager.js +269 -0
- package/dist/utils/processAnchorIds.d.ts +6 -0
- package/dist/utils/processAnchorIds.js +47 -0
- package/dist/utils/sanitizeFileContent.d.ts +6 -0
- package/dist/utils/sanitizeFileContent.js +29 -0
- package/dist/utils/validateMdx.d.ts +10 -0
- package/dist/utils/validateMdx.js +25 -0
- package/package.json +3 -3
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import * as t from '@babel/types';
|
|
2
|
+
import generateModule from '@babel/generator';
|
|
3
|
+
// Handle CommonJS/ESM interop
|
|
4
|
+
const generate = generateModule.default || generateModule;
|
|
5
|
+
const MEANINGFUL_REGEX = /[\p{L}\p{N}]/u;
|
|
6
|
+
/**
|
|
7
|
+
* Checks if a node is meaningful. Does not recurse into children.
|
|
8
|
+
* @param node - The node to check
|
|
9
|
+
* @returns Whether the node is meaningful
|
|
10
|
+
*/
|
|
11
|
+
export function isMeaningful(node) {
|
|
12
|
+
if (t.isStringLiteral(node) || t.isJSXText(node)) {
|
|
13
|
+
return MEANINGFUL_REGEX.test(node.value);
|
|
14
|
+
}
|
|
15
|
+
// Handle template literals without expressions
|
|
16
|
+
if (t.isTemplateLiteral(node) && node.expressions.length === 0) {
|
|
17
|
+
return MEANINGFUL_REGEX.test(node.quasis[0].value.raw);
|
|
18
|
+
}
|
|
19
|
+
if (t.isJSXExpressionContainer(node)) {
|
|
20
|
+
const value = isStaticExpression(node.expression);
|
|
21
|
+
if (value.isStatic && value.value) {
|
|
22
|
+
return MEANINGFUL_REGEX.test(value.value);
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
if (t.isBinaryExpression(node)) {
|
|
26
|
+
if (node.operator === '+') {
|
|
27
|
+
return isMeaningful(node.left) || isMeaningful(node.right);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
return false;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Checks if an expression is static (does not contain any variables which could change at runtime).
|
|
34
|
+
* @param expr - The expression to check
|
|
35
|
+
* @returns An object containing the result of the static check
|
|
36
|
+
*/
|
|
37
|
+
export function isStaticExpression(expr) {
|
|
38
|
+
// Handle empty expressions
|
|
39
|
+
if (t.isJSXEmptyExpression(expr)) {
|
|
40
|
+
return { isStatic: true, value: '' };
|
|
41
|
+
}
|
|
42
|
+
// Handle direct string literals
|
|
43
|
+
if (t.isStringLiteral(expr)) {
|
|
44
|
+
return { isStatic: true, value: expr.value };
|
|
45
|
+
}
|
|
46
|
+
// Handle template literals without expressions
|
|
47
|
+
if (t.isTemplateLiteral(expr) && expr.expressions.length === 0) {
|
|
48
|
+
return { isStatic: true, value: expr.quasis[0].value.raw };
|
|
49
|
+
}
|
|
50
|
+
// Binary expressions are not static
|
|
51
|
+
if (t.isBinaryExpression(expr)) {
|
|
52
|
+
// Not a static expression
|
|
53
|
+
return { isStatic: false };
|
|
54
|
+
}
|
|
55
|
+
// Handle parenthesized expressions
|
|
56
|
+
if (t.isParenthesizedExpression(expr)) {
|
|
57
|
+
return isStaticExpression(expr.expression);
|
|
58
|
+
}
|
|
59
|
+
// Handle numeric literals by converting them to strings
|
|
60
|
+
if (t.isNumericLiteral(expr)) {
|
|
61
|
+
return { isStatic: true, value: String(expr.value) };
|
|
62
|
+
}
|
|
63
|
+
// Handle boolean literals by converting them to strings
|
|
64
|
+
if (t.isBooleanLiteral(expr)) {
|
|
65
|
+
return { isStatic: true, value: String(expr.value) };
|
|
66
|
+
}
|
|
67
|
+
// Handle null literal
|
|
68
|
+
if (t.isNullLiteral(expr)) {
|
|
69
|
+
return { isStatic: true, value: 'null' };
|
|
70
|
+
}
|
|
71
|
+
// Not a static expression
|
|
72
|
+
return { isStatic: false };
|
|
73
|
+
}
|
|
74
|
+
export function isStaticValue(expr) {
|
|
75
|
+
if (t.isStringLiteral(expr)) {
|
|
76
|
+
return true;
|
|
77
|
+
}
|
|
78
|
+
if (t.isNumericLiteral(expr)) {
|
|
79
|
+
return true;
|
|
80
|
+
}
|
|
81
|
+
if (t.isTemplateLiteral(expr)) {
|
|
82
|
+
return true;
|
|
83
|
+
}
|
|
84
|
+
return false;
|
|
85
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export declare function trimJsxStringChild(child: string, index: number, childrenTypes: ('expression' | 'text' | 'element')[]): string;
|
|
2
|
+
/**
|
|
3
|
+
* Handles whitespace in children of a JSX element.
|
|
4
|
+
* @param currentTree - The current tree to handle
|
|
5
|
+
* @returns The processed tree with whitespace handled
|
|
6
|
+
*/
|
|
7
|
+
export declare const handleChildrenWhitespace: (currentTree: any) => any;
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import { isAcceptedPluralForm } from 'generaltranslation/internal';
|
|
2
|
+
export function trimJsxStringChild(child, index, childrenTypes) {
|
|
3
|
+
// Normalize line endings to \n for consistency across platforms
|
|
4
|
+
let result = child.replace(/\r\n|\r/g, '\n');
|
|
5
|
+
// Collapse multiple spaces/tabs into a single space
|
|
6
|
+
result = result.replace(/[\t ]+/g, ' ');
|
|
7
|
+
let newResult = '';
|
|
8
|
+
let newline = false;
|
|
9
|
+
for (const char of result) {
|
|
10
|
+
if (char === '\n') {
|
|
11
|
+
if (newResult.trim())
|
|
12
|
+
newResult += ' ';
|
|
13
|
+
else
|
|
14
|
+
newResult = '';
|
|
15
|
+
newline = true;
|
|
16
|
+
continue;
|
|
17
|
+
}
|
|
18
|
+
if (!newline) {
|
|
19
|
+
newResult += char;
|
|
20
|
+
continue;
|
|
21
|
+
}
|
|
22
|
+
if (char.trim() === '')
|
|
23
|
+
continue;
|
|
24
|
+
newResult += char;
|
|
25
|
+
newline = false;
|
|
26
|
+
}
|
|
27
|
+
if (newline)
|
|
28
|
+
newResult = newResult.trimEnd();
|
|
29
|
+
result = newResult;
|
|
30
|
+
// Collapse multiple spaces/tabs into a single space
|
|
31
|
+
result = result.replace(/[\t ]+/g, ' ');
|
|
32
|
+
return result;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Handles whitespace in children of a JSX element.
|
|
36
|
+
* @param currentTree - The current tree to handle
|
|
37
|
+
* @returns The processed tree with whitespace handled
|
|
38
|
+
*/
|
|
39
|
+
export const handleChildrenWhitespace = (currentTree) => {
|
|
40
|
+
if (Array.isArray(currentTree)) {
|
|
41
|
+
const childrenTypes = currentTree.map((child) => {
|
|
42
|
+
if (typeof child === 'string')
|
|
43
|
+
return 'text';
|
|
44
|
+
if (typeof child === 'object' && 'expression' in child)
|
|
45
|
+
return 'expression';
|
|
46
|
+
return 'element';
|
|
47
|
+
});
|
|
48
|
+
const newChildren = [];
|
|
49
|
+
currentTree.forEach((child, index) => {
|
|
50
|
+
if (childrenTypes[index] === 'text') {
|
|
51
|
+
const string = trimJsxStringChild(child, index, childrenTypes);
|
|
52
|
+
if (string)
|
|
53
|
+
newChildren.push(string);
|
|
54
|
+
}
|
|
55
|
+
else if (childrenTypes[index] === 'expression') {
|
|
56
|
+
newChildren.push(child.result);
|
|
57
|
+
}
|
|
58
|
+
else {
|
|
59
|
+
newChildren.push(handleChildrenWhitespace(child));
|
|
60
|
+
}
|
|
61
|
+
});
|
|
62
|
+
return newChildren.length === 1 ? newChildren[0] : newChildren;
|
|
63
|
+
}
|
|
64
|
+
else if (currentTree?.props) {
|
|
65
|
+
// Process all props recursively
|
|
66
|
+
const elementIsPlural = currentTree.type === 'Plural';
|
|
67
|
+
const elementIsBranch = currentTree.type === 'Branch';
|
|
68
|
+
const processedProps = Object.fromEntries(Object.entries(currentTree.props).map(([key, value]) => {
|
|
69
|
+
let shouldProcess = false;
|
|
70
|
+
if (key === 'children')
|
|
71
|
+
shouldProcess = true;
|
|
72
|
+
if (elementIsPlural && isAcceptedPluralForm(key))
|
|
73
|
+
shouldProcess = true;
|
|
74
|
+
if (elementIsBranch && key !== 'branch')
|
|
75
|
+
shouldProcess = true;
|
|
76
|
+
// Add your validation logic here
|
|
77
|
+
if (shouldProcess) {
|
|
78
|
+
return [key, handleChildrenWhitespace(value)];
|
|
79
|
+
}
|
|
80
|
+
return [key, value];
|
|
81
|
+
}));
|
|
82
|
+
return {
|
|
83
|
+
...currentTree,
|
|
84
|
+
props: processedProps,
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
else if (typeof currentTree === 'object' &&
|
|
88
|
+
'expression' in currentTree === true) {
|
|
89
|
+
return currentTree.result;
|
|
90
|
+
}
|
|
91
|
+
else if (typeof currentTree === 'string') {
|
|
92
|
+
return trimJsxStringChild(currentTree, 0, ['text']);
|
|
93
|
+
}
|
|
94
|
+
return currentTree;
|
|
95
|
+
};
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export declare const MSG_TRANSLATION_HOOK = "msg";
|
|
2
|
+
export declare const INLINE_TRANSLATION_HOOK = "useGT";
|
|
3
|
+
export declare const INLINE_TRANSLATION_HOOK_ASYNC = "getGT";
|
|
4
|
+
export declare const INLINE_MESSAGE_HOOK = "useMessages";
|
|
5
|
+
export declare const INLINE_MESSAGE_HOOK_ASYNC = "getMessages";
|
|
6
|
+
export declare const GT_TRANSLATION_FUNCS: string[];
|
|
7
|
+
export declare const VARIABLE_COMPONENTS: string[];
|
|
8
|
+
export declare const GT_ATTRIBUTES_WITH_SUGAR: string[];
|
|
9
|
+
export declare const GT_ATTRIBUTES: string[];
|
|
10
|
+
export declare function mapAttributeName(attrName: string): string;
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
export const MSG_TRANSLATION_HOOK = 'msg';
|
|
2
|
+
export const INLINE_TRANSLATION_HOOK = 'useGT';
|
|
3
|
+
export const INLINE_TRANSLATION_HOOK_ASYNC = 'getGT';
|
|
4
|
+
export const INLINE_MESSAGE_HOOK = 'useMessages';
|
|
5
|
+
export const INLINE_MESSAGE_HOOK_ASYNC = 'getMessages';
|
|
6
|
+
// GT translation functions
|
|
7
|
+
export const GT_TRANSLATION_FUNCS = [
|
|
8
|
+
INLINE_TRANSLATION_HOOK,
|
|
9
|
+
INLINE_TRANSLATION_HOOK_ASYNC,
|
|
10
|
+
INLINE_MESSAGE_HOOK,
|
|
11
|
+
INLINE_MESSAGE_HOOK_ASYNC,
|
|
12
|
+
MSG_TRANSLATION_HOOK,
|
|
13
|
+
'T',
|
|
14
|
+
'Var',
|
|
15
|
+
'DateTime',
|
|
16
|
+
'Currency',
|
|
17
|
+
'Num',
|
|
18
|
+
'Branch',
|
|
19
|
+
'Plural',
|
|
20
|
+
];
|
|
21
|
+
// Valid variable components
|
|
22
|
+
export const VARIABLE_COMPONENTS = ['Var', 'DateTime', 'Currency', 'Num'];
|
|
23
|
+
export const GT_ATTRIBUTES_WITH_SUGAR = ['$id', '$context'];
|
|
24
|
+
export const GT_ATTRIBUTES = ['id', 'context', ...GT_ATTRIBUTES_WITH_SUGAR];
|
|
25
|
+
export function mapAttributeName(attrName) {
|
|
26
|
+
if (attrName === '$id')
|
|
27
|
+
return 'id';
|
|
28
|
+
if (attrName === '$context')
|
|
29
|
+
return 'context';
|
|
30
|
+
return attrName;
|
|
31
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import * as t from '@babel/types';
|
|
2
|
+
import { ParseResult } from '@babel/parser';
|
|
3
|
+
import { ImportDeclaration, VariableDeclaration } from '@babel/types';
|
|
4
|
+
export declare function determineModuleType(ast: ParseResult<t.File>): boolean;
|
|
5
|
+
export type ImportItem = string | {
|
|
6
|
+
local: string;
|
|
7
|
+
imported: string;
|
|
8
|
+
source: string;
|
|
9
|
+
};
|
|
10
|
+
export declare function generateImports(needsImport: ImportItem[], isESM: boolean, importMap: Record<string, {
|
|
11
|
+
name: string;
|
|
12
|
+
source: string;
|
|
13
|
+
}>): (t.ImportDeclaration | t.VariableDeclaration)[];
|
|
14
|
+
export declare function generateImportMap(ast: ParseResult<t.File>, pkg: string): {
|
|
15
|
+
initialImports: string[];
|
|
16
|
+
importAlias: {
|
|
17
|
+
TComponent: string;
|
|
18
|
+
VarComponent: string;
|
|
19
|
+
};
|
|
20
|
+
};
|
|
21
|
+
export declare function insertImports(ast: ParseResult<t.File>, importNodes: (t.ImportDeclaration | t.VariableDeclaration)[]): void;
|
|
22
|
+
export declare function createImports(ast: ParseResult<t.File>, needsImport: ImportItem[], importMap: Record<string, {
|
|
23
|
+
name: string;
|
|
24
|
+
source: string;
|
|
25
|
+
}>): void;
|
|
26
|
+
export interface ImportNameResult {
|
|
27
|
+
local: string;
|
|
28
|
+
original: string;
|
|
29
|
+
}
|
|
30
|
+
export declare function extractImportName(node: ImportDeclaration | VariableDeclaration, pkg: string, translationFuncs: string[]): ImportNameResult[];
|
|
@@ -0,0 +1,277 @@
|
|
|
1
|
+
import traverseModule from '@babel/traverse';
|
|
2
|
+
// Handle CommonJS/ESM interop
|
|
3
|
+
const traverse = traverseModule.default || traverseModule;
|
|
4
|
+
import * as babel from '@babel/types';
|
|
5
|
+
export function determineModuleType(ast) {
|
|
6
|
+
let isESM = false;
|
|
7
|
+
traverse(ast, {
|
|
8
|
+
ImportDeclaration() {
|
|
9
|
+
isESM = true;
|
|
10
|
+
},
|
|
11
|
+
ExportDefaultDeclaration() {
|
|
12
|
+
isESM = true;
|
|
13
|
+
},
|
|
14
|
+
ExportNamedDeclaration() {
|
|
15
|
+
isESM = true;
|
|
16
|
+
},
|
|
17
|
+
});
|
|
18
|
+
return isESM;
|
|
19
|
+
}
|
|
20
|
+
export function generateImports(needsImport, isESM, importMap) {
|
|
21
|
+
// Group imports by their source
|
|
22
|
+
const importsBySource = needsImport.reduce((acc, imp) => {
|
|
23
|
+
if (typeof imp === 'string') {
|
|
24
|
+
// Handle standard GT component imports
|
|
25
|
+
const importInfo = importMap[imp];
|
|
26
|
+
const source = importInfo.source;
|
|
27
|
+
if (!acc[source])
|
|
28
|
+
acc[source] = [];
|
|
29
|
+
acc[source].push({ local: imp, imported: importInfo.name });
|
|
30
|
+
}
|
|
31
|
+
else {
|
|
32
|
+
// Handle custom imports (like config)
|
|
33
|
+
const source = imp.source;
|
|
34
|
+
if (!acc[source])
|
|
35
|
+
acc[source] = [];
|
|
36
|
+
acc[source].push({ local: imp.local, imported: imp.imported });
|
|
37
|
+
}
|
|
38
|
+
return acc;
|
|
39
|
+
}, {});
|
|
40
|
+
// Generate import nodes for each source
|
|
41
|
+
const importNodes = Object.entries(importsBySource).map(([source, imports]) => {
|
|
42
|
+
if (isESM) {
|
|
43
|
+
return babel.importDeclaration(imports.map((imp) => imp.imported === 'default'
|
|
44
|
+
? babel.importDefaultSpecifier(babel.identifier(imp.local))
|
|
45
|
+
: babel.importSpecifier(babel.identifier(imp.local), babel.identifier(imp.imported))), babel.stringLiteral(source));
|
|
46
|
+
}
|
|
47
|
+
else {
|
|
48
|
+
// For CommonJS, handle default imports differently
|
|
49
|
+
return babel.variableDeclaration('const', [
|
|
50
|
+
babel.variableDeclarator(imports.some((imp) => imp.imported === 'default')
|
|
51
|
+
? babel.identifier(imports[0].local)
|
|
52
|
+
: babel.objectPattern(imports.map((imp) => babel.objectProperty(babel.identifier(imp.local), babel.identifier(imp.imported), false, imp.local === imp.imported))), babel.callExpression(babel.identifier('require'), [
|
|
53
|
+
babel.stringLiteral(source),
|
|
54
|
+
])),
|
|
55
|
+
]);
|
|
56
|
+
}
|
|
57
|
+
});
|
|
58
|
+
return importNodes;
|
|
59
|
+
}
|
|
60
|
+
/*
|
|
61
|
+
* This function traverses the AST and records the relevant imports for the pkg.
|
|
62
|
+
* It also records the import aliases for the T and Var components. (in case of conflicts)
|
|
63
|
+
*/
|
|
64
|
+
export function generateImportMap(ast, pkg) {
|
|
65
|
+
const importAlias = { TComponent: 'T', VarComponent: 'Var' };
|
|
66
|
+
// Check existing imports
|
|
67
|
+
let initialImports = [];
|
|
68
|
+
traverse(ast, {
|
|
69
|
+
ImportDeclaration(path) {
|
|
70
|
+
const source = path.node.source.value;
|
|
71
|
+
if (source === pkg) {
|
|
72
|
+
initialImports = [
|
|
73
|
+
...initialImports,
|
|
74
|
+
...path.node.specifiers.map((spec) => {
|
|
75
|
+
// For named imports (import { x as y }), use the original name
|
|
76
|
+
if (babel.isImportSpecifier(spec)) {
|
|
77
|
+
return babel.isIdentifier(spec.imported)
|
|
78
|
+
? spec.imported.name
|
|
79
|
+
: spec.imported.value;
|
|
80
|
+
}
|
|
81
|
+
// For default imports, fall back to local name
|
|
82
|
+
return spec.local.name;
|
|
83
|
+
}),
|
|
84
|
+
];
|
|
85
|
+
}
|
|
86
|
+
// Check for conflicting imports only if they're not from gt libraries
|
|
87
|
+
if (source !== pkg) {
|
|
88
|
+
path.node.specifiers.forEach((spec) => {
|
|
89
|
+
if (babel.isImportSpecifier(spec) ||
|
|
90
|
+
babel.isImportDefaultSpecifier(spec)) {
|
|
91
|
+
if (spec.local.name === 'T')
|
|
92
|
+
importAlias.TComponent = 'GTT';
|
|
93
|
+
if (spec.local.name === 'Var')
|
|
94
|
+
importAlias.VarComponent = 'GTVar';
|
|
95
|
+
}
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
},
|
|
99
|
+
VariableDeclaration(path) {
|
|
100
|
+
const declaration = path.node.declarations[0];
|
|
101
|
+
if (!declaration)
|
|
102
|
+
return;
|
|
103
|
+
// Handle const { T, Var } = require('pkg')
|
|
104
|
+
if (babel.isCallExpression(declaration.init) &&
|
|
105
|
+
babel.isIdentifier(declaration.init.callee) &&
|
|
106
|
+
declaration.init.callee.name === 'require' &&
|
|
107
|
+
babel.isStringLiteral(declaration.init.arguments[0]) &&
|
|
108
|
+
declaration.init.arguments[0].value === pkg &&
|
|
109
|
+
babel.isObjectPattern(declaration.id)) {
|
|
110
|
+
initialImports = [
|
|
111
|
+
...initialImports,
|
|
112
|
+
...declaration.id.properties
|
|
113
|
+
.map((prop) => {
|
|
114
|
+
if (babel.isObjectProperty(prop) &&
|
|
115
|
+
babel.isIdentifier(prop.key)) {
|
|
116
|
+
return prop.key.name;
|
|
117
|
+
}
|
|
118
|
+
return '';
|
|
119
|
+
})
|
|
120
|
+
.filter(Boolean),
|
|
121
|
+
];
|
|
122
|
+
}
|
|
123
|
+
// Handle const temp = require('pkg') followed by const { T, Var } = temp
|
|
124
|
+
if (babel.isCallExpression(declaration.init) &&
|
|
125
|
+
babel.isIdentifier(declaration.init.callee) &&
|
|
126
|
+
declaration.init.callee.name === 'require' &&
|
|
127
|
+
babel.isStringLiteral(declaration.init.arguments[0]) &&
|
|
128
|
+
declaration.init.arguments[0].value === pkg &&
|
|
129
|
+
babel.isIdentifier(declaration.id)) {
|
|
130
|
+
const requireVarName = declaration.id.name;
|
|
131
|
+
const parentBody = babel.isProgram(path.parent) || babel.isBlockStatement(path.parent)
|
|
132
|
+
? path.parent.body
|
|
133
|
+
: [];
|
|
134
|
+
// Look for subsequent destructuring
|
|
135
|
+
for (const node of parentBody) {
|
|
136
|
+
if (babel.isVariableDeclaration(node) &&
|
|
137
|
+
node.declarations[0] &&
|
|
138
|
+
babel.isObjectPattern(node.declarations[0].id) &&
|
|
139
|
+
babel.isMemberExpression(node.declarations[0].init) &&
|
|
140
|
+
babel.isIdentifier(node.declarations[0].init.object) &&
|
|
141
|
+
node.declarations[0].init.object.name === requireVarName) {
|
|
142
|
+
initialImports = [
|
|
143
|
+
...initialImports,
|
|
144
|
+
...node.declarations[0].id.properties
|
|
145
|
+
.map((prop) => {
|
|
146
|
+
if (babel.isObjectProperty(prop) &&
|
|
147
|
+
babel.isIdentifier(prop.key)) {
|
|
148
|
+
return prop.key.name;
|
|
149
|
+
}
|
|
150
|
+
return '';
|
|
151
|
+
})
|
|
152
|
+
.filter(Boolean),
|
|
153
|
+
];
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
// Check for conflicting requires
|
|
158
|
+
if (babel.isCallExpression(declaration.init) &&
|
|
159
|
+
babel.isIdentifier(declaration.init.callee) &&
|
|
160
|
+
declaration.init.callee.name === 'require' &&
|
|
161
|
+
babel.isStringLiteral(declaration.init.arguments[0]) &&
|
|
162
|
+
declaration.init.arguments[0].value !== pkg &&
|
|
163
|
+
babel.isObjectPattern(declaration.id)) {
|
|
164
|
+
declaration.id.properties.forEach((prop) => {
|
|
165
|
+
if (babel.isObjectProperty(prop) && babel.isIdentifier(prop.value)) {
|
|
166
|
+
if (prop.value.name === 'T')
|
|
167
|
+
importAlias.TComponent = 'GTT';
|
|
168
|
+
if (prop.value.name === 'Var')
|
|
169
|
+
importAlias.VarComponent = 'GTVar';
|
|
170
|
+
}
|
|
171
|
+
});
|
|
172
|
+
}
|
|
173
|
+
// Add check for intermediate variable conflict
|
|
174
|
+
if (babel.isIdentifier(declaration.id)) {
|
|
175
|
+
if (declaration.id.name === 'T')
|
|
176
|
+
importAlias.TComponent = 'GTT';
|
|
177
|
+
if (declaration.id.name === 'Var')
|
|
178
|
+
importAlias.VarComponent = 'GTVar';
|
|
179
|
+
}
|
|
180
|
+
},
|
|
181
|
+
});
|
|
182
|
+
return { initialImports, importAlias };
|
|
183
|
+
}
|
|
184
|
+
export function insertImports(ast, importNodes) {
|
|
185
|
+
// Find the best position to insert the imports
|
|
186
|
+
let insertIndex = 0;
|
|
187
|
+
for (let i = 0; i < ast.program.body.length; i++) {
|
|
188
|
+
if (!babel.isImportDeclaration(ast.program.body[i])) {
|
|
189
|
+
insertIndex = i;
|
|
190
|
+
break;
|
|
191
|
+
}
|
|
192
|
+
insertIndex = i + 1;
|
|
193
|
+
}
|
|
194
|
+
// Insert all import nodes
|
|
195
|
+
ast.program.body.splice(insertIndex, 0, ...importNodes);
|
|
196
|
+
}
|
|
197
|
+
export function createImports(ast, needsImport, importMap) {
|
|
198
|
+
const isESM = determineModuleType(ast);
|
|
199
|
+
const importNodes = generateImports(needsImport, isESM, importMap);
|
|
200
|
+
insertImports(ast, importNodes);
|
|
201
|
+
}
|
|
202
|
+
export function extractImportName(node, pkg, translationFuncs) {
|
|
203
|
+
const results = [];
|
|
204
|
+
if (node.type === 'ImportDeclaration') {
|
|
205
|
+
// Handle ES6 imports
|
|
206
|
+
if (node.source.value.startsWith(pkg)) {
|
|
207
|
+
for (const specifier of node.specifiers) {
|
|
208
|
+
if (specifier.type === 'ImportSpecifier' &&
|
|
209
|
+
'name' in specifier.imported &&
|
|
210
|
+
translationFuncs.includes(specifier.imported.name)) {
|
|
211
|
+
results.push({
|
|
212
|
+
local: specifier.local.name,
|
|
213
|
+
original: specifier.imported.name,
|
|
214
|
+
});
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
else if (node.type === 'VariableDeclaration') {
|
|
220
|
+
// Handle CJS requires
|
|
221
|
+
for (const declaration of node.declarations) {
|
|
222
|
+
// Handle direct require with destructuring
|
|
223
|
+
if (declaration.init?.type === 'CallExpression' &&
|
|
224
|
+
declaration.init.callee.type === 'Identifier' &&
|
|
225
|
+
declaration.init.callee.name === 'require' &&
|
|
226
|
+
declaration.init.arguments[0]?.type === 'StringLiteral' &&
|
|
227
|
+
declaration.init.arguments[0].value.startsWith(pkg)) {
|
|
228
|
+
// Handle destructuring case: const { T } = require('gt-next')
|
|
229
|
+
if (declaration.id.type === 'ObjectPattern') {
|
|
230
|
+
for (const prop of declaration.id.properties) {
|
|
231
|
+
if (prop.type === 'ObjectProperty' &&
|
|
232
|
+
prop.key.type === 'Identifier' &&
|
|
233
|
+
translationFuncs.includes(prop.key.name) &&
|
|
234
|
+
prop.value.type === 'Identifier') {
|
|
235
|
+
results.push({
|
|
236
|
+
local: prop.value.name,
|
|
237
|
+
original: prop.key.name,
|
|
238
|
+
});
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
// Handle intermediate variable case: const temp = require('gt-next')
|
|
243
|
+
else if (declaration.id.type === 'Identifier') {
|
|
244
|
+
const requireVarName = declaration.id.name;
|
|
245
|
+
const parentBody = node.parent?.body;
|
|
246
|
+
if (parentBody) {
|
|
247
|
+
for (let i = 0; i < parentBody.length; i++) {
|
|
248
|
+
const stmt = parentBody[i];
|
|
249
|
+
if (stmt.type === 'VariableDeclaration' &&
|
|
250
|
+
stmt.declarations[0]?.init?.type === 'MemberExpression' &&
|
|
251
|
+
stmt.declarations[0].init.object.type === 'Identifier' &&
|
|
252
|
+
stmt.declarations[0].init.object.name === requireVarName &&
|
|
253
|
+
stmt.declarations[0].init.property.type === 'Identifier' &&
|
|
254
|
+
translationFuncs.includes(stmt.declarations[0].init.property.name)) {
|
|
255
|
+
results.push({
|
|
256
|
+
local: stmt.declarations[0].id.name,
|
|
257
|
+
original: stmt.declarations[0].init.property.name,
|
|
258
|
+
});
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
// Handle member expression assignment: const TranslateFunc = temp.T
|
|
265
|
+
if (declaration.init?.type === 'MemberExpression' &&
|
|
266
|
+
declaration.init.property.type === 'Identifier' &&
|
|
267
|
+
translationFuncs.includes(declaration.init.property.name) &&
|
|
268
|
+
declaration.id.type === 'Identifier') {
|
|
269
|
+
results.push({
|
|
270
|
+
local: declaration.id.name,
|
|
271
|
+
original: declaration.init.property.name,
|
|
272
|
+
});
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
return results;
|
|
277
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { Updates } from '../../../types/index.js';
|
|
2
|
+
import * as t from '@babel/types';
|
|
3
|
+
/**
|
|
4
|
+
* Builds a JSX tree from a given node, recursively handling children.
|
|
5
|
+
* @param node - The node to build the tree from
|
|
6
|
+
* @param unwrappedExpressions - An array to store unwrapped expressions
|
|
7
|
+
* @param updates - The updates array
|
|
8
|
+
* @param errors - The errors array
|
|
9
|
+
* @param file - The file name
|
|
10
|
+
* @param insideT - Whether the current node is inside a <T> component
|
|
11
|
+
* @returns The built JSX tree
|
|
12
|
+
*/
|
|
13
|
+
export declare function buildJSXTree(importAliases: Record<string, string>, node: any, unwrappedExpressions: string[], updates: Updates, errors: string[], warnings: Set<string>, file: string, insideT: boolean): {
|
|
14
|
+
expression?: boolean;
|
|
15
|
+
result?: string;
|
|
16
|
+
type?: string;
|
|
17
|
+
props?: {
|
|
18
|
+
children?: any;
|
|
19
|
+
};
|
|
20
|
+
} | string | null;
|
|
21
|
+
export declare function parseJSXElement(importAliases: Record<string, string>, node: t.JSXElement, updates: Updates, errors: string[], warnings: Set<string>, file: string): void;
|