gtx-cli 1.2.20 → 1.2.21
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +6 -0
- package/dist/console/logging.js +5 -1
- package/dist/fs/getPackageResource.d.ts +1 -0
- package/dist/fs/getPackageResource.js +10 -0
- package/dist/react/data-_gt/addGTIdentifierToSyntaxTree.js +1 -1
- package/dist/react/jsx/utils/parseJsx.js +6 -2
- package/dist/react/jsx/utils/parseStringFunction.d.ts +10 -5
- package/dist/react/jsx/utils/parseStringFunction.js +250 -50
- package/dist/react/parse/createInlineUpdates.js +8 -3
- package/dist/utils/packageJson.d.ts +1 -0
- package/dist/utils/packageJson.js +14 -0
- package/package.json +5 -2
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
# gtx-cli
|
|
2
2
|
|
|
3
|
+
## 1.2.21
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- [#324](https://github.com/generaltranslation/gt/pull/324) [`34a8c97`](https://github.com/generaltranslation/gt/commit/34a8c97a9d4c9efb3b441eecf0f7ea77ccc1ad7a) Thanks [@brian-lou](https://github.com/brian-lou)! - Add support for passing useGT and getGT function callback into other functions
|
|
8
|
+
|
|
3
9
|
## 1.2.20
|
|
4
10
|
|
|
5
11
|
### Patch Changes
|
package/dist/console/logging.js
CHANGED
|
@@ -32,6 +32,7 @@ exports.warnTemplateLiteral = warnTemplateLiteral;
|
|
|
32
32
|
exports.warnTernary = warnTernary;
|
|
33
33
|
const prompts_1 = require("@clack/prompts");
|
|
34
34
|
const chalk_1 = __importDefault(require("chalk"));
|
|
35
|
+
const packageJson_1 = require("../utils/packageJson");
|
|
35
36
|
// Basic logging functions
|
|
36
37
|
function logInfo(message) {
|
|
37
38
|
prompts_1.log.info(message);
|
|
@@ -81,7 +82,10 @@ Y8, 88 88
|
|
|
81
82
|
\`"Y88888P" 88 `));
|
|
82
83
|
}
|
|
83
84
|
function displayInitializingText() {
|
|
84
|
-
|
|
85
|
+
const version = (0, packageJson_1.getCLIVersion)();
|
|
86
|
+
console.log(`\n${chalk_1.default.bold.blue('General Translation, Inc.')}
|
|
87
|
+
${chalk_1.default.gray('https://generaltranslation.com/docs')}
|
|
88
|
+
${chalk_1.default.gray(`CLI Version: ${version}\n`)}`);
|
|
85
89
|
}
|
|
86
90
|
function displayProjectId(projectId) {
|
|
87
91
|
logMessage(chalk_1.default.gray(`Project ID: ${chalk_1.default.bold(projectId)}`));
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function fromPackageRoot(relative: string): string;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.fromPackageRoot = fromPackageRoot;
|
|
7
|
+
const node_path_1 = __importDefault(require("node:path"));
|
|
8
|
+
function fromPackageRoot(relative) {
|
|
9
|
+
return node_path_1.default.resolve(__dirname, `../../`, relative);
|
|
10
|
+
}
|
|
@@ -40,7 +40,7 @@ function addGTIdentifierToSyntaxTree(tree, startingIndex = 0) {
|
|
|
40
40
|
key: (0, getVariableName_1.getVariableName)({ ...props, 'data-_gt': generaltranslation }, 'datetime'),
|
|
41
41
|
};
|
|
42
42
|
}
|
|
43
|
-
else if (type ===
|
|
43
|
+
else if (type === '' || type === 'React.Fragment') {
|
|
44
44
|
generaltranslation.transformation = 'fragment';
|
|
45
45
|
}
|
|
46
46
|
if (type === 'Plural') {
|
|
@@ -128,7 +128,9 @@ function buildJSXTree(importAliases, node, unwrappedExpressions, updates, errors
|
|
|
128
128
|
if (elementIsVariable) {
|
|
129
129
|
parseJSXElement(importAliases, element, updates, errors, file);
|
|
130
130
|
return {
|
|
131
|
-
|
|
131
|
+
// if componentType is undefined, use typeName
|
|
132
|
+
// Basically, if componentType is not a GT component, use typeName such as <div>
|
|
133
|
+
type: componentType ?? typeName,
|
|
132
134
|
props,
|
|
133
135
|
};
|
|
134
136
|
}
|
|
@@ -142,7 +144,9 @@ function buildJSXTree(importAliases, node, unwrappedExpressions, updates, errors
|
|
|
142
144
|
props.children = children;
|
|
143
145
|
}
|
|
144
146
|
return {
|
|
145
|
-
|
|
147
|
+
// if componentType is undefined, use typeName
|
|
148
|
+
// Basically, if componentType is not a GT component, use typeName such as <div>
|
|
149
|
+
type: componentType ?? typeName,
|
|
146
150
|
props,
|
|
147
151
|
};
|
|
148
152
|
}
|
|
@@ -2,11 +2,16 @@ import { NodePath } from '@babel/traverse';
|
|
|
2
2
|
import { Updates } from '../../../types';
|
|
3
3
|
export declare const attributes: string[];
|
|
4
4
|
/**
|
|
5
|
-
*
|
|
6
|
-
* const t = useGT();
|
|
7
|
-
* t('string to translate', { id: 'exampleId', context: 'exampleContext' });
|
|
5
|
+
* Main entry point for parsing translation strings from useGT() and getGT() calls.
|
|
8
6
|
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
7
|
+
* Supports complex patterns including:
|
|
8
|
+
* 1. Direct calls: const t = useGT(); t('hello');
|
|
9
|
+
* 2. Function parameters: const t = useGT(); getInfo(t); where getInfo uses t() internally
|
|
10
|
+
* 3. Cross-file function calls: imported functions that receive t as a parameter
|
|
11
|
+
*
|
|
12
|
+
* Example flow:
|
|
13
|
+
* - const t = useGT();
|
|
14
|
+
* - const { home } = getInfo(t); // getInfo is imported from './constants'
|
|
15
|
+
* - This will parse constants.ts to find t() calls within getInfo function
|
|
11
16
|
*/
|
|
12
17
|
export declare function parseStrings(importName: string, path: NodePath, updates: Updates, errors: string[], file: string): void;
|
|
@@ -43,17 +43,227 @@ const t = __importStar(require("@babel/types"));
|
|
|
43
43
|
const evaluateJsx_1 = require("../evaluateJsx");
|
|
44
44
|
const console_1 = require("../../../console");
|
|
45
45
|
const generator_1 = __importDefault(require("@babel/generator"));
|
|
46
|
+
const node_fs_1 = __importDefault(require("node:fs"));
|
|
47
|
+
const node_path_1 = __importDefault(require("node:path"));
|
|
48
|
+
const parser_1 = require("@babel/parser");
|
|
49
|
+
const traverse_1 = __importDefault(require("@babel/traverse"));
|
|
50
|
+
const tsconfig_paths_1 = require("tsconfig-paths");
|
|
51
|
+
const resolve = __importStar(require("resolve"));
|
|
46
52
|
exports.attributes = ['id', 'context'];
|
|
47
53
|
/**
|
|
48
|
-
*
|
|
49
|
-
*
|
|
50
|
-
* t('string to translate', { id: 'exampleId', context: 'exampleContext' });
|
|
54
|
+
* Processes a single translation function call (e.g., t('hello world', { id: 'greeting' })).
|
|
55
|
+
* Extracts the translatable string content and metadata, then adds it to the updates array.
|
|
51
56
|
*
|
|
52
|
-
*
|
|
53
|
-
*
|
|
57
|
+
* Handles:
|
|
58
|
+
* - String literals: t('hello')
|
|
59
|
+
* - Template literals without expressions: t(`hello`)
|
|
60
|
+
* - Metadata extraction from options object
|
|
61
|
+
* - Error reporting for non-static expressions and template literals with expressions
|
|
62
|
+
*/
|
|
63
|
+
function processTranslationCall(tPath, updates, errors, file) {
|
|
64
|
+
if (tPath.parent.type === 'CallExpression' &&
|
|
65
|
+
tPath.parent.arguments.length > 0) {
|
|
66
|
+
const arg = tPath.parent.arguments[0];
|
|
67
|
+
if (arg.type === 'StringLiteral' ||
|
|
68
|
+
(t.isTemplateLiteral(arg) && arg.expressions.length === 0)) {
|
|
69
|
+
const source = arg.type === 'StringLiteral' ? arg.value : arg.quasis[0].value.raw;
|
|
70
|
+
// split the string into content (same as runtime behavior)
|
|
71
|
+
const content = (0, generaltranslation_1.splitStringToContent)(source);
|
|
72
|
+
// get metadata and id from options
|
|
73
|
+
const options = tPath.parent.arguments[1];
|
|
74
|
+
const metadata = {};
|
|
75
|
+
if (options && options.type === 'ObjectExpression') {
|
|
76
|
+
options.properties.forEach((prop) => {
|
|
77
|
+
if (prop.type === 'ObjectProperty' &&
|
|
78
|
+
prop.key.type === 'Identifier') {
|
|
79
|
+
const attribute = prop.key.name;
|
|
80
|
+
if (exports.attributes.includes(attribute) && t.isExpression(prop.value)) {
|
|
81
|
+
const result = (0, evaluateJsx_1.isStaticExpression)(prop.value);
|
|
82
|
+
if (!result.isStatic) {
|
|
83
|
+
errors.push((0, console_1.warnNonStaticExpressionSync)(file, attribute, (0, generator_1.default)(prop.value).code, `${prop.loc?.start?.line}:${prop.loc?.start?.column}`));
|
|
84
|
+
}
|
|
85
|
+
if (result.isStatic && result.value) {
|
|
86
|
+
metadata[attribute] = result.value;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
updates.push({
|
|
93
|
+
dataFormat: 'JSX',
|
|
94
|
+
source: content,
|
|
95
|
+
metadata,
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
else if (t.isTemplateLiteral(arg)) {
|
|
99
|
+
// warn if template literal
|
|
100
|
+
errors.push((0, console_1.warnTemplateLiteralSync)(file, (0, generator_1.default)(arg).code, `${arg.loc?.start?.line}:${arg.loc?.start?.column}`));
|
|
101
|
+
}
|
|
102
|
+
else {
|
|
103
|
+
errors.push((0, console_1.warnNonStringSync)(file, (0, generator_1.default)(arg).code, `${arg.loc?.start?.line}:${arg.loc?.start?.column}`));
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Finds all usages of a function parameter within a function's scope and processes
|
|
109
|
+
* any translation calls made with that parameter.
|
|
110
|
+
*
|
|
111
|
+
* Example: In function getInfo(t) { return t('hello'); }, this finds the t('hello') call.
|
|
112
|
+
*/
|
|
113
|
+
function findFunctionParameterUsage(functionPath, parameterName, updates, errors, file) {
|
|
114
|
+
// Look for the function body and find all usages of the parameter
|
|
115
|
+
if (functionPath.isFunction()) {
|
|
116
|
+
const functionScope = functionPath.scope;
|
|
117
|
+
const binding = functionScope.bindings[parameterName];
|
|
118
|
+
if (binding) {
|
|
119
|
+
binding.referencePaths.forEach((refPath) => {
|
|
120
|
+
processTranslationCall(refPath, updates, errors, file);
|
|
121
|
+
});
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
/**
|
|
126
|
+
* Resolves import paths to absolute file paths using battle-tested libraries.
|
|
127
|
+
* Handles relative paths, TypeScript paths, and node module resolution.
|
|
128
|
+
*
|
|
129
|
+
* Examples:
|
|
130
|
+
* - './constants' -> '/full/path/to/constants.ts'
|
|
131
|
+
* - '@/components/ui/button' -> '/full/path/to/src/components/ui/button.tsx'
|
|
132
|
+
* - '@shared/utils' -> '/full/path/to/packages/utils/index.ts'
|
|
133
|
+
*/
|
|
134
|
+
function resolveImportPath(currentFile, importPath) {
|
|
135
|
+
const basedir = node_path_1.default.dirname(currentFile);
|
|
136
|
+
const extensions = ['.tsx', '.ts', '.jsx', '.js'];
|
|
137
|
+
// 1. Try tsconfig-paths resolution first (handles TypeScript path mapping)
|
|
138
|
+
const tsConfigResult = (0, tsconfig_paths_1.loadConfig)(basedir);
|
|
139
|
+
if (tsConfigResult.resultType === 'success') {
|
|
140
|
+
const matchPath = (0, tsconfig_paths_1.createMatchPath)(tsConfigResult.absoluteBaseUrl, tsConfigResult.paths, ['main', 'module', 'browser']);
|
|
141
|
+
// First try without any extension
|
|
142
|
+
let tsResolved = matchPath(importPath);
|
|
143
|
+
if (tsResolved && node_fs_1.default.existsSync(tsResolved)) {
|
|
144
|
+
return tsResolved;
|
|
145
|
+
}
|
|
146
|
+
// Then try with each extension
|
|
147
|
+
for (const ext of extensions) {
|
|
148
|
+
tsResolved = matchPath(importPath + ext);
|
|
149
|
+
if (tsResolved && node_fs_1.default.existsSync(tsResolved)) {
|
|
150
|
+
return tsResolved;
|
|
151
|
+
}
|
|
152
|
+
// Also try the resolved path with extension
|
|
153
|
+
tsResolved = matchPath(importPath);
|
|
154
|
+
if (tsResolved) {
|
|
155
|
+
const resolvedWithExt = tsResolved + ext;
|
|
156
|
+
if (node_fs_1.default.existsSync(resolvedWithExt)) {
|
|
157
|
+
return resolvedWithExt;
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
// 2. Fallback to Node.js resolution (handles relative paths and node_modules)
|
|
163
|
+
try {
|
|
164
|
+
return resolve.sync(importPath, { basedir, extensions });
|
|
165
|
+
}
|
|
166
|
+
catch {
|
|
167
|
+
return null;
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
/**
|
|
171
|
+
* Searches for a specific function in a file and analyzes how a particular parameter
|
|
172
|
+
* (at argIndex position) is used within that function for translation calls.
|
|
173
|
+
*
|
|
174
|
+
* Handles multiple function declaration patterns:
|
|
175
|
+
* - function getInfo(t) { ... }
|
|
176
|
+
* - export function getInfo(t) { ... }
|
|
177
|
+
* - const getInfo = (t) => { ... }
|
|
178
|
+
*/
|
|
179
|
+
function findFunctionInFile(filePath, functionName, argIndex, updates, errors) {
|
|
180
|
+
try {
|
|
181
|
+
const code = node_fs_1.default.readFileSync(filePath, 'utf8');
|
|
182
|
+
const ast = (0, parser_1.parse)(code, {
|
|
183
|
+
sourceType: 'module',
|
|
184
|
+
plugins: ['jsx', 'typescript'],
|
|
185
|
+
});
|
|
186
|
+
(0, traverse_1.default)(ast, {
|
|
187
|
+
// Handle function declarations: function getInfo(t) { ... }
|
|
188
|
+
FunctionDeclaration(path) {
|
|
189
|
+
if (path.node.id?.name === functionName &&
|
|
190
|
+
path.node.params.length > argIndex) {
|
|
191
|
+
const param = path.node.params[argIndex];
|
|
192
|
+
if (t.isIdentifier(param)) {
|
|
193
|
+
findFunctionParameterUsage(path, param.name, updates, errors, filePath);
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
},
|
|
197
|
+
// Handle exported function declarations: export function getInfo(t) { ... }
|
|
198
|
+
ExportNamedDeclaration(path) {
|
|
199
|
+
if (path.node.declaration &&
|
|
200
|
+
t.isFunctionDeclaration(path.node.declaration)) {
|
|
201
|
+
const func = path.node.declaration;
|
|
202
|
+
if (func.id?.name === functionName && func.params.length > argIndex) {
|
|
203
|
+
const param = func.params[argIndex];
|
|
204
|
+
if (t.isIdentifier(param)) {
|
|
205
|
+
findFunctionParameterUsage(path.get('declaration'), param.name, updates, errors, filePath);
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
},
|
|
210
|
+
// Handle variable declarations: const getInfo = (t) => { ... }
|
|
211
|
+
VariableDeclarator(path) {
|
|
212
|
+
if (t.isIdentifier(path.node.id) &&
|
|
213
|
+
path.node.id.name === functionName &&
|
|
214
|
+
path.node.init &&
|
|
215
|
+
(t.isArrowFunctionExpression(path.node.init) ||
|
|
216
|
+
t.isFunctionExpression(path.node.init)) &&
|
|
217
|
+
path.node.init.params.length > argIndex) {
|
|
218
|
+
const param = path.node.init.params[argIndex];
|
|
219
|
+
if (t.isIdentifier(param)) {
|
|
220
|
+
const initPath = path.get('init');
|
|
221
|
+
findFunctionParameterUsage(initPath, param.name, updates, errors, filePath);
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
},
|
|
225
|
+
});
|
|
226
|
+
}
|
|
227
|
+
catch {
|
|
228
|
+
// Silently skip files that can't be parsed or accessed
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
/**
|
|
232
|
+
* Main entry point for parsing translation strings from useGT() and getGT() calls.
|
|
233
|
+
*
|
|
234
|
+
* Supports complex patterns including:
|
|
235
|
+
* 1. Direct calls: const t = useGT(); t('hello');
|
|
236
|
+
* 2. Function parameters: const t = useGT(); getInfo(t); where getInfo uses t() internally
|
|
237
|
+
* 3. Cross-file function calls: imported functions that receive t as a parameter
|
|
238
|
+
*
|
|
239
|
+
* Example flow:
|
|
240
|
+
* - const t = useGT();
|
|
241
|
+
* - const { home } = getInfo(t); // getInfo is imported from './constants'
|
|
242
|
+
* - This will parse constants.ts to find t() calls within getInfo function
|
|
54
243
|
*/
|
|
55
244
|
function parseStrings(importName, path, updates, errors, file) {
|
|
56
|
-
|
|
245
|
+
// First, collect all imports in this file to track cross-file function calls
|
|
246
|
+
const importMap = new Map(); // functionName -> importPath
|
|
247
|
+
path.scope.getProgramParent().path.traverse({
|
|
248
|
+
ImportDeclaration(importPath) {
|
|
249
|
+
if (t.isStringLiteral(importPath.node.source)) {
|
|
250
|
+
const importSource = importPath.node.source.value;
|
|
251
|
+
importPath.node.specifiers.forEach((spec) => {
|
|
252
|
+
if (t.isImportSpecifier(spec) &&
|
|
253
|
+
t.isIdentifier(spec.imported) &&
|
|
254
|
+
t.isIdentifier(spec.local)) {
|
|
255
|
+
importMap.set(spec.local.name, importSource);
|
|
256
|
+
}
|
|
257
|
+
else if (t.isImportDefaultSpecifier(spec) &&
|
|
258
|
+
t.isIdentifier(spec.local)) {
|
|
259
|
+
importMap.set(spec.local.name, importSource);
|
|
260
|
+
}
|
|
261
|
+
});
|
|
262
|
+
}
|
|
263
|
+
},
|
|
264
|
+
});
|
|
265
|
+
const referencePaths = path.scope.bindings[importName]?.referencePaths || [];
|
|
266
|
+
for (const refPath of referencePaths) {
|
|
57
267
|
// Find call expressions of useGT() / await getGT()
|
|
58
268
|
const callExpr = refPath.findParent((p) => p.isCallExpression());
|
|
59
269
|
if (callExpr) {
|
|
@@ -68,54 +278,44 @@ function parseStrings(importName, path, updates, errors, file) {
|
|
|
68
278
|
const tFuncName = effectiveParent.node.id.name;
|
|
69
279
|
// Get the scope from the variable declaration
|
|
70
280
|
const variableScope = effectiveParent.scope;
|
|
71
|
-
variableScope.bindings[tFuncName]?.referencePaths
|
|
281
|
+
const tReferencePaths = variableScope.bindings[tFuncName]?.referencePaths || [];
|
|
282
|
+
for (const tPath of tReferencePaths) {
|
|
283
|
+
// Check if this is a direct call to the translation function
|
|
72
284
|
if (tPath.parent.type === 'CallExpression' &&
|
|
73
|
-
tPath.parent.
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
}
|
|
285
|
+
tPath.parent.callee === tPath.node) {
|
|
286
|
+
processTranslationCall(tPath, updates, errors, file);
|
|
287
|
+
}
|
|
288
|
+
// Check if this is being passed as an argument to another function
|
|
289
|
+
else if (tPath.parent.type === 'CallExpression' &&
|
|
290
|
+
t.isExpression(tPath.node) &&
|
|
291
|
+
tPath.parent.arguments.includes(tPath.node)) {
|
|
292
|
+
// Find which parameter position this is
|
|
293
|
+
const argIndex = tPath.parent.arguments.indexOf(tPath.node);
|
|
294
|
+
// Try to find the function definition being called
|
|
295
|
+
const callee = tPath.parent.callee;
|
|
296
|
+
if (t.isIdentifier(callee)) {
|
|
297
|
+
// Look for function declarations or function expressions with this name
|
|
298
|
+
const calleeBinding = tPath.scope.getBinding(callee.name);
|
|
299
|
+
if (calleeBinding && calleeBinding.path.isFunction()) {
|
|
300
|
+
const functionPath = calleeBinding.path;
|
|
301
|
+
const params = functionPath.node.params;
|
|
302
|
+
if (params[argIndex] && t.isIdentifier(params[argIndex])) {
|
|
303
|
+
const paramName = params[argIndex].name;
|
|
304
|
+
findFunctionParameterUsage(functionPath, paramName, updates, errors, file);
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
// If not found locally, check if it's an imported function
|
|
308
|
+
else if (importMap.has(callee.name)) {
|
|
309
|
+
const importPath = importMap.get(callee.name);
|
|
310
|
+
const resolvedPath = resolveImportPath(file, importPath);
|
|
311
|
+
if (resolvedPath) {
|
|
312
|
+
findFunctionInFile(resolvedPath, callee.name, argIndex, updates, errors);
|
|
313
|
+
}
|
|
102
314
|
}
|
|
103
|
-
updates.push({
|
|
104
|
-
dataFormat: 'JSX',
|
|
105
|
-
source: content,
|
|
106
|
-
metadata,
|
|
107
|
-
});
|
|
108
|
-
}
|
|
109
|
-
else if (t.isTemplateLiteral(arg)) {
|
|
110
|
-
// warn if template literal
|
|
111
|
-
errors.push((0, console_1.warnTemplateLiteralSync)(file, (0, generator_1.default)(arg).code, `${arg.loc?.start?.line}:${arg.loc?.start?.column}`));
|
|
112
|
-
}
|
|
113
|
-
else {
|
|
114
|
-
errors.push((0, console_1.warnNonStringSync)(file, (0, generator_1.default)(arg).code, `${arg.loc?.start?.line}:${arg.loc?.start?.column}`));
|
|
115
315
|
}
|
|
116
316
|
}
|
|
117
|
-
}
|
|
317
|
+
}
|
|
118
318
|
}
|
|
119
319
|
}
|
|
120
|
-
}
|
|
320
|
+
}
|
|
121
321
|
}
|
|
@@ -72,14 +72,15 @@ async function createInlineUpdates(options, pkg) {
|
|
|
72
72
|
'Plural',
|
|
73
73
|
];
|
|
74
74
|
const importAliases = {};
|
|
75
|
-
//
|
|
75
|
+
// First pass: collect imports and process translation functions
|
|
76
|
+
const translationPaths = [];
|
|
76
77
|
(0, traverse_1.default)(ast, {
|
|
77
78
|
ImportDeclaration(path) {
|
|
78
79
|
if (path.node.source.value.startsWith(pkg)) {
|
|
79
80
|
const importName = (0, parseAst_1.extractImportName)(path.node, pkg, translationFuncs);
|
|
80
81
|
for (const name of importName) {
|
|
81
82
|
if (name.original === 'useGT' || name.original === 'getGT') {
|
|
82
|
-
(
|
|
83
|
+
translationPaths.push({ name: name.local, path });
|
|
83
84
|
}
|
|
84
85
|
else {
|
|
85
86
|
importAliases[name.local] = name.original;
|
|
@@ -102,7 +103,7 @@ async function createInlineUpdates(options, pkg) {
|
|
|
102
103
|
const importName = (0, parseAst_1.extractImportName)(parentPath.node, pkg, translationFuncs);
|
|
103
104
|
for (const name of importName) {
|
|
104
105
|
if (name.original === 'useGT' || name.original === 'getGT') {
|
|
105
|
-
(
|
|
106
|
+
translationPaths.push({ name: name.local, path: parentPath });
|
|
106
107
|
}
|
|
107
108
|
else {
|
|
108
109
|
importAliases[name.local] = name.original;
|
|
@@ -113,6 +114,10 @@ async function createInlineUpdates(options, pkg) {
|
|
|
113
114
|
}
|
|
114
115
|
},
|
|
115
116
|
});
|
|
117
|
+
// Process translation functions asynchronously
|
|
118
|
+
for (const { name, path } of translationPaths) {
|
|
119
|
+
(0, parseStringFunction_1.parseStrings)(name, path, updates, errors, file);
|
|
120
|
+
}
|
|
116
121
|
// Parse <T> components
|
|
117
122
|
(0, traverse_1.default)(ast, {
|
|
118
123
|
JSXElement(path) {
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
export declare function searchForPackageJson(): Promise<Record<string, any> | null>;
|
|
2
2
|
export declare function getPackageJson(): Promise<Record<string, any>>;
|
|
3
|
+
export declare function getCLIVersion(): string;
|
|
3
4
|
export declare function updatePackageJson(packageJson: Record<string, any>): Promise<void>;
|
|
4
5
|
export declare function isPackageInstalled(packageName: string, packageJson: Record<string, any>, asDevDependency?: boolean, checkBoth?: boolean): boolean;
|
|
5
6
|
export declare function getPackageVersion(packageName: string, packageJson: Record<string, any>): string | undefined;
|
|
@@ -5,6 +5,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
exports.searchForPackageJson = searchForPackageJson;
|
|
7
7
|
exports.getPackageJson = getPackageJson;
|
|
8
|
+
exports.getCLIVersion = getCLIVersion;
|
|
8
9
|
exports.updatePackageJson = updatePackageJson;
|
|
9
10
|
exports.isPackageInstalled = isPackageInstalled;
|
|
10
11
|
exports.getPackageVersion = getPackageVersion;
|
|
@@ -13,6 +14,7 @@ const chalk_1 = __importDefault(require("chalk"));
|
|
|
13
14
|
const node_path_1 = __importDefault(require("node:path"));
|
|
14
15
|
const node_fs_1 = __importDefault(require("node:fs"));
|
|
15
16
|
const console_2 = require("../console");
|
|
17
|
+
const getPackageResource_1 = require("../fs/getPackageResource");
|
|
16
18
|
// search for package.json such that we can run init in non-js projects
|
|
17
19
|
async function searchForPackageJson() {
|
|
18
20
|
// Get the current working directory (where the CLI is being run)
|
|
@@ -45,6 +47,18 @@ async function getPackageJson() {
|
|
|
45
47
|
process.exit(1);
|
|
46
48
|
}
|
|
47
49
|
}
|
|
50
|
+
function getCLIVersion() {
|
|
51
|
+
const packageJsonPath = (0, getPackageResource_1.fromPackageRoot)('package.json');
|
|
52
|
+
if (!node_fs_1.default.existsSync(packageJsonPath)) {
|
|
53
|
+
return 'unknown';
|
|
54
|
+
}
|
|
55
|
+
try {
|
|
56
|
+
return JSON.parse(node_fs_1.default.readFileSync(packageJsonPath, 'utf8')).version;
|
|
57
|
+
}
|
|
58
|
+
catch (error) {
|
|
59
|
+
return 'unknown';
|
|
60
|
+
}
|
|
61
|
+
}
|
|
48
62
|
async function updatePackageJson(packageJson) {
|
|
49
63
|
try {
|
|
50
64
|
await node_fs_1.default.promises.writeFile(node_path_1.default.join(process.cwd(), 'package.json'), JSON.stringify(packageJson, null, 2));
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "gtx-cli",
|
|
3
|
-
"version": "1.2.
|
|
3
|
+
"version": "1.2.21",
|
|
4
4
|
"main": "dist/index.js",
|
|
5
5
|
"bin": "dist/main.js",
|
|
6
6
|
"files": [
|
|
@@ -81,7 +81,9 @@
|
|
|
81
81
|
"form-data": "^4.0.2",
|
|
82
82
|
"generaltranslation": "^6.2.9",
|
|
83
83
|
"open": "^10.1.1",
|
|
84
|
-
"ora": "^8.2.0"
|
|
84
|
+
"ora": "^8.2.0",
|
|
85
|
+
"resolve": "^1.22.10",
|
|
86
|
+
"tsconfig-paths": "^4.2.0"
|
|
85
87
|
},
|
|
86
88
|
"devDependencies": {
|
|
87
89
|
"@biomejs/biome": "1.9.4",
|
|
@@ -91,6 +93,7 @@
|
|
|
91
93
|
"@types/mock-require": "^2.0.3",
|
|
92
94
|
"@types/node": "^22.5.1",
|
|
93
95
|
"@types/react": "^18.3.4",
|
|
96
|
+
"@types/resolve": "^1.20.2",
|
|
94
97
|
"eslint": "^9.20.0",
|
|
95
98
|
"esm": "^3.2.25",
|
|
96
99
|
"prettier": "^3.4.2",
|