gtx-cli 0.0.1 → 0.0.2

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.
Files changed (84) hide show
  1. package/README.md +4 -7
  2. package/dist/api/waitForUpdates.d.ts +1 -0
  3. package/dist/api/waitForUpdates.js +89 -0
  4. package/dist/cli/base.d.ts +3 -0
  5. package/dist/cli/base.js +11 -0
  6. package/dist/cli/next.d.ts +18 -0
  7. package/dist/cli/next.js +162 -0
  8. package/dist/cli/react.d.ts +29 -0
  9. package/dist/cli/react.js +550 -0
  10. package/dist/console/console.d.ts +8 -0
  11. package/dist/console/console.js +65 -0
  12. package/dist/console/errors.d.ts +1 -0
  13. package/dist/console/errors.js +4 -0
  14. package/dist/console/index.d.ts +1 -0
  15. package/dist/console/index.js +2 -0
  16. package/dist/console/warnings.d.ts +7 -0
  17. package/dist/console/warnings.js +47 -0
  18. package/dist/fs/config/loadConfig.d.ts +1 -0
  19. package/dist/fs/config/loadConfig.js +15 -0
  20. package/dist/fs/config/setupConfig.d.ts +8 -0
  21. package/dist/fs/config/setupConfig.js +37 -0
  22. package/dist/fs/config/updateConfig.d.ts +10 -0
  23. package/dist/fs/config/updateConfig.js +33 -0
  24. package/dist/fs/findFilepath.d.ts +15 -0
  25. package/dist/fs/findFilepath.js +49 -0
  26. package/dist/fs/findJsxFilepath.d.ts +7 -0
  27. package/dist/fs/findJsxFilepath.js +36 -0
  28. package/dist/fs/index.d.ts +1 -0
  29. package/dist/fs/index.js +2 -0
  30. package/dist/fs/loadJSON.d.ts +6 -0
  31. package/dist/fs/loadJSON.js +23 -0
  32. package/dist/fs/saveTranslations.d.ts +3 -0
  33. package/dist/fs/saveTranslations.js +57 -0
  34. package/dist/hooks/postProcess.d.ts +4 -0
  35. package/dist/hooks/postProcess.js +101 -0
  36. package/dist/index.d.ts +3 -0
  37. package/dist/index.js +84 -0
  38. package/dist/main.d.ts +2 -0
  39. package/dist/main.js +11 -0
  40. package/dist/next/config/parseNextConfig.d.ts +10 -0
  41. package/dist/next/config/parseNextConfig.js +55 -0
  42. package/dist/next/jsx/utils.d.ts +7 -0
  43. package/dist/next/jsx/utils.js +82 -0
  44. package/dist/next/parse/handleInitGT.d.ts +5 -0
  45. package/dist/next/parse/handleInitGT.js +167 -0
  46. package/dist/next/parse/index.d.ts +4 -0
  47. package/dist/next/parse/index.js +14 -0
  48. package/dist/next/parse/scanForContent.d.ts +13 -0
  49. package/dist/next/parse/scanForContent.js +189 -0
  50. package/dist/react/config/createESBuildConfig.d.ts +2 -0
  51. package/dist/react/config/createESBuildConfig.js +134 -0
  52. package/dist/react/data-_gt/addGTIdentifierToSyntaxTree.d.ts +1 -0
  53. package/dist/react/data-_gt/addGTIdentifierToSyntaxTree.js +92 -0
  54. package/dist/react/jsx/evaluateJsx.d.ts +17 -0
  55. package/dist/react/jsx/evaluateJsx.js +133 -0
  56. package/dist/react/jsx/trimJsxStringChildren.d.ts +7 -0
  57. package/dist/react/jsx/trimJsxStringChildren.js +97 -0
  58. package/dist/react/jsx/utils/parseAst.d.ts +30 -0
  59. package/dist/react/jsx/utils/parseAst.js +320 -0
  60. package/dist/react/jsx/utils/parseJsx.d.ts +13 -0
  61. package/dist/react/jsx/utils/parseJsx.js +236 -0
  62. package/dist/react/jsx/utils/parseStringFunction.d.ts +12 -0
  63. package/dist/react/jsx/utils/parseStringFunction.js +120 -0
  64. package/dist/react/jsx/wrapJsx.d.ts +51 -0
  65. package/dist/react/jsx/wrapJsx.js +407 -0
  66. package/dist/react/parse/createDictionaryUpdates.d.ts +5 -0
  67. package/dist/react/parse/createDictionaryUpdates.js +77 -0
  68. package/dist/react/parse/createInlineUpdates.d.ts +5 -0
  69. package/dist/react/parse/createInlineUpdates.js +141 -0
  70. package/dist/react/parse/index.d.ts +3 -0
  71. package/dist/react/parse/index.js +12 -0
  72. package/dist/react/parse/scanForContent.d.ts +13 -0
  73. package/dist/react/parse/scanForContent.js +200 -0
  74. package/dist/react/types.d.ts +13 -0
  75. package/dist/react/types.js +2 -0
  76. package/dist/react/utils/flattenDictionary.d.ts +10 -0
  77. package/dist/react/utils/flattenDictionary.js +38 -0
  78. package/dist/react/utils/getEntryAndMetadata.d.ts +5 -0
  79. package/dist/react/utils/getEntryAndMetadata.js +14 -0
  80. package/dist/react/utils/getVariableName.d.ts +2 -0
  81. package/dist/react/utils/getVariableName.js +20 -0
  82. package/dist/types.d.ts +58 -0
  83. package/dist/types.js +2 -0
  84. package/package.json +9 -2
@@ -0,0 +1,120 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ var __importDefault = (this && this.__importDefault) || function (mod) {
36
+ return (mod && mod.__esModule) ? mod : { "default": mod };
37
+ };
38
+ Object.defineProperty(exports, "__esModule", { value: true });
39
+ exports.attributes = void 0;
40
+ exports.parseStrings = parseStrings;
41
+ const generaltranslation_1 = require("generaltranslation");
42
+ const t = __importStar(require("@babel/types"));
43
+ const evaluateJsx_1 = require("../evaluateJsx");
44
+ const warnings_1 = require("../../../console/warnings");
45
+ const generator_1 = __importDefault(require("@babel/generator"));
46
+ exports.attributes = ['id', 'context'];
47
+ /**
48
+ * For the following example code:
49
+ * const tx = useGT();
50
+ * tx('string to translate', { id: 'exampleId', context: 'exampleContext' });
51
+ *
52
+ * This function will find all call expressions of useGT(), then find all call expressions
53
+ * of the subsequent tx() calls, and append the content and metadata to the updates array.
54
+ */
55
+ function parseStrings(importName, path, updates, errors, file) {
56
+ var _a;
57
+ (_a = path.scope.bindings[importName]) === null || _a === void 0 ? void 0 : _a.referencePaths.forEach((refPath) => {
58
+ var _a;
59
+ // Find call expressions of useGT() / await getGT()
60
+ const callExpr = refPath.findParent((p) => p.isCallExpression());
61
+ if (callExpr) {
62
+ // Get the parent, handling both await and non-await cases
63
+ const parentPath = callExpr.parentPath;
64
+ const effectiveParent = (parentPath === null || parentPath === void 0 ? void 0 : parentPath.node.type) === 'AwaitExpression'
65
+ ? parentPath.parentPath
66
+ : parentPath;
67
+ if (effectiveParent &&
68
+ effectiveParent.node.type === 'VariableDeclarator' &&
69
+ effectiveParent.node.id.type === 'Identifier') {
70
+ const tFuncName = effectiveParent.node.id.name;
71
+ // Get the scope from the variable declaration
72
+ const variableScope = effectiveParent.scope;
73
+ (_a = variableScope.bindings[tFuncName]) === null || _a === void 0 ? void 0 : _a.referencePaths.forEach((tPath) => {
74
+ if (tPath.parent.type === 'CallExpression' &&
75
+ tPath.parent.arguments.length > 0) {
76
+ const arg = tPath.parent.arguments[0];
77
+ if (arg.type === 'StringLiteral' ||
78
+ (t.isTemplateLiteral(arg) && arg.expressions.length === 0)) {
79
+ const source = arg.type === 'StringLiteral'
80
+ ? arg.value
81
+ : arg.quasis[0].value.raw;
82
+ // split the string into content (same as runtime behavior)
83
+ const content = (0, generaltranslation_1.splitStringToContent)(source);
84
+ // get metadata and id from options
85
+ const options = tPath.parent.arguments[1];
86
+ let metadata = {};
87
+ if (options && options.type === 'ObjectExpression') {
88
+ options.properties.forEach((prop) => {
89
+ if (prop.type === 'ObjectProperty' &&
90
+ prop.key.type === 'Identifier') {
91
+ const attribute = prop.key.name;
92
+ if (exports.attributes.includes(attribute) &&
93
+ t.isExpression(prop.value)) {
94
+ const result = (0, evaluateJsx_1.isStaticExpression)(prop.value);
95
+ if (!result.isStatic) {
96
+ errors.push((0, warnings_1.warnNonStaticExpression)(file, attribute, (0, generator_1.default)(prop.value).code));
97
+ }
98
+ if (result.isStatic && result.value) {
99
+ metadata[attribute] = result.value;
100
+ }
101
+ }
102
+ }
103
+ });
104
+ }
105
+ updates.push({
106
+ type: 'content',
107
+ source: content,
108
+ metadata,
109
+ });
110
+ }
111
+ else if (t.isTemplateLiteral(arg)) {
112
+ // warn if template literal
113
+ errors.push((0, warnings_1.warnTemplateLiteral)(file, (0, generator_1.default)(arg).code));
114
+ }
115
+ }
116
+ });
117
+ }
118
+ }
119
+ });
120
+ }
@@ -0,0 +1,51 @@
1
+ import * as t from '@babel/types';
2
+ import { ImportItem } from './utils/parseAst';
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;
@@ -0,0 +1,407 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.wrapJsxElement = wrapJsxElement;
37
+ exports.handleJsxElement = handleJsxElement;
38
+ const t = __importStar(require("@babel/types"));
39
+ const evaluateJsx_1 = require("./evaluateJsx");
40
+ const warnings_1 = require("../../console/warnings");
41
+ function wrapJsxExpression(node, options, isMeaningful, mark) {
42
+ const expression = t.isParenthesizedExpression(node.expression)
43
+ ? node.expression.expression
44
+ : node.expression;
45
+ // Ignore all template literals - they should not be counted as meaningful
46
+ if (t.isTemplateLiteral(expression) && expression.expressions.length > 0) {
47
+ return {
48
+ node,
49
+ hasMeaningfulContent: false,
50
+ wrappedInT: false,
51
+ };
52
+ }
53
+ // Handle both JSX Elements and Fragments
54
+ if (t.isJSXElement(expression) || t.isJSXFragment(expression)) {
55
+ const result = wrapJsxElement(expression, options, isMeaningful, mark);
56
+ // re-wrap the result in a JSXExpressionContainer
57
+ if (t.isParenthesizedExpression(node.expression)) {
58
+ node.expression.expression = result.node;
59
+ }
60
+ else {
61
+ node.expression = result.node;
62
+ }
63
+ return {
64
+ node,
65
+ hasMeaningfulContent: result.hasMeaningfulContent,
66
+ wrappedInT: result.wrappedInT,
67
+ };
68
+ }
69
+ // Handle conditional expressions (ternary)
70
+ else if (t.isConditionalExpression(expression)) {
71
+ const consequent = t.isParenthesizedExpression(expression.consequent)
72
+ ? expression.consequent.expression
73
+ : expression.consequent;
74
+ const alternate = t.isParenthesizedExpression(expression.alternate)
75
+ ? expression.alternate.expression
76
+ : expression.alternate;
77
+ // Handle consequent
78
+ if (t.isJSXElement(consequent) || t.isJSXFragment(consequent)) {
79
+ const result = handleJsxElement(consequent, options, isMeaningful);
80
+ // Re-insert into parenthesized expression if necessary
81
+ if (t.isParenthesizedExpression(expression.consequent)) {
82
+ expression.consequent.expression = result.node;
83
+ }
84
+ else {
85
+ expression.consequent = result.node;
86
+ }
87
+ // Warn about ternary (should use branch instead)
88
+ if (result.wrappedInT && !mark) {
89
+ options.warnings.push((0, warnings_1.warnTernary)(options.file));
90
+ }
91
+ }
92
+ else if (t.isConditionalExpression(consequent) ||
93
+ t.isLogicalExpression(consequent)) {
94
+ // Recursively handle nested ternary in consequent
95
+ const consequentResult = wrapJsxExpression(t.jsxExpressionContainer(consequent), options, isMeaningful, mark);
96
+ if (t.isJSXExpressionContainer(consequentResult.node) &&
97
+ t.isExpression(consequentResult.node.expression)) {
98
+ expression.consequent = consequentResult.node.expression;
99
+ // Re-insert into parenthesized expression if necessary
100
+ if (t.isParenthesizedExpression(expression.consequent)) {
101
+ expression.consequent.expression = consequentResult.node.expression;
102
+ }
103
+ else {
104
+ expression.consequent = consequentResult.node.expression;
105
+ }
106
+ }
107
+ }
108
+ else if (t.isTemplateLiteral(consequent) &&
109
+ consequent.expressions.length > 0) {
110
+ // Ignore template literals in consequent with expressions (${}), don't wrap them
111
+ // Do nothing
112
+ }
113
+ else {
114
+ if ((0, evaluateJsx_1.isStaticValue)(consequent)) {
115
+ const wrapped = wrapExpressionWithT(consequent, options, false);
116
+ // Re-insert into parenthesized expression if necessary
117
+ if (t.isParenthesizedExpression(expression.consequent)) {
118
+ expression.consequent.expression = wrapped;
119
+ }
120
+ else {
121
+ expression.consequent = wrapped;
122
+ }
123
+ }
124
+ }
125
+ // Handle alternate
126
+ if (t.isJSXElement(alternate) || t.isJSXFragment(alternate)) {
127
+ const result = handleJsxElement(alternate, options, isMeaningful);
128
+ // Re-insert into parenthesized expression if necessary
129
+ if (t.isParenthesizedExpression(expression.alternate)) {
130
+ expression.alternate.expression = result.node;
131
+ }
132
+ else {
133
+ expression.alternate = result.node;
134
+ }
135
+ }
136
+ else if (t.isConditionalExpression(alternate) ||
137
+ t.isLogicalExpression(alternate)) {
138
+ // Recursively handle nested ternary in alternate
139
+ const alternateResult = wrapJsxExpression(t.jsxExpressionContainer(alternate), options, isMeaningful, mark);
140
+ if (t.isJSXExpressionContainer(alternateResult.node) &&
141
+ t.isExpression(alternateResult.node.expression)) {
142
+ expression.alternate = alternateResult.node.expression;
143
+ // Re-insert into parenthesized expression if necessary
144
+ if (t.isParenthesizedExpression(expression.alternate)) {
145
+ expression.alternate.expression = alternateResult.node.expression;
146
+ }
147
+ else {
148
+ expression.alternate = alternateResult.node.expression;
149
+ }
150
+ }
151
+ }
152
+ else if (t.isTemplateLiteral(alternate) &&
153
+ alternate.expressions.length > 0) {
154
+ // Ignore template literals in alternate with expressions (${}), don't wrap them
155
+ // Do nothing
156
+ }
157
+ else {
158
+ if ((0, evaluateJsx_1.isStaticValue)(alternate)) {
159
+ const wrapped = wrapExpressionWithT(alternate, options, false);
160
+ // Re-insert into parenthesized expression if necessary
161
+ if (t.isParenthesizedExpression(expression.alternate)) {
162
+ expression.alternate.expression = wrapped;
163
+ }
164
+ else {
165
+ expression.alternate = wrapped;
166
+ }
167
+ }
168
+ }
169
+ }
170
+ // Handle logical expressions (&& and ||)
171
+ else if (t.isLogicalExpression(expression)) {
172
+ const left = t.isParenthesizedExpression(expression.left)
173
+ ? expression.left.expression
174
+ : expression.left;
175
+ const right = t.isParenthesizedExpression(expression.right)
176
+ ? expression.right.expression
177
+ : expression.right;
178
+ if (t.isJSXElement(left) || t.isJSXFragment(left)) {
179
+ const result = handleJsxElement(left, options, isMeaningful);
180
+ // Re-insert into parenthesized expression if necessary
181
+ if (t.isParenthesizedExpression(expression.left)) {
182
+ expression.left.expression = result.node;
183
+ }
184
+ else {
185
+ expression.left = result.node;
186
+ }
187
+ }
188
+ else if (t.isLogicalExpression(left) || t.isConditionalExpression(left)) {
189
+ // Recursively handle nested logical expressions
190
+ const leftResult = wrapJsxExpression(t.jsxExpressionContainer(left), options, isMeaningful, mark);
191
+ if (t.isJSXExpressionContainer(leftResult.node) &&
192
+ t.isExpression(leftResult.node.expression)) {
193
+ // Re-insert into parenthesized expression if necessary
194
+ if (t.isParenthesizedExpression(expression.left)) {
195
+ expression.left.expression = leftResult.node.expression;
196
+ }
197
+ else {
198
+ expression.left = leftResult.node.expression;
199
+ }
200
+ }
201
+ }
202
+ else if (t.isTemplateLiteral(left) && left.expressions.length > 0) {
203
+ // Ignore template literals with expressions (${}) in left side of logical expression
204
+ // Do nothing - don't wrap them
205
+ }
206
+ else {
207
+ if ((0, evaluateJsx_1.isStaticValue)(left) && expression.operator !== '&&') {
208
+ const wrapped = wrapExpressionWithT(left, options, false);
209
+ // Re-insert into parenthesized expression if necessary
210
+ if (t.isParenthesizedExpression(expression.left)) {
211
+ expression.left.expression = wrapped;
212
+ }
213
+ else {
214
+ expression.left = wrapped;
215
+ }
216
+ }
217
+ }
218
+ if (t.isJSXElement(right) || t.isJSXFragment(right)) {
219
+ const result = handleJsxElement(right, options, isMeaningful);
220
+ // Re-insert into parenthesized expression if necessary
221
+ if (t.isParenthesizedExpression(expression.right)) {
222
+ expression.right.expression = result.node;
223
+ }
224
+ else {
225
+ expression.right = result.node;
226
+ }
227
+ }
228
+ else if (t.isLogicalExpression(right) ||
229
+ t.isConditionalExpression(right)) {
230
+ // Recursively handle nested logical expressions
231
+ const rightResult = wrapJsxExpression(t.jsxExpressionContainer(right), options, isMeaningful, mark);
232
+ if (t.isJSXExpressionContainer(rightResult.node) &&
233
+ t.isExpression(rightResult.node.expression)) {
234
+ // Re-insert into parenthesized expression if necessary
235
+ if (t.isParenthesizedExpression(expression.right)) {
236
+ expression.right.expression = rightResult.node.expression;
237
+ }
238
+ else {
239
+ expression.right = rightResult.node.expression;
240
+ }
241
+ }
242
+ }
243
+ else if (t.isTemplateLiteral(right) && right.expressions.length > 0) {
244
+ // Ignore template literals with expressions (${}) in right side of logical expression
245
+ // Do nothing - don't wrap them
246
+ }
247
+ else {
248
+ if ((0, evaluateJsx_1.isStaticValue)(right)) {
249
+ const wrapped = wrapExpressionWithT(right, options, false);
250
+ // Re-insert into parenthesized expression if necessary
251
+ if (t.isParenthesizedExpression(expression.right)) {
252
+ expression.right.expression = wrapped;
253
+ }
254
+ else {
255
+ expression.right = wrapped;
256
+ }
257
+ }
258
+ }
259
+ }
260
+ const staticCheck = (0, evaluateJsx_1.isStaticExpression)(expression);
261
+ // If the expression is not static or if it's already wrapped in T,
262
+ // wrap with Var
263
+ if (!staticCheck.isStatic) {
264
+ return {
265
+ node: wrapWithVar(node, options, mark),
266
+ hasMeaningfulContent: false,
267
+ wrappedInT: false,
268
+ };
269
+ }
270
+ // If it's a static expression, check if it's meaningful
271
+ return {
272
+ node,
273
+ hasMeaningfulContent: false,
274
+ wrappedInT: false,
275
+ };
276
+ }
277
+ /**
278
+ * Recursively traverse a JSX element and wrap variables with a <Var> component
279
+ * @param node - The JSX element to wrap
280
+ * @param options - Optional component names for T and Var
281
+ * @param isMeaningful - A function to determine if a node is meaningful
282
+ * @returns The wrapped JSX element
283
+ */
284
+ function wrapJsxElement(node, options, isMeaningful, mark) {
285
+ const TComponentName = options.TComponent || 'T';
286
+ const VarComponentName = options.VarComponent || 'Var';
287
+ // Handle both JSX Elements and Fragments
288
+ if (t.isJSXElement(node) || t.isJSXFragment(node)) {
289
+ // For elements, check if it's already a T or Var component
290
+ if (t.isJSXElement(node)) {
291
+ const name = node.openingElement.name;
292
+ if (t.isJSXIdentifier(name) &&
293
+ (name.name === TComponentName || name.name === VarComponentName)) {
294
+ return {
295
+ node,
296
+ hasMeaningfulContent: false,
297
+ wrappedInT: name.name === TComponentName,
298
+ };
299
+ }
300
+ }
301
+ // Process children recursively (DFS postorder)
302
+ let hasMeaningfulContent = false;
303
+ let wrappedInT = false;
304
+ const processedChildren = node.children.map((child) => {
305
+ if (t.isJSXElement(child) || t.isJSXFragment(child)) {
306
+ const result = wrapJsxElement(child, options, isMeaningful, mark);
307
+ hasMeaningfulContent =
308
+ hasMeaningfulContent || result.hasMeaningfulContent;
309
+ wrappedInT = wrappedInT || result.wrappedInT;
310
+ return result.node;
311
+ }
312
+ if (t.isJSXExpressionContainer(child)) {
313
+ const result = wrapJsxExpression(child, options, isMeaningful, mark);
314
+ wrappedInT = wrappedInT || result.wrappedInT;
315
+ // Expressions are never meaningful because they will either:
316
+ // 1. be sub-wrapped in a T (if they contain meaningful content)
317
+ // 2. be wrapped in a Var (if they are not static)
318
+ return result.node;
319
+ }
320
+ const isMeaningfulVal = isMeaningful(child);
321
+ if (isMeaningfulVal) {
322
+ hasMeaningfulContent = true;
323
+ }
324
+ return child;
325
+ });
326
+ node.children = processedChildren;
327
+ return {
328
+ node,
329
+ hasMeaningfulContent: hasMeaningfulContent,
330
+ wrappedInT: wrappedInT,
331
+ };
332
+ }
333
+ // For any other node types, return as-is
334
+ return {
335
+ node,
336
+ hasMeaningfulContent: false,
337
+ wrappedInT: false,
338
+ };
339
+ }
340
+ /**
341
+ * Wraps a JSX element with a <T> component and unique id
342
+ * @param rootNode - The JSX element to wrap
343
+ * @param options - Optional component names for T and Var
344
+ * @param isMeaningful - A function to determine if a node is meaningful
345
+ * @returns The wrapped JSX element
346
+ */
347
+ function handleJsxElement(rootNode, options, isMeaningful) {
348
+ const result = wrapJsxElement(rootNode, options, isMeaningful, true);
349
+ // Only wrap with T at the root level if there's meaningful content
350
+ if (result.hasMeaningfulContent) {
351
+ const output = wrapJsxElement(result.node, options, isMeaningful, false);
352
+ const node = wrapWithT(output.node, options, false);
353
+ return {
354
+ node,
355
+ hasMeaningfulContent: true,
356
+ wrappedInT: true,
357
+ };
358
+ }
359
+ return {
360
+ node: result.node,
361
+ hasMeaningfulContent: false,
362
+ wrappedInT: result.wrappedInT,
363
+ };
364
+ }
365
+ function wrapWithT(node, options, mark) {
366
+ if (mark) {
367
+ return node;
368
+ }
369
+ const TComponentName = options.TComponent || 'T';
370
+ const uniqueId = `${options.idPrefix}.${options.idCount}`;
371
+ options.modified = true;
372
+ options.idCount++;
373
+ if (!options.usedImports.includes(TComponentName)) {
374
+ options.usedImports.push(TComponentName);
375
+ }
376
+ if (options.createIds) {
377
+ return t.jsxElement(t.jsxOpeningElement(t.jsxIdentifier(TComponentName), [t.jsxAttribute(t.jsxIdentifier('id'), t.stringLiteral(uniqueId))], false), t.jsxClosingElement(t.jsxIdentifier(TComponentName)), [node], false);
378
+ }
379
+ return t.jsxElement(t.jsxOpeningElement(t.jsxIdentifier(TComponentName), [], false), t.jsxClosingElement(t.jsxIdentifier(TComponentName)), [node], false);
380
+ }
381
+ function wrapExpressionWithT(node, options, mark) {
382
+ if (mark) {
383
+ return node;
384
+ }
385
+ const TComponentName = options.TComponent || 'T';
386
+ const uniqueId = `${options.idPrefix}.${options.idCount}`;
387
+ options.modified = true;
388
+ options.idCount++;
389
+ if (!options.usedImports.includes(TComponentName)) {
390
+ options.usedImports.push(TComponentName);
391
+ }
392
+ if (options.createIds) {
393
+ 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);
394
+ }
395
+ return t.jsxElement(t.jsxOpeningElement(t.jsxIdentifier(TComponentName), [], false), t.jsxClosingElement(t.jsxIdentifier(TComponentName)), [t.jsxExpressionContainer(node)], false);
396
+ }
397
+ function wrapWithVar(node, options, mark) {
398
+ if (mark) {
399
+ return node;
400
+ }
401
+ const VarComponentName = options.VarComponent || 'Var';
402
+ options.modified = true;
403
+ if (!options.usedImports.includes(VarComponentName)) {
404
+ options.usedImports.push(VarComponentName);
405
+ }
406
+ return t.jsxElement(t.jsxOpeningElement(t.jsxIdentifier(VarComponentName), [], false), t.jsxClosingElement(t.jsxIdentifier(VarComponentName)), [node], false);
407
+ }
@@ -0,0 +1,5 @@
1
+ import { BuildOptions } from 'esbuild';
2
+ import { Options, Updates } from '../../types';
3
+ export default function createDictionaryUpdates(options: Options & {
4
+ dictionary: string;
5
+ }, esbuildConfig: BuildOptions): Promise<Updates>;
@@ -0,0 +1,77 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ var __importDefault = (this && this.__importDefault) || function (mod) {
12
+ return (mod && mod.__esModule) ? mod : { "default": mod };
13
+ };
14
+ Object.defineProperty(exports, "__esModule", { value: true });
15
+ exports.default = createDictionaryUpdates;
16
+ const react_1 = __importDefault(require("react"));
17
+ const fs_1 = __importDefault(require("fs"));
18
+ const path_1 = __importDefault(require("path"));
19
+ const os_1 = __importDefault(require("os"));
20
+ const esbuild_1 = require("esbuild");
21
+ const flattenDictionary_1 = __importDefault(require("../utils/flattenDictionary"));
22
+ const generaltranslation_1 = require("generaltranslation");
23
+ const loadJSON_1 = __importDefault(require("../../fs/loadJSON"));
24
+ const id_1 = require("generaltranslation/id");
25
+ const getEntryAndMetadata_1 = __importDefault(require("../utils/getEntryAndMetadata"));
26
+ function createDictionaryUpdates(options, esbuildConfig) {
27
+ return __awaiter(this, void 0, void 0, function* () {
28
+ let dictionary;
29
+ // ---- HANDLE JSON STRING DICTIONARY ----- //
30
+ if (options.dictionary.endsWith('.json')) {
31
+ dictionary = (0, flattenDictionary_1.default)((0, loadJSON_1.default)(options.dictionary) || {});
32
+ }
33
+ // ----- HANDLE REACT DICTIONARY ---- //
34
+ else {
35
+ const result = yield (0, esbuild_1.build)(Object.assign(Object.assign({}, esbuildConfig), { entryPoints: [options.dictionary], write: false }));
36
+ const bundledCode = result.outputFiles[0].text;
37
+ const tempFilePath = path_1.default.join(os_1.default.tmpdir(), 'bundled-dictionary.js');
38
+ fs_1.default.writeFileSync(tempFilePath, bundledCode);
39
+ globalThis.React = react_1.default;
40
+ // Load the module using require
41
+ let dictionaryModule;
42
+ try {
43
+ dictionaryModule = require(tempFilePath);
44
+ }
45
+ catch (error) {
46
+ console.error(`Failed to load the bundled dictionary code:`, error);
47
+ process.exit(1);
48
+ }
49
+ finally {
50
+ // Clean up the temporary file
51
+ fs_1.default.unlinkSync(tempFilePath);
52
+ }
53
+ dictionary = (0, flattenDictionary_1.default)(dictionaryModule.default ||
54
+ dictionaryModule.dictionary ||
55
+ dictionaryModule);
56
+ }
57
+ if (!Object.keys(dictionary).length)
58
+ throw new Error(`Dictionary filepath provided: "${options.dictionary}", but no entries found.`);
59
+ // ----- CREATE PARTIAL UPDATES ----- //
60
+ let updates = [];
61
+ for (const id of Object.keys(dictionary)) {
62
+ let { entry, metadata: props, // context, etc.
63
+ } = (0, getEntryAndMetadata_1.default)(dictionary[id]);
64
+ const source = (0, generaltranslation_1.splitStringToContent)(entry);
65
+ const context = props === null || props === void 0 ? void 0 : props.context;
66
+ const metadata = Object.assign(Object.assign({ id }, (context && { context })), {
67
+ // This hash isn't actually used by the GT API, just for consistency sake
68
+ hash: (0, id_1.hashJsxChildren)(Object.assign(Object.assign({ source }, (context && { context })), (id && { id }))) });
69
+ updates.push({
70
+ type: 'content',
71
+ source,
72
+ metadata,
73
+ });
74
+ }
75
+ return updates;
76
+ });
77
+ }
@@ -0,0 +1,5 @@
1
+ import { Options, Updates } from '../../types';
2
+ export default function createInlineUpdates(options: Options, pkg: 'gt-react' | 'gt-next'): Promise<{
3
+ updates: Updates;
4
+ errors: string[];
5
+ }>;