gtx-cli 2.3.5 → 2.3.6-alpha.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/package.json +23 -18
- package/dist/api/checkFileTranslations.d.ts +0 -23
- package/dist/api/checkFileTranslations.js +0 -236
- package/dist/api/downloadFileBatch.d.ts +0 -20
- package/dist/api/downloadFileBatch.js +0 -113
- package/dist/api/sendFiles.d.ts +0 -17
- package/dist/api/sendFiles.js +0 -115
- package/dist/api/uploadFiles.d.ts +0 -27
- package/dist/api/uploadFiles.js +0 -40
- package/dist/cli/base.d.ts +0 -32
- package/dist/cli/base.js +0 -335
- package/dist/cli/commands/stage.d.ts +0 -5
- package/dist/cli/commands/stage.js +0 -100
- package/dist/cli/commands/translate.d.ts +0 -6
- package/dist/cli/commands/translate.js +0 -63
- package/dist/cli/flags.d.ts +0 -3
- package/dist/cli/flags.js +0 -38
- package/dist/cli/next.d.ts +0 -11
- package/dist/cli/next.js +0 -20
- package/dist/cli/react.d.ts +0 -18
- package/dist/cli/react.js +0 -175
- package/dist/config/generateSettings.d.ts +0 -9
- package/dist/config/generateSettings.js +0 -176
- package/dist/config/optionPresets.d.ts +0 -2
- package/dist/config/optionPresets.js +0 -56
- package/dist/config/resolveConfig.d.ts +0 -4
- package/dist/config/resolveConfig.js +0 -19
- package/dist/config/utils.d.ts +0 -2
- package/dist/config/utils.js +0 -4
- package/dist/config/validateSettings.d.ts +0 -3
- package/dist/config/validateSettings.js +0 -32
- package/dist/console/colors.d.ts +0 -5
- package/dist/console/colors.js +0 -16
- package/dist/console/index.d.ts +0 -21
- package/dist/console/index.js +0 -24
- package/dist/console/logging.d.ts +0 -53
- package/dist/console/logging.js +0 -185
- package/dist/formats/files/fileMapping.d.ts +0 -11
- package/dist/formats/files/fileMapping.js +0 -82
- package/dist/formats/files/save.d.ts +0 -5
- package/dist/formats/files/save.js +0 -17
- package/dist/formats/files/supportedFiles.d.ts +0 -10
- package/dist/formats/files/supportedFiles.js +0 -18
- package/dist/formats/files/translate.d.ts +0 -4
- package/dist/formats/files/translate.js +0 -119
- package/dist/formats/files/upload.d.ts +0 -13
- package/dist/formats/files/upload.js +0 -136
- package/dist/formats/gt/save.d.ts +0 -9
- package/dist/formats/gt/save.js +0 -26
- package/dist/formats/json/flattenJson.d.ts +0 -14
- package/dist/formats/json/flattenJson.js +0 -64
- package/dist/formats/json/mergeJson.d.ts +0 -13
- package/dist/formats/json/mergeJson.js +0 -257
- package/dist/formats/json/parseJson.d.ts +0 -2
- package/dist/formats/json/parseJson.js +0 -108
- package/dist/formats/json/utils.d.ts +0 -47
- package/dist/formats/json/utils.js +0 -149
- package/dist/formats/utils.d.ts +0 -2
- package/dist/formats/utils.js +0 -24
- package/dist/formats/yaml/mergeYaml.d.ts +0 -5
- package/dist/formats/yaml/mergeYaml.js +0 -55
- package/dist/formats/yaml/parseYaml.d.ts +0 -5
- package/dist/formats/yaml/parseYaml.js +0 -23
- package/dist/formats/yaml/utils.d.ts +0 -2
- package/dist/formats/yaml/utils.js +0 -22
- package/dist/fs/config/loadConfig.d.ts +0 -1
- package/dist/fs/config/loadConfig.js +0 -9
- package/dist/fs/config/parseFilesConfig.d.ts +0 -27
- package/dist/fs/config/parseFilesConfig.js +0 -129
- package/dist/fs/config/setupConfig.d.ts +0 -17
- package/dist/fs/config/setupConfig.js +0 -50
- package/dist/fs/config/updateConfig.d.ts +0 -10
- package/dist/fs/config/updateConfig.js +0 -36
- package/dist/fs/config/updateVersions.d.ts +0 -10
- package/dist/fs/config/updateVersions.js +0 -30
- package/dist/fs/copyFile.d.ts +0 -7
- package/dist/fs/copyFile.js +0 -39
- package/dist/fs/createLoadTranslationsFile.d.ts +0 -1
- package/dist/fs/createLoadTranslationsFile.js +0 -36
- package/dist/fs/determineFramework.d.ts +0 -5
- package/dist/fs/determineFramework.js +0 -46
- package/dist/fs/findFilepath.d.ts +0 -36
- package/dist/fs/findFilepath.js +0 -89
- package/dist/fs/getPackageResource.d.ts +0 -1
- package/dist/fs/getPackageResource.js +0 -6
- package/dist/fs/index.d.ts +0 -1
- package/dist/fs/index.js +0 -1
- package/dist/fs/loadJSON.d.ts +0 -6
- package/dist/fs/loadJSON.js +0 -17
- package/dist/fs/matchFiles.d.ts +0 -1
- package/dist/fs/matchFiles.js +0 -8
- package/dist/fs/saveJSON.d.ts +0 -1
- package/dist/fs/saveJSON.js +0 -7
- package/dist/fs/utils.d.ts +0 -1
- package/dist/fs/utils.js +0 -16
- package/dist/hooks/postProcess.d.ts +0 -4
- package/dist/hooks/postProcess.js +0 -110
- package/dist/index.d.ts +0 -4
- package/dist/index.js +0 -20
- package/dist/main.d.ts +0 -2
- package/dist/main.js +0 -9
- package/dist/next/config/parseNextConfig.d.ts +0 -10
- package/dist/next/config/parseNextConfig.js +0 -53
- package/dist/next/jsx/utils.d.ts +0 -7
- package/dist/next/jsx/utils.js +0 -42
- package/dist/next/parse/handleInitGT.d.ts +0 -7
- package/dist/next/parse/handleInitGT.js +0 -208
- package/dist/next/parse/wrapContent.d.ts +0 -11
- package/dist/next/parse/wrapContent.js +0 -163
- package/dist/react/config/createESBuildConfig.d.ts +0 -2
- package/dist/react/config/createESBuildConfig.js +0 -119
- package/dist/react/data-_gt/addGTIdentifierToSyntaxTree.d.ts +0 -8
- package/dist/react/data-_gt/addGTIdentifierToSyntaxTree.js +0 -111
- package/dist/react/jsx/evaluateJsx.d.ts +0 -17
- package/dist/react/jsx/evaluateJsx.js +0 -85
- package/dist/react/jsx/trimJsxStringChildren.d.ts +0 -7
- package/dist/react/jsx/trimJsxStringChildren.js +0 -95
- package/dist/react/jsx/utils/constants.d.ts +0 -10
- package/dist/react/jsx/utils/constants.js +0 -31
- package/dist/react/jsx/utils/parseAst.d.ts +0 -30
- package/dist/react/jsx/utils/parseAst.js +0 -277
- package/dist/react/jsx/utils/parseJsx.d.ts +0 -21
- package/dist/react/jsx/utils/parseJsx.js +0 -244
- package/dist/react/jsx/utils/parseStringFunction.d.ts +0 -16
- package/dist/react/jsx/utils/parseStringFunction.js +0 -411
- package/dist/react/jsx/utils/validateStringFunction.d.ts +0 -7
- package/dist/react/jsx/utils/validateStringFunction.js +0 -31
- package/dist/react/jsx/wrapJsx.d.ts +0 -51
- package/dist/react/jsx/wrapJsx.js +0 -387
- package/dist/react/parse/createDictionaryUpdates.d.ts +0 -3
- package/dist/react/parse/createDictionaryUpdates.js +0 -169
- package/dist/react/parse/createInlineUpdates.d.ts +0 -6
- package/dist/react/parse/createInlineUpdates.js +0 -122
- package/dist/react/parse/wrapContent.d.ts +0 -11
- package/dist/react/parse/wrapContent.js +0 -162
- package/dist/react/utils/flattenDictionary.d.ts +0 -20
- package/dist/react/utils/flattenDictionary.js +0 -75
- package/dist/react/utils/getEntryAndMetadata.d.ts +0 -5
- package/dist/react/utils/getEntryAndMetadata.js +0 -11
- package/dist/react/utils/getVariableName.d.ts +0 -25
- package/dist/react/utils/getVariableName.js +0 -37
- package/dist/setup/userInput.d.ts +0 -4
- package/dist/setup/userInput.js +0 -29
- package/dist/setup/wizard.d.ts +0 -2
- package/dist/setup/wizard.js +0 -127
- package/dist/translation/parse.d.ts +0 -15
- package/dist/translation/parse.js +0 -76
- package/dist/translation/stage.d.ts +0 -2
- package/dist/translation/stage.js +0 -44
- package/dist/translation/validate.d.ts +0 -2
- package/dist/translation/validate.js +0 -50
- package/dist/types/data/json.d.ts +0 -6
- package/dist/types/data/json.js +0 -1
- package/dist/types/data.d.ts +0 -30
- package/dist/types/data.js +0 -1
- package/dist/types/files.d.ts +0 -1
- package/dist/types/files.js +0 -1
- package/dist/types/index.d.ts +0 -173
- package/dist/types/index.js +0 -1
- package/dist/utils/addExplicitAnchorIds.d.ts +0 -24
- package/dist/utils/addExplicitAnchorIds.js +0 -260
- package/dist/utils/constants.d.ts +0 -2
- package/dist/utils/constants.js +0 -2
- package/dist/utils/credentials.d.ts +0 -12
- package/dist/utils/credentials.js +0 -119
- package/dist/utils/flattenJsonFiles.d.ts +0 -2
- package/dist/utils/flattenJsonFiles.js +0 -36
- package/dist/utils/gt.d.ts +0 -2
- package/dist/utils/gt.js +0 -2
- package/dist/utils/hash.d.ts +0 -6
- package/dist/utils/hash.js +0 -11
- package/dist/utils/headers.d.ts +0 -1
- package/dist/utils/headers.js +0 -14
- package/dist/utils/installPackage.d.ts +0 -3
- package/dist/utils/installPackage.js +0 -77
- package/dist/utils/localizeStaticImports.d.ts +0 -15
- package/dist/utils/localizeStaticImports.js +0 -341
- package/dist/utils/localizeStaticUrls.d.ts +0 -19
- package/dist/utils/localizeStaticUrls.js +0 -432
- package/dist/utils/packageInfo.d.ts +0 -3
- package/dist/utils/packageInfo.js +0 -17
- package/dist/utils/packageJson.d.ts +0 -6
- package/dist/utils/packageJson.js +0 -76
- package/dist/utils/packageManager.d.ts +0 -28
- package/dist/utils/packageManager.js +0 -269
- package/dist/utils/processAnchorIds.d.ts +0 -6
- package/dist/utils/processAnchorIds.js +0 -47
- package/dist/utils/sanitizeFileContent.d.ts +0 -6
- package/dist/utils/sanitizeFileContent.js +0 -29
- package/dist/utils/validateMdx.d.ts +0 -10
- package/dist/utils/validateMdx.js +0 -25
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
import { warnAsyncUseGT, warnSyncGetGT } from '../../../console/index.js';
|
|
2
|
-
import { INLINE_TRANSLATION_HOOK, INLINE_TRANSLATION_HOOK_ASYNC, } from './constants.js';
|
|
3
|
-
/**
|
|
4
|
-
* Validate useGT() / await getGT() calls
|
|
5
|
-
* 1. Validates that the call does not violate the rules of React (no hooks in async functions)
|
|
6
|
-
*/
|
|
7
|
-
export function validateStringFunction(localImportName, path, updates, errors, file, originalImportName) {
|
|
8
|
-
// Get the root program node to traverse the entire file
|
|
9
|
-
const program = path.scope.getProgramParent().path;
|
|
10
|
-
program.traverse({
|
|
11
|
-
CallExpression(callPath) {
|
|
12
|
-
if (callPath.node.callee.type === 'Identifier' &&
|
|
13
|
-
callPath.node.callee.name === localImportName) {
|
|
14
|
-
// Check the function scope
|
|
15
|
-
const functionScope = callPath.getFunctionParent();
|
|
16
|
-
if (originalImportName === INLINE_TRANSLATION_HOOK) {
|
|
17
|
-
// useGT should NOT be in an async function
|
|
18
|
-
if (functionScope && functionScope.node.async) {
|
|
19
|
-
errors.push(warnAsyncUseGT(file, `${callPath.node.loc?.start?.line}:${callPath.node.loc?.start?.column}`));
|
|
20
|
-
}
|
|
21
|
-
}
|
|
22
|
-
else if (originalImportName === INLINE_TRANSLATION_HOOK_ASYNC) {
|
|
23
|
-
// getGT should be in an async function
|
|
24
|
-
if (!functionScope || !functionScope.node.async) {
|
|
25
|
-
errors.push(warnSyncGetGT(file, `${callPath.node.loc?.start?.line}:${callPath.node.loc?.start?.column}`));
|
|
26
|
-
}
|
|
27
|
-
}
|
|
28
|
-
}
|
|
29
|
-
},
|
|
30
|
-
});
|
|
31
|
-
}
|
|
@@ -1,51 +0,0 @@
|
|
|
1
|
-
import * as t from '@babel/types';
|
|
2
|
-
import { ImportItem } from './utils/parseAst.js';
|
|
3
|
-
/**
|
|
4
|
-
* Recursively wraps a JSX element with a <T> component and unique id
|
|
5
|
-
* @param node - The JSX element to wrap
|
|
6
|
-
* @param updates - The updates array
|
|
7
|
-
* @param errors - The errors array
|
|
8
|
-
* @param file - The file name
|
|
9
|
-
* @param options - Optional component names for T and Var
|
|
10
|
-
*/
|
|
11
|
-
export interface WrapResult {
|
|
12
|
-
node: t.JSXElement | t.JSXFragment;
|
|
13
|
-
hasMeaningfulContent: boolean;
|
|
14
|
-
wrappedInT: boolean;
|
|
15
|
-
}
|
|
16
|
-
/**
|
|
17
|
-
* Recursively traverse a JSX element and wrap variables with a <Var> component
|
|
18
|
-
* @param node - The JSX element to wrap
|
|
19
|
-
* @param options - Optional component names for T and Var
|
|
20
|
-
* @param isMeaningful - A function to determine if a node is meaningful
|
|
21
|
-
* @returns The wrapped JSX element
|
|
22
|
-
*/
|
|
23
|
-
export declare function wrapJsxElement(node: t.JSXElement | t.JSXFragment, options: {
|
|
24
|
-
createIds: boolean;
|
|
25
|
-
TComponent?: string;
|
|
26
|
-
VarComponent?: string;
|
|
27
|
-
idPrefix: string;
|
|
28
|
-
idCount: number;
|
|
29
|
-
usedImports: ImportItem[];
|
|
30
|
-
modified: boolean;
|
|
31
|
-
warnings: string[];
|
|
32
|
-
file: string;
|
|
33
|
-
}, isMeaningful: (node: t.Node) => boolean, mark: boolean): WrapResult;
|
|
34
|
-
/**
|
|
35
|
-
* Wraps a JSX element with a <T> component and unique id
|
|
36
|
-
* @param rootNode - The JSX element to wrap
|
|
37
|
-
* @param options - Optional component names for T and Var
|
|
38
|
-
* @param isMeaningful - A function to determine if a node is meaningful
|
|
39
|
-
* @returns The wrapped JSX element
|
|
40
|
-
*/
|
|
41
|
-
export declare function handleJsxElement(rootNode: t.JSXElement | t.JSXFragment, options: {
|
|
42
|
-
createIds: boolean;
|
|
43
|
-
usedImports: ImportItem[];
|
|
44
|
-
TComponent?: string;
|
|
45
|
-
VarComponent?: string;
|
|
46
|
-
idPrefix: string;
|
|
47
|
-
idCount: number;
|
|
48
|
-
modified: boolean;
|
|
49
|
-
warnings: string[];
|
|
50
|
-
file: string;
|
|
51
|
-
}, isMeaningful: (node: t.Node) => boolean): WrapResult;
|
|
@@ -1,387 +0,0 @@
|
|
|
1
|
-
import * as t from '@babel/types';
|
|
2
|
-
import { isStaticExpression, isStaticValue } from './evaluateJsx.js';
|
|
3
|
-
import { warnTernarySync } from '../../console/index.js';
|
|
4
|
-
function wrapJsxExpression(node, options, isMeaningful, mark) {
|
|
5
|
-
const expression = t.isParenthesizedExpression(node.expression)
|
|
6
|
-
? node.expression.expression
|
|
7
|
-
: node.expression;
|
|
8
|
-
// Ignore template literals containing quasis - they should not be counted as meaningful
|
|
9
|
-
if (t.isTemplateLiteral(expression) && expression.expressions.length > 0) {
|
|
10
|
-
return {
|
|
11
|
-
node,
|
|
12
|
-
hasMeaningfulContent: false,
|
|
13
|
-
wrappedInT: false,
|
|
14
|
-
};
|
|
15
|
-
}
|
|
16
|
-
// Handle both JSX Elements and Fragments
|
|
17
|
-
if (t.isJSXElement(expression) ||
|
|
18
|
-
t.isJSXFragment(expression) ||
|
|
19
|
-
t.isStringLiteral(expression) ||
|
|
20
|
-
t.isJSXText(expression) ||
|
|
21
|
-
t.isTemplateLiteral(expression)) {
|
|
22
|
-
if (t.isJSXElement(expression) || t.isJSXFragment(expression)) {
|
|
23
|
-
const result = wrapJsxElement(expression, options, isMeaningful, mark);
|
|
24
|
-
// re-wrap the result in a JSXExpressionContainer
|
|
25
|
-
if (t.isParenthesizedExpression(node.expression)) {
|
|
26
|
-
node.expression.expression = result.node;
|
|
27
|
-
}
|
|
28
|
-
else {
|
|
29
|
-
node.expression = result.node;
|
|
30
|
-
}
|
|
31
|
-
return {
|
|
32
|
-
node,
|
|
33
|
-
hasMeaningfulContent: result.hasMeaningfulContent,
|
|
34
|
-
wrappedInT: result.wrappedInT,
|
|
35
|
-
};
|
|
36
|
-
}
|
|
37
|
-
return {
|
|
38
|
-
node,
|
|
39
|
-
hasMeaningfulContent: isMeaningful(expression),
|
|
40
|
-
wrappedInT: false,
|
|
41
|
-
};
|
|
42
|
-
}
|
|
43
|
-
// Handle conditional expressions (ternary)
|
|
44
|
-
else if (t.isConditionalExpression(expression)) {
|
|
45
|
-
const consequent = t.isParenthesizedExpression(expression.consequent)
|
|
46
|
-
? expression.consequent.expression
|
|
47
|
-
: expression.consequent;
|
|
48
|
-
const alternate = t.isParenthesizedExpression(expression.alternate)
|
|
49
|
-
? expression.alternate.expression
|
|
50
|
-
: expression.alternate;
|
|
51
|
-
// Handle consequent
|
|
52
|
-
if (t.isJSXElement(consequent) || t.isJSXFragment(consequent)) {
|
|
53
|
-
const result = handleJsxElement(consequent, options, isMeaningful);
|
|
54
|
-
// Re-insert into parenthesized expression if necessary
|
|
55
|
-
if (t.isParenthesizedExpression(expression.consequent)) {
|
|
56
|
-
expression.consequent.expression = result.node;
|
|
57
|
-
}
|
|
58
|
-
else {
|
|
59
|
-
expression.consequent = result.node;
|
|
60
|
-
}
|
|
61
|
-
// Warn about ternary (should use branch instead)
|
|
62
|
-
if (result.wrappedInT && !mark) {
|
|
63
|
-
options.warnings.push(warnTernarySync(options.file, `${consequent.loc?.start?.line}:${consequent.loc?.start?.column}`));
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
|
-
else if (t.isConditionalExpression(consequent) ||
|
|
67
|
-
t.isLogicalExpression(consequent)) {
|
|
68
|
-
// Recursively handle nested ternary in consequent
|
|
69
|
-
const consequentResult = wrapJsxExpression(t.jsxExpressionContainer(consequent), options, isMeaningful, mark);
|
|
70
|
-
if (t.isJSXExpressionContainer(consequentResult.node) &&
|
|
71
|
-
t.isExpression(consequentResult.node.expression)) {
|
|
72
|
-
expression.consequent = consequentResult.node.expression;
|
|
73
|
-
// Re-insert into parenthesized expression if necessary
|
|
74
|
-
if (t.isParenthesizedExpression(expression.consequent)) {
|
|
75
|
-
expression.consequent.expression = consequentResult.node.expression;
|
|
76
|
-
}
|
|
77
|
-
else {
|
|
78
|
-
expression.consequent = consequentResult.node.expression;
|
|
79
|
-
}
|
|
80
|
-
}
|
|
81
|
-
}
|
|
82
|
-
else if (t.isTemplateLiteral(consequent) &&
|
|
83
|
-
consequent.expressions.length > 0) {
|
|
84
|
-
// Ignore template literals in consequent with expressions (${}), don't wrap them
|
|
85
|
-
// Do nothing
|
|
86
|
-
}
|
|
87
|
-
else {
|
|
88
|
-
if (isStaticValue(consequent) && isMeaningful(consequent)) {
|
|
89
|
-
const wrapped = wrapExpressionWithT(consequent, options, false);
|
|
90
|
-
// Re-insert into parenthesized expression if necessary
|
|
91
|
-
if (t.isParenthesizedExpression(expression.consequent)) {
|
|
92
|
-
expression.consequent.expression = wrapped;
|
|
93
|
-
}
|
|
94
|
-
else {
|
|
95
|
-
expression.consequent = wrapped;
|
|
96
|
-
}
|
|
97
|
-
}
|
|
98
|
-
}
|
|
99
|
-
// Handle alternate
|
|
100
|
-
if (t.isJSXElement(alternate) || t.isJSXFragment(alternate)) {
|
|
101
|
-
const result = handleJsxElement(alternate, options, isMeaningful);
|
|
102
|
-
// Re-insert into parenthesized expression if necessary
|
|
103
|
-
if (t.isParenthesizedExpression(expression.alternate)) {
|
|
104
|
-
expression.alternate.expression = result.node;
|
|
105
|
-
}
|
|
106
|
-
else {
|
|
107
|
-
expression.alternate = result.node;
|
|
108
|
-
}
|
|
109
|
-
}
|
|
110
|
-
else if (t.isConditionalExpression(alternate) ||
|
|
111
|
-
t.isLogicalExpression(alternate)) {
|
|
112
|
-
// Recursively handle nested ternary in alternate
|
|
113
|
-
const alternateResult = wrapJsxExpression(t.jsxExpressionContainer(alternate), options, isMeaningful, mark);
|
|
114
|
-
if (t.isJSXExpressionContainer(alternateResult.node) &&
|
|
115
|
-
t.isExpression(alternateResult.node.expression)) {
|
|
116
|
-
expression.alternate = alternateResult.node.expression;
|
|
117
|
-
// Re-insert into parenthesized expression if necessary
|
|
118
|
-
if (t.isParenthesizedExpression(expression.alternate)) {
|
|
119
|
-
expression.alternate.expression = alternateResult.node.expression;
|
|
120
|
-
}
|
|
121
|
-
else {
|
|
122
|
-
expression.alternate = alternateResult.node.expression;
|
|
123
|
-
}
|
|
124
|
-
}
|
|
125
|
-
}
|
|
126
|
-
else if (t.isTemplateLiteral(alternate) &&
|
|
127
|
-
alternate.expressions.length > 0) {
|
|
128
|
-
// Ignore template literals in alternate with expressions (${}), don't wrap them
|
|
129
|
-
// Do nothing
|
|
130
|
-
}
|
|
131
|
-
else {
|
|
132
|
-
if (isStaticValue(alternate) && isMeaningful(alternate)) {
|
|
133
|
-
const wrapped = wrapExpressionWithT(alternate, options, false);
|
|
134
|
-
// Re-insert into parenthesized expression if necessary
|
|
135
|
-
if (t.isParenthesizedExpression(expression.alternate)) {
|
|
136
|
-
expression.alternate.expression = wrapped;
|
|
137
|
-
}
|
|
138
|
-
else {
|
|
139
|
-
expression.alternate = wrapped;
|
|
140
|
-
}
|
|
141
|
-
}
|
|
142
|
-
}
|
|
143
|
-
}
|
|
144
|
-
// Handle logical expressions (&& and ||)
|
|
145
|
-
else if (t.isLogicalExpression(expression)) {
|
|
146
|
-
const left = t.isParenthesizedExpression(expression.left)
|
|
147
|
-
? expression.left.expression
|
|
148
|
-
: expression.left;
|
|
149
|
-
const right = t.isParenthesizedExpression(expression.right)
|
|
150
|
-
? expression.right.expression
|
|
151
|
-
: expression.right;
|
|
152
|
-
if (t.isJSXElement(left) || t.isJSXFragment(left)) {
|
|
153
|
-
const result = handleJsxElement(left, options, isMeaningful);
|
|
154
|
-
// Re-insert into parenthesized expression if necessary
|
|
155
|
-
if (t.isParenthesizedExpression(expression.left)) {
|
|
156
|
-
expression.left.expression = result.node;
|
|
157
|
-
}
|
|
158
|
-
else {
|
|
159
|
-
expression.left = result.node;
|
|
160
|
-
}
|
|
161
|
-
}
|
|
162
|
-
else if (t.isLogicalExpression(left) || t.isConditionalExpression(left)) {
|
|
163
|
-
// Recursively handle nested logical expressions
|
|
164
|
-
const leftResult = wrapJsxExpression(t.jsxExpressionContainer(left), options, isMeaningful, mark);
|
|
165
|
-
if (t.isJSXExpressionContainer(leftResult.node) &&
|
|
166
|
-
t.isExpression(leftResult.node.expression)) {
|
|
167
|
-
// Re-insert into parenthesized expression if necessary
|
|
168
|
-
if (t.isParenthesizedExpression(expression.left)) {
|
|
169
|
-
expression.left.expression = leftResult.node.expression;
|
|
170
|
-
}
|
|
171
|
-
else {
|
|
172
|
-
expression.left = leftResult.node.expression;
|
|
173
|
-
}
|
|
174
|
-
}
|
|
175
|
-
}
|
|
176
|
-
else if (t.isTemplateLiteral(left) && left.expressions.length > 0) {
|
|
177
|
-
// Ignore template literals with expressions (${}) in left side of logical expression
|
|
178
|
-
// Do nothing - don't wrap them
|
|
179
|
-
}
|
|
180
|
-
else {
|
|
181
|
-
if (isStaticValue(left) &&
|
|
182
|
-
isMeaningful(left) &&
|
|
183
|
-
expression.operator !== '&&') {
|
|
184
|
-
const wrapped = wrapExpressionWithT(left, options, false);
|
|
185
|
-
// Re-insert into parenthesized expression if necessary
|
|
186
|
-
if (t.isParenthesizedExpression(expression.left)) {
|
|
187
|
-
expression.left.expression = wrapped;
|
|
188
|
-
}
|
|
189
|
-
else {
|
|
190
|
-
expression.left = wrapped;
|
|
191
|
-
}
|
|
192
|
-
}
|
|
193
|
-
}
|
|
194
|
-
if (t.isJSXElement(right) || t.isJSXFragment(right)) {
|
|
195
|
-
const result = handleJsxElement(right, options, isMeaningful);
|
|
196
|
-
// Re-insert into parenthesized expression if necessary
|
|
197
|
-
if (t.isParenthesizedExpression(expression.right)) {
|
|
198
|
-
expression.right.expression = result.node;
|
|
199
|
-
}
|
|
200
|
-
else {
|
|
201
|
-
expression.right = result.node;
|
|
202
|
-
}
|
|
203
|
-
}
|
|
204
|
-
else if (t.isLogicalExpression(right) ||
|
|
205
|
-
t.isConditionalExpression(right)) {
|
|
206
|
-
// Recursively handle nested logical expressions
|
|
207
|
-
const rightResult = wrapJsxExpression(t.jsxExpressionContainer(right), options, isMeaningful, mark);
|
|
208
|
-
if (t.isJSXExpressionContainer(rightResult.node) &&
|
|
209
|
-
t.isExpression(rightResult.node.expression)) {
|
|
210
|
-
// Re-insert into parenthesized expression if necessary
|
|
211
|
-
if (t.isParenthesizedExpression(expression.right)) {
|
|
212
|
-
expression.right.expression = rightResult.node.expression;
|
|
213
|
-
}
|
|
214
|
-
else {
|
|
215
|
-
expression.right = rightResult.node.expression;
|
|
216
|
-
}
|
|
217
|
-
}
|
|
218
|
-
}
|
|
219
|
-
else if (t.isTemplateLiteral(right) && right.expressions.length > 0) {
|
|
220
|
-
// Ignore template literals with expressions (${}) in right side of logical expression
|
|
221
|
-
// Do nothing - don't wrap them
|
|
222
|
-
}
|
|
223
|
-
else {
|
|
224
|
-
if (isStaticValue(right) &&
|
|
225
|
-
isMeaningful(right) &&
|
|
226
|
-
expression.operator !== '||') {
|
|
227
|
-
const wrapped = wrapExpressionWithT(right, options, false);
|
|
228
|
-
// Re-insert into parenthesized expression if necessary
|
|
229
|
-
if (t.isParenthesizedExpression(expression.right)) {
|
|
230
|
-
expression.right.expression = wrapped;
|
|
231
|
-
}
|
|
232
|
-
else {
|
|
233
|
-
expression.right = wrapped;
|
|
234
|
-
}
|
|
235
|
-
}
|
|
236
|
-
}
|
|
237
|
-
}
|
|
238
|
-
const staticCheck = isStaticExpression(expression);
|
|
239
|
-
// If the expression is not static or if it's already wrapped in T,
|
|
240
|
-
// wrap with Var
|
|
241
|
-
if (!staticCheck.isStatic) {
|
|
242
|
-
return {
|
|
243
|
-
node: wrapWithVar(node, options, mark),
|
|
244
|
-
hasMeaningfulContent: false,
|
|
245
|
-
wrappedInT: false,
|
|
246
|
-
};
|
|
247
|
-
}
|
|
248
|
-
// If it's a static expression, check if it's meaningful
|
|
249
|
-
return {
|
|
250
|
-
node,
|
|
251
|
-
hasMeaningfulContent: false,
|
|
252
|
-
wrappedInT: false,
|
|
253
|
-
};
|
|
254
|
-
}
|
|
255
|
-
/**
|
|
256
|
-
* Recursively traverse a JSX element and wrap variables with a <Var> component
|
|
257
|
-
* @param node - The JSX element to wrap
|
|
258
|
-
* @param options - Optional component names for T and Var
|
|
259
|
-
* @param isMeaningful - A function to determine if a node is meaningful
|
|
260
|
-
* @returns The wrapped JSX element
|
|
261
|
-
*/
|
|
262
|
-
export function wrapJsxElement(node, options, isMeaningful, mark) {
|
|
263
|
-
const TComponentName = options.TComponent || 'T';
|
|
264
|
-
const VarComponentName = options.VarComponent || 'Var';
|
|
265
|
-
// Handle both JSX Elements and Fragments
|
|
266
|
-
if (t.isJSXElement(node) || t.isJSXFragment(node)) {
|
|
267
|
-
// For elements, check if it's already a T or Var component
|
|
268
|
-
if (t.isJSXElement(node)) {
|
|
269
|
-
const name = node.openingElement.name;
|
|
270
|
-
if (t.isJSXIdentifier(name) &&
|
|
271
|
-
(name.name === TComponentName || name.name === VarComponentName)) {
|
|
272
|
-
return {
|
|
273
|
-
node,
|
|
274
|
-
hasMeaningfulContent: false,
|
|
275
|
-
wrappedInT: name.name === TComponentName,
|
|
276
|
-
};
|
|
277
|
-
}
|
|
278
|
-
}
|
|
279
|
-
// Process children recursively (DFS postorder)
|
|
280
|
-
let hasMeaningfulContent = false;
|
|
281
|
-
let wrappedInT = false;
|
|
282
|
-
const processedChildren = node.children.map((child) => {
|
|
283
|
-
if (t.isJSXElement(child) || t.isJSXFragment(child)) {
|
|
284
|
-
const result = wrapJsxElement(child, options, isMeaningful, mark);
|
|
285
|
-
hasMeaningfulContent =
|
|
286
|
-
hasMeaningfulContent || result.hasMeaningfulContent;
|
|
287
|
-
wrappedInT = wrappedInT || result.wrappedInT;
|
|
288
|
-
return result.node;
|
|
289
|
-
}
|
|
290
|
-
if (t.isJSXExpressionContainer(child)) {
|
|
291
|
-
const result = wrapJsxExpression(child, options, isMeaningful, mark);
|
|
292
|
-
wrappedInT = wrappedInT || result.wrappedInT;
|
|
293
|
-
hasMeaningfulContent =
|
|
294
|
-
hasMeaningfulContent || result.hasMeaningfulContent;
|
|
295
|
-
// Expressions are never meaningful because they will either:
|
|
296
|
-
// 1. be sub-wrapped in a T (if they contain meaningful content)
|
|
297
|
-
// 2. be wrapped in a Var (if they are not static)
|
|
298
|
-
return result.node;
|
|
299
|
-
}
|
|
300
|
-
const isMeaningfulVal = isMeaningful(child);
|
|
301
|
-
if (isMeaningfulVal) {
|
|
302
|
-
hasMeaningfulContent = true;
|
|
303
|
-
}
|
|
304
|
-
return child;
|
|
305
|
-
});
|
|
306
|
-
node.children = processedChildren;
|
|
307
|
-
return {
|
|
308
|
-
node,
|
|
309
|
-
hasMeaningfulContent: hasMeaningfulContent,
|
|
310
|
-
wrappedInT: wrappedInT,
|
|
311
|
-
};
|
|
312
|
-
}
|
|
313
|
-
// For any other node types, return as-is
|
|
314
|
-
return {
|
|
315
|
-
node,
|
|
316
|
-
hasMeaningfulContent: false,
|
|
317
|
-
wrappedInT: false,
|
|
318
|
-
};
|
|
319
|
-
}
|
|
320
|
-
/**
|
|
321
|
-
* Wraps a JSX element with a <T> component and unique id
|
|
322
|
-
* @param rootNode - The JSX element to wrap
|
|
323
|
-
* @param options - Optional component names for T and Var
|
|
324
|
-
* @param isMeaningful - A function to determine if a node is meaningful
|
|
325
|
-
* @returns The wrapped JSX element
|
|
326
|
-
*/
|
|
327
|
-
export function handleJsxElement(rootNode, options, isMeaningful) {
|
|
328
|
-
const result = wrapJsxElement(rootNode, options, isMeaningful, true);
|
|
329
|
-
// Only wrap with T at the root level if there's meaningful content
|
|
330
|
-
if (result.hasMeaningfulContent) {
|
|
331
|
-
const output = wrapJsxElement(result.node, options, isMeaningful, false);
|
|
332
|
-
const node = wrapWithT(output.node, options, false);
|
|
333
|
-
return {
|
|
334
|
-
node,
|
|
335
|
-
hasMeaningfulContent: true,
|
|
336
|
-
wrappedInT: true,
|
|
337
|
-
};
|
|
338
|
-
}
|
|
339
|
-
return {
|
|
340
|
-
node: result.node,
|
|
341
|
-
hasMeaningfulContent: false,
|
|
342
|
-
wrappedInT: result.wrappedInT,
|
|
343
|
-
};
|
|
344
|
-
}
|
|
345
|
-
function wrapWithT(node, options, mark) {
|
|
346
|
-
if (mark) {
|
|
347
|
-
return node;
|
|
348
|
-
}
|
|
349
|
-
const TComponentName = options.TComponent || 'T';
|
|
350
|
-
const uniqueId = `${options.idPrefix}.${options.idCount}`;
|
|
351
|
-
options.modified = true;
|
|
352
|
-
options.idCount++;
|
|
353
|
-
if (!options.usedImports.includes(TComponentName)) {
|
|
354
|
-
options.usedImports.push(TComponentName);
|
|
355
|
-
}
|
|
356
|
-
if (options.createIds) {
|
|
357
|
-
return t.jsxElement(t.jsxOpeningElement(t.jsxIdentifier(TComponentName), [t.jsxAttribute(t.jsxIdentifier('id'), t.stringLiteral(uniqueId))], false), t.jsxClosingElement(t.jsxIdentifier(TComponentName)), [node], false);
|
|
358
|
-
}
|
|
359
|
-
return t.jsxElement(t.jsxOpeningElement(t.jsxIdentifier(TComponentName), [], false), t.jsxClosingElement(t.jsxIdentifier(TComponentName)), [node], false);
|
|
360
|
-
}
|
|
361
|
-
function wrapExpressionWithT(node, options, mark) {
|
|
362
|
-
if (mark) {
|
|
363
|
-
return node;
|
|
364
|
-
}
|
|
365
|
-
const TComponentName = options.TComponent || 'T';
|
|
366
|
-
const uniqueId = `${options.idPrefix}.${options.idCount}`;
|
|
367
|
-
options.modified = true;
|
|
368
|
-
options.idCount++;
|
|
369
|
-
if (!options.usedImports.includes(TComponentName)) {
|
|
370
|
-
options.usedImports.push(TComponentName);
|
|
371
|
-
}
|
|
372
|
-
if (options.createIds) {
|
|
373
|
-
return t.jsxElement(t.jsxOpeningElement(t.jsxIdentifier(TComponentName), [t.jsxAttribute(t.jsxIdentifier('id'), t.stringLiteral(uniqueId))], false), t.jsxClosingElement(t.jsxIdentifier(TComponentName)), [t.jsxExpressionContainer(node)], false);
|
|
374
|
-
}
|
|
375
|
-
return t.jsxElement(t.jsxOpeningElement(t.jsxIdentifier(TComponentName), [], false), t.jsxClosingElement(t.jsxIdentifier(TComponentName)), [t.jsxExpressionContainer(node)], false);
|
|
376
|
-
}
|
|
377
|
-
function wrapWithVar(node, options, mark) {
|
|
378
|
-
if (mark) {
|
|
379
|
-
return node;
|
|
380
|
-
}
|
|
381
|
-
const VarComponentName = options.VarComponent || 'Var';
|
|
382
|
-
options.modified = true;
|
|
383
|
-
if (!options.usedImports.includes(VarComponentName)) {
|
|
384
|
-
options.usedImports.push(VarComponentName);
|
|
385
|
-
}
|
|
386
|
-
return t.jsxElement(t.jsxOpeningElement(t.jsxIdentifier(VarComponentName), [], false), t.jsxClosingElement(t.jsxIdentifier(VarComponentName)), [node], false);
|
|
387
|
-
}
|
|
@@ -1,169 +0,0 @@
|
|
|
1
|
-
import fs from 'node:fs';
|
|
2
|
-
import path from 'node:path';
|
|
3
|
-
import os from 'os';
|
|
4
|
-
import { build } from 'esbuild';
|
|
5
|
-
import flattenDictionary from '../utils/flattenDictionary.js';
|
|
6
|
-
import loadJSON from '../../fs/loadJSON.js';
|
|
7
|
-
import { hashSource } from 'generaltranslation/id';
|
|
8
|
-
import getEntryAndMetadata from '../utils/getEntryAndMetadata.js';
|
|
9
|
-
import { logError } from '../../console/logging.js';
|
|
10
|
-
import { randomUUID } from 'node:crypto';
|
|
11
|
-
export async function createDictionaryUpdates(dictionaryPath, esbuildConfig) {
|
|
12
|
-
let dictionary;
|
|
13
|
-
// ---- HANDLE JSON STRING DICTIONARY ----- //
|
|
14
|
-
if (dictionaryPath.endsWith('.json')) {
|
|
15
|
-
dictionary = flattenDictionary(loadJSON(dictionaryPath) || {});
|
|
16
|
-
}
|
|
17
|
-
// ----- HANDLE REACT DICTIONARY ---- //
|
|
18
|
-
else {
|
|
19
|
-
const result = await build({
|
|
20
|
-
...esbuildConfig,
|
|
21
|
-
entryPoints: [dictionaryPath],
|
|
22
|
-
write: false,
|
|
23
|
-
});
|
|
24
|
-
const bundledCode = result.outputFiles[0].text;
|
|
25
|
-
const tempFilePath = path.join(os.tmpdir(), `bundled-dictionary-${randomUUID()}.js`);
|
|
26
|
-
await fs.promises.writeFile(tempFilePath, bundledCode);
|
|
27
|
-
// Load the module using dynamic import
|
|
28
|
-
let dictionaryModule;
|
|
29
|
-
try {
|
|
30
|
-
dictionaryModule = await import(tempFilePath);
|
|
31
|
-
}
|
|
32
|
-
catch (error) {
|
|
33
|
-
logError(`Failed to load the bundled dictionary code: ${error}`);
|
|
34
|
-
process.exit(1);
|
|
35
|
-
}
|
|
36
|
-
finally {
|
|
37
|
-
// Clean up the temporary file
|
|
38
|
-
await fs.promises.unlink(tempFilePath);
|
|
39
|
-
}
|
|
40
|
-
const unwrappedDictionary = unwrapDictionaryModule(dictionaryModule);
|
|
41
|
-
dictionary = flattenDictionary(unwrappedDictionary);
|
|
42
|
-
}
|
|
43
|
-
// ----- CREATE PARTIAL UPDATES ----- //
|
|
44
|
-
const updates = [];
|
|
45
|
-
for (const id of Object.keys(dictionary)) {
|
|
46
|
-
const { entry, metadata: props, // context, etc.
|
|
47
|
-
} = getEntryAndMetadata(dictionary[id]);
|
|
48
|
-
// Map $context to context
|
|
49
|
-
const context = props?.$context;
|
|
50
|
-
const metadata = {
|
|
51
|
-
id,
|
|
52
|
-
...(context && { context }),
|
|
53
|
-
// This hash isn't actually used by the GT API, just for consistency sake
|
|
54
|
-
hash: hashSource({
|
|
55
|
-
source: entry,
|
|
56
|
-
...(context && { context }),
|
|
57
|
-
...(id && { id }),
|
|
58
|
-
dataFormat: 'ICU',
|
|
59
|
-
}),
|
|
60
|
-
};
|
|
61
|
-
updates.push({
|
|
62
|
-
dataFormat: 'ICU',
|
|
63
|
-
source: entry,
|
|
64
|
-
metadata,
|
|
65
|
-
});
|
|
66
|
-
}
|
|
67
|
-
return updates;
|
|
68
|
-
}
|
|
69
|
-
function unwrapDictionaryModule(mod) {
|
|
70
|
-
let current = mod;
|
|
71
|
-
// Keep unwrapping until we get to the actual dictionary
|
|
72
|
-
while (current && typeof current === 'object') {
|
|
73
|
-
const keys = Object.keys(current);
|
|
74
|
-
// Check if this looks like a module namespace object (has only module-related keys)
|
|
75
|
-
const isModuleNamespace = keys.every((key) => key === 'default' || key === 'module.exports' || key === '__esModule');
|
|
76
|
-
// Check if this is a module with named exports (has 'dictionary' export)
|
|
77
|
-
// Only check for named exports if it's NOT a pure module namespace
|
|
78
|
-
const hasNamedDictionary = !isModuleNamespace &&
|
|
79
|
-
'dictionary' in current &&
|
|
80
|
-
current.dictionary &&
|
|
81
|
-
typeof current.dictionary === 'object' &&
|
|
82
|
-
!Array.isArray(current.dictionary);
|
|
83
|
-
if (hasNamedDictionary) {
|
|
84
|
-
// If there's a named 'dictionary' export, use that
|
|
85
|
-
return current.dictionary;
|
|
86
|
-
}
|
|
87
|
-
else if (isModuleNamespace) {
|
|
88
|
-
// Try to get the default export
|
|
89
|
-
if ('default' in current) {
|
|
90
|
-
let result = current.default;
|
|
91
|
-
// If the default export is a function (getter), call it
|
|
92
|
-
if (typeof result === 'function') {
|
|
93
|
-
try {
|
|
94
|
-
result = result();
|
|
95
|
-
}
|
|
96
|
-
catch {
|
|
97
|
-
// If calling fails, break the loop
|
|
98
|
-
break;
|
|
99
|
-
}
|
|
100
|
-
}
|
|
101
|
-
// If we have a valid object, check if we should continue unwrapping
|
|
102
|
-
if (result && typeof result === 'object' && !Array.isArray(result)) {
|
|
103
|
-
const resultKeys = Object.keys(result);
|
|
104
|
-
// Only continue unwrapping if this looks like a getter-based module layer
|
|
105
|
-
// We should NOT continue if this is just a user dictionary with a 'default' property
|
|
106
|
-
const hasGetterProperties = resultKeys.some((key) => {
|
|
107
|
-
try {
|
|
108
|
-
const descriptor = Object.getOwnPropertyDescriptor(result, key);
|
|
109
|
-
return descriptor && typeof descriptor.get === 'function';
|
|
110
|
-
}
|
|
111
|
-
catch {
|
|
112
|
-
return false;
|
|
113
|
-
}
|
|
114
|
-
});
|
|
115
|
-
if (hasGetterProperties) {
|
|
116
|
-
current = result;
|
|
117
|
-
continue;
|
|
118
|
-
}
|
|
119
|
-
else {
|
|
120
|
-
// This is the actual dictionary, return it
|
|
121
|
-
return result;
|
|
122
|
-
}
|
|
123
|
-
}
|
|
124
|
-
}
|
|
125
|
-
// Try module.exports as fallback
|
|
126
|
-
if ('module.exports' in current) {
|
|
127
|
-
let result = current['module.exports'];
|
|
128
|
-
if (typeof result === 'function') {
|
|
129
|
-
try {
|
|
130
|
-
result = result();
|
|
131
|
-
}
|
|
132
|
-
catch {
|
|
133
|
-
// If calling fails, break the loop
|
|
134
|
-
break;
|
|
135
|
-
}
|
|
136
|
-
}
|
|
137
|
-
if (result && typeof result === 'object' && !Array.isArray(result)) {
|
|
138
|
-
const resultKeys = Object.keys(result);
|
|
139
|
-
// Only continue unwrapping if this looks like a getter-based module layer
|
|
140
|
-
// We should NOT continue if this is just a user dictionary with a 'default' property
|
|
141
|
-
const hasGetterProperties = resultKeys.some((key) => {
|
|
142
|
-
try {
|
|
143
|
-
const descriptor = Object.getOwnPropertyDescriptor(result, key);
|
|
144
|
-
return descriptor && typeof descriptor.get === 'function';
|
|
145
|
-
}
|
|
146
|
-
catch {
|
|
147
|
-
return false;
|
|
148
|
-
}
|
|
149
|
-
});
|
|
150
|
-
if (hasGetterProperties) {
|
|
151
|
-
current = result;
|
|
152
|
-
continue;
|
|
153
|
-
}
|
|
154
|
-
else {
|
|
155
|
-
// This is the actual dictionary, return it
|
|
156
|
-
return result;
|
|
157
|
-
}
|
|
158
|
-
}
|
|
159
|
-
}
|
|
160
|
-
// If we can't unwrap further, break
|
|
161
|
-
break;
|
|
162
|
-
}
|
|
163
|
-
else {
|
|
164
|
-
// This appears to be the actual dictionary object, not a module wrapper
|
|
165
|
-
break;
|
|
166
|
-
}
|
|
167
|
-
}
|
|
168
|
-
return current || {};
|
|
169
|
-
}
|