gtx-cli 2.5.0-alpha.3 → 2.5.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.
Files changed (39) hide show
  1. package/CHANGELOG.md +29 -0
  2. package/dist/config/generateSettings.js +8 -1
  3. package/dist/console/colors.d.ts +1 -0
  4. package/dist/console/colors.js +3 -0
  5. package/dist/console/index.d.ts +8 -0
  6. package/dist/console/index.js +15 -2
  7. package/dist/react/jsx/evaluateJsx.d.ts +9 -6
  8. package/dist/react/jsx/evaluateJsx.js +33 -5
  9. package/dist/react/jsx/utils/buildImportMap.d.ts +9 -0
  10. package/dist/react/jsx/utils/buildImportMap.js +30 -0
  11. package/dist/react/jsx/utils/constants.d.ts +2 -0
  12. package/dist/react/jsx/utils/constants.js +11 -2
  13. package/dist/react/jsx/utils/getPathsAndAliases.d.ts +17 -0
  14. package/dist/react/jsx/utils/getPathsAndAliases.js +89 -0
  15. package/dist/react/{data-_gt → jsx/utils/jsxParsing}/addGTIdentifierToSyntaxTree.d.ts +2 -1
  16. package/dist/react/{data-_gt → jsx/utils/jsxParsing}/addGTIdentifierToSyntaxTree.js +30 -6
  17. package/dist/react/jsx/utils/jsxParsing/handleChildrenWhitespace.d.ts +6 -0
  18. package/dist/react/jsx/utils/jsxParsing/handleChildrenWhitespace.js +199 -0
  19. package/dist/react/jsx/utils/jsxParsing/multiplication/findMultiplicationNode.d.ts +13 -0
  20. package/dist/react/jsx/utils/jsxParsing/multiplication/findMultiplicationNode.js +42 -0
  21. package/dist/react/jsx/utils/jsxParsing/multiplication/multiplyJsxTree.d.ts +5 -0
  22. package/dist/react/jsx/utils/jsxParsing/multiplication/multiplyJsxTree.js +69 -0
  23. package/dist/react/jsx/utils/jsxParsing/parseJsx.d.ts +61 -0
  24. package/dist/react/jsx/utils/jsxParsing/parseJsx.js +1015 -0
  25. package/dist/react/jsx/utils/jsxParsing/parseTProps.d.ts +8 -0
  26. package/dist/react/jsx/utils/jsxParsing/parseTProps.js +47 -0
  27. package/dist/react/jsx/utils/jsxParsing/removeNullChildrenFields.d.ts +2 -0
  28. package/dist/react/jsx/utils/jsxParsing/removeNullChildrenFields.js +61 -0
  29. package/dist/react/jsx/utils/jsxParsing/types.d.ts +48 -0
  30. package/dist/react/jsx/utils/jsxParsing/types.js +34 -0
  31. package/dist/react/jsx/utils/parseStringFunction.js +4 -141
  32. package/dist/react/jsx/utils/resolveImportPath.d.ts +11 -0
  33. package/dist/react/jsx/utils/resolveImportPath.js +111 -0
  34. package/dist/react/parse/createInlineUpdates.js +19 -70
  35. package/package.json +2 -2
  36. package/dist/react/jsx/trimJsxStringChildren.d.ts +0 -7
  37. package/dist/react/jsx/trimJsxStringChildren.js +0 -122
  38. package/dist/react/jsx/utils/parseJsx.d.ts +0 -21
  39. package/dist/react/jsx/utils/parseJsx.js +0 -259
@@ -0,0 +1,199 @@
1
+ import { isAcceptedPluralForm } from 'generaltranslation/internal';
2
+ import { isElementNode, isExpressionNode, isMultiplicationNode, } from './types.js';
3
+ // JSX whitespace characters (space, tab, newline, carriage return)
4
+ // Does NOT include non-breaking space (U+00A0) which should be preserved
5
+ const isJsxWhitespace = (char) => {
6
+ return char === ' ' || char === '\t' || char === '\n' || char === '\r';
7
+ };
8
+ const trimJsxWhitespace = (str, side = 'both') => {
9
+ let start = 0;
10
+ let end = str.length;
11
+ if (side === 'start' || side === 'both') {
12
+ while (start < end && isJsxWhitespace(str[start])) {
13
+ start++;
14
+ }
15
+ }
16
+ if (side === 'end' || side === 'both') {
17
+ while (end > start && isJsxWhitespace(str[end - 1])) {
18
+ end--;
19
+ }
20
+ }
21
+ return str.slice(start, end);
22
+ };
23
+ const hasNonJsxWhitespace = (str) => {
24
+ for (const char of str) {
25
+ if (!isJsxWhitespace(char))
26
+ return true;
27
+ }
28
+ return false;
29
+ };
30
+ export function trimJsxStringChild(child) {
31
+ if (!child.includes('\n') && !child.includes('\r')) {
32
+ return child;
33
+ }
34
+ // Normalize line endings to \n for consistency across platforms
35
+ let result = child.replace(/\r\n|\r/g, '\n');
36
+ // Collapse multiple spaces/tabs into a single space (but not nbsp)
37
+ result = result.replace(/[\t ]+/g, ' ');
38
+ let newResult = '';
39
+ let newline = false;
40
+ for (const char of result) {
41
+ if (char === '\n') {
42
+ if (hasNonJsxWhitespace(newResult))
43
+ newResult += ' ';
44
+ else
45
+ newResult = '';
46
+ newline = true;
47
+ continue;
48
+ }
49
+ if (!newline) {
50
+ newResult += char;
51
+ continue;
52
+ }
53
+ if (isJsxWhitespace(char))
54
+ continue;
55
+ newResult += char;
56
+ newline = false;
57
+ }
58
+ if (newline)
59
+ newResult = trimJsxWhitespace(newResult, 'end');
60
+ result = newResult;
61
+ // Collapse multiple spaces/tabs into a single space (but not nbsp)
62
+ result = result.replace(/[\t ]+/g, ' ');
63
+ return result;
64
+ }
65
+ /**
66
+ * Handles whitespace in children of a JSX element, and strips elements
67
+ * @param currentTree - The current tree to handle
68
+ * @returns The processed tree with whitespace handled
69
+ *
70
+ * For unresolved functions, we just make it so that Static has no children
71
+ *
72
+ * The typing was so much worse before this. Don't come for me. All I did was enforce the typing.
73
+ */
74
+ export function handleChildrenWhitespace(currentTree, parentNodeType = undefined) {
75
+ if (Array.isArray(currentTree)) {
76
+ const childrenTypes = currentTree.map((child) => {
77
+ if (typeof child === 'string')
78
+ return 'text';
79
+ if (isExpressionNode(child))
80
+ return 'expression';
81
+ if (isElementNode(child))
82
+ return 'element';
83
+ if (isMultiplicationNode(child))
84
+ return 'multiplication';
85
+ return 'other';
86
+ });
87
+ const newChildren = [];
88
+ currentTree.forEach((child, index) => {
89
+ switch (childrenTypes[index]) {
90
+ case 'text':
91
+ const textNode = child;
92
+ if (parentNodeType === 'multiplication') {
93
+ // This should be treated like a new tree (no parent here b/c its a new tree)
94
+ const result = handleChildrenWhitespace(textNode);
95
+ if (result)
96
+ newChildren.push(result);
97
+ }
98
+ else {
99
+ const string = trimJsxStringChild(textNode);
100
+ if (string)
101
+ newChildren.push(string);
102
+ }
103
+ break;
104
+ case 'expression':
105
+ // Strip expressions
106
+ const result = child.result;
107
+ if (isMultiplicationNode(result)) {
108
+ newChildren.push(handleChildrenWhitespace(result));
109
+ }
110
+ else if (typeof result === 'string') {
111
+ newChildren.push(result);
112
+ }
113
+ else {
114
+ // other case
115
+ newChildren.push(result);
116
+ }
117
+ break;
118
+ case 'element':
119
+ const newElement = handleChildrenWhitespace(child);
120
+ newChildren.push(newElement);
121
+ break;
122
+ case 'multiplication':
123
+ // I dont think this case is possible, at least in the array case
124
+ // Can only be child of element or multiplication nodes
125
+ newChildren.push({
126
+ nodeType: 'multiplication',
127
+ branches: handleChildrenWhitespace(child.branches, 'multiplication'),
128
+ });
129
+ break;
130
+ case 'other':
131
+ // Return number or boolean or null
132
+ newChildren.push(child);
133
+ break;
134
+ }
135
+ });
136
+ if (parentNodeType === 'multiplication') {
137
+ // Return the branches as an array
138
+ return newChildren;
139
+ }
140
+ return newChildren.length === 1 ? newChildren[0] : newChildren;
141
+ }
142
+ else if (isElementNode(currentTree)) {
143
+ // Process all props recursively
144
+ // What if there is a different component sharing the same name?
145
+ const elementIsPlural = currentTree.type === 'Plural';
146
+ const elementIsBranch = currentTree.type === 'Branch';
147
+ const processedProps = !currentTree.props
148
+ ? undefined
149
+ : Object.fromEntries(Object.entries(currentTree.props).map(([key, value]) => {
150
+ let shouldProcess = false;
151
+ // Process children
152
+ if (key === 'children')
153
+ shouldProcess = true;
154
+ // Process plural children
155
+ if (elementIsPlural && isAcceptedPluralForm(key))
156
+ shouldProcess = true;
157
+ // Process branch children
158
+ if (elementIsBranch && key !== 'branch')
159
+ shouldProcess = true;
160
+ // Do not process raw strings
161
+ if (typeof value === 'string' && key !== 'children')
162
+ shouldProcess = false;
163
+ // Process props
164
+ if (!shouldProcess) {
165
+ return [key, value];
166
+ }
167
+ return [key, handleChildrenWhitespace(value)];
168
+ }));
169
+ return {
170
+ nodeType: 'element',
171
+ type: currentTree.type,
172
+ ...(processedProps ? { props: processedProps } : {}),
173
+ };
174
+ }
175
+ else if (isExpressionNode(currentTree)) {
176
+ // Strip expression
177
+ const result = currentTree.result;
178
+ if (isMultiplicationNode(result)) {
179
+ return handleChildrenWhitespace(result);
180
+ }
181
+ else if (typeof result === 'string') {
182
+ return result;
183
+ }
184
+ else {
185
+ return result;
186
+ }
187
+ }
188
+ else if (isMultiplicationNode(currentTree)) {
189
+ return {
190
+ nodeType: 'multiplication',
191
+ branches: handleChildrenWhitespace(currentTree.branches, 'multiplication'),
192
+ };
193
+ }
194
+ else if (typeof currentTree === 'string') {
195
+ return trimJsxStringChild(currentTree);
196
+ }
197
+ // null or number or boolean
198
+ return currentTree;
199
+ }
@@ -0,0 +1,13 @@
1
+ import { WhitespaceJsxTreeResult, WhitespaceMultiplicationNode } from '../types.js';
2
+ export type MultiplicationNodeResult = {
3
+ parent: any | undefined;
4
+ key: string | undefined;
5
+ node: WhitespaceMultiplicationNode;
6
+ };
7
+ /**
8
+ * Finds the immediate multiplication node from the given root (eg no nested multiplication nodes)
9
+ * TODO: I am sure there is some optimization to be done here
10
+ *
11
+ * Maybe there is an optimization here with caching used paths btwn calls
12
+ */
13
+ export declare function findMultiplicationNode(root: WhitespaceJsxTreeResult | WhitespaceMultiplicationNode | (WhitespaceJsxTreeResult | WhitespaceMultiplicationNode)[]): MultiplicationNodeResult | undefined;
@@ -0,0 +1,42 @@
1
+ import { isWhitespaceMultiplicationNode, isWhitespaceJsxTree, } from '../types.js';
2
+ /**
3
+ * Finds the immediate multiplication node from the given root (eg no nested multiplication nodes)
4
+ * TODO: I am sure there is some optimization to be done here
5
+ *
6
+ * Maybe there is an optimization here with caching used paths btwn calls
7
+ */
8
+ export function findMultiplicationNode(root) {
9
+ // Entry point
10
+ return handleChildren(root, undefined, undefined);
11
+ // Helper function to handle children
12
+ function handleChildren(curr, parent, key) {
13
+ if (Array.isArray(curr)) {
14
+ for (const [index, child] of Object.entries(curr)) {
15
+ const result = handleChild(child, curr, index);
16
+ if (result)
17
+ return result;
18
+ }
19
+ return undefined;
20
+ }
21
+ else {
22
+ return handleChild(curr, parent, key);
23
+ }
24
+ }
25
+ // Helper function to handle a single child
26
+ function handleChild(curr, parent, key) {
27
+ if (isWhitespaceMultiplicationNode(curr)) {
28
+ return { parent, key, node: curr };
29
+ }
30
+ else if (isWhitespaceJsxTree(curr)) {
31
+ if (curr.props?.children) {
32
+ return handleChildren(curr.props.children, curr.props, 'children');
33
+ }
34
+ else {
35
+ return undefined;
36
+ }
37
+ }
38
+ else {
39
+ return undefined;
40
+ }
41
+ }
42
+ }
@@ -0,0 +1,5 @@
1
+ import { MultipliedTreeNode, WhitespaceJsxTreeResult } from '../types.js';
2
+ /**
3
+ * Given a JSX tree, multiply the static function nodes
4
+ */
5
+ export declare function multiplyJsxTree(tree: WhitespaceJsxTreeResult | WhitespaceJsxTreeResult[]): MultipliedTreeNode[];
@@ -0,0 +1,69 @@
1
+ import { findMultiplicationNode } from './findMultiplicationNode.js';
2
+ /**
3
+ * Given a JSX tree, multiply the static function nodes
4
+ */
5
+ export function multiplyJsxTree(tree) {
6
+ if (!Array.isArray(tree)) {
7
+ return multiplyBranches([tree]);
8
+ }
9
+ else {
10
+ // when tree is an array, this is just sibbling elements within the <T>, so we need to treat them as a single branch
11
+ const wrapperElement = {
12
+ nodeType: 'element',
13
+ type: 'T',
14
+ props: {
15
+ children: tree,
16
+ },
17
+ };
18
+ // Multiply the wrapper element
19
+ const multipliedBranches = multiplyBranches([
20
+ wrapperElement,
21
+ ]);
22
+ // Unwrap the branches
23
+ return multipliedBranches.map((branch) => branch.props.children);
24
+ }
25
+ }
26
+ /**
27
+ * Given a list of branches, multiply recursively (DFS)
28
+ * @param branches
29
+ */
30
+ function multiplyBranches(branches) {
31
+ // Queue of branches to process
32
+ const branchQueue = branches;
33
+ // Finalized branches
34
+ const newBranches = [];
35
+ // Process branches until exhausted
36
+ while (branchQueue.length) {
37
+ // Pop the next branch
38
+ const branch = branchQueue.shift();
39
+ // Get closest multiplication node
40
+ const currentNode = findMultiplicationNode(branch);
41
+ // No multiplication nodes, just add the branch to the final list
42
+ if (!currentNode) {
43
+ newBranches.push(branch);
44
+ continue;
45
+ }
46
+ const { node, parent, key } = currentNode;
47
+ // Recursive call
48
+ const subBranches = multiplyBranches(node.branches);
49
+ // For every sub branch, create a new cloned branch
50
+ for (const subBranch of subBranches) {
51
+ // Placeholder for the new branch
52
+ let newBranch = undefined;
53
+ // Create a clone of the original with the sub branch swapped in
54
+ if (parent === undefined || key === undefined) {
55
+ // This means the subBranch directly replaces the branch itself
56
+ newBranches.push(subBranch);
57
+ }
58
+ else {
59
+ // Replace the multiplication node with the sub branch
60
+ parent[key] = subBranch;
61
+ // eslint-disable-next-line no-undef
62
+ newBranch = structuredClone(branch);
63
+ // Add the new branch to the list
64
+ branchQueue.push(newBranch);
65
+ }
66
+ }
67
+ }
68
+ return newBranches;
69
+ }
@@ -0,0 +1,61 @@
1
+ import { Updates } from '../../../../types/index.js';
2
+ import * as t from '@babel/types';
3
+ import { NodePath } from '@babel/traverse';
4
+ import { ParsingConfigOptions } from '../../../../types/parsing.js';
5
+ import traverseModule from '@babel/traverse';
6
+ import { JsxTree } from './types.js';
7
+ /**
8
+ * Entry point for JSX parsing
9
+ */
10
+ export declare function parseTranslationComponent({ originalName, importAliases, localName, path, updates, errors, warnings, file, parsingOptions, pkg, }: {
11
+ ast: any;
12
+ pkg: 'gt-react' | 'gt-next';
13
+ originalName: string;
14
+ importAliases: Record<string, string>;
15
+ path: traverseModule.NodePath<traverseModule.Node>;
16
+ localName: string;
17
+ updates: Updates;
18
+ errors: string[];
19
+ warnings: Set<string>;
20
+ file: string;
21
+ parsingOptions: ParsingConfigOptions;
22
+ }): void;
23
+ /**
24
+ * Builds a JSX tree from a given node, recursively handling children.
25
+ * @param node - The node to build the tree from
26
+ * @param unwrappedExpressions - An array to store unwrapped expressions
27
+ * @param updates - The updates array
28
+ * @param errors - The errors array
29
+ * @param file - The file name
30
+ * @param insideT - Whether the current node is inside a <T> component
31
+ * @returns The built JSX tree
32
+ */
33
+ export declare function buildJSXTree({ importAliases, node, unwrappedExpressions, visited, callStack, updates, errors, warnings, file, insideT, parsingOptions, scopeNode, importedFunctionsMap, pkg, }: {
34
+ importAliases: Record<string, string>;
35
+ node: any;
36
+ callStack: string[];
37
+ unwrappedExpressions: string[];
38
+ visited: Set<string>;
39
+ updates: Updates;
40
+ errors: string[];
41
+ warnings: Set<string>;
42
+ file: string;
43
+ insideT: boolean;
44
+ parsingOptions: ParsingConfigOptions;
45
+ scopeNode: NodePath;
46
+ importedFunctionsMap: Map<string, string>;
47
+ pkg: 'gt-react' | 'gt-next';
48
+ }): JsxTree;
49
+ export declare function parseJSXElement({ importAliases, node, originalName, pkg, updates, errors, warnings, file, parsingOptions, scopeNode, importedFunctionsMap, }: {
50
+ importAliases: Record<string, string>;
51
+ node: t.JSXElement;
52
+ originalName: string;
53
+ pkg: 'gt-react' | 'gt-next';
54
+ updates: Updates;
55
+ errors: string[];
56
+ warnings: Set<string>;
57
+ file: string;
58
+ parsingOptions: ParsingConfigOptions;
59
+ scopeNode: NodePath<t.JSXElement>;
60
+ importedFunctionsMap: Map<string, string>;
61
+ }): void;