gtx-cli 2.1.8-alpha.1 → 2.1.8

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.
@@ -1,6 +1,3 @@
1
- export declare const MSG_TRANSLATION_HOOK = "msg";
2
- export declare const INLINE_TRANSLATION_HOOK = "useGT";
3
- export declare const INLINE_TRANSLATION_HOOK_ASYNC = "getGT";
4
1
  export declare const GT_TRANSLATION_FUNCS: string[];
5
2
  export declare const VARIABLE_COMPONENTS: string[];
6
3
  export declare const GT_ATTRIBUTES_WITH_SUGAR: string[];
@@ -1,11 +1,7 @@
1
- export const MSG_TRANSLATION_HOOK = 'msg';
2
- export const INLINE_TRANSLATION_HOOK = 'useGT';
3
- export const INLINE_TRANSLATION_HOOK_ASYNC = 'getGT';
4
1
  // GT translation functions
5
2
  export const GT_TRANSLATION_FUNCS = [
6
- INLINE_TRANSLATION_HOOK,
7
- INLINE_TRANSLATION_HOOK_ASYNC,
8
- MSG_TRANSLATION_HOOK,
3
+ 'useGT',
4
+ 'getGT',
9
5
  'T',
10
6
  'Var',
11
7
  'DateTime',
@@ -1,6 +1,6 @@
1
1
  import * as t from '@babel/types';
2
2
  import { isStaticExpression } from '../evaluateJsx.js';
3
- import { GT_ATTRIBUTES_WITH_SUGAR, MSG_TRANSLATION_HOOK, INLINE_TRANSLATION_HOOK, INLINE_TRANSLATION_HOOK_ASYNC, mapAttributeName, } from './constants.js';
3
+ import { GT_ATTRIBUTES_WITH_SUGAR, mapAttributeName } from './constants.js';
4
4
  import { warnNonStaticExpressionSync, warnNonStringSync, warnTemplateLiteralSync, warnAsyncUseGT, warnSyncGetGT, } from '../../../console/index.js';
5
5
  import generateModule from '@babel/generator';
6
6
  import traverseModule from '@babel/traverse';
@@ -22,7 +22,7 @@ import resolve from 'resolve';
22
22
  * - Metadata extraction from options object
23
23
  * - Error reporting for non-static expressions and template literals with expressions
24
24
  */
25
- function processTranslationCall(tPath, updates, errors, file, ignoreAdditionalData) {
25
+ function processTranslationCall(tPath, updates, errors, file) {
26
26
  if (tPath.parent.type === 'CallExpression' &&
27
27
  tPath.parent.arguments.length > 0) {
28
28
  const arg = tPath.parent.arguments[0];
@@ -43,7 +43,7 @@ function processTranslationCall(tPath, updates, errors, file, ignoreAdditionalDa
43
43
  if (!result.isStatic) {
44
44
  errors.push(warnNonStaticExpressionSync(file, attribute, generate(prop.value).code, `${prop.loc?.start?.line}:${prop.loc?.start?.column}`));
45
45
  }
46
- if (result.isStatic && result.value && !ignoreAdditionalData) {
46
+ if (result.isStatic && result.value) {
47
47
  // Map $id and $context to id and context
48
48
  metadata[mapAttributeName(attribute)] = result.value;
49
49
  }
@@ -145,11 +145,11 @@ function resolveVariableAliases(scope, variableName, visited = new Set()) {
145
145
  * This covers both direct translation calls (t('hello')) and prop drilling
146
146
  * where the translation callback is passed to other functions (getData(t)).
147
147
  */
148
- function handleFunctionCall(tPath, updates, errors, file, importMap, ignoreAdditionalData) {
148
+ function handleFunctionCall(tPath, updates, errors, file, importMap) {
149
149
  if (tPath.parent.type === 'CallExpression' &&
150
150
  tPath.parent.callee === tPath.node) {
151
151
  // Direct translation call: t('hello')
152
- processTranslationCall(tPath, updates, errors, file, ignoreAdditionalData);
152
+ processTranslationCall(tPath, updates, errors, file);
153
153
  }
154
154
  else if (tPath.parent.type === 'CallExpression' &&
155
155
  t.isExpression(tPath.node) &&
@@ -161,7 +161,7 @@ function handleFunctionCall(tPath, updates, errors, file, importMap, ignoreAddit
161
161
  const calleeBinding = tPath.scope.getBinding(callee.name);
162
162
  if (calleeBinding && calleeBinding.path.isFunction()) {
163
163
  const functionPath = calleeBinding.path;
164
- processFunctionIfMatches(callee.name, argIndex, functionPath.node, functionPath, updates, errors, file, ignoreAdditionalData);
164
+ processFunctionIfMatches(callee.name, argIndex, functionPath.node, functionPath, updates, errors, file);
165
165
  }
166
166
  // Handle arrow functions assigned to variables: const getData = (t) => {...}
167
167
  else if (calleeBinding &&
@@ -170,14 +170,14 @@ function handleFunctionCall(tPath, updates, errors, file, importMap, ignoreAddit
170
170
  (t.isArrowFunctionExpression(calleeBinding.path.node.init) ||
171
171
  t.isFunctionExpression(calleeBinding.path.node.init))) {
172
172
  const initPath = calleeBinding.path.get('init');
173
- processFunctionIfMatches(callee.name, argIndex, calleeBinding.path.node.init, initPath, updates, errors, file, ignoreAdditionalData);
173
+ processFunctionIfMatches(callee.name, argIndex, calleeBinding.path.node.init, initPath, updates, errors, file);
174
174
  }
175
175
  // If not found locally, check if it's an imported function
176
176
  else if (importMap.has(callee.name)) {
177
177
  const importPath = importMap.get(callee.name);
178
178
  const resolvedPath = resolveImportPath(file, importPath);
179
179
  if (resolvedPath) {
180
- findFunctionInFile(resolvedPath, callee.name, argIndex, updates, errors, ignoreAdditionalData);
180
+ findFunctionInFile(resolvedPath, callee.name, argIndex, updates, errors);
181
181
  }
182
182
  }
183
183
  }
@@ -188,12 +188,12 @@ function handleFunctionCall(tPath, updates, errors, file, importMap, ignoreAddit
188
188
  * Validates the function has enough parameters and traces how the translation callback
189
189
  * is used within that function's body.
190
190
  */
191
- function processFunctionIfMatches(_functionName, argIndex, functionNode, functionPath, updates, errors, filePath, ignoreAdditionalData) {
191
+ function processFunctionIfMatches(_functionName, argIndex, functionNode, functionPath, updates, errors, filePath) {
192
192
  if (functionNode.params.length > argIndex) {
193
193
  const param = functionNode.params[argIndex];
194
194
  const paramName = extractParameterName(param);
195
195
  if (paramName) {
196
- findFunctionParameterUsage(functionPath, paramName, updates, errors, filePath, ignoreAdditionalData);
196
+ findFunctionParameterUsage(functionPath, paramName, updates, errors, filePath);
197
197
  }
198
198
  }
199
199
  }
@@ -205,7 +205,7 @@ function processFunctionIfMatches(_functionName, argIndex, functionNode, functio
205
205
  * Example: In function getInfo(t) { return t('hello'); }, this finds the t('hello') call.
206
206
  * Example: In function getData(t) { return getFooter(t); }, this finds and traces into getFooter.
207
207
  */
208
- function findFunctionParameterUsage(functionPath, parameterName, updates, errors, file, ignoreAdditionalData) {
208
+ function findFunctionParameterUsage(functionPath, parameterName, updates, errors, file) {
209
209
  // Look for the function body and find all usages of the parameter
210
210
  if (functionPath.isFunction()) {
211
211
  const functionScope = functionPath.scope;
@@ -220,7 +220,7 @@ function findFunctionParameterUsage(functionPath, parameterName, updates, errors
220
220
  const binding = functionScope.bindings[name];
221
221
  if (binding) {
222
222
  binding.referencePaths.forEach((refPath) => {
223
- handleFunctionCall(refPath, updates, errors, file, importMap, ignoreAdditionalData);
223
+ handleFunctionCall(refPath, updates, errors, file, importMap);
224
224
  });
225
225
  }
226
226
  });
@@ -299,7 +299,7 @@ function resolveImportPath(currentFile, importPath) {
299
299
  * - export function getInfo(t) { ... }
300
300
  * - const getInfo = (t) => { ... }
301
301
  */
302
- function findFunctionInFile(filePath, functionName, argIndex, updates, errors, ignoreAdditionalData) {
302
+ function findFunctionInFile(filePath, functionName, argIndex, updates, errors) {
303
303
  try {
304
304
  const code = fs.readFileSync(filePath, 'utf8');
305
305
  const ast = parse(code, {
@@ -310,7 +310,7 @@ function findFunctionInFile(filePath, functionName, argIndex, updates, errors, i
310
310
  // Handle function declarations: function getInfo(t) { ... }
311
311
  FunctionDeclaration(path) {
312
312
  if (path.node.id?.name === functionName) {
313
- processFunctionIfMatches(functionName, argIndex, path.node, path, updates, errors, filePath, ignoreAdditionalData);
313
+ processFunctionIfMatches(functionName, argIndex, path.node, path, updates, errors, filePath);
314
314
  }
315
315
  },
316
316
  // Handle variable declarations: const getInfo = (t) => { ... }
@@ -321,7 +321,7 @@ function findFunctionInFile(filePath, functionName, argIndex, updates, errors, i
321
321
  (t.isArrowFunctionExpression(path.node.init) ||
322
322
  t.isFunctionExpression(path.node.init))) {
323
323
  const initPath = path.get('init');
324
- processFunctionIfMatches(functionName, argIndex, path.node.init, initPath, updates, errors, filePath, ignoreAdditionalData);
324
+ processFunctionIfMatches(functionName, argIndex, path.node.init, initPath, updates, errors, filePath);
325
325
  }
326
326
  },
327
327
  });
@@ -348,33 +348,21 @@ export function parseStrings(importName, originalName, path, updates, errors, fi
348
348
  const importMap = buildImportMap(path.scope.getProgramParent().path);
349
349
  const referencePaths = path.scope.bindings[importName]?.referencePaths || [];
350
350
  for (const refPath of referencePaths) {
351
- // Handle msg() calls directly without variable assignment
352
- if (originalName === MSG_TRANSLATION_HOOK) {
353
- const ignoreAdditionalData = true;
354
- // Check if this is a direct call to msg('string')
355
- if (refPath.parent.type === 'CallExpression' &&
356
- refPath.parent.callee === refPath.node) {
357
- processTranslationCall(refPath, updates, errors, file, ignoreAdditionalData);
358
- }
359
- continue;
360
- }
361
- // Handle useGT() and getGT() calls that need variable assignment
351
+ // Find call expressions of useGT() / await getGT()
362
352
  const callExpr = refPath.findParent((p) => p.isCallExpression());
363
353
  if (callExpr) {
364
354
  // Get the parent, handling both await and non-await cases
365
355
  const parentPath = callExpr.parentPath;
366
356
  const parentFunction = refPath.getFunctionParent();
367
357
  const asyncScope = parentFunction?.node.async;
368
- if (asyncScope && originalName === INLINE_TRANSLATION_HOOK) {
358
+ if (asyncScope && originalName === 'useGT') {
369
359
  errors.push(warnAsyncUseGT(file, `${refPath.node.loc?.start?.line}:${refPath.node.loc?.start?.column}`));
370
360
  return;
371
361
  }
372
- else if (!asyncScope &&
373
- originalName === INLINE_TRANSLATION_HOOK_ASYNC) {
362
+ else if (!asyncScope && originalName === 'getGT') {
374
363
  errors.push(warnSyncGetGT(file, `${refPath.node.loc?.start?.line}:${refPath.node.loc?.start?.column}`));
375
364
  return;
376
365
  }
377
- const ignoreAdditionalData = false;
378
366
  const effectiveParent = parentPath?.node.type === 'AwaitExpression'
379
367
  ? parentPath.parentPath
380
368
  : parentPath;
@@ -384,16 +372,10 @@ export function parseStrings(importName, originalName, path, updates, errors, fi
384
372
  const tFuncName = effectiveParent.node.id.name;
385
373
  // Get the scope from the variable declaration
386
374
  const variableScope = effectiveParent.scope;
387
- // Resolve all aliases of the translation function
388
- // Example: translate -> [translate, t, a, b] for const t = translate; const a = t; const b = a;
389
- const allTranslationNames = resolveVariableAliases(variableScope, tFuncName);
390
- // Process references for all translation function names and their aliases
391
- allTranslationNames.forEach((name) => {
392
- const tReferencePaths = variableScope.bindings[name]?.referencePaths || [];
393
- for (const tPath of tReferencePaths) {
394
- handleFunctionCall(tPath, updates, errors, file, importMap, ignoreAdditionalData);
395
- }
396
- });
375
+ const tReferencePaths = variableScope.bindings[tFuncName]?.referencePaths || [];
376
+ for (const tPath of tReferencePaths) {
377
+ handleFunctionCall(tPath, updates, errors, file, importMap);
378
+ }
397
379
  }
398
380
  }
399
381
  }
@@ -1,5 +1,4 @@
1
1
  import { warnAsyncUseGT, warnSyncGetGT } from '../../../console/index.js';
2
- import { INLINE_TRANSLATION_HOOK, INLINE_TRANSLATION_HOOK_ASYNC, } from './constants.js';
3
2
  /**
4
3
  * Validate useGT() / await getGT() calls
5
4
  * 1. Validates that the call does not violate the rules of React (no hooks in async functions)
@@ -13,13 +12,13 @@ export function validateStringFunction(localImportName, path, updates, errors, f
13
12
  callPath.node.callee.name === localImportName) {
14
13
  // Check the function scope
15
14
  const functionScope = callPath.getFunctionParent();
16
- if (originalImportName === INLINE_TRANSLATION_HOOK) {
15
+ if (originalImportName === 'useGT') {
17
16
  // useGT should NOT be in an async function
18
17
  if (functionScope && functionScope.node.async) {
19
18
  errors.push(warnAsyncUseGT(file, `${callPath.node.loc?.start?.line}:${callPath.node.loc?.start?.column}`));
20
19
  }
21
20
  }
22
- else if (originalImportName === INLINE_TRANSLATION_HOOK_ASYNC) {
21
+ else if (originalImportName === 'getGT') {
23
22
  // getGT should be in an async function
24
23
  if (!functionScope || !functionScope.node.async) {
25
24
  errors.push(warnSyncGetGT(file, `${callPath.node.loc?.start?.line}:${callPath.node.loc?.start?.column}`));
@@ -8,7 +8,7 @@ import { parseJSXElement } from '../jsx/utils/parseJsx.js';
8
8
  import { parseStrings } from '../jsx/utils/parseStringFunction.js';
9
9
  import { extractImportName } from '../jsx/utils/parseAst.js';
10
10
  import { logError } from '../../console/logging.js';
11
- import { GT_TRANSLATION_FUNCS, INLINE_TRANSLATION_HOOK, INLINE_TRANSLATION_HOOK_ASYNC, MSG_TRANSLATION_HOOK, } from '../jsx/utils/constants.js';
11
+ import { GT_TRANSLATION_FUNCS } from '../jsx/utils/constants.js';
12
12
  import { matchFiles } from '../../fs/matchFiles.js';
13
13
  import { DEFAULT_SRC_PATTERNS } from '../../config/generateSettings.js';
14
14
  export async function createInlineUpdates(pkg, validate, filePatterns) {
@@ -38,9 +38,7 @@ export async function createInlineUpdates(pkg, validate, filePatterns) {
38
38
  if (path.node.source.value.startsWith(pkg)) {
39
39
  const importName = extractImportName(path.node, pkg, GT_TRANSLATION_FUNCS);
40
40
  for (const name of importName) {
41
- if (name.original === INLINE_TRANSLATION_HOOK ||
42
- name.original === INLINE_TRANSLATION_HOOK_ASYNC ||
43
- name.original === MSG_TRANSLATION_HOOK) {
41
+ if (name.original === 'useGT' || name.original === 'getGT') {
44
42
  translationPaths.push({
45
43
  localName: name.local,
46
44
  path,
@@ -67,9 +65,7 @@ export async function createInlineUpdates(pkg, validate, filePatterns) {
67
65
  if (parentPath.isVariableDeclaration()) {
68
66
  const importName = extractImportName(parentPath.node, pkg, GT_TRANSLATION_FUNCS);
69
67
  for (const name of importName) {
70
- if (name.original === INLINE_TRANSLATION_HOOK ||
71
- name.original === INLINE_TRANSLATION_HOOK_ASYNC ||
72
- name.original === MSG_TRANSLATION_HOOK) {
68
+ if (name.original === 'useGT' || name.original === 'getGT') {
73
69
  translationPaths.push({
74
70
  localName: name.local,
75
71
  path: parentPath,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "gtx-cli",
3
- "version": "2.1.8-alpha.1",
3
+ "version": "2.1.8",
4
4
  "main": "dist/index.js",
5
5
  "bin": "dist/main.js",
6
6
  "files": [