gt 2.14.58 → 2.14.60

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 (79) hide show
  1. package/CHANGELOG.md +279 -0
  2. package/dist/cli/base.d.ts +8 -0
  3. package/dist/cli/base.js +44 -1
  4. package/dist/cli/base.js.map +1 -1
  5. package/dist/cli/commands/download.js +1 -2
  6. package/dist/cli/commands/download.js.map +1 -1
  7. package/dist/cli/commands/enqueue.js +1 -2
  8. package/dist/cli/commands/enqueue.js.map +1 -1
  9. package/dist/cli/commands/stage.js +6 -2
  10. package/dist/cli/commands/stage.js.map +1 -1
  11. package/dist/cli/flags.js +1 -1
  12. package/dist/cli/flags.js.map +1 -1
  13. package/dist/cli/inline.js +2 -3
  14. package/dist/cli/inline.js.map +1 -1
  15. package/dist/cli/node.js +2 -1
  16. package/dist/cli/node.js.map +1 -1
  17. package/dist/cli/react.js +2 -1
  18. package/dist/cli/react.js.map +1 -1
  19. package/dist/config/defaults.js +2 -1
  20. package/dist/config/defaults.js.map +1 -1
  21. package/dist/config/generateSettings.d.ts +1 -0
  22. package/dist/config/generateSettings.js +2 -0
  23. package/dist/config/generateSettings.js.map +1 -1
  24. package/dist/console/index.d.ts +0 -2
  25. package/dist/console/index.js +4 -6
  26. package/dist/console/index.js.map +1 -1
  27. package/dist/extraction/postProcess.js +0 -1
  28. package/dist/extraction/postProcess.js.map +1 -1
  29. package/dist/formats/files/aggregateFiles.d.ts +0 -1
  30. package/dist/formats/files/aggregateFiles.js +1 -6
  31. package/dist/formats/files/aggregateFiles.js.map +1 -1
  32. package/dist/formats/files/collectFiles.js +2 -5
  33. package/dist/formats/files/collectFiles.js.map +1 -1
  34. package/dist/fs/config/parseFilesConfig.js +0 -4
  35. package/dist/fs/config/parseFilesConfig.js.map +1 -1
  36. package/dist/fs/config/updateConfig.d.ts +1 -0
  37. package/dist/fs/config/updateConfig.js +3 -2
  38. package/dist/fs/config/updateConfig.js.map +1 -1
  39. package/dist/generated/version.d.ts +1 -1
  40. package/dist/generated/version.js +1 -1
  41. package/dist/generated/version.js.map +1 -1
  42. package/dist/git/mergeDrivers.d.ts +11 -0
  43. package/dist/git/mergeDrivers.js +281 -0
  44. package/dist/git/mergeDrivers.js.map +1 -0
  45. package/dist/git/setupMergeDrivers.d.ts +27 -0
  46. package/dist/git/setupMergeDrivers.js +147 -0
  47. package/dist/git/setupMergeDrivers.js.map +1 -0
  48. package/dist/next/parse/handleInitGT.js +1 -6
  49. package/dist/next/parse/handleInitGT.js.map +1 -1
  50. package/dist/react/jsx/utils/constants.d.ts +3 -9
  51. package/dist/react/jsx/utils/constants.js +7 -14
  52. package/dist/react/jsx/utils/constants.js.map +1 -1
  53. package/dist/react/jsx/utils/jsxParsing/autoInsertion.d.ts +2 -2
  54. package/dist/react/jsx/utils/jsxParsing/autoInsertion.js +7 -7
  55. package/dist/react/jsx/utils/jsxParsing/autoInsertion.js.map +1 -1
  56. package/dist/react/jsx/utils/jsxParsing/parseJsx.js +2 -2
  57. package/dist/react/jsx/utils/jsxParsing/parseJsx.js.map +1 -1
  58. package/dist/react/jsx/utils/stringParsing/derivation/containsDeriveCall.d.ts +1 -1
  59. package/dist/react/jsx/utils/stringParsing/derivation/containsDeriveCall.js +1 -1
  60. package/dist/react/jsx/utils/stringParsing/derivation/containsDeriveCall.js.map +1 -1
  61. package/dist/react/jsx/utils/stringParsing/derivation/isDeriveCall.js.map +1 -1
  62. package/dist/react/parse/createDictionaryUpdates.js +0 -1
  63. package/dist/react/parse/createDictionaryUpdates.js.map +1 -1
  64. package/dist/react/parse/createInlineUpdates.js +1 -1
  65. package/dist/react/parse/createInlineUpdates.js.map +1 -1
  66. package/dist/translation/parse.js.map +1 -1
  67. package/dist/types/index.d.ts +2 -0
  68. package/dist/types/parsing.d.ts +2 -0
  69. package/dist/types/parsing.js.map +1 -1
  70. package/dist/utils/fetch.js +1 -1
  71. package/dist/utils/fetch.js.map +1 -1
  72. package/package.json +7 -7
  73. package/dist/extraction/index.d.ts +0 -3
  74. package/dist/extraction/index.js +0 -3
  75. package/dist/extraction/types.d.ts +0 -1
  76. package/dist/extraction/types.js +0 -1
  77. package/dist/utils/headers.d.ts +0 -1
  78. package/dist/utils/headers.js +0 -10
  79. package/dist/utils/headers.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"parseJsx.js","names":[],"sources":["../../../../../src/react/jsx/utils/jsxParsing/parseJsx.ts"],"sourcesContent":["import { Updates } from '../../../../types/index.js';\nimport { randomUUID } from 'node:crypto';\nimport generateModule from '@babel/generator';\n// Handle CommonJS/ESM interop\nconst generate = generateModule.default || generateModule;\n\nimport * as t from '@babel/types';\nimport fs from 'node:fs';\nimport { parse } from '@babel/parser';\nimport addGTIdentifierToSyntaxTree from './addGTIdentifierToSyntaxTree.js';\nimport {\n warnHasUnwrappedExpressionSync,\n warnNestedTComponent,\n warnFunctionNotFoundSync,\n warnMissingReturnSync,\n warnDuplicateFunctionDefinitionSync,\n warnInvalidDeriveInitSync,\n warnRecursiveFunctionCallSync,\n warnDataAttrOnBranch,\n warnNestedInternalTComponent,\n warnDeriveNonConstVariableSync,\n warnDeriveDestructuringSync,\n} from '../../../../console/index.js';\nimport { isAcceptedPluralForm } from 'generaltranslation/internal';\nimport { isStaticExpression } from '../../evaluateJsx.js';\nimport {\n DATA_ATTR_PREFIX,\n STATIC_COMPONENT,\n DERIVE_COMPONENT,\n TRANSLATION_COMPONENT,\n INTERNAL_TRANSLATION_COMPONENT,\n VARIABLE_COMPONENTS,\n} from '../constants.js';\nimport {\n HTML_CONTENT_PROPS,\n type JsxChildren,\n} from '@generaltranslation/format/types';\nimport type { Metadata } from 'generaltranslation/types';\nimport { NodePath } from '@babel/traverse';\nimport { ParsingConfigOptions } from '../../../../types/parsing.js';\nimport { resolveImportPath } from '../resolveImportPath.js';\n\nimport traverseModule from '@babel/traverse';\nimport { buildImportMap } from '../buildImportMap.js';\nimport { getPathsAndAliases } from '../getPathsAndAliases.js';\nimport { parseTProps } from './parseTProps.js';\nimport { handleChildrenWhitespace } from './handleChildrenWhitespace.js';\nimport { MultiplicationNode, JsxTree, isElementNode } from './types.js';\nimport { multiplyJsxTree } from './multiplication/multiplyJsxTree.js';\nimport { removeNullChildrenFields } from './removeNullChildrenFields.js';\nimport {\n ensureTAndVarImported,\n autoInsertJsxComponents,\n} from './autoInsertion.js';\nimport { GTLibrary } from '../../../../types/libraries.js';\nimport path from 'node:path';\nimport { extractSourceCode } from '../extractSourceCode.js';\nimport { SURROUNDING_LINE_COUNT } from '../../../../utils/constants.js';\nimport { handleDerivation } from '../stringParsing/derivation/handleDerivation.js';\nimport { parseStringExpression, nodeToStrings } from '../parseString.js';\n\n// Handle CommonJS/ESM interop\nconst traverse = traverseModule.default || traverseModule;\n\n// For tracking Derive\ntype DerivableTracker = {\n isDerivable: boolean;\n};\n\n/**\n * Union type representing all possible JSX child node types from Babel.\n */\ntype JSXChildNode =\n | t.JSXText\n | t.JSXExpressionContainer\n | t.JSXSpreadChild\n | t.JSXElement\n | t.JSXFragment;\n\n/**\n * Props object for JSX elements and fragments.\n */\ntype JSXProps = {\n children?: JsxTree | MultiplicationNode | (JsxTree | MultiplicationNode)[];\n [key: string]:\n | string\n | number\n | boolean\n | JsxTree\n | MultiplicationNode\n | (JsxTree | MultiplicationNode)[]\n | null\n | undefined;\n};\n\n/**\n * Immutable configuration options for parsing.\n */\ntype ConfigOptions = {\n parsingOptions: ParsingConfigOptions;\n importAliases: Record<string, string>;\n pkgs: GTLibrary[];\n file: string;\n includeSourceCodeContext?: boolean;\n enableAutoJsxInjection?: boolean;\n autoderive?: boolean;\n};\n\n/**\n * Mutable state for tracking parsing progress.\n */\ntype StateTracker = {\n visited: Set<string> | null;\n callStack: string[];\n derivableTracker: DerivableTracker;\n importedFunctionsMap: Map<string, string>;\n};\n\n/**\n * Collectors for errors, warnings, and unwrapped expressions.\n */\ntype OutputCollector = {\n errors: string[];\n warnings: Set<string>;\n unwrappedExpressions: string[];\n};\n\n// TODO: currently we cover VariableDeclaration and FunctionDeclaration nodes, but are there others we should cover as well?\n\n/**\n * Cache for resolved import paths to avoid redundant I/O operations.\n * Key: `${currentFile}::${importPath}`\n * Value: resolved absolute path or null\n */\nconst resolveImportPathCache = new Map<string, string | null>();\n\n/**\n * Cache for processed functions to avoid re-parsing the same files.\n * Key: `${filePath}::${functionName}::${argIndex}`\n * Value: boolean indicating whether the function was found and processed\n */\nconst processFunctionCache = new Map<string, MultiplicationNode | null>();\n\n/**\n * Entry point for JSX parsing\n */\nexport function parseTranslationComponent({\n originalName,\n localName,\n path,\n updates,\n config,\n output,\n}: {\n originalName: string;\n localName: string;\n path: traverseModule.NodePath<traverseModule.Node>;\n updates: Updates;\n config: ConfigOptions;\n output: OutputCollector;\n}) {\n // First, collect all imports in this file to track cross-file function calls\n const importedFunctionsMap: Map<string, string> = buildImportMap(\n path.scope.getProgramParent().path\n );\n const referencePaths = path.scope.bindings[localName]?.referencePaths || [];\n for (const refPath of referencePaths) {\n // Only start at opening tag\n if (\n !t.isJSXOpeningElement(refPath.parent) ||\n !refPath.parentPath?.parentPath\n ) {\n continue;\n }\n\n // Get the JSX element NodePath\n const jsxElementPath = refPath.parentPath\n ?.parentPath as NodePath<t.JSXElement>;\n\n // Parse <T> component\n parseJSXElement({\n scopeNode: jsxElementPath,\n node: jsxElementPath.node,\n originalName,\n updates,\n config,\n state: {\n visited: null,\n callStack: [],\n derivableTracker: { isDerivable: false },\n importedFunctionsMap,\n },\n output,\n });\n }\n}\n\n/**\n * Builds a JSX tree from a given node, recursively handling children.\n * @param node - The node to build the tree from\n * @param helperPath - NodePath for AST traversal\n * @param scopeNode - Scope node for binding resolution\n * @param insideT - Whether the current node is inside a <T> component\n * @param inDerive - Whether we're inside a <Derive> component\n * @param config - Immutable configuration options\n * @param state - Mutable state tracking\n * @param output - Error/warning collectors\n * @returns The built JSX tree\n */\nfunction buildJSXTree({\n node,\n helperPath,\n scopeNode,\n insideT,\n inDerive,\n config,\n state,\n output,\n}: {\n node: t.Node | null | undefined;\n helperPath: NodePath;\n scopeNode: NodePath;\n insideT: boolean;\n inDerive: boolean;\n config: ConfigOptions;\n state: StateTracker;\n output: OutputCollector;\n}): JsxTree | MultiplicationNode | (JsxTree | MultiplicationNode)[] {\n if (t.isJSXExpressionContainer(node)) {\n // Skip JSX comments\n if (t.isJSXEmptyExpression(node.expression)) {\n return null;\n }\n\n if (inDerive) {\n return processDeriveExpression({\n config,\n state,\n output,\n expressionNodePath: helperPath.get(\n 'expression'\n ) as NodePath<t.Expression>,\n scopeNode,\n });\n }\n\n const expr = node.expression;\n if (t.isJSXElement(expr) || t.isJSXFragment(expr)) {\n return buildJSXTree({\n node: expr,\n insideT,\n inDerive: inDerive,\n scopeNode,\n helperPath: helperPath.get('expression'),\n config,\n state,\n output,\n });\n }\n\n const staticAnalysis = isStaticExpression(expr, true);\n if (staticAnalysis.isStatic && staticAnalysis.value !== undefined) {\n // Preserve the exact whitespace for static string expressions\n return {\n nodeType: 'expression',\n result: staticAnalysis.value,\n };\n }\n\n // Keep existing behavior for non-static expressions\n const code = generate(node).code;\n output.unwrappedExpressions.push(code); // Keep track of unwrapped expressions for error reporting\n return code;\n } else if (t.isJSXText(node)) {\n // Updated JSX Text handling\n // JSX Text handling following React's rules\n const text = node.value;\n return text;\n } else if (t.isJSXElement(node)) {\n const element = node;\n const elementName = element.openingElement.name;\n\n let typeName;\n if (t.isJSXIdentifier(elementName)) {\n typeName = elementName.name;\n } else if (t.isJSXMemberExpression(elementName)) {\n typeName = generate(elementName).code;\n } else {\n typeName = null;\n }\n\n // Convert from alias to original name\n const componentType = config.importAliases[typeName ?? ''];\n\n // When enableAutoJsxInjection is on and we're inside a Derive context,\n // any auto-inserted T component will be stripped at runtime by\n // removeInjectedT. Unwrap it transparently — process the T's children\n // as if the T wasn't there. Check this BEFORE the nested-T warning\n // so we don't emit spurious errors for expected auto-inserted nesting.\n if (\n componentType === INTERNAL_TRANSLATION_COMPONENT &&\n inDerive &&\n config.enableAutoJsxInjection\n ) {\n const childResults: (JsxTree | MultiplicationNode)[] = [];\n const helperChildren = helperPath.get('children');\n for (let i = 0; i < element.children.length; i++) {\n const child = element.children[i];\n const helperChild = helperChildren[i];\n const result = buildJSXTree({\n node: child,\n helperPath: helperChild,\n scopeNode,\n insideT: true,\n inDerive: true,\n config,\n state,\n output,\n });\n if (result !== null) {\n if (Array.isArray(result)) {\n childResults.push(...result);\n } else {\n childResults.push(result);\n }\n }\n }\n if (childResults.length === 0) return null;\n if (childResults.length === 1) return childResults[0];\n // Return array — callers flatten this into parent's children\n return childResults;\n }\n\n if (\n (componentType === TRANSLATION_COMPONENT ||\n componentType === INTERNAL_TRANSLATION_COMPONENT) &&\n insideT\n ) {\n // Add warning: Nested <T> components are allowed, but they are advised against\n output.warnings.add(\n warnNestedTComponent(\n config.file,\n `${element.loc?.start?.line}:${element.loc?.start?.column}`\n )\n );\n if (componentType === INTERNAL_TRANSLATION_COMPONENT) {\n output.errors.push(\n warnNestedInternalTComponent(\n config.file,\n `${element.loc?.start?.line}:${element.loc?.start?.column}`\n )\n );\n }\n }\n\n // If this JSXElement is one of the recognized variable components,\n const elementIsVariable = VARIABLE_COMPONENTS.includes(componentType);\n\n const props: JSXProps = {};\n\n const elementIsPlural = componentType === 'Plural';\n const elementIsBranch = componentType === 'Branch';\n\n element.openingElement.attributes.forEach((attr, index) => {\n const helperAttribute = helperPath\n .get('openingElement')\n .get('attributes')[index];\n if (t.isJSXAttribute(attr)) {\n const attrName =\n typeof attr.name.name === 'string'\n ? attr.name.name\n : attr.name.name.name;\n let attrValue = null;\n if (elementIsBranch && attrName.startsWith(DATA_ATTR_PREFIX)) {\n const location = `${attr.loc?.start?.line}:${attr.loc?.start?.column}`;\n output.errors.push(\n warnDataAttrOnBranch(config.file, attrName, location)\n );\n }\n if (attr.value) {\n if (t.isStringLiteral(attr.value)) {\n attrValue = attr.value.value;\n } else if (t.isJSXExpressionContainer(attr.value)) {\n const helperValue = helperAttribute.get(\n 'value'\n ) as NodePath<t.JSXExpressionContainer>;\n // Check if this is an HTML content prop (title, placeholder, alt, etc.)\n const isHtmlContentProp = (\n Object.values(HTML_CONTENT_PROPS) as string[]\n ).includes(attrName);\n\n // If its a plural or branch prop\n if (\n (elementIsPlural && isAcceptedPluralForm(attrName as string)) ||\n (elementIsBranch &&\n attrName !== 'branch' &&\n !attrName.startsWith(DATA_ATTR_PREFIX))\n ) {\n // Make sure that variable strings like {`I have ${count} book`} are invalid!\n if (\n t.isTemplateLiteral(attr.value.expression) &&\n !isStaticExpression(attr.value.expression, true).isStatic\n ) {\n output.unwrappedExpressions.push(generate(attr.value).code);\n }\n // If it's an array, flag as an unwrapped expression\n if (t.isArrayExpression(attr.value.expression)) {\n output.unwrappedExpressions.push(\n generate(attr.value.expression).code\n );\n }\n attrValue = buildJSXTree({\n node: attr.value,\n insideT: true,\n inDerive: inDerive,\n scopeNode,\n helperPath: helperValue,\n config,\n state,\n output,\n });\n }\n // For HTML content props, only accept static string expressions\n else if (isHtmlContentProp) {\n const staticAnalysis = isStaticExpression(\n attr.value.expression,\n true\n );\n if (\n staticAnalysis.isStatic &&\n staticAnalysis.value !== undefined\n ) {\n attrValue = staticAnalysis.value;\n }\n // Otherwise attrValue stays null and won't be included\n }\n }\n }\n props[attrName] = attrValue;\n }\n });\n\n if (elementIsVariable) {\n if (\n componentType === STATIC_COMPONENT ||\n componentType === DERIVE_COMPONENT\n ) {\n const helperElement = helperPath.get('children');\n const results = {\n nodeType: 'element' as const,\n type: componentType,\n props,\n };\n // Create children array if necessary\n const childrenArray: (JsxTree | MultiplicationNode)[] = [];\n if (state.visited === null) {\n state.visited = new Set();\n }\n for (let index = 0; index < element.children.length; index++) {\n const helperChild = helperElement[index];\n const result = buildJSXTree({\n node: helperChild.node,\n insideT: true,\n inDerive: true,\n scopeNode,\n helperPath: helperChild,\n config,\n state,\n output,\n });\n // Flatten array results from _T transparency unwrap inside Derive\n if (Array.isArray(result)) {\n childrenArray.push(...result);\n } else {\n childrenArray.push(result);\n }\n }\n if (childrenArray.length) {\n results.props.children = childrenArray;\n }\n return results;\n }\n\n return {\n nodeType: 'element',\n // if componentType is undefined, use typeName\n // Basically, if componentType is not a GT component, use typeName such as <div>\n type: componentType ?? typeName ?? '',\n props,\n };\n }\n\n const children: (JsxTree | MultiplicationNode)[] = element.children\n .flatMap((child, index) => {\n const result = buildJSXTree({\n node: child,\n insideT: true,\n inDerive: inDerive,\n scopeNode,\n helperPath: helperPath.get('children')[index],\n config,\n state,\n output,\n });\n // Flatten array results from _T transparency unwrap inside Derive\n if (Array.isArray(result)) return result;\n return [result];\n })\n .filter(\n (child): child is JsxTree | MultiplicationNode =>\n child !== null && child !== ''\n );\n\n if (children.length === 1) {\n props.children = children[0];\n } else if (children.length > 1) {\n props.children = children;\n }\n\n return {\n nodeType: 'element',\n // if componentType is undefined, use typeName\n // Basically, if componentType is not a GT component, use typeName such as <div>\n type: componentType ?? typeName,\n props,\n };\n }\n // If it's a JSX fragment\n else if (t.isJSXFragment(node)) {\n const children = node.children\n .flatMap((child: JSXChildNode, index: number) => {\n const result = buildJSXTree({\n node: child,\n insideT: true,\n inDerive: inDerive,\n scopeNode,\n helperPath: helperPath.get('children')[index],\n config,\n state,\n output,\n });\n // Flatten array results from _T transparency unwrap inside Derive\n if (Array.isArray(result)) return result;\n return [result];\n })\n .filter(\n (child): child is JsxTree | MultiplicationNode =>\n child !== null && child !== ''\n );\n\n const props: JSXProps = {};\n\n if (children.length === 1) {\n props.children = children[0];\n } else if (children.length > 1) {\n props.children = children;\n }\n\n return {\n nodeType: 'element',\n type: '',\n props,\n };\n }\n // If it's a string literal (standalone)\n else if (t.isStringLiteral(node)) {\n return node.value;\n }\n // If it's a template literal\n else if (t.isTemplateLiteral(node)) {\n // We've already checked that it's derivable, and and added a warning if it's not, this check is just for fallback behavior\n if (\n !isStaticExpression(node, true).isStatic ||\n node.quasis[0].value.cooked === undefined\n ) {\n return generate(node).code;\n }\n return node.quasis[0].value.cooked;\n } else if (t.isNullLiteral(node)) {\n // If it's null, return null\n return null;\n } else if (t.isBooleanLiteral(node)) {\n // If it's a boolean, return the boolean\n return node.value;\n } else if (t.isNumericLiteral(node)) {\n // If it's a number, return the number\n return node.value.toString();\n }\n // Negative\n else if (t.isUnaryExpression(node)) {\n // If it's a unary expression, return the expression\n const staticAnalysis = isStaticExpression(node, true);\n if (staticAnalysis.isStatic && staticAnalysis.value !== undefined) {\n return staticAnalysis.value;\n }\n return generate(node).code;\n } else if (\n (t.isCallExpression(node) && t.isIdentifier(node.callee)) ||\n (t.isAwaitExpression(node) &&\n t.isCallExpression(node.argument) &&\n t.isIdentifier(node.argument.callee))\n ) {\n if (inDerive) {\n const callExpression = (\n node.type === 'AwaitExpression' ? node.argument : node\n ) as t.CallExpression;\n const callee = callExpression.callee as t.Identifier;\n const calleeBinding = scopeNode.scope.getBinding(callee.name);\n if (!calleeBinding) {\n output.warnings.add(\n warnFunctionNotFoundSync(\n config.file,\n callee.name,\n `${callee.loc?.start?.line}:${callee.loc?.start?.column}`\n )\n );\n return null;\n }\n return resolveDeriveFunctionInvocationFromBinding({\n calleeBinding,\n callee,\n config,\n state,\n output,\n });\n } else {\n output.unwrappedExpressions.push(generate(node).code);\n }\n } else if (t.isParenthesizedExpression(node)) {\n const child = node.expression;\n return buildJSXTree({\n node: child,\n insideT,\n inDerive: inDerive,\n scopeNode,\n helperPath: helperPath.get('expression'),\n config,\n state,\n output,\n });\n }\n // If it's some other JS expression\n else if (\n t.isIdentifier(node) ||\n t.isMemberExpression(node) ||\n t.isCallExpression(node) ||\n t.isBinaryExpression(node) ||\n t.isLogicalExpression(node) ||\n t.isConditionalExpression(node)\n ) {\n output.unwrappedExpressions.push(generate(node).code);\n } else {\n if (node === undefined || node === null) {\n output.unwrappedExpressions.push(String(node));\n } else {\n output.unwrappedExpressions.push(generate(node).code);\n }\n }\n return null;\n}\n// end buildJSXTree\n\n// Parses a JSX element and adds it to the updates array\nfunction parseJSXElement({\n node,\n originalName,\n scopeNode,\n updates,\n config,\n state,\n output,\n}: {\n node: t.JSXElement;\n originalName: string;\n scopeNode: NodePath<t.JSXElement>;\n updates: Updates;\n config: ConfigOptions;\n state: StateTracker;\n output: OutputCollector;\n}) {\n const openingElement = node.openingElement;\n const name = openingElement.name;\n\n // Only proceed if it's <T> ...\n // TODO: i don't think this condition is needed anymore\n if (\n !(\n name.type === 'JSXIdentifier' &&\n (originalName === TRANSLATION_COMPONENT ||\n originalName === INTERNAL_TRANSLATION_COMPONENT)\n )\n ) {\n return;\n }\n\n const componentErrors: string[] = [];\n const componentWarnings: Set<string> = new Set();\n const metadata: Metadata = {};\n const relativeFilepath = path.relative(process.cwd(), config.file);\n metadata.filePaths = [relativeFilepath];\n\n // Extract surrounding lines from source file\n const startLine = node.loc?.start?.line;\n const endLine = node.loc?.end?.line;\n if (config.includeSourceCodeContext && startLine && endLine) {\n const entry = extractSourceCode(\n config.file,\n startLine,\n endLine,\n SURROUNDING_LINE_COUNT\n );\n if (entry && relativeFilepath) {\n metadata.sourceCode = { [relativeFilepath]: [entry] };\n }\n }\n\n // We'll track this flag to know if any unwrapped {variable} is found in children\n const unwrappedExpressions: string[] = [];\n\n // Gather <T>'s props\n parseTProps({\n openingElement,\n metadata,\n componentErrors,\n file: config.file,\n });\n\n // Flag for if contains derivable content\n const derivableTracker: DerivableTracker = {\n isDerivable: false,\n };\n\n // Build the JSX tree for this component\n const treeResult = buildJSXTree({\n node,\n scopeNode,\n insideT: false,\n inDerive: config.autoderive ?? false,\n helperPath: scopeNode,\n config,\n state: {\n visited: null,\n callStack: [],\n derivableTracker: derivableTracker,\n importedFunctionsMap: state.importedFunctionsMap,\n },\n output: {\n unwrappedExpressions,\n errors: componentErrors,\n warnings: componentWarnings,\n },\n }) as JsxTree;\n\n // Strip the outer <T> component if necessary\n const jsxTree =\n isElementNode(treeResult) && treeResult.props?.children\n ? // We know this b/c the direct children of <T> will never be a multiplication node\n (treeResult.props.children as JsxTree | JsxTree[])\n : treeResult;\n\n // Update warnings\n if (componentWarnings.size > 0) {\n componentWarnings.forEach((warning) => output.warnings.add(warning));\n }\n\n // Update errors\n if (componentErrors.length > 0) {\n output.errors.push(...componentErrors);\n return;\n }\n\n // Handle whitespace in children\n const whitespaceHandledTree = handleChildrenWhitespace(jsxTree);\n\n // Multiply the tree\n const multipliedTrees = multiplyJsxTree(whitespaceHandledTree);\n\n // Add GT identifiers to the tree\n // TODO: do this in parallel\n const minifiedTress: JsxChildren[] = [];\n for (const multipliedTree of multipliedTrees) {\n // Build set of confirmed GT variable names from importAliases.\n // Only pass when enableAutoJsxInjection is on, to avoid breaking\n // existing behavior where importAliases may be incomplete.\n const gtVariableNames = config.enableAutoJsxInjection\n ? new Set(\n Object.values(config.importAliases).filter(\n (name) =>\n VARIABLE_COMPONENTS.includes(name) &&\n name !== DERIVE_COMPONENT &&\n name !== STATIC_COMPONENT\n )\n )\n : undefined;\n const minifiedTree = addGTIdentifierToSyntaxTree(\n multipliedTree,\n 0,\n gtVariableNames\n );\n minifiedTress.push(\n Array.isArray(minifiedTree) && minifiedTree.length === 1\n ? minifiedTree[0]\n : minifiedTree\n );\n }\n\n // If we found an unwrapped expression, skip\n if (unwrappedExpressions.length > 0) {\n output.errors.push(\n warnHasUnwrappedExpressionSync(\n config.file,\n unwrappedExpressions,\n metadata.id,\n `${node.loc?.start?.line}:${node.loc?.start?.column}`\n )\n );\n return;\n }\n\n // Create a temporary unique flag for derivable content\n const temporaryDeriveId = `derive-temp-id-${randomUUID()}`;\n\n // Resolve derive context variants if present\n let contextVariants: string[] | undefined;\n if (metadata._contextDeriveExpr) {\n const contextExpr = metadata._contextDeriveExpr as t.Expression;\n delete metadata._contextDeriveExpr;\n\n const contextNode = handleDerivation({\n expr: contextExpr,\n tPath: scopeNode,\n file: config.file,\n parsingOptions: config.parsingOptions,\n errors: componentErrors,\n warnings: componentWarnings,\n });\n if (contextNode) {\n contextVariants = nodeToStrings(contextNode);\n }\n }\n\n // <T> is valid here\n for (const minifiedTree of minifiedTress) {\n // Clean the tree by removing null 'c' fields from JsxElements\n const cleanedTree = removeNullChildrenFields(minifiedTree);\n\n if (contextVariants) {\n for (const context of contextVariants) {\n updates.push({\n dataFormat: 'JSX',\n source: cleanedTree,\n metadata: {\n ...structuredClone(metadata),\n context,\n staticId: temporaryDeriveId,\n },\n });\n }\n } else {\n updates.push({\n dataFormat: 'JSX',\n source: cleanedTree,\n metadata: {\n ...structuredClone(metadata),\n ...(derivableTracker.isDerivable && { staticId: temporaryDeriveId }),\n },\n });\n }\n }\n}\n\nfunction resolveDeriveFunctionInvocationFromBinding({\n calleeBinding,\n callee,\n config,\n state,\n output,\n}: {\n calleeBinding: traverseModule.Binding;\n callee: t.Identifier;\n config: ConfigOptions;\n state: StateTracker;\n output: OutputCollector;\n}): MultiplicationNode | null {\n // Stop recursive calls\n type RecursiveGuardCallback = () =>\n | ReturnType<typeof processFunctionDeclarationNodePath>\n | ReturnType<typeof processVariableDeclarationNodePath>\n | ReturnType<typeof processFunctionInFile>;\n function withRecusionGuard({\n cb,\n filename,\n functionName,\n }: {\n cb: RecursiveGuardCallback;\n filename: string;\n functionName: string;\n }) {\n const cacheKey = `${filename}::${functionName}`;\n if (state.callStack.includes(cacheKey)) {\n output.errors.push(\n warnRecursiveFunctionCallSync(config.file, functionName)\n );\n return null;\n }\n state.callStack.push(cacheKey);\n const result = cb();\n state.callStack.pop();\n return result;\n }\n\n // check for recursive calls\n if (calleeBinding.path.isFunctionDeclaration()) {\n // Handle function declarations: function getSubject() { ... }\n const functionName = callee.name;\n const path = calleeBinding.path;\n return withRecusionGuard({\n filename: config.file,\n functionName,\n cb: () =>\n processFunctionDeclarationNodePath({\n config,\n state,\n output,\n path,\n }),\n });\n } else if (\n calleeBinding.path.isVariableDeclarator() &&\n calleeBinding.path.node.init &&\n (t.isArrowFunctionExpression(calleeBinding.path.node.init) ||\n t.isFunctionExpression(calleeBinding.path.node.init))\n ) {\n // Handle arrow functions assigned to variables: const getData = (t) => {...}\n const functionName = callee.name;\n const path = calleeBinding.path;\n return withRecusionGuard({\n filename: config.file,\n functionName,\n cb: () =>\n processVariableDeclarationNodePath({\n config,\n state,\n output,\n functionName,\n path,\n }),\n });\n } else if (state.importedFunctionsMap.has(callee.name)) {\n // Get the original function name\n let originalName: string | undefined;\n if (calleeBinding.path.isImportSpecifier()) {\n originalName = t.isIdentifier(calleeBinding.path.node.imported)\n ? calleeBinding.path.node.imported.name\n : calleeBinding.path.node.imported.value;\n } else if (calleeBinding.path.isImportDefaultSpecifier()) {\n originalName = calleeBinding.path.node.local.name;\n } else if (calleeBinding.path.isImportNamespaceSpecifier()) {\n originalName = calleeBinding.path.node.local.name;\n }\n\n // Function is being imported\n const importPath = state.importedFunctionsMap.get(callee.name)!;\n const filePath = resolveImportPath(\n config.file,\n importPath,\n config.parsingOptions,\n resolveImportPathCache\n );\n if (filePath && originalName) {\n const result = withRecusionGuard({\n filename: filePath,\n functionName: originalName,\n cb: () =>\n processFunctionInFile({\n config,\n state,\n output,\n filePath,\n functionName: originalName,\n }),\n });\n if (result !== null) {\n return result;\n }\n }\n }\n output.warnings.add(\n warnFunctionNotFoundSync(\n config.file,\n callee.name,\n `${callee.loc?.start?.line}:${callee.loc?.start?.column}`\n )\n );\n return null;\n}\n\n/**\n * Searches for a specific user-defined function in a file.\n * This is the resolution logic\n *\n * Handles multiple function declaration patterns:\n * - function getInfo() { ... }\n * - export function getInfo() { ... }\n * - const getInfo = () => { ... }\n *\n * If the function is not found in the file, follows re-exports (export * from './other')\n */\nfunction processFunctionInFile({\n config,\n state,\n output,\n filePath,\n functionName,\n}: {\n config: ConfigOptions;\n state: StateTracker;\n output: OutputCollector;\n filePath: string;\n functionName: string;\n}): MultiplicationNode | null {\n // Create a custom key for the function call\n const cacheKey = `${filePath}::${functionName}`;\n // Check cache first to avoid redundant parsing\n if (processFunctionCache.has(cacheKey)) {\n return processFunctionCache.get(cacheKey) ?? null;\n }\n\n // Prevent infinite loops from circular re-exports\n if (state.visited && state.visited.has(filePath)) {\n return null;\n }\n if (state.visited) {\n state.visited.add(filePath);\n }\n\n let result: MultiplicationNode | null | undefined = undefined;\n try {\n const code = fs.readFileSync(filePath, 'utf8');\n const ast = parse(code, {\n sourceType: 'module',\n plugins: ['jsx', 'typescript'],\n });\n\n const pathsResult = getPathsAndAliases(ast, config.pkgs);\n const importAliases = { ...pathsResult.importAliases };\n // Merge translation component names into importAliases so\n // autoInsertJsxComponents can recognize user T/Var and skip them\n for (const {\n localName,\n originalName,\n } of pathsResult.translationComponentPaths) {\n importAliases[localName] = originalName;\n }\n\n // Auto-inject T/Var into the cross-file AST when enabled,\n // so that Derive extraction sees the same structure as same-file\n if (config.enableAutoJsxInjection) {\n ensureTAndVarImported(ast, importAliases);\n autoInsertJsxComponents(ast, importAliases);\n }\n\n // Collect all imports in this file to track cross-file function calls\n let importedFunctionsMap: Map<string, string> = new Map();\n traverse(ast, {\n Program(path) {\n importedFunctionsMap = buildImportMap(path);\n },\n });\n\n const reExports: string[] = [];\n\n const warnDuplicateFuncDef = (path: NodePath) => {\n output.warnings.add(\n warnDuplicateFunctionDefinitionSync(\n filePath,\n functionName,\n `${path.node.loc?.start?.line}:${path.node.loc?.start?.column}`\n )\n );\n };\n\n traverse(ast, {\n // Handle function declarations: function getInfo() { ... }\n FunctionDeclaration(path) {\n if (path.node.id?.name === functionName) {\n if (result !== undefined) return warnDuplicateFuncDef(path);\n result = processFunctionDeclarationNodePath({\n config: {\n importAliases,\n parsingOptions: config.parsingOptions,\n pkgs: config.pkgs,\n file: filePath,\n enableAutoJsxInjection: config.enableAutoJsxInjection,\n },\n state: {\n ...state,\n importedFunctionsMap,\n },\n output,\n path,\n });\n }\n },\n // Handle variable declarations: const getInfo = () => { ... }\n VariableDeclarator(path) {\n if (\n t.isIdentifier(path.node.id) &&\n path.node.id.name === functionName &&\n path.node.init &&\n (t.isArrowFunctionExpression(path.node.init) ||\n t.isFunctionExpression(path.node.init))\n ) {\n if (result !== undefined) return warnDuplicateFuncDef(path);\n result = processVariableDeclarationNodePath({\n config: {\n importAliases,\n parsingOptions: config.parsingOptions,\n pkgs: config.pkgs,\n file: filePath,\n enableAutoJsxInjection: config.enableAutoJsxInjection,\n },\n state: {\n ...state,\n importedFunctionsMap,\n },\n output,\n functionName,\n path,\n });\n }\n },\n // Collect re-exports: export * from './other'\n ExportAllDeclaration(path) {\n if (t.isStringLiteral(path.node.source)) {\n reExports.push(path.node.source.value);\n }\n },\n // Collect named re-exports: export { foo } from './other'\n ExportNamedDeclaration(path) {\n if (path.node.source && t.isStringLiteral(path.node.source)) {\n // Check if this export includes our function\n const exportsFunction = path.node.specifiers.some((spec) => {\n if (t.isExportSpecifier(spec)) {\n const exportedName = t.isIdentifier(spec.exported)\n ? spec.exported.name\n : spec.exported.value;\n return exportedName === functionName;\n }\n return false;\n });\n if (exportsFunction) {\n reExports.push(path.node.source.value);\n }\n }\n },\n });\n\n // If function not found, follow re-exports\n if (result === undefined && reExports.length > 0) {\n for (const reExportPath of reExports) {\n const resolvedPath = resolveImportPath(\n filePath,\n reExportPath,\n config.parsingOptions,\n resolveImportPathCache\n );\n if (resolvedPath) {\n const foundResult = processFunctionInFile({\n config: {\n importAliases,\n parsingOptions: config.parsingOptions,\n pkgs: config.pkgs,\n file: filePath,\n enableAutoJsxInjection: config.enableAutoJsxInjection,\n },\n state: {\n ...state,\n importedFunctionsMap,\n },\n output,\n filePath: resolvedPath,\n functionName,\n });\n if (foundResult != null) {\n result = foundResult;\n break;\n }\n }\n }\n }\n\n // Mark this function search as processed in the cache\n processFunctionCache.set(cacheKey, result !== undefined ? result : null);\n } catch {\n // Silently skip files that can't be parsed or accessed\n // Still mark as processed to avoid retrying failed parses\n processFunctionCache.set(cacheKey, null);\n }\n return result !== undefined ? result : null;\n}\n\n/**\n * Process a function declaration\n * function getInfo() { ... }\n */\nfunction processFunctionDeclarationNodePath({\n config,\n state,\n output,\n path,\n}: {\n config: ConfigOptions;\n state: StateTracker;\n output: OutputCollector;\n path: NodePath<t.FunctionDeclaration>;\n}): MultiplicationNode | null {\n const result: MultiplicationNode = {\n nodeType: 'multiplication',\n branches: [],\n };\n path.traverse({\n Function(path) {\n path.skip();\n },\n ReturnStatement(returnPath) {\n const returnNodePath = returnPath.get('argument');\n if (!returnNodePath.isExpression()) {\n return;\n }\n const deriveResult = processDeriveExpression({\n config,\n state,\n output,\n expressionNodePath: returnNodePath,\n scopeNode: returnPath,\n });\n if (Array.isArray(deriveResult)) {\n result.branches.push(...deriveResult);\n } else {\n result.branches.push(deriveResult);\n }\n },\n });\n if (result.branches.length === 0) {\n return null;\n }\n return result;\n}\n\n/**\n * Process a variable declaration of a function\n * const getInfo = () => { ... }\n *\n * IMPORTANT: the RHand value must be the function definition, or this will fail\n */\nfunction processVariableDeclarationNodePath({\n config,\n state,\n output,\n functionName,\n path,\n}: {\n config: ConfigOptions;\n state: StateTracker;\n output: OutputCollector;\n functionName: string;\n path: NodePath<t.VariableDeclarator>;\n}): MultiplicationNode | null {\n const result: MultiplicationNode = {\n nodeType: 'multiplication',\n branches: [],\n };\n\n // Enforce the Rhand is a function definition\n const arrowFunctionPath = path.get('init');\n if (!arrowFunctionPath.isArrowFunctionExpression()) {\n output.errors.push(\n warnInvalidDeriveInitSync(\n config.file,\n functionName,\n `${path.node.loc?.start?.line}:${path.node.loc?.start?.column}`\n )\n );\n return null;\n }\n\n const bodyNodePath = arrowFunctionPath.get('body');\n if (bodyNodePath.isExpression()) {\n // process expression return\n const deriveResult = processDeriveExpression({\n config,\n state,\n output,\n expressionNodePath: bodyNodePath,\n scopeNode: arrowFunctionPath,\n });\n if (Array.isArray(deriveResult)) {\n result.branches.push(...deriveResult);\n } else {\n result.branches.push(deriveResult);\n }\n } else {\n // search for a return statement\n bodyNodePath.traverse({\n Function(path) {\n path.skip();\n },\n ReturnStatement(returnPath) {\n const returnNodePath = returnPath.get('argument');\n if (!returnNodePath.isExpression()) {\n return;\n }\n const deriveResult = processDeriveExpression({\n config,\n state,\n output,\n expressionNodePath: returnNodePath,\n scopeNode: returnPath,\n });\n if (Array.isArray(deriveResult)) {\n result.branches.push(...deriveResult);\n } else {\n result.branches.push(deriveResult);\n }\n },\n });\n }\n\n if (result.branches.length === 0) {\n output.errors.push(\n warnMissingReturnSync(\n config.file,\n functionName,\n `${path.node.loc?.start?.line}:${path.node.loc?.start?.column}`\n )\n );\n return null;\n }\n return result;\n}\n\n/**\n * Process a <Derive> expression\n */\nfunction processDeriveExpression({\n config,\n state,\n output,\n expressionNodePath,\n scopeNode,\n}: {\n config: ConfigOptions;\n state: StateTracker;\n output: OutputCollector;\n expressionNodePath: NodePath<t.Expression>;\n scopeNode: NodePath;\n}): JsxTree | MultiplicationNode | (JsxTree | MultiplicationNode)[] {\n // Mark the derivable tracker as true\n state.derivableTracker.isDerivable = true;\n\n // Remove parentheses if they exist\n if (t.isParenthesizedExpression(expressionNodePath.node)) {\n // ex: return (value)\n return processDeriveExpression({\n config,\n state,\n output,\n scopeNode,\n expressionNodePath: expressionNodePath.get('expression'),\n });\n } else if (\n t.isCallExpression(expressionNodePath.node) &&\n t.isIdentifier(expressionNodePath.node.callee)\n ) {\n // ex: return someFunc()\n const callee = expressionNodePath.node.callee;\n const calleeBinding = scopeNode.scope.getBinding(callee.name);\n if (!calleeBinding) {\n output.warnings.add(\n warnFunctionNotFoundSync(\n config.file,\n callee.name,\n `${callee.loc?.start?.line}:${callee.loc?.start?.column}`\n )\n );\n return null;\n }\n // Function is found\n return resolveDeriveFunctionInvocationFromBinding({\n calleeBinding,\n callee,\n config,\n state,\n output,\n });\n } else if (\n t.isAwaitExpression(expressionNodePath.node) &&\n t.isCallExpression(expressionNodePath.node.argument) &&\n t.isIdentifier(expressionNodePath.node.argument.callee)\n ) {\n // ex: return await someFunc()\n const callee = expressionNodePath.node.argument.callee;\n const calleeBinding = scopeNode.scope.getBinding(callee.name);\n if (!calleeBinding) {\n output.warnings.add(\n warnFunctionNotFoundSync(\n config.file,\n callee.name,\n `${callee.loc?.start?.line}:${callee.loc?.start?.column}`\n )\n );\n return null;\n }\n // Function is found\n return resolveDeriveFunctionInvocationFromBinding({\n calleeBinding,\n callee,\n config,\n state,\n output,\n });\n } else if (\n t.isJSXElement(expressionNodePath.node) ||\n t.isJSXFragment(expressionNodePath.node)\n ) {\n // ex: return <div>Jsx content</div>\n return buildJSXTree({\n node: expressionNodePath.node,\n helperPath: expressionNodePath,\n scopeNode,\n insideT: true,\n inDerive: true,\n config,\n state,\n output,\n });\n } else if (t.isConditionalExpression(expressionNodePath.node)) {\n // ex: return condition ? <div>Jsx content</div> : <div>Jsx content</div>\n // since two options here we must construct a new multiplication node\n const consequentNodePath = expressionNodePath.get('consequent');\n const alternateNodePath = expressionNodePath.get('alternate');\n const result: MultiplicationNode = {\n nodeType: 'multiplication' as const,\n branches: [consequentNodePath, alternateNodePath].flatMap(\n (expressionNodePath) => {\n const r = processDeriveExpression({\n config,\n state,\n output,\n scopeNode,\n expressionNodePath,\n });\n return Array.isArray(r) ? r : [r];\n }\n ),\n };\n return result;\n } else if (t.isIdentifier(expressionNodePath.node)) {\n // Resolve variable declarations: const label = cond ? \"boy\" : \"girl\"\n const name = expressionNodePath.node.name;\n const binding = scopeNode.scope.getBinding(name);\n\n if (\n binding &&\n binding.path.isVariableDeclarator() &&\n binding.path.node.init\n ) {\n // Reject destructuring patterns\n if (\n t.isObjectPattern(binding.path.node.id) ||\n t.isArrayPattern(binding.path.node.id)\n ) {\n output.errors.push(\n warnDeriveDestructuringSync(\n config.file,\n name,\n `${expressionNodePath.node.loc?.start?.line}:${expressionNodePath.node.loc?.start?.column}`\n )\n );\n return null;\n }\n\n // Enforce const-only\n const declaration = binding.path.parentPath;\n if (\n declaration?.isVariableDeclaration() &&\n declaration.node.kind !== 'const'\n ) {\n output.warnings.add(\n warnDeriveNonConstVariableSync(\n config.file,\n name,\n declaration.node.kind,\n `${expressionNodePath.node.loc?.start?.line}:${expressionNodePath.node.loc?.start?.column}`\n )\n );\n return null;\n }\n\n // Resolve via parseStringExpression (handles all derivable expression types)\n const errorsBefore = output.errors.length;\n const stringNode = parseStringExpression(\n binding.path.node.init,\n binding.path,\n config.file,\n config.parsingOptions,\n output.warnings,\n output.errors\n );\n if (stringNode) {\n const strings = nodeToStrings(stringNode);\n if (strings.length === 0) {\n return null;\n }\n if (strings.length === 1) {\n return strings[0];\n }\n return {\n nodeType: 'multiplication' as const,\n branches: strings.map((s) => s),\n };\n }\n // parseStringExpression returned null — if it already pushed errors,\n // avoid double-reporting by skipping the buildJSXTree fallthrough.\n if (output.errors.length > errorsBefore) {\n return null;\n }\n }\n\n // Not resolvable — fall through to existing buildJSXTree behavior\n return buildJSXTree({\n node: expressionNodePath.node,\n helperPath: expressionNodePath,\n scopeNode,\n insideT: true,\n inDerive: true,\n config,\n state,\n output,\n });\n } else {\n return buildJSXTree({\n node: expressionNodePath.node,\n helperPath: expressionNodePath,\n scopeNode,\n insideT: true,\n inDerive: true,\n config,\n state,\n output,\n });\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"parseJsx.js","names":[],"sources":["../../../../../src/react/jsx/utils/jsxParsing/parseJsx.ts"],"sourcesContent":["import { Updates } from '../../../../types/index.js';\nimport { randomUUID } from 'node:crypto';\nimport generateModule from '@babel/generator';\n// Handle CommonJS/ESM interop\nconst generate = generateModule.default || generateModule;\n\nimport * as t from '@babel/types';\nimport fs from 'node:fs';\nimport { parse } from '@babel/parser';\nimport addGTIdentifierToSyntaxTree from './addGTIdentifierToSyntaxTree.js';\nimport {\n warnHasUnwrappedExpressionSync,\n warnNestedTComponent,\n warnFunctionNotFoundSync,\n warnMissingReturnSync,\n warnDuplicateFunctionDefinitionSync,\n warnInvalidDeriveInitSync,\n warnRecursiveFunctionCallSync,\n warnDataAttrOnBranch,\n warnNestedInternalTComponent,\n warnDeriveNonConstVariableSync,\n warnDeriveDestructuringSync,\n} from '../../../../console/index.js';\nimport { isAcceptedPluralForm } from 'generaltranslation/internal';\nimport { isStaticExpression } from '../../evaluateJsx.js';\nimport {\n DATA_ATTR_PREFIX,\n DERIVE_COMPONENT,\n TRANSLATION_COMPONENT,\n INTERNAL_TRANSLATION_COMPONENT,\n VARIABLE_COMPONENTS,\n} from '../constants.js';\nimport {\n HTML_CONTENT_PROPS,\n type JsxChildren,\n} from '@generaltranslation/format/types';\nimport type { Metadata } from 'generaltranslation/types';\nimport { NodePath } from '@babel/traverse';\nimport { ParsingConfigOptions } from '../../../../types/parsing.js';\nimport { resolveImportPath } from '../resolveImportPath.js';\n\nimport traverseModule from '@babel/traverse';\nimport { buildImportMap } from '../buildImportMap.js';\nimport { getPathsAndAliases } from '../getPathsAndAliases.js';\nimport { parseTProps } from './parseTProps.js';\nimport { handleChildrenWhitespace } from './handleChildrenWhitespace.js';\nimport { MultiplicationNode, JsxTree, isElementNode } from './types.js';\nimport { multiplyJsxTree } from './multiplication/multiplyJsxTree.js';\nimport { removeNullChildrenFields } from './removeNullChildrenFields.js';\nimport {\n ensureTAndVarImported,\n autoInsertJsxComponents,\n} from './autoInsertion.js';\nimport { GTLibrary } from '../../../../types/libraries.js';\nimport path from 'node:path';\nimport { extractSourceCode } from '../extractSourceCode.js';\nimport { SURROUNDING_LINE_COUNT } from '../../../../utils/constants.js';\nimport { handleDerivation } from '../stringParsing/derivation/handleDerivation.js';\nimport { parseStringExpression, nodeToStrings } from '../parseString.js';\n\n// Handle CommonJS/ESM interop\nconst traverse = traverseModule.default || traverseModule;\n\n// For tracking Derive\ntype DerivableTracker = {\n isDerivable: boolean;\n};\n\n/**\n * Union type representing all possible JSX child node types from Babel.\n */\ntype JSXChildNode =\n | t.JSXText\n | t.JSXExpressionContainer\n | t.JSXSpreadChild\n | t.JSXElement\n | t.JSXFragment;\n\n/**\n * Props object for JSX elements and fragments.\n */\ntype JSXProps = {\n children?: JsxTree | MultiplicationNode | (JsxTree | MultiplicationNode)[];\n [key: string]:\n | string\n | number\n | boolean\n | JsxTree\n | MultiplicationNode\n | (JsxTree | MultiplicationNode)[]\n | null\n | undefined;\n};\n\n/**\n * Immutable configuration options for parsing.\n */\ntype ConfigOptions = {\n parsingOptions: ParsingConfigOptions;\n importAliases: Record<string, string>;\n pkgs: GTLibrary[];\n file: string;\n includeSourceCodeContext?: boolean;\n enableAutoJsxInjection?: boolean;\n autoderive?: boolean;\n};\n\n/**\n * Mutable state for tracking parsing progress.\n */\ntype StateTracker = {\n visited: Set<string> | null;\n callStack: string[];\n derivableTracker: DerivableTracker;\n importedFunctionsMap: Map<string, string>;\n};\n\n/**\n * Collectors for errors, warnings, and unwrapped expressions.\n */\ntype OutputCollector = {\n errors: string[];\n warnings: Set<string>;\n unwrappedExpressions: string[];\n};\n\n// TODO: currently we cover VariableDeclaration and FunctionDeclaration nodes, but are there others we should cover as well?\n\n/**\n * Cache for resolved import paths to avoid redundant I/O operations.\n * Key: `${currentFile}::${importPath}`\n * Value: resolved absolute path or null\n */\nconst resolveImportPathCache = new Map<string, string | null>();\n\n/**\n * Cache for processed functions to avoid re-parsing the same files.\n * Key: `${filePath}::${functionName}::${argIndex}`\n * Value: boolean indicating whether the function was found and processed\n */\nconst processFunctionCache = new Map<string, MultiplicationNode | null>();\n\n/**\n * Entry point for JSX parsing\n */\nexport function parseTranslationComponent({\n originalName,\n localName,\n path,\n updates,\n config,\n output,\n}: {\n originalName: string;\n localName: string;\n path: traverseModule.NodePath<traverseModule.Node>;\n updates: Updates;\n config: ConfigOptions;\n output: OutputCollector;\n}) {\n // First, collect all imports in this file to track cross-file function calls\n const importedFunctionsMap: Map<string, string> = buildImportMap(\n path.scope.getProgramParent().path\n );\n const referencePaths = path.scope.bindings[localName]?.referencePaths || [];\n for (const refPath of referencePaths) {\n // Only start at opening tag\n if (\n !t.isJSXOpeningElement(refPath.parent) ||\n !refPath.parentPath?.parentPath\n ) {\n continue;\n }\n\n // Get the JSX element NodePath\n const jsxElementPath = refPath.parentPath\n ?.parentPath as NodePath<t.JSXElement>;\n\n // Parse <T> component\n parseJSXElement({\n scopeNode: jsxElementPath,\n node: jsxElementPath.node,\n originalName,\n updates,\n config,\n state: {\n visited: null,\n callStack: [],\n derivableTracker: { isDerivable: false },\n importedFunctionsMap,\n },\n output,\n });\n }\n}\n\n/**\n * Builds a JSX tree from a given node, recursively handling children.\n * @param node - The node to build the tree from\n * @param helperPath - NodePath for AST traversal\n * @param scopeNode - Scope node for binding resolution\n * @param insideT - Whether the current node is inside a <T> component\n * @param inDerive - Whether we're inside a <Derive> component\n * @param config - Immutable configuration options\n * @param state - Mutable state tracking\n * @param output - Error/warning collectors\n * @returns The built JSX tree\n */\nfunction buildJSXTree({\n node,\n helperPath,\n scopeNode,\n insideT,\n inDerive,\n config,\n state,\n output,\n}: {\n node: t.Node | null | undefined;\n helperPath: NodePath;\n scopeNode: NodePath;\n insideT: boolean;\n inDerive: boolean;\n config: ConfigOptions;\n state: StateTracker;\n output: OutputCollector;\n}): JsxTree | MultiplicationNode | (JsxTree | MultiplicationNode)[] {\n if (t.isJSXExpressionContainer(node)) {\n // Skip JSX comments\n if (t.isJSXEmptyExpression(node.expression)) {\n return null;\n }\n\n if (inDerive) {\n return processDeriveExpression({\n config,\n state,\n output,\n expressionNodePath: helperPath.get(\n 'expression'\n ) as NodePath<t.Expression>,\n scopeNode,\n });\n }\n\n const expr = node.expression;\n if (t.isJSXElement(expr) || t.isJSXFragment(expr)) {\n return buildJSXTree({\n node: expr,\n insideT,\n inDerive: inDerive,\n scopeNode,\n helperPath: helperPath.get('expression'),\n config,\n state,\n output,\n });\n }\n\n const staticAnalysis = isStaticExpression(expr, true);\n if (staticAnalysis.isStatic && staticAnalysis.value !== undefined) {\n // Preserve the exact whitespace for static string expressions\n return {\n nodeType: 'expression',\n result: staticAnalysis.value,\n };\n }\n\n // Keep existing behavior for non-static expressions\n const code = generate(node).code;\n output.unwrappedExpressions.push(code); // Keep track of unwrapped expressions for error reporting\n return code;\n } else if (t.isJSXText(node)) {\n // Updated JSX Text handling\n // JSX Text handling following React's rules\n const text = node.value;\n return text;\n } else if (t.isJSXElement(node)) {\n const element = node;\n const elementName = element.openingElement.name;\n\n let typeName;\n if (t.isJSXIdentifier(elementName)) {\n typeName = elementName.name;\n } else if (t.isJSXMemberExpression(elementName)) {\n typeName = generate(elementName).code;\n } else {\n typeName = null;\n }\n\n // Convert from alias to original name\n const componentType = config.importAliases[typeName ?? ''];\n\n // When enableAutoJsxInjection is on and we're inside a Derive context,\n // any auto-inserted T component will be stripped at runtime by\n // removeInjectedT. Unwrap it transparently — process the T's children\n // as if the T wasn't there. Check this BEFORE the nested-T warning\n // so we don't emit spurious errors for expected auto-inserted nesting.\n if (\n componentType === INTERNAL_TRANSLATION_COMPONENT &&\n inDerive &&\n config.enableAutoJsxInjection\n ) {\n const childResults: (JsxTree | MultiplicationNode)[] = [];\n const helperChildren = helperPath.get('children');\n for (let i = 0; i < element.children.length; i++) {\n const child = element.children[i];\n const helperChild = helperChildren[i];\n const result = buildJSXTree({\n node: child,\n helperPath: helperChild,\n scopeNode,\n insideT: true,\n inDerive: true,\n config,\n state,\n output,\n });\n if (result !== null) {\n if (Array.isArray(result)) {\n childResults.push(...result);\n } else {\n childResults.push(result);\n }\n }\n }\n if (childResults.length === 0) return null;\n if (childResults.length === 1) return childResults[0];\n // Return array — callers flatten this into parent's children\n return childResults;\n }\n\n if (\n (componentType === TRANSLATION_COMPONENT ||\n componentType === INTERNAL_TRANSLATION_COMPONENT) &&\n insideT\n ) {\n // Add warning: Nested <T> components are allowed, but they are advised against\n output.warnings.add(\n warnNestedTComponent(\n config.file,\n `${element.loc?.start?.line}:${element.loc?.start?.column}`\n )\n );\n if (componentType === INTERNAL_TRANSLATION_COMPONENT) {\n output.errors.push(\n warnNestedInternalTComponent(\n config.file,\n `${element.loc?.start?.line}:${element.loc?.start?.column}`\n )\n );\n }\n }\n\n // If this JSXElement is one of the recognized variable components,\n const elementIsVariable = VARIABLE_COMPONENTS.includes(componentType);\n\n const props: JSXProps = {};\n\n const elementIsPlural = componentType === 'Plural';\n const elementIsBranch = componentType === 'Branch';\n\n element.openingElement.attributes.forEach((attr, index) => {\n const helperAttribute = helperPath\n .get('openingElement')\n .get('attributes')[index];\n if (t.isJSXAttribute(attr)) {\n const attrName =\n typeof attr.name.name === 'string'\n ? attr.name.name\n : attr.name.name.name;\n let attrValue = null;\n if (elementIsBranch && attrName.startsWith(DATA_ATTR_PREFIX)) {\n const location = `${attr.loc?.start?.line}:${attr.loc?.start?.column}`;\n output.errors.push(\n warnDataAttrOnBranch(config.file, attrName, location)\n );\n }\n if (attr.value) {\n if (t.isStringLiteral(attr.value)) {\n attrValue = attr.value.value;\n } else if (t.isJSXExpressionContainer(attr.value)) {\n const helperValue = helperAttribute.get(\n 'value'\n ) as NodePath<t.JSXExpressionContainer>;\n // Check if this is an HTML content prop (title, placeholder, alt, etc.)\n const isHtmlContentProp = (\n Object.values(HTML_CONTENT_PROPS) as string[]\n ).includes(attrName);\n\n // If its a plural or branch prop\n if (\n (elementIsPlural && isAcceptedPluralForm(attrName as string)) ||\n (elementIsBranch &&\n attrName !== 'branch' &&\n !attrName.startsWith(DATA_ATTR_PREFIX))\n ) {\n // Make sure that variable strings like {`I have ${count} book`} are invalid!\n if (\n t.isTemplateLiteral(attr.value.expression) &&\n !isStaticExpression(attr.value.expression, true).isStatic\n ) {\n output.unwrappedExpressions.push(generate(attr.value).code);\n }\n // If it's an array, flag as an unwrapped expression\n if (t.isArrayExpression(attr.value.expression)) {\n output.unwrappedExpressions.push(\n generate(attr.value.expression).code\n );\n }\n attrValue = buildJSXTree({\n node: attr.value,\n insideT: true,\n inDerive: inDerive,\n scopeNode,\n helperPath: helperValue,\n config,\n state,\n output,\n });\n }\n // For HTML content props, only accept static string expressions\n else if (isHtmlContentProp) {\n const staticAnalysis = isStaticExpression(\n attr.value.expression,\n true\n );\n if (\n staticAnalysis.isStatic &&\n staticAnalysis.value !== undefined\n ) {\n attrValue = staticAnalysis.value;\n }\n // Otherwise attrValue stays null and won't be included\n }\n }\n }\n props[attrName] = attrValue;\n }\n });\n\n if (elementIsVariable) {\n if (componentType === DERIVE_COMPONENT) {\n const helperElement = helperPath.get('children');\n const results = {\n nodeType: 'element' as const,\n type: componentType,\n props,\n };\n // Create children array if necessary\n const childrenArray: (JsxTree | MultiplicationNode)[] = [];\n if (state.visited === null) {\n state.visited = new Set();\n }\n for (let index = 0; index < element.children.length; index++) {\n const helperChild = helperElement[index];\n const result = buildJSXTree({\n node: helperChild.node,\n insideT: true,\n inDerive: true,\n scopeNode,\n helperPath: helperChild,\n config,\n state,\n output,\n });\n // Flatten array results from _T transparency unwrap inside Derive\n if (Array.isArray(result)) {\n childrenArray.push(...result);\n } else {\n childrenArray.push(result);\n }\n }\n if (childrenArray.length) {\n results.props.children = childrenArray;\n }\n return results;\n }\n\n return {\n nodeType: 'element',\n // if componentType is undefined, use typeName\n // Basically, if componentType is not a GT component, use typeName such as <div>\n type: componentType ?? typeName ?? '',\n props,\n };\n }\n\n const children: (JsxTree | MultiplicationNode)[] = element.children\n .flatMap((child, index) => {\n const result = buildJSXTree({\n node: child,\n insideT: true,\n inDerive: inDerive,\n scopeNode,\n helperPath: helperPath.get('children')[index],\n config,\n state,\n output,\n });\n // Flatten array results from _T transparency unwrap inside Derive\n if (Array.isArray(result)) return result;\n return [result];\n })\n .filter(\n (child): child is JsxTree | MultiplicationNode =>\n child !== null && child !== ''\n );\n\n if (children.length === 1) {\n props.children = children[0];\n } else if (children.length > 1) {\n props.children = children;\n }\n\n return {\n nodeType: 'element',\n // if componentType is undefined, use typeName\n // Basically, if componentType is not a GT component, use typeName such as <div>\n type: componentType ?? typeName,\n props,\n };\n }\n // If it's a JSX fragment\n else if (t.isJSXFragment(node)) {\n const children = node.children\n .flatMap((child: JSXChildNode, index: number) => {\n const result = buildJSXTree({\n node: child,\n insideT: true,\n inDerive: inDerive,\n scopeNode,\n helperPath: helperPath.get('children')[index],\n config,\n state,\n output,\n });\n // Flatten array results from _T transparency unwrap inside Derive\n if (Array.isArray(result)) return result;\n return [result];\n })\n .filter(\n (child): child is JsxTree | MultiplicationNode =>\n child !== null && child !== ''\n );\n\n const props: JSXProps = {};\n\n if (children.length === 1) {\n props.children = children[0];\n } else if (children.length > 1) {\n props.children = children;\n }\n\n return {\n nodeType: 'element',\n type: '',\n props,\n };\n }\n // If it's a string literal (standalone)\n else if (t.isStringLiteral(node)) {\n return node.value;\n }\n // If it's a template literal\n else if (t.isTemplateLiteral(node)) {\n // We've already checked that it's derivable, and and added a warning if it's not, this check is just for fallback behavior\n if (\n !isStaticExpression(node, true).isStatic ||\n node.quasis[0].value.cooked === undefined\n ) {\n return generate(node).code;\n }\n return node.quasis[0].value.cooked;\n } else if (t.isNullLiteral(node)) {\n // If it's null, return null\n return null;\n } else if (t.isBooleanLiteral(node)) {\n // If it's a boolean, return the boolean\n return node.value;\n } else if (t.isNumericLiteral(node)) {\n // If it's a number, return the number\n return node.value.toString();\n }\n // Negative\n else if (t.isUnaryExpression(node)) {\n // If it's a unary expression, return the expression\n const staticAnalysis = isStaticExpression(node, true);\n if (staticAnalysis.isStatic && staticAnalysis.value !== undefined) {\n return staticAnalysis.value;\n }\n return generate(node).code;\n } else if (\n (t.isCallExpression(node) && t.isIdentifier(node.callee)) ||\n (t.isAwaitExpression(node) &&\n t.isCallExpression(node.argument) &&\n t.isIdentifier(node.argument.callee))\n ) {\n if (inDerive) {\n const callExpression = (\n node.type === 'AwaitExpression' ? node.argument : node\n ) as t.CallExpression;\n const callee = callExpression.callee as t.Identifier;\n const calleeBinding = scopeNode.scope.getBinding(callee.name);\n if (!calleeBinding) {\n output.warnings.add(\n warnFunctionNotFoundSync(\n config.file,\n callee.name,\n `${callee.loc?.start?.line}:${callee.loc?.start?.column}`\n )\n );\n return null;\n }\n return resolveDeriveFunctionInvocationFromBinding({\n calleeBinding,\n callee,\n config,\n state,\n output,\n });\n } else {\n output.unwrappedExpressions.push(generate(node).code);\n }\n } else if (t.isParenthesizedExpression(node)) {\n const child = node.expression;\n return buildJSXTree({\n node: child,\n insideT,\n inDerive: inDerive,\n scopeNode,\n helperPath: helperPath.get('expression'),\n config,\n state,\n output,\n });\n }\n // If it's some other JS expression\n else if (\n t.isIdentifier(node) ||\n t.isMemberExpression(node) ||\n t.isCallExpression(node) ||\n t.isBinaryExpression(node) ||\n t.isLogicalExpression(node) ||\n t.isConditionalExpression(node)\n ) {\n output.unwrappedExpressions.push(generate(node).code);\n } else {\n if (node === undefined || node === null) {\n output.unwrappedExpressions.push(String(node));\n } else {\n output.unwrappedExpressions.push(generate(node).code);\n }\n }\n return null;\n}\n// end buildJSXTree\n\n// Parses a JSX element and adds it to the updates array\nfunction parseJSXElement({\n node,\n originalName,\n scopeNode,\n updates,\n config,\n state,\n output,\n}: {\n node: t.JSXElement;\n originalName: string;\n scopeNode: NodePath<t.JSXElement>;\n updates: Updates;\n config: ConfigOptions;\n state: StateTracker;\n output: OutputCollector;\n}) {\n const openingElement = node.openingElement;\n const name = openingElement.name;\n\n // Only proceed if it's <T> ...\n // TODO: i don't think this condition is needed anymore\n if (\n !(\n name.type === 'JSXIdentifier' &&\n (originalName === TRANSLATION_COMPONENT ||\n originalName === INTERNAL_TRANSLATION_COMPONENT)\n )\n ) {\n return;\n }\n\n const componentErrors: string[] = [];\n const componentWarnings: Set<string> = new Set();\n const metadata: Metadata = {};\n const relativeFilepath = path.relative(process.cwd(), config.file);\n metadata.filePaths = [relativeFilepath];\n\n // Extract surrounding lines from source file\n const startLine = node.loc?.start?.line;\n const endLine = node.loc?.end?.line;\n if (config.includeSourceCodeContext && startLine && endLine) {\n const entry = extractSourceCode(\n config.file,\n startLine,\n endLine,\n SURROUNDING_LINE_COUNT\n );\n if (entry && relativeFilepath) {\n metadata.sourceCode = { [relativeFilepath]: [entry] };\n }\n }\n\n // We'll track this flag to know if any unwrapped {variable} is found in children\n const unwrappedExpressions: string[] = [];\n\n // Gather <T>'s props\n parseTProps({\n openingElement,\n metadata,\n componentErrors,\n file: config.file,\n });\n\n // Flag for if contains derivable content\n const derivableTracker: DerivableTracker = {\n isDerivable: false,\n };\n\n // Build the JSX tree for this component\n const treeResult = buildJSXTree({\n node,\n scopeNode,\n insideT: false,\n inDerive: config.autoderive ?? false,\n helperPath: scopeNode,\n config,\n state: {\n visited: null,\n callStack: [],\n derivableTracker: derivableTracker,\n importedFunctionsMap: state.importedFunctionsMap,\n },\n output: {\n unwrappedExpressions,\n errors: componentErrors,\n warnings: componentWarnings,\n },\n }) as JsxTree;\n\n // Strip the outer <T> component if necessary\n const jsxTree =\n isElementNode(treeResult) && treeResult.props?.children\n ? // We know this b/c the direct children of <T> will never be a multiplication node\n (treeResult.props.children as JsxTree | JsxTree[])\n : treeResult;\n\n // Update warnings\n if (componentWarnings.size > 0) {\n componentWarnings.forEach((warning) => output.warnings.add(warning));\n }\n\n // Update errors\n if (componentErrors.length > 0) {\n output.errors.push(...componentErrors);\n return;\n }\n\n // Handle whitespace in children\n const whitespaceHandledTree = handleChildrenWhitespace(jsxTree);\n\n // Multiply the tree\n const multipliedTrees = multiplyJsxTree(whitespaceHandledTree);\n\n // Add GT identifiers to the tree\n // TODO: do this in parallel\n const minifiedTress: JsxChildren[] = [];\n for (const multipliedTree of multipliedTrees) {\n // Build set of confirmed GT variable names from importAliases.\n // Only pass when enableAutoJsxInjection is on, to avoid breaking\n // existing behavior where importAliases may be incomplete.\n const gtVariableNames = config.enableAutoJsxInjection\n ? new Set(\n Object.values(config.importAliases).filter(\n (name) =>\n VARIABLE_COMPONENTS.includes(name) && name !== DERIVE_COMPONENT\n )\n )\n : undefined;\n const minifiedTree = addGTIdentifierToSyntaxTree(\n multipliedTree,\n 0,\n gtVariableNames\n );\n minifiedTress.push(\n Array.isArray(minifiedTree) && minifiedTree.length === 1\n ? minifiedTree[0]\n : minifiedTree\n );\n }\n\n // If we found an unwrapped expression, skip\n if (unwrappedExpressions.length > 0) {\n output.errors.push(\n warnHasUnwrappedExpressionSync(\n config.file,\n unwrappedExpressions,\n metadata.id,\n `${node.loc?.start?.line}:${node.loc?.start?.column}`\n )\n );\n return;\n }\n\n // Create a temporary unique flag for derivable content\n const temporaryDeriveId = `derive-temp-id-${randomUUID()}`;\n\n // Resolve derive context variants if present\n let contextVariants: string[] | undefined;\n if (metadata._contextDeriveExpr) {\n const contextExpr = metadata._contextDeriveExpr as t.Expression;\n delete metadata._contextDeriveExpr;\n\n const contextNode = handleDerivation({\n expr: contextExpr,\n tPath: scopeNode,\n file: config.file,\n parsingOptions: config.parsingOptions,\n errors: componentErrors,\n warnings: componentWarnings,\n });\n if (contextNode) {\n contextVariants = nodeToStrings(contextNode);\n }\n }\n\n // <T> is valid here\n for (const minifiedTree of minifiedTress) {\n // Clean the tree by removing null 'c' fields from JsxElements\n const cleanedTree = removeNullChildrenFields(minifiedTree);\n\n if (contextVariants) {\n for (const context of contextVariants) {\n updates.push({\n dataFormat: 'JSX',\n source: cleanedTree,\n metadata: {\n ...structuredClone(metadata),\n context,\n staticId: temporaryDeriveId,\n },\n });\n }\n } else {\n updates.push({\n dataFormat: 'JSX',\n source: cleanedTree,\n metadata: {\n ...structuredClone(metadata),\n ...(derivableTracker.isDerivable && { staticId: temporaryDeriveId }),\n },\n });\n }\n }\n}\n\nfunction resolveDeriveFunctionInvocationFromBinding({\n calleeBinding,\n callee,\n config,\n state,\n output,\n}: {\n calleeBinding: traverseModule.Binding;\n callee: t.Identifier;\n config: ConfigOptions;\n state: StateTracker;\n output: OutputCollector;\n}): MultiplicationNode | null {\n // Stop recursive calls\n type RecursiveGuardCallback = () =>\n | ReturnType<typeof processFunctionDeclarationNodePath>\n | ReturnType<typeof processVariableDeclarationNodePath>\n | ReturnType<typeof processFunctionInFile>;\n function withRecusionGuard({\n cb,\n filename,\n functionName,\n }: {\n cb: RecursiveGuardCallback;\n filename: string;\n functionName: string;\n }) {\n const cacheKey = `${filename}::${functionName}`;\n if (state.callStack.includes(cacheKey)) {\n output.errors.push(\n warnRecursiveFunctionCallSync(config.file, functionName)\n );\n return null;\n }\n state.callStack.push(cacheKey);\n const result = cb();\n state.callStack.pop();\n return result;\n }\n\n // check for recursive calls\n if (calleeBinding.path.isFunctionDeclaration()) {\n // Handle function declarations: function getSubject() { ... }\n const functionName = callee.name;\n const path = calleeBinding.path;\n return withRecusionGuard({\n filename: config.file,\n functionName,\n cb: () =>\n processFunctionDeclarationNodePath({\n config,\n state,\n output,\n path,\n }),\n });\n } else if (\n calleeBinding.path.isVariableDeclarator() &&\n calleeBinding.path.node.init &&\n (t.isArrowFunctionExpression(calleeBinding.path.node.init) ||\n t.isFunctionExpression(calleeBinding.path.node.init))\n ) {\n // Handle arrow functions assigned to variables: const getData = (t) => {...}\n const functionName = callee.name;\n const path = calleeBinding.path;\n return withRecusionGuard({\n filename: config.file,\n functionName,\n cb: () =>\n processVariableDeclarationNodePath({\n config,\n state,\n output,\n functionName,\n path,\n }),\n });\n } else if (state.importedFunctionsMap.has(callee.name)) {\n // Get the original function name\n let originalName: string | undefined;\n if (calleeBinding.path.isImportSpecifier()) {\n originalName = t.isIdentifier(calleeBinding.path.node.imported)\n ? calleeBinding.path.node.imported.name\n : calleeBinding.path.node.imported.value;\n } else if (calleeBinding.path.isImportDefaultSpecifier()) {\n originalName = calleeBinding.path.node.local.name;\n } else if (calleeBinding.path.isImportNamespaceSpecifier()) {\n originalName = calleeBinding.path.node.local.name;\n }\n\n // Function is being imported\n const importPath = state.importedFunctionsMap.get(callee.name)!;\n const filePath = resolveImportPath(\n config.file,\n importPath,\n config.parsingOptions,\n resolveImportPathCache\n );\n if (filePath && originalName) {\n const result = withRecusionGuard({\n filename: filePath,\n functionName: originalName,\n cb: () =>\n processFunctionInFile({\n config,\n state,\n output,\n filePath,\n functionName: originalName,\n }),\n });\n if (result !== null) {\n return result;\n }\n }\n }\n output.warnings.add(\n warnFunctionNotFoundSync(\n config.file,\n callee.name,\n `${callee.loc?.start?.line}:${callee.loc?.start?.column}`\n )\n );\n return null;\n}\n\n/**\n * Searches for a specific user-defined function in a file.\n * This is the resolution logic\n *\n * Handles multiple function declaration patterns:\n * - function getInfo() { ... }\n * - export function getInfo() { ... }\n * - const getInfo = () => { ... }\n *\n * If the function is not found in the file, follows re-exports (export * from './other')\n */\nfunction processFunctionInFile({\n config,\n state,\n output,\n filePath,\n functionName,\n}: {\n config: ConfigOptions;\n state: StateTracker;\n output: OutputCollector;\n filePath: string;\n functionName: string;\n}): MultiplicationNode | null {\n // Create a custom key for the function call\n const cacheKey = `${filePath}::${functionName}`;\n // Check cache first to avoid redundant parsing\n if (processFunctionCache.has(cacheKey)) {\n return processFunctionCache.get(cacheKey) ?? null;\n }\n\n // Prevent infinite loops from circular re-exports\n if (state.visited && state.visited.has(filePath)) {\n return null;\n }\n if (state.visited) {\n state.visited.add(filePath);\n }\n\n let result: MultiplicationNode | null | undefined = undefined;\n try {\n const code = fs.readFileSync(filePath, 'utf8');\n const ast = parse(code, {\n sourceType: 'module',\n plugins: ['jsx', 'typescript'],\n });\n\n const pathsResult = getPathsAndAliases(ast, config.pkgs);\n const importAliases = { ...pathsResult.importAliases };\n // Merge translation component names into importAliases so\n // autoInsertJsxComponents can recognize user T/Var and skip them\n for (const {\n localName,\n originalName,\n } of pathsResult.translationComponentPaths) {\n importAliases[localName] = originalName;\n }\n\n // Auto-inject T/Var into the cross-file AST when enabled,\n // so that Derive extraction sees the same structure as same-file\n if (config.enableAutoJsxInjection) {\n ensureTAndVarImported(ast, importAliases);\n autoInsertJsxComponents(ast, importAliases);\n }\n\n // Collect all imports in this file to track cross-file function calls\n let importedFunctionsMap: Map<string, string> = new Map();\n traverse(ast, {\n Program(path) {\n importedFunctionsMap = buildImportMap(path);\n },\n });\n\n const reExports: string[] = [];\n\n const warnDuplicateFuncDef = (path: NodePath) => {\n output.warnings.add(\n warnDuplicateFunctionDefinitionSync(\n filePath,\n functionName,\n `${path.node.loc?.start?.line}:${path.node.loc?.start?.column}`\n )\n );\n };\n\n traverse(ast, {\n // Handle function declarations: function getInfo() { ... }\n FunctionDeclaration(path) {\n if (path.node.id?.name === functionName) {\n if (result !== undefined) return warnDuplicateFuncDef(path);\n result = processFunctionDeclarationNodePath({\n config: {\n importAliases,\n parsingOptions: config.parsingOptions,\n pkgs: config.pkgs,\n file: filePath,\n enableAutoJsxInjection: config.enableAutoJsxInjection,\n },\n state: {\n ...state,\n importedFunctionsMap,\n },\n output,\n path,\n });\n }\n },\n // Handle variable declarations: const getInfo = () => { ... }\n VariableDeclarator(path) {\n if (\n t.isIdentifier(path.node.id) &&\n path.node.id.name === functionName &&\n path.node.init &&\n (t.isArrowFunctionExpression(path.node.init) ||\n t.isFunctionExpression(path.node.init))\n ) {\n if (result !== undefined) return warnDuplicateFuncDef(path);\n result = processVariableDeclarationNodePath({\n config: {\n importAliases,\n parsingOptions: config.parsingOptions,\n pkgs: config.pkgs,\n file: filePath,\n enableAutoJsxInjection: config.enableAutoJsxInjection,\n },\n state: {\n ...state,\n importedFunctionsMap,\n },\n output,\n functionName,\n path,\n });\n }\n },\n // Collect re-exports: export * from './other'\n ExportAllDeclaration(path) {\n if (t.isStringLiteral(path.node.source)) {\n reExports.push(path.node.source.value);\n }\n },\n // Collect named re-exports: export { foo } from './other'\n ExportNamedDeclaration(path) {\n if (path.node.source && t.isStringLiteral(path.node.source)) {\n // Check if this export includes our function\n const exportsFunction = path.node.specifiers.some((spec) => {\n if (t.isExportSpecifier(spec)) {\n const exportedName = t.isIdentifier(spec.exported)\n ? spec.exported.name\n : spec.exported.value;\n return exportedName === functionName;\n }\n return false;\n });\n if (exportsFunction) {\n reExports.push(path.node.source.value);\n }\n }\n },\n });\n\n // If function not found, follow re-exports\n if (result === undefined && reExports.length > 0) {\n for (const reExportPath of reExports) {\n const resolvedPath = resolveImportPath(\n filePath,\n reExportPath,\n config.parsingOptions,\n resolveImportPathCache\n );\n if (resolvedPath) {\n const foundResult = processFunctionInFile({\n config: {\n importAliases,\n parsingOptions: config.parsingOptions,\n pkgs: config.pkgs,\n file: filePath,\n enableAutoJsxInjection: config.enableAutoJsxInjection,\n },\n state: {\n ...state,\n importedFunctionsMap,\n },\n output,\n filePath: resolvedPath,\n functionName,\n });\n if (foundResult != null) {\n result = foundResult;\n break;\n }\n }\n }\n }\n\n // Mark this function search as processed in the cache\n processFunctionCache.set(cacheKey, result !== undefined ? result : null);\n } catch {\n // Silently skip files that can't be parsed or accessed\n // Still mark as processed to avoid retrying failed parses\n processFunctionCache.set(cacheKey, null);\n }\n return result !== undefined ? result : null;\n}\n\n/**\n * Process a function declaration\n * function getInfo() { ... }\n */\nfunction processFunctionDeclarationNodePath({\n config,\n state,\n output,\n path,\n}: {\n config: ConfigOptions;\n state: StateTracker;\n output: OutputCollector;\n path: NodePath<t.FunctionDeclaration>;\n}): MultiplicationNode | null {\n const result: MultiplicationNode = {\n nodeType: 'multiplication',\n branches: [],\n };\n path.traverse({\n Function(path) {\n path.skip();\n },\n ReturnStatement(returnPath) {\n const returnNodePath = returnPath.get('argument');\n if (!returnNodePath.isExpression()) {\n return;\n }\n const deriveResult = processDeriveExpression({\n config,\n state,\n output,\n expressionNodePath: returnNodePath,\n scopeNode: returnPath,\n });\n if (Array.isArray(deriveResult)) {\n result.branches.push(...deriveResult);\n } else {\n result.branches.push(deriveResult);\n }\n },\n });\n if (result.branches.length === 0) {\n return null;\n }\n return result;\n}\n\n/**\n * Process a variable declaration of a function\n * const getInfo = () => { ... }\n *\n * IMPORTANT: the RHand value must be the function definition, or this will fail\n */\nfunction processVariableDeclarationNodePath({\n config,\n state,\n output,\n functionName,\n path,\n}: {\n config: ConfigOptions;\n state: StateTracker;\n output: OutputCollector;\n functionName: string;\n path: NodePath<t.VariableDeclarator>;\n}): MultiplicationNode | null {\n const result: MultiplicationNode = {\n nodeType: 'multiplication',\n branches: [],\n };\n\n // Enforce the Rhand is a function definition\n const arrowFunctionPath = path.get('init');\n if (!arrowFunctionPath.isArrowFunctionExpression()) {\n output.errors.push(\n warnInvalidDeriveInitSync(\n config.file,\n functionName,\n `${path.node.loc?.start?.line}:${path.node.loc?.start?.column}`\n )\n );\n return null;\n }\n\n const bodyNodePath = arrowFunctionPath.get('body');\n if (bodyNodePath.isExpression()) {\n // process expression return\n const deriveResult = processDeriveExpression({\n config,\n state,\n output,\n expressionNodePath: bodyNodePath,\n scopeNode: arrowFunctionPath,\n });\n if (Array.isArray(deriveResult)) {\n result.branches.push(...deriveResult);\n } else {\n result.branches.push(deriveResult);\n }\n } else {\n // search for a return statement\n bodyNodePath.traverse({\n Function(path) {\n path.skip();\n },\n ReturnStatement(returnPath) {\n const returnNodePath = returnPath.get('argument');\n if (!returnNodePath.isExpression()) {\n return;\n }\n const deriveResult = processDeriveExpression({\n config,\n state,\n output,\n expressionNodePath: returnNodePath,\n scopeNode: returnPath,\n });\n if (Array.isArray(deriveResult)) {\n result.branches.push(...deriveResult);\n } else {\n result.branches.push(deriveResult);\n }\n },\n });\n }\n\n if (result.branches.length === 0) {\n output.errors.push(\n warnMissingReturnSync(\n config.file,\n functionName,\n `${path.node.loc?.start?.line}:${path.node.loc?.start?.column}`\n )\n );\n return null;\n }\n return result;\n}\n\n/**\n * Process a <Derive> expression\n */\nfunction processDeriveExpression({\n config,\n state,\n output,\n expressionNodePath,\n scopeNode,\n}: {\n config: ConfigOptions;\n state: StateTracker;\n output: OutputCollector;\n expressionNodePath: NodePath<t.Expression>;\n scopeNode: NodePath;\n}): JsxTree | MultiplicationNode | (JsxTree | MultiplicationNode)[] {\n // Mark the derivable tracker as true\n state.derivableTracker.isDerivable = true;\n\n // Remove parentheses if they exist\n if (t.isParenthesizedExpression(expressionNodePath.node)) {\n // ex: return (value)\n return processDeriveExpression({\n config,\n state,\n output,\n scopeNode,\n expressionNodePath: expressionNodePath.get('expression'),\n });\n } else if (\n t.isCallExpression(expressionNodePath.node) &&\n t.isIdentifier(expressionNodePath.node.callee)\n ) {\n // ex: return someFunc()\n const callee = expressionNodePath.node.callee;\n const calleeBinding = scopeNode.scope.getBinding(callee.name);\n if (!calleeBinding) {\n output.warnings.add(\n warnFunctionNotFoundSync(\n config.file,\n callee.name,\n `${callee.loc?.start?.line}:${callee.loc?.start?.column}`\n )\n );\n return null;\n }\n // Function is found\n return resolveDeriveFunctionInvocationFromBinding({\n calleeBinding,\n callee,\n config,\n state,\n output,\n });\n } else if (\n t.isAwaitExpression(expressionNodePath.node) &&\n t.isCallExpression(expressionNodePath.node.argument) &&\n t.isIdentifier(expressionNodePath.node.argument.callee)\n ) {\n // ex: return await someFunc()\n const callee = expressionNodePath.node.argument.callee;\n const calleeBinding = scopeNode.scope.getBinding(callee.name);\n if (!calleeBinding) {\n output.warnings.add(\n warnFunctionNotFoundSync(\n config.file,\n callee.name,\n `${callee.loc?.start?.line}:${callee.loc?.start?.column}`\n )\n );\n return null;\n }\n // Function is found\n return resolveDeriveFunctionInvocationFromBinding({\n calleeBinding,\n callee,\n config,\n state,\n output,\n });\n } else if (\n t.isJSXElement(expressionNodePath.node) ||\n t.isJSXFragment(expressionNodePath.node)\n ) {\n // ex: return <div>Jsx content</div>\n return buildJSXTree({\n node: expressionNodePath.node,\n helperPath: expressionNodePath,\n scopeNode,\n insideT: true,\n inDerive: true,\n config,\n state,\n output,\n });\n } else if (t.isConditionalExpression(expressionNodePath.node)) {\n // ex: return condition ? <div>Jsx content</div> : <div>Jsx content</div>\n // since two options here we must construct a new multiplication node\n const consequentNodePath = expressionNodePath.get('consequent');\n const alternateNodePath = expressionNodePath.get('alternate');\n const result: MultiplicationNode = {\n nodeType: 'multiplication' as const,\n branches: [consequentNodePath, alternateNodePath].flatMap(\n (expressionNodePath) => {\n const r = processDeriveExpression({\n config,\n state,\n output,\n scopeNode,\n expressionNodePath,\n });\n return Array.isArray(r) ? r : [r];\n }\n ),\n };\n return result;\n } else if (t.isIdentifier(expressionNodePath.node)) {\n // Resolve variable declarations: const label = cond ? \"boy\" : \"girl\"\n const name = expressionNodePath.node.name;\n const binding = scopeNode.scope.getBinding(name);\n\n if (\n binding &&\n binding.path.isVariableDeclarator() &&\n binding.path.node.init\n ) {\n // Reject destructuring patterns\n if (\n t.isObjectPattern(binding.path.node.id) ||\n t.isArrayPattern(binding.path.node.id)\n ) {\n output.errors.push(\n warnDeriveDestructuringSync(\n config.file,\n name,\n `${expressionNodePath.node.loc?.start?.line}:${expressionNodePath.node.loc?.start?.column}`\n )\n );\n return null;\n }\n\n // Enforce const-only\n const declaration = binding.path.parentPath;\n if (\n declaration?.isVariableDeclaration() &&\n declaration.node.kind !== 'const'\n ) {\n output.warnings.add(\n warnDeriveNonConstVariableSync(\n config.file,\n name,\n declaration.node.kind,\n `${expressionNodePath.node.loc?.start?.line}:${expressionNodePath.node.loc?.start?.column}`\n )\n );\n return null;\n }\n\n // Resolve via parseStringExpression (handles all derivable expression types)\n const errorsBefore = output.errors.length;\n const stringNode = parseStringExpression(\n binding.path.node.init,\n binding.path,\n config.file,\n config.parsingOptions,\n output.warnings,\n output.errors\n );\n if (stringNode) {\n const strings = nodeToStrings(stringNode);\n if (strings.length === 0) {\n return null;\n }\n if (strings.length === 1) {\n return strings[0];\n }\n return {\n nodeType: 'multiplication' as const,\n branches: strings.map((s) => s),\n };\n }\n // parseStringExpression returned null — if it already pushed errors,\n // avoid double-reporting by skipping the buildJSXTree fallthrough.\n if (output.errors.length > errorsBefore) {\n return null;\n }\n }\n\n // Not resolvable — fall through to existing buildJSXTree behavior\n return buildJSXTree({\n node: expressionNodePath.node,\n helperPath: expressionNodePath,\n scopeNode,\n insideT: true,\n inDerive: true,\n config,\n state,\n output,\n });\n } else {\n return buildJSXTree({\n node: expressionNodePath.node,\n helperPath: expressionNodePath,\n scopeNode,\n insideT: true,\n inDerive: true,\n config,\n state,\n output,\n });\n }\n}\n"],"mappings":"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"}
@@ -1,7 +1,7 @@
1
1
  import * as t from '@babel/types';
2
2
  /**
3
3
  * Lightweight name-based check for whether an expression tree contains
4
- * a derive()/declareStatic() call. Does NOT validate imports or scope —
4
+ * a derive() call. Does NOT validate imports or scope —
5
5
  * used as a fast gate before full resolution via handleDerivation().
6
6
  */
7
7
  export declare function containsDeriveCall(expr: t.Expression): boolean;
@@ -3,7 +3,7 @@ import * as t from "@babel/types";
3
3
  //#region src/react/jsx/utils/stringParsing/derivation/containsDeriveCall.ts
4
4
  /**
5
5
  * Lightweight name-based check for whether an expression tree contains
6
- * a derive()/declareStatic() call. Does NOT validate imports or scope —
6
+ * a derive() call. Does NOT validate imports or scope —
7
7
  * used as a fast gate before full resolution via handleDerivation().
8
8
  */
9
9
  function containsDeriveCall(expr) {
@@ -1 +1 @@
1
- {"version":3,"file":"containsDeriveCall.js","names":[],"sources":["../../../../../../src/react/jsx/utils/stringParsing/derivation/containsDeriveCall.ts"],"sourcesContent":["import * as t from '@babel/types';\nimport { GT_DERIVE_STRING_FUNCTIONS } from '../../constants.js';\n\n/**\n * Lightweight name-based check for whether an expression tree contains\n * a derive()/declareStatic() call. Does NOT validate imports or scope —\n * used as a fast gate before full resolution via handleDerivation().\n */\nexport function containsDeriveCall(expr: t.Expression): boolean {\n if (t.isCallExpression(expr) && t.isIdentifier(expr.callee)) {\n return GT_DERIVE_STRING_FUNCTIONS.includes(\n expr.callee.name as (typeof GT_DERIVE_STRING_FUNCTIONS)[number]\n );\n }\n if (t.isBinaryExpression(expr)) {\n return (\n (t.isExpression(expr.left) && containsDeriveCall(expr.left)) ||\n (t.isExpression(expr.right) && containsDeriveCall(expr.right))\n );\n }\n if (t.isTemplateLiteral(expr)) {\n return expr.expressions.some(\n (e) => t.isExpression(e) && containsDeriveCall(e)\n );\n }\n if (t.isConditionalExpression(expr)) {\n return (\n containsDeriveCall(expr.consequent) || containsDeriveCall(expr.alternate)\n );\n }\n if (t.isParenthesizedExpression(expr)) {\n return containsDeriveCall(expr.expression);\n }\n return false;\n}\n"],"mappings":";;;;;;;;AAQA,SAAgB,mBAAmB,MAA6B;AAC9D,KAAI,EAAE,iBAAiB,KAAK,IAAI,EAAE,aAAa,KAAK,OAAO,CACzD,QAAO,2BAA2B,SAChC,KAAK,OAAO,KACb;AAEH,KAAI,EAAE,mBAAmB,KAAK,CAC5B,QACG,EAAE,aAAa,KAAK,KAAK,IAAI,mBAAmB,KAAK,KAAK,IAC1D,EAAE,aAAa,KAAK,MAAM,IAAI,mBAAmB,KAAK,MAAM;AAGjE,KAAI,EAAE,kBAAkB,KAAK,CAC3B,QAAO,KAAK,YAAY,MACrB,MAAM,EAAE,aAAa,EAAE,IAAI,mBAAmB,EAAE,CAClD;AAEH,KAAI,EAAE,wBAAwB,KAAK,CACjC,QACE,mBAAmB,KAAK,WAAW,IAAI,mBAAmB,KAAK,UAAU;AAG7E,KAAI,EAAE,0BAA0B,KAAK,CACnC,QAAO,mBAAmB,KAAK,WAAW;AAE5C,QAAO"}
1
+ {"version":3,"file":"containsDeriveCall.js","names":[],"sources":["../../../../../../src/react/jsx/utils/stringParsing/derivation/containsDeriveCall.ts"],"sourcesContent":["import * as t from '@babel/types';\nimport { GT_DERIVE_STRING_FUNCTIONS } from '../../constants.js';\n\n/**\n * Lightweight name-based check for whether an expression tree contains\n * a derive() call. Does NOT validate imports or scope —\n * used as a fast gate before full resolution via handleDerivation().\n */\nexport function containsDeriveCall(expr: t.Expression): boolean {\n if (t.isCallExpression(expr) && t.isIdentifier(expr.callee)) {\n return GT_DERIVE_STRING_FUNCTIONS.includes(\n expr.callee.name as (typeof GT_DERIVE_STRING_FUNCTIONS)[number]\n );\n }\n if (t.isBinaryExpression(expr)) {\n return (\n (t.isExpression(expr.left) && containsDeriveCall(expr.left)) ||\n (t.isExpression(expr.right) && containsDeriveCall(expr.right))\n );\n }\n if (t.isTemplateLiteral(expr)) {\n return expr.expressions.some(\n (e) => t.isExpression(e) && containsDeriveCall(e)\n );\n }\n if (t.isConditionalExpression(expr)) {\n return (\n containsDeriveCall(expr.consequent) || containsDeriveCall(expr.alternate)\n );\n }\n if (t.isParenthesizedExpression(expr)) {\n return containsDeriveCall(expr.expression);\n }\n return false;\n}\n"],"mappings":";;;;;;;;AAQA,SAAgB,mBAAmB,MAA6B;AAC9D,KAAI,EAAE,iBAAiB,KAAK,IAAI,EAAE,aAAa,KAAK,OAAO,CACzD,QAAO,2BAA2B,SAChC,KAAK,OAAO,KACb;AAEH,KAAI,EAAE,mBAAmB,KAAK,CAC5B,QACG,EAAE,aAAa,KAAK,KAAK,IAAI,mBAAmB,KAAK,KAAK,IAC1D,EAAE,aAAa,KAAK,MAAM,IAAI,mBAAmB,KAAK,MAAM;AAGjE,KAAI,EAAE,kBAAkB,KAAK,CAC3B,QAAO,KAAK,YAAY,MACrB,MAAM,EAAE,aAAa,EAAE,IAAI,mBAAmB,EAAE,CAClD;AAEH,KAAI,EAAE,wBAAwB,KAAK,CACjC,QACE,mBAAmB,KAAK,WAAW,IAAI,mBAAmB,KAAK,UAAU;AAG7E,KAAI,EAAE,0BAA0B,KAAK,CACnC,QAAO,mBAAmB,KAAK,WAAW;AAE5C,QAAO"}
@@ -1 +1 @@
1
- {"version":3,"file":"isDeriveCall.js","names":[],"sources":["../../../../../../src/react/jsx/utils/stringParsing/derivation/isDeriveCall.ts"],"sourcesContent":["import * as t from '@babel/types';\nimport { NodePath } from '@babel/traverse';\nimport { GT_DERIVE_STRING_FUNCTIONS } from '../../constants.js';\nimport { GT_LIBRARIES, GTLibrary } from '../../../../../types/libraries.js';\n\n/**\n * Given an expression, determine if it is a derive call\n * @param expr - The expression to check\n * @returns True if the expression is a derive call, false otherwise\n */\nexport function isDeriveCall({\n expr,\n tPath,\n}: {\n expr: t.Expression;\n tPath: NodePath;\n}): boolean {\n // Check if the expression is a call expression\n if (!t.isCallExpression(expr)) return false;\n const callee = expr.callee;\n if (!t.isIdentifier(callee)) return false;\n\n // Fail if no binding\n const calleeName = callee.name;\n const binding = tPath.scope.getBinding(calleeName);\n if (!binding) return false;\n\n // Check if the callee is imported from GT\n if (!binding.path.isImportSpecifier()) return false;\n const source = binding.path.parentPath?.isImportDeclaration()\n ? binding.path.parentPath?.node.source.value\n : undefined;\n if (!GT_LIBRARIES.includes(source as GTLibrary)) return false;\n\n // Fail if the original name is not 'derive' (or the deprecated 'declareStatic')\n const imported = binding.path.node.imported;\n const originalName = t.isIdentifier(imported)\n ? imported.name\n : imported.value;\n if (\n !GT_DERIVE_STRING_FUNCTIONS.includes(\n originalName as (typeof GT_DERIVE_STRING_FUNCTIONS)[number]\n )\n ) {\n return false;\n }\n\n return true;\n}\n"],"mappings":";;;;;;;;;AAUA,SAAgB,aAAa,EAC3B,MACA,SAIU;AAEV,KAAI,CAAC,EAAE,iBAAiB,KAAK,CAAE,QAAO;CACtC,MAAM,SAAS,KAAK;AACpB,KAAI,CAAC,EAAE,aAAa,OAAO,CAAE,QAAO;CAGpC,MAAM,aAAa,OAAO;CAC1B,MAAM,UAAU,MAAM,MAAM,WAAW,WAAW;AAClD,KAAI,CAAC,QAAS,QAAO;AAGrB,KAAI,CAAC,QAAQ,KAAK,mBAAmB,CAAE,QAAO;CAC9C,MAAM,SAAS,QAAQ,KAAK,YAAY,qBAAqB,GACzD,QAAQ,KAAK,YAAY,KAAK,OAAO,QACrC,KAAA;AACJ,KAAI,CAAC,aAAa,SAAS,OAAoB,CAAE,QAAO;CAGxD,MAAM,WAAW,QAAQ,KAAK,KAAK;CACnC,MAAM,eAAe,EAAE,aAAa,SAAS,GACzC,SAAS,OACT,SAAS;AACb,KACE,CAAC,2BAA2B,SAC1B,aACD,CAED,QAAO;AAGT,QAAO"}
1
+ {"version":3,"file":"isDeriveCall.js","names":[],"sources":["../../../../../../src/react/jsx/utils/stringParsing/derivation/isDeriveCall.ts"],"sourcesContent":["import * as t from '@babel/types';\nimport { NodePath } from '@babel/traverse';\nimport { GT_DERIVE_STRING_FUNCTIONS } from '../../constants.js';\nimport { GT_LIBRARIES, GTLibrary } from '../../../../../types/libraries.js';\n\n/**\n * Given an expression, determine if it is a derive call\n * @param expr - The expression to check\n * @returns True if the expression is a derive call, false otherwise\n */\nexport function isDeriveCall({\n expr,\n tPath,\n}: {\n expr: t.Expression;\n tPath: NodePath;\n}): boolean {\n // Check if the expression is a call expression\n if (!t.isCallExpression(expr)) return false;\n const callee = expr.callee;\n if (!t.isIdentifier(callee)) return false;\n\n // Fail if no binding\n const calleeName = callee.name;\n const binding = tPath.scope.getBinding(calleeName);\n if (!binding) return false;\n\n // Check if the callee is imported from GT\n if (!binding.path.isImportSpecifier()) return false;\n const source = binding.path.parentPath?.isImportDeclaration()\n ? binding.path.parentPath?.node.source.value\n : undefined;\n if (!GT_LIBRARIES.includes(source as GTLibrary)) return false;\n\n // Fail if the original name is not 'derive'\n const imported = binding.path.node.imported;\n const originalName = t.isIdentifier(imported)\n ? imported.name\n : imported.value;\n if (\n !GT_DERIVE_STRING_FUNCTIONS.includes(\n originalName as (typeof GT_DERIVE_STRING_FUNCTIONS)[number]\n )\n ) {\n return false;\n }\n\n return true;\n}\n"],"mappings":";;;;;;;;;AAUA,SAAgB,aAAa,EAC3B,MACA,SAIU;AAEV,KAAI,CAAC,EAAE,iBAAiB,KAAK,CAAE,QAAO;CACtC,MAAM,SAAS,KAAK;AACpB,KAAI,CAAC,EAAE,aAAa,OAAO,CAAE,QAAO;CAGpC,MAAM,aAAa,OAAO;CAC1B,MAAM,UAAU,MAAM,MAAM,WAAW,WAAW;AAClD,KAAI,CAAC,QAAS,QAAO;AAGrB,KAAI,CAAC,QAAQ,KAAK,mBAAmB,CAAE,QAAO;CAC9C,MAAM,SAAS,QAAQ,KAAK,YAAY,qBAAqB,GACzD,QAAQ,KAAK,YAAY,KAAK,OAAO,QACrC,KAAA;AACJ,KAAI,CAAC,aAAa,SAAS,OAAoB,CAAE,QAAO;CAGxD,MAAM,WAAW,QAAQ,KAAK,KAAK;CACnC,MAAM,eAAe,EAAE,aAAa,SAAS,GACzC,SAAS,OACT,SAAS;AACb,KACE,CAAC,2BAA2B,SAC1B,aACD,CAED,QAAO;AAGT,QAAO"}
@@ -55,7 +55,6 @@ async function createDictionaryUpdates(dictionaryPath, errors, warnings, esbuild
55
55
  hash: hashSource({
56
56
  source: entry,
57
57
  ...context && { context },
58
- ...id && { id },
59
58
  ...maxChars != null && { maxChars: Math.abs(maxChars) },
60
59
  dataFormat: "ICU"
61
60
  })
@@ -1 +1 @@
1
- {"version":3,"file":"createDictionaryUpdates.js","names":[],"sources":["../../../src/react/parse/createDictionaryUpdates.ts"],"sourcesContent":["import fs from 'node:fs';\nimport path from 'node:path';\nimport os from 'os';\nimport { build, BuildOptions } from 'esbuild';\nimport { Updates } from '../../types/index.js';\nimport flattenDictionary from '../utils/flattenDictionary.js';\nimport loadJSON from '../../fs/loadJSON.js';\nimport { hashSource } from 'generaltranslation/id';\nimport getEntryAndMetadata from '../utils/getEntryAndMetadata.js';\nimport { logger } from '../../console/logger.js';\nimport { randomUUID } from 'node:crypto';\nimport { isValidIcu } from '../jsx/evaluateJsx.js';\nimport {\n warnInvalidIcuSync,\n warnInvalidMaxCharsSync,\n} from '../../console/index.js';\nimport { exitSync } from '../../console/logging.js';\nimport type { Dictionary, DictionaryEntry } from '../../types/data.js';\n\nexport async function createDictionaryUpdates(\n dictionaryPath: string,\n errors: string[],\n warnings: string[],\n esbuildConfig?: BuildOptions\n): Promise<Updates> {\n let dictionary: Dictionary = {};\n // ---- HANDLE JSON STRING DICTIONARY ----- //\n\n if (dictionaryPath.endsWith('.json')) {\n dictionary = flattenDictionary(\n (loadJSON(dictionaryPath) || {}) as Dictionary\n );\n }\n\n // ----- HANDLE REACT DICTIONARY ---- //\n else {\n const result = await build({\n ...esbuildConfig,\n entryPoints: [dictionaryPath],\n write: false,\n });\n\n const bundledCode = result.outputFiles[0].text;\n const tempFilePath = path.join(\n os.tmpdir(),\n `bundled-dictionary-${randomUUID()}.js`\n );\n await fs.promises.writeFile(tempFilePath, bundledCode);\n\n // Load the module using dynamic import\n let dictionaryModule;\n try {\n dictionaryModule = await import(tempFilePath);\n } catch (error) {\n logger.error(`Failed to load the bundled dictionary code: ${error}`);\n exitSync(1);\n } finally {\n // Clean up the temporary file\n await fs.promises.unlink(tempFilePath);\n }\n const unwrappedDictionary = unwrapDictionaryModule(dictionaryModule);\n dictionary = flattenDictionary(unwrappedDictionary as Dictionary);\n }\n\n // ----- CREATE PARTIAL UPDATES ----- //\n\n const updates: Updates = [];\n\n for (const id of Object.keys(dictionary)) {\n const {\n entry,\n metadata: props, // context, etc.\n } = getEntryAndMetadata(dictionary[id] as DictionaryEntry);\n\n // Validate ICU\n const { isValid, error } = isValidIcu(entry);\n if (!isValid) {\n warnings.push(\n warnInvalidIcuSync(dictionaryPath, entry, error ?? 'Unknown error')\n );\n continue;\n }\n\n // Validate maxChars\n if (\n props?.$maxChars &&\n (isNaN(props.$maxChars) || !Number.isInteger(props.$maxChars))\n ) {\n errors.push(\n warnInvalidMaxCharsSync(dictionaryPath, String(props.$maxChars), id)\n );\n continue;\n }\n\n // Map $context to context\n const context = props?.$context;\n const maxChars = props?.$maxChars;\n const metadata: Record<string, unknown> = {\n id,\n ...(context && { context }),\n ...(maxChars != null && { maxChars: Math.abs(maxChars) }),\n // This hash isn't actually used by the GT API, just for consistency sake\n hash: hashSource({\n source: entry,\n ...(context && { context }),\n ...(id && { id }),\n ...(maxChars != null && { maxChars: Math.abs(maxChars) }),\n dataFormat: 'ICU',\n }),\n };\n updates.push({\n dataFormat: 'ICU',\n source: entry,\n metadata,\n });\n }\n\n return updates;\n}\n\nfunction unwrapDictionaryModule(mod: unknown): Dictionary {\n let current = mod;\n\n // Keep unwrapping until we get to the actual dictionary\n while (current && typeof current === 'object') {\n const currentObject = current as Record<string, unknown>;\n const keys = Object.keys(currentObject);\n\n // Check if this looks like a module namespace object (has only module-related keys)\n const isModuleNamespace = keys.every(\n (key) =>\n key === 'default' || key === 'module.exports' || key === '__esModule'\n );\n\n // Check if this is a module with named exports (has 'dictionary' export)\n // Only check for named exports if it's NOT a pure module namespace\n const hasNamedDictionary =\n !isModuleNamespace &&\n 'dictionary' in currentObject &&\n currentObject.dictionary &&\n typeof currentObject.dictionary === 'object' &&\n !Array.isArray(currentObject.dictionary);\n\n if (hasNamedDictionary) {\n // If there's a named 'dictionary' export, use that\n return currentObject.dictionary as Dictionary;\n } else if (isModuleNamespace) {\n // Try to get the default export\n if ('default' in currentObject) {\n let result = currentObject.default;\n\n // If the default export is a function (getter), call it\n if (typeof result === 'function') {\n try {\n result = result();\n } catch {\n // If calling fails, break the loop\n break;\n }\n }\n\n // If we have a valid object, check if we should continue unwrapping\n if (result && typeof result === 'object' && !Array.isArray(result)) {\n const resultKeys = Object.keys(result);\n // Only continue unwrapping if this looks like a getter-based module layer\n // We should NOT continue if this is just a user dictionary with a 'default' property\n const hasGetterProperties = resultKeys.some((key) => {\n try {\n const descriptor = Object.getOwnPropertyDescriptor(result, key);\n return descriptor && typeof descriptor.get === 'function';\n } catch {\n return false;\n }\n });\n\n if (hasGetterProperties) {\n current = result;\n continue;\n } else {\n // This is the actual dictionary, return it\n return result as Dictionary;\n }\n }\n }\n\n // Try module.exports as fallback\n if ('module.exports' in currentObject) {\n let result = currentObject['module.exports'];\n\n if (typeof result === 'function') {\n try {\n result = result();\n } catch {\n // If calling fails, break the loop\n break;\n }\n }\n\n if (result && typeof result === 'object' && !Array.isArray(result)) {\n const resultKeys = Object.keys(result);\n // Only continue unwrapping if this looks like a getter-based module layer\n // We should NOT continue if this is just a user dictionary with a 'default' property\n const hasGetterProperties = resultKeys.some((key) => {\n try {\n const descriptor = Object.getOwnPropertyDescriptor(result, key);\n return descriptor && typeof descriptor.get === 'function';\n } catch {\n return false;\n }\n });\n\n if (hasGetterProperties) {\n current = result;\n continue;\n } else {\n // This is the actual dictionary, return it\n return result as Dictionary;\n }\n }\n }\n\n // If we can't unwrap further, break\n break;\n } else {\n // This appears to be the actual dictionary object, not a module wrapper\n break;\n }\n }\n\n return (current || {}) as Dictionary;\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"createDictionaryUpdates.js","names":[],"sources":["../../../src/react/parse/createDictionaryUpdates.ts"],"sourcesContent":["import fs from 'node:fs';\nimport path from 'node:path';\nimport os from 'os';\nimport { build, BuildOptions } from 'esbuild';\nimport { Updates } from '../../types/index.js';\nimport flattenDictionary from '../utils/flattenDictionary.js';\nimport loadJSON from '../../fs/loadJSON.js';\nimport { hashSource } from 'generaltranslation/id';\nimport getEntryAndMetadata from '../utils/getEntryAndMetadata.js';\nimport { logger } from '../../console/logger.js';\nimport { randomUUID } from 'node:crypto';\nimport { isValidIcu } from '../jsx/evaluateJsx.js';\nimport {\n warnInvalidIcuSync,\n warnInvalidMaxCharsSync,\n} from '../../console/index.js';\nimport { exitSync } from '../../console/logging.js';\nimport type { Dictionary, DictionaryEntry } from '../../types/data.js';\n\nexport async function createDictionaryUpdates(\n dictionaryPath: string,\n errors: string[],\n warnings: string[],\n esbuildConfig?: BuildOptions\n): Promise<Updates> {\n let dictionary: Dictionary = {};\n // ---- HANDLE JSON STRING DICTIONARY ----- //\n\n if (dictionaryPath.endsWith('.json')) {\n dictionary = flattenDictionary(\n (loadJSON(dictionaryPath) || {}) as Dictionary\n );\n }\n\n // ----- HANDLE REACT DICTIONARY ---- //\n else {\n const result = await build({\n ...esbuildConfig,\n entryPoints: [dictionaryPath],\n write: false,\n });\n\n const bundledCode = result.outputFiles[0].text;\n const tempFilePath = path.join(\n os.tmpdir(),\n `bundled-dictionary-${randomUUID()}.js`\n );\n await fs.promises.writeFile(tempFilePath, bundledCode);\n\n // Load the module using dynamic import\n let dictionaryModule;\n try {\n dictionaryModule = await import(tempFilePath);\n } catch (error) {\n logger.error(`Failed to load the bundled dictionary code: ${error}`);\n exitSync(1);\n } finally {\n // Clean up the temporary file\n await fs.promises.unlink(tempFilePath);\n }\n const unwrappedDictionary = unwrapDictionaryModule(dictionaryModule);\n dictionary = flattenDictionary(unwrappedDictionary as Dictionary);\n }\n\n // ----- CREATE PARTIAL UPDATES ----- //\n\n const updates: Updates = [];\n\n for (const id of Object.keys(dictionary)) {\n const {\n entry,\n metadata: props, // context, etc.\n } = getEntryAndMetadata(dictionary[id] as DictionaryEntry);\n\n // Validate ICU\n const { isValid, error } = isValidIcu(entry);\n if (!isValid) {\n warnings.push(\n warnInvalidIcuSync(dictionaryPath, entry, error ?? 'Unknown error')\n );\n continue;\n }\n\n // Validate maxChars\n if (\n props?.$maxChars &&\n (isNaN(props.$maxChars) || !Number.isInteger(props.$maxChars))\n ) {\n errors.push(\n warnInvalidMaxCharsSync(dictionaryPath, String(props.$maxChars), id)\n );\n continue;\n }\n\n // Map $context to context\n const context = props?.$context;\n const maxChars = props?.$maxChars;\n const metadata: Record<string, unknown> = {\n id,\n ...(context && { context }),\n ...(maxChars != null && { maxChars: Math.abs(maxChars) }),\n // This hash isn't actually used by the GT API, just for consistency sake\n hash: hashSource({\n source: entry,\n ...(context && { context }),\n ...(maxChars != null && { maxChars: Math.abs(maxChars) }),\n dataFormat: 'ICU',\n }),\n };\n updates.push({\n dataFormat: 'ICU',\n source: entry,\n metadata,\n });\n }\n\n return updates;\n}\n\nfunction unwrapDictionaryModule(mod: unknown): Dictionary {\n let current = mod;\n\n // Keep unwrapping until we get to the actual dictionary\n while (current && typeof current === 'object') {\n const currentObject = current as Record<string, unknown>;\n const keys = Object.keys(currentObject);\n\n // Check if this looks like a module namespace object (has only module-related keys)\n const isModuleNamespace = keys.every(\n (key) =>\n key === 'default' || key === 'module.exports' || key === '__esModule'\n );\n\n // Check if this is a module with named exports (has 'dictionary' export)\n // Only check for named exports if it's NOT a pure module namespace\n const hasNamedDictionary =\n !isModuleNamespace &&\n 'dictionary' in currentObject &&\n currentObject.dictionary &&\n typeof currentObject.dictionary === 'object' &&\n !Array.isArray(currentObject.dictionary);\n\n if (hasNamedDictionary) {\n // If there's a named 'dictionary' export, use that\n return currentObject.dictionary as Dictionary;\n } else if (isModuleNamespace) {\n // Try to get the default export\n if ('default' in currentObject) {\n let result = currentObject.default;\n\n // If the default export is a function (getter), call it\n if (typeof result === 'function') {\n try {\n result = result();\n } catch {\n // If calling fails, break the loop\n break;\n }\n }\n\n // If we have a valid object, check if we should continue unwrapping\n if (result && typeof result === 'object' && !Array.isArray(result)) {\n const resultKeys = Object.keys(result);\n // Only continue unwrapping if this looks like a getter-based module layer\n // We should NOT continue if this is just a user dictionary with a 'default' property\n const hasGetterProperties = resultKeys.some((key) => {\n try {\n const descriptor = Object.getOwnPropertyDescriptor(result, key);\n return descriptor && typeof descriptor.get === 'function';\n } catch {\n return false;\n }\n });\n\n if (hasGetterProperties) {\n current = result;\n continue;\n } else {\n // This is the actual dictionary, return it\n return result as Dictionary;\n }\n }\n }\n\n // Try module.exports as fallback\n if ('module.exports' in currentObject) {\n let result = currentObject['module.exports'];\n\n if (typeof result === 'function') {\n try {\n result = result();\n } catch {\n // If calling fails, break the loop\n break;\n }\n }\n\n if (result && typeof result === 'object' && !Array.isArray(result)) {\n const resultKeys = Object.keys(result);\n // Only continue unwrapping if this looks like a getter-based module layer\n // We should NOT continue if this is just a user dictionary with a 'default' property\n const hasGetterProperties = resultKeys.some((key) => {\n try {\n const descriptor = Object.getOwnPropertyDescriptor(result, key);\n return descriptor && typeof descriptor.get === 'function';\n } catch {\n return false;\n }\n });\n\n if (hasGetterProperties) {\n current = result;\n continue;\n } else {\n // This is the actual dictionary, return it\n return result as Dictionary;\n }\n }\n }\n\n // If we can't unwrap further, break\n break;\n } else {\n // This appears to be the actual dictionary object, not a module wrapper\n break;\n }\n }\n\n return (current || {}) as Dictionary;\n}\n"],"mappings":";;;;;;;;;;;;;;AAmBA,eAAsB,wBACpB,gBACA,QACA,UACA,eACkB;CAClB,IAAI,aAAyB,EAAE;AAG/B,KAAI,eAAe,SAAS,QAAQ,CAClC,cAAa,kBACV,SAAS,eAAe,IAAI,EAAE,CAChC;MAIE;EAOH,MAAM,eAAc,MANC,MAAM;GACzB,GAAG;GACH,aAAa,CAAC,eAAe;GAC7B,OAAO;GACR,CAAC,EAEyB,YAAY,GAAG;EAC1C,MAAM,eAAe,KAAK,KACxB,GAAG,QAAQ,EACX,sBAAsB,YAAY,CAAC,KACpC;AACD,QAAM,GAAG,SAAS,UAAU,cAAc,YAAY;EAGtD,IAAI;AACJ,MAAI;AACF,sBAAmB,MAAM,OAAO;WACzB,OAAO;AACd,UAAO,MAAM,+CAA+C,QAAQ;AACpE,YAAS,EAAE;YACH;AAER,SAAM,GAAG,SAAS,OAAO,aAAa;;AAGxC,eAAa,kBADe,uBAAuB,iBACD,CAAe;;CAKnE,MAAM,UAAmB,EAAE;AAE3B,MAAK,MAAM,MAAM,OAAO,KAAK,WAAW,EAAE;EACxC,MAAM,EACJ,OACA,UAAU,UACR,oBAAoB,WAAW,IAAuB;EAG1D,MAAM,EAAE,SAAS,UAAU,WAAW,MAAM;AAC5C,MAAI,CAAC,SAAS;AACZ,YAAS,KACP,mBAAmB,gBAAgB,OAAO,SAAS,gBAAgB,CACpE;AACD;;AAIF,MACE,OAAO,cACN,MAAM,MAAM,UAAU,IAAI,CAAC,OAAO,UAAU,MAAM,UAAU,GAC7D;AACA,UAAO,KACL,wBAAwB,gBAAgB,OAAO,MAAM,UAAU,EAAE,GAAG,CACrE;AACD;;EAIF,MAAM,UAAU,OAAO;EACvB,MAAM,WAAW,OAAO;EACxB,MAAM,WAAoC;GACxC;GACA,GAAI,WAAW,EAAE,SAAS;GAC1B,GAAI,YAAY,QAAQ,EAAE,UAAU,KAAK,IAAI,SAAS,EAAE;GAExD,MAAM,WAAW;IACf,QAAQ;IACR,GAAI,WAAW,EAAE,SAAS;IAC1B,GAAI,YAAY,QAAQ,EAAE,UAAU,KAAK,IAAI,SAAS,EAAE;IACxD,YAAY;IACb,CAAC;GACH;AACD,UAAQ,KAAK;GACX,YAAY;GACZ,QAAQ;GACR;GACD,CAAC;;AAGJ,QAAO;;AAGT,SAAS,uBAAuB,KAA0B;CACxD,IAAI,UAAU;AAGd,QAAO,WAAW,OAAO,YAAY,UAAU;EAC7C,MAAM,gBAAgB;EAItB,MAAM,oBAHO,OAAO,KAAK,cAGK,CAAC,OAC5B,QACC,QAAQ,aAAa,QAAQ,oBAAoB,QAAQ,aAC5D;AAWD,MANE,CAAC,qBACD,gBAAgB,iBAChB,cAAc,cACd,OAAO,cAAc,eAAe,YACpC,CAAC,MAAM,QAAQ,cAAc,WAAW,CAIxC,QAAO,cAAc;WACZ,mBAAmB;AAE5B,OAAI,aAAa,eAAe;IAC9B,IAAI,SAAS,cAAc;AAG3B,QAAI,OAAO,WAAW,WACpB,KAAI;AACF,cAAS,QAAQ;YACX;AAEN;;AAKJ,QAAI,UAAU,OAAO,WAAW,YAAY,CAAC,MAAM,QAAQ,OAAO,CAahE,KAZmB,OAAO,KAAK,OAGO,CAAC,MAAM,QAAQ;AACnD,SAAI;MACF,MAAM,aAAa,OAAO,yBAAyB,QAAQ,IAAI;AAC/D,aAAO,cAAc,OAAO,WAAW,QAAQ;aACzC;AACN,aAAO;;MAIY,EAAE;AACvB,eAAU;AACV;UAGA,QAAO;;AAMb,OAAI,oBAAoB,eAAe;IACrC,IAAI,SAAS,cAAc;AAE3B,QAAI,OAAO,WAAW,WACpB,KAAI;AACF,cAAS,QAAQ;YACX;AAEN;;AAIJ,QAAI,UAAU,OAAO,WAAW,YAAY,CAAC,MAAM,QAAQ,OAAO,CAahE,KAZmB,OAAO,KAAK,OAGO,CAAC,MAAM,QAAQ;AACnD,SAAI;MACF,MAAM,aAAa,OAAO,yBAAyB,QAAQ,IAAI;AAC/D,aAAO,cAAc,OAAO,WAAW,QAAQ;aACzC;AACN,aAAO;;MAIY,EAAE;AACvB,eAAU;AACV;UAGA,QAAO;;AAMb;QAGA;;AAIJ,QAAQ,WAAW,EAAE"}
@@ -72,7 +72,7 @@ async function createInlineUpdates(pkg, validate, filePatterns, parsingFlags, pa
72
72
  });
73
73
  if (parsingFlags.enableAutoJsxInjection) {
74
74
  for (const { localName, originalName } of translationComponentPaths) importAliases[localName] = originalName;
75
- ensureTAndVarImported(ast, importAliases);
75
+ ensureTAndVarImported(ast, importAliases, parsingFlags.legacyGtReactImportSource);
76
76
  autoInsertJsxComponents(ast, importAliases);
77
77
  traverse(ast, { Program(programPath) {
78
78
  programPath.scope.crawl();
@@ -1 +1 @@
1
- {"version":3,"file":"createInlineUpdates.js","names":[],"sources":["../../../src/react/parse/createInlineUpdates.ts"],"sourcesContent":["import fs from 'node:fs';\nimport { Updates } from '../../types/index.js';\n\nimport { parse } from '@babel/parser';\nimport { parseTranslationComponent } from '../jsx/utils/jsxParsing/parseJsx.js';\nimport { parseStrings } from '../jsx/utils/parseStringFunction.js';\nimport { logger } from '../../console/logger.js';\nimport { matchFiles } from '../../fs/matchFiles.js';\nimport { DEFAULT_SRC_PATTERNS } from '../../config/generateSettings.js';\nimport type {\n ParsingConfigOptions,\n GTParsingFlags,\n} from '../../types/parsing.js';\nimport { resolveAutoderive } from '../../types/parsing.js';\nimport { getPathsAndAliases } from '../jsx/utils/getPathsAndAliases.js';\nimport {\n GTLibrary,\n GT_LIBRARIES_UPSTREAM,\n REACT_LIBRARIES,\n ReactLibrary,\n} from '../../types/libraries.js';\nimport {\n calculateHashes,\n dedupeUpdates,\n linkDeriveUpdates,\n} from '../../extraction/postProcess.js';\nimport {\n ensureTAndVarImported,\n autoInsertJsxComponents,\n} from '../jsx/utils/jsxParsing/autoInsertion.js';\nimport { INTERNAL_TRANSLATION_COMPONENT } from '../jsx/utils/constants.js';\nimport traverseModule from '@babel/traverse';\nconst traverse = traverseModule.default || traverseModule;\n\nexport async function createInlineUpdates(\n pkg: GTLibrary,\n validate: boolean,\n filePatterns: string[] | undefined,\n parsingFlags: GTParsingFlags,\n parsingOptions: ParsingConfigOptions\n): Promise<{ updates: Updates; errors: string[]; warnings: string[] }> {\n const updates: Updates = [];\n\n const errors: string[] = [];\n const warnings: Set<string> = new Set();\n\n const pkgs = getUpstreamPackages(pkg);\n\n const autoderive = resolveAutoderive(parsingFlags.autoderive);\n\n // Use the provided app directory or default to the current directory\n const files = matchFiles(process.cwd(), filePatterns || DEFAULT_SRC_PATTERNS);\n\n for (const file of files) {\n const code = await fs.promises.readFile(file, 'utf8');\n let ast;\n try {\n ast = parse(code, {\n sourceType: 'module',\n plugins: ['jsx', 'typescript'],\n });\n } catch (error) {\n logger.error(`Error parsing file ${file}: ${error}`);\n continue;\n }\n\n // First pass: collect imports and process translation functions\n const { importAliases, inlineTranslationPaths, translationComponentPaths } =\n getPathsAndAliases(ast, pkgs);\n\n // Process translation functions asynchronously\n for (const {\n localName: name,\n originalName,\n path,\n } of inlineTranslationPaths) {\n parseStrings(\n name,\n originalName,\n path,\n {\n parsingOptions,\n file,\n ignoreInlineMetadata: false,\n ignoreDynamicContent: false,\n ignoreInvalidIcu: false,\n ignoreInlineListContent: false,\n includeSourceCodeContext: parsingFlags.includeSourceCodeContext,\n ignoreTaggedTemplates: false,\n ignoreGlobalTaggedTemplates: false,\n // User configurable, otherwise default to AUTO\n autoderiveMethod: autoderive.strings ? 'AUTO' : 'DISABLED',\n },\n { updates, errors, warnings }\n );\n }\n\n // Parse <T> components — PASS 1: user-written T\n if (REACT_LIBRARIES.includes(pkg as ReactLibrary)) {\n for (const { localName, path } of translationComponentPaths) {\n parseTranslationComponent({\n originalName: localName,\n localName,\n path,\n updates,\n config: {\n importAliases,\n parsingOptions,\n pkgs,\n file,\n includeSourceCodeContext: parsingFlags.includeSourceCodeContext,\n autoderive: autoderive.jsx,\n },\n output: {\n errors,\n warnings,\n unwrappedExpressions: [],\n },\n });\n }\n\n // PASS 2: Auto-inject GtInternalTranslateJsx and GtInternalVar and extract (flag-gated)\n if (parsingFlags.enableAutoJsxInjection) {\n // Add translation component names to importAliases so autoInsertJsxComponents\n // recognizes user T as hands-off (getPathsAndAliases separates them out)\n for (const { localName, originalName } of translationComponentPaths) {\n importAliases[localName] = originalName;\n }\n\n // Ensure GtInternalTranslateJsx and GtInternalVar are imported in the AST\n ensureTAndVarImported(ast, importAliases);\n\n // Insert T/Var into the AST\n autoInsertJsxComponents(ast, importAliases);\n\n // Refresh scope to pick up new T references\n traverse(ast, {\n Program(programPath) {\n programPath.scope.crawl();\n },\n });\n\n // Re-collect with updated AST\n const refreshed = getPathsAndAliases(ast, pkgs);\n\n // Add translation component names to refreshed aliases so parseJsx\n // can recognize GtInternalTranslateJsx inside Derive for transparent unwrap\n for (const {\n localName: tLocalName,\n originalName: tOrigName,\n } of refreshed.translationComponentPaths) {\n refreshed.importAliases[tLocalName] = tOrigName;\n }\n\n // Extract only from auto-injected GtInternalTranslateJsx — never re-extract user T\n for (const {\n localName,\n path,\n originalName,\n } of refreshed.translationComponentPaths) {\n if (originalName !== INTERNAL_TRANSLATION_COMPONENT) continue;\n parseTranslationComponent({\n originalName: localName,\n localName,\n path,\n updates,\n config: {\n importAliases: refreshed.importAliases,\n parsingOptions,\n pkgs,\n file,\n includeSourceCodeContext: parsingFlags.includeSourceCodeContext,\n enableAutoJsxInjection: true,\n autoderive: autoderive.jsx,\n },\n output: {\n errors,\n warnings,\n unwrappedExpressions: [],\n },\n });\n }\n }\n }\n }\n\n // Post processing steps:\n await calculateHashes(updates);\n dedupeUpdates(updates);\n linkDeriveUpdates(updates);\n\n return { updates, errors, warnings: [...warnings] };\n}\n\n/**\n * Given a package name, return the upstream packages that it depends on\n * @param pkg - The package name\n * @returns The upstream packages that the package depends on\n */\nfunction getUpstreamPackages(pkg: GTLibrary): GTLibrary[] {\n return GT_LIBRARIES_UPSTREAM[pkg];\n}\n\nexport { dedupeUpdates as _test_dedupeUpdates };\n"],"mappings":";;;;;;;;;;;;;;;AAgCA,MAAM,WAAW,eAAe,WAAW;AAE3C,eAAsB,oBACpB,KACA,UACA,cACA,cACA,gBACqE;CACrE,MAAM,UAAmB,EAAE;CAE3B,MAAM,SAAmB,EAAE;CAC3B,MAAM,2BAAwB,IAAI,KAAK;CAEvC,MAAM,OAAO,oBAAoB,IAAI;CAErC,MAAM,aAAa,kBAAkB,aAAa,WAAW;CAG7D,MAAM,QAAQ,WAAW,QAAQ,KAAK,EAAE,gBAAgB,qBAAqB;AAE7E,MAAK,MAAM,QAAQ,OAAO;EACxB,MAAM,OAAO,MAAM,GAAG,SAAS,SAAS,MAAM,OAAO;EACrD,IAAI;AACJ,MAAI;AACF,SAAM,MAAM,MAAM;IAChB,YAAY;IACZ,SAAS,CAAC,OAAO,aAAa;IAC/B,CAAC;WACK,OAAO;AACd,UAAO,MAAM,sBAAsB,KAAK,IAAI,QAAQ;AACpD;;EAIF,MAAM,EAAE,eAAe,wBAAwB,8BAC7C,mBAAmB,KAAK,KAAK;AAG/B,OAAK,MAAM,EACT,WAAW,MACX,cACA,UACG,uBACH,cACE,MACA,cACA,MACA;GACE;GACA;GACA,sBAAsB;GACtB,sBAAsB;GACtB,kBAAkB;GAClB,yBAAyB;GACzB,0BAA0B,aAAa;GACvC,uBAAuB;GACvB,6BAA6B;GAE7B,kBAAkB,WAAW,UAAU,SAAS;GACjD,EACD;GAAE;GAAS;GAAQ;GAAU,CAC9B;AAIH,MAAI,gBAAgB,SAAS,IAAoB,EAAE;AACjD,QAAK,MAAM,EAAE,WAAW,UAAU,0BAChC,2BAA0B;IACxB,cAAc;IACd;IACA;IACA;IACA,QAAQ;KACN;KACA;KACA;KACA;KACA,0BAA0B,aAAa;KACvC,YAAY,WAAW;KACxB;IACD,QAAQ;KACN;KACA;KACA,sBAAsB,EAAE;KACzB;IACF,CAAC;AAIJ,OAAI,aAAa,wBAAwB;AAGvC,SAAK,MAAM,EAAE,WAAW,kBAAkB,0BACxC,eAAc,aAAa;AAI7B,0BAAsB,KAAK,cAAc;AAGzC,4BAAwB,KAAK,cAAc;AAG3C,aAAS,KAAK,EACZ,QAAQ,aAAa;AACnB,iBAAY,MAAM,OAAO;OAE5B,CAAC;IAGF,MAAM,YAAY,mBAAmB,KAAK,KAAK;AAI/C,SAAK,MAAM,EACT,WAAW,YACX,cAAc,eACX,UAAU,0BACb,WAAU,cAAc,cAAc;AAIxC,SAAK,MAAM,EACT,WACA,MACA,kBACG,UAAU,2BAA2B;AACxC,SAAI,iBAAA,yBAAiD;AACrD,+BAA0B;MACxB,cAAc;MACd;MACA;MACA;MACA,QAAQ;OACN,eAAe,UAAU;OACzB;OACA;OACA;OACA,0BAA0B,aAAa;OACvC,wBAAwB;OACxB,YAAY,WAAW;OACxB;MACD,QAAQ;OACN;OACA;OACA,sBAAsB,EAAE;OACzB;MACF,CAAC;;;;;AAOV,OAAM,gBAAgB,QAAQ;AAC9B,eAAc,QAAQ;AACtB,mBAAkB,QAAQ;AAE1B,QAAO;EAAE;EAAS;EAAQ,UAAU,CAAC,GAAG,SAAS;EAAE;;;;;;;AAQrD,SAAS,oBAAoB,KAA6B;AACxD,QAAO,sBAAsB"}
1
+ {"version":3,"file":"createInlineUpdates.js","names":[],"sources":["../../../src/react/parse/createInlineUpdates.ts"],"sourcesContent":["import fs from 'node:fs';\nimport { Updates } from '../../types/index.js';\n\nimport { parse } from '@babel/parser';\nimport { parseTranslationComponent } from '../jsx/utils/jsxParsing/parseJsx.js';\nimport { parseStrings } from '../jsx/utils/parseStringFunction.js';\nimport { logger } from '../../console/logger.js';\nimport { matchFiles } from '../../fs/matchFiles.js';\nimport { DEFAULT_SRC_PATTERNS } from '../../config/generateSettings.js';\nimport type {\n ParsingConfigOptions,\n GTParsingFlags,\n} from '../../types/parsing.js';\nimport { resolveAutoderive } from '../../types/parsing.js';\nimport { getPathsAndAliases } from '../jsx/utils/getPathsAndAliases.js';\nimport {\n GTLibrary,\n GT_LIBRARIES_UPSTREAM,\n REACT_LIBRARIES,\n ReactLibrary,\n} from '../../types/libraries.js';\nimport {\n calculateHashes,\n dedupeUpdates,\n linkDeriveUpdates,\n} from '../../extraction/postProcess.js';\nimport {\n ensureTAndVarImported,\n autoInsertJsxComponents,\n} from '../jsx/utils/jsxParsing/autoInsertion.js';\nimport { INTERNAL_TRANSLATION_COMPONENT } from '../jsx/utils/constants.js';\nimport traverseModule from '@babel/traverse';\nconst traverse = traverseModule.default || traverseModule;\n\nexport async function createInlineUpdates(\n pkg: GTLibrary,\n validate: boolean,\n filePatterns: string[] | undefined,\n parsingFlags: GTParsingFlags,\n parsingOptions: ParsingConfigOptions\n): Promise<{ updates: Updates; errors: string[]; warnings: string[] }> {\n const updates: Updates = [];\n\n const errors: string[] = [];\n const warnings: Set<string> = new Set();\n\n const pkgs = getUpstreamPackages(pkg);\n\n const autoderive = resolveAutoderive(parsingFlags.autoderive);\n\n // Use the provided app directory or default to the current directory\n const files = matchFiles(process.cwd(), filePatterns || DEFAULT_SRC_PATTERNS);\n\n for (const file of files) {\n const code = await fs.promises.readFile(file, 'utf8');\n let ast;\n try {\n ast = parse(code, {\n sourceType: 'module',\n plugins: ['jsx', 'typescript'],\n });\n } catch (error) {\n logger.error(`Error parsing file ${file}: ${error}`);\n continue;\n }\n\n // First pass: collect imports and process translation functions\n const { importAliases, inlineTranslationPaths, translationComponentPaths } =\n getPathsAndAliases(ast, pkgs);\n\n // Process translation functions asynchronously\n for (const {\n localName: name,\n originalName,\n path,\n } of inlineTranslationPaths) {\n parseStrings(\n name,\n originalName,\n path,\n {\n parsingOptions,\n file,\n ignoreInlineMetadata: false,\n ignoreDynamicContent: false,\n ignoreInvalidIcu: false,\n ignoreInlineListContent: false,\n includeSourceCodeContext: parsingFlags.includeSourceCodeContext,\n ignoreTaggedTemplates: false,\n ignoreGlobalTaggedTemplates: false,\n // User configurable, otherwise default to AUTO\n autoderiveMethod: autoderive.strings ? 'AUTO' : 'DISABLED',\n },\n { updates, errors, warnings }\n );\n }\n\n // Parse <T> components — PASS 1: user-written T\n if (REACT_LIBRARIES.includes(pkg as ReactLibrary)) {\n for (const { localName, path } of translationComponentPaths) {\n parseTranslationComponent({\n originalName: localName,\n localName,\n path,\n updates,\n config: {\n importAliases,\n parsingOptions,\n pkgs,\n file,\n includeSourceCodeContext: parsingFlags.includeSourceCodeContext,\n autoderive: autoderive.jsx,\n },\n output: {\n errors,\n warnings,\n unwrappedExpressions: [],\n },\n });\n }\n\n // PASS 2: Auto-inject GtInternalTranslateJsx and GtInternalVar and extract (flag-gated)\n if (parsingFlags.enableAutoJsxInjection) {\n // Add translation component names to importAliases so autoInsertJsxComponents\n // recognizes user T as hands-off (getPathsAndAliases separates them out)\n for (const { localName, originalName } of translationComponentPaths) {\n importAliases[localName] = originalName;\n }\n\n // Ensure GtInternalTranslateJsx and GtInternalVar are imported in the AST\n ensureTAndVarImported(\n ast,\n importAliases,\n parsingFlags.legacyGtReactImportSource\n );\n\n // Insert T/Var into the AST\n autoInsertJsxComponents(ast, importAliases);\n\n // Refresh scope to pick up new T references\n traverse(ast, {\n Program(programPath) {\n programPath.scope.crawl();\n },\n });\n\n // Re-collect with updated AST\n const refreshed = getPathsAndAliases(ast, pkgs);\n\n // Add translation component names to refreshed aliases so parseJsx\n // can recognize GtInternalTranslateJsx inside Derive for transparent unwrap\n for (const {\n localName: tLocalName,\n originalName: tOrigName,\n } of refreshed.translationComponentPaths) {\n refreshed.importAliases[tLocalName] = tOrigName;\n }\n\n // Extract only from auto-injected GtInternalTranslateJsx — never re-extract user T\n for (const {\n localName,\n path,\n originalName,\n } of refreshed.translationComponentPaths) {\n if (originalName !== INTERNAL_TRANSLATION_COMPONENT) continue;\n parseTranslationComponent({\n originalName: localName,\n localName,\n path,\n updates,\n config: {\n importAliases: refreshed.importAliases,\n parsingOptions,\n pkgs,\n file,\n includeSourceCodeContext: parsingFlags.includeSourceCodeContext,\n enableAutoJsxInjection: true,\n autoderive: autoderive.jsx,\n },\n output: {\n errors,\n warnings,\n unwrappedExpressions: [],\n },\n });\n }\n }\n }\n }\n\n // Post processing steps:\n await calculateHashes(updates);\n dedupeUpdates(updates);\n linkDeriveUpdates(updates);\n\n return { updates, errors, warnings: [...warnings] };\n}\n\n/**\n * Given a package name, return the upstream packages that it depends on\n * @param pkg - The package name\n * @returns The upstream packages that the package depends on\n */\nfunction getUpstreamPackages(pkg: GTLibrary): GTLibrary[] {\n return GT_LIBRARIES_UPSTREAM[pkg];\n}\n\nexport { dedupeUpdates as _test_dedupeUpdates };\n"],"mappings":";;;;;;;;;;;;;;;AAgCA,MAAM,WAAW,eAAe,WAAW;AAE3C,eAAsB,oBACpB,KACA,UACA,cACA,cACA,gBACqE;CACrE,MAAM,UAAmB,EAAE;CAE3B,MAAM,SAAmB,EAAE;CAC3B,MAAM,2BAAwB,IAAI,KAAK;CAEvC,MAAM,OAAO,oBAAoB,IAAI;CAErC,MAAM,aAAa,kBAAkB,aAAa,WAAW;CAG7D,MAAM,QAAQ,WAAW,QAAQ,KAAK,EAAE,gBAAgB,qBAAqB;AAE7E,MAAK,MAAM,QAAQ,OAAO;EACxB,MAAM,OAAO,MAAM,GAAG,SAAS,SAAS,MAAM,OAAO;EACrD,IAAI;AACJ,MAAI;AACF,SAAM,MAAM,MAAM;IAChB,YAAY;IACZ,SAAS,CAAC,OAAO,aAAa;IAC/B,CAAC;WACK,OAAO;AACd,UAAO,MAAM,sBAAsB,KAAK,IAAI,QAAQ;AACpD;;EAIF,MAAM,EAAE,eAAe,wBAAwB,8BAC7C,mBAAmB,KAAK,KAAK;AAG/B,OAAK,MAAM,EACT,WAAW,MACX,cACA,UACG,uBACH,cACE,MACA,cACA,MACA;GACE;GACA;GACA,sBAAsB;GACtB,sBAAsB;GACtB,kBAAkB;GAClB,yBAAyB;GACzB,0BAA0B,aAAa;GACvC,uBAAuB;GACvB,6BAA6B;GAE7B,kBAAkB,WAAW,UAAU,SAAS;GACjD,EACD;GAAE;GAAS;GAAQ;GAAU,CAC9B;AAIH,MAAI,gBAAgB,SAAS,IAAoB,EAAE;AACjD,QAAK,MAAM,EAAE,WAAW,UAAU,0BAChC,2BAA0B;IACxB,cAAc;IACd;IACA;IACA;IACA,QAAQ;KACN;KACA;KACA;KACA;KACA,0BAA0B,aAAa;KACvC,YAAY,WAAW;KACxB;IACD,QAAQ;KACN;KACA;KACA,sBAAsB,EAAE;KACzB;IACF,CAAC;AAIJ,OAAI,aAAa,wBAAwB;AAGvC,SAAK,MAAM,EAAE,WAAW,kBAAkB,0BACxC,eAAc,aAAa;AAI7B,0BACE,KACA,eACA,aAAa,0BACd;AAGD,4BAAwB,KAAK,cAAc;AAG3C,aAAS,KAAK,EACZ,QAAQ,aAAa;AACnB,iBAAY,MAAM,OAAO;OAE5B,CAAC;IAGF,MAAM,YAAY,mBAAmB,KAAK,KAAK;AAI/C,SAAK,MAAM,EACT,WAAW,YACX,cAAc,eACX,UAAU,0BACb,WAAU,cAAc,cAAc;AAIxC,SAAK,MAAM,EACT,WACA,MACA,kBACG,UAAU,2BAA2B;AACxC,SAAI,iBAAA,yBAAiD;AACrD,+BAA0B;MACxB,cAAc;MACd;MACA;MACA;MACA,QAAQ;OACN,eAAe,UAAU;OACzB;OACA;OACA;OACA,0BAA0B,aAAa;OACvC,wBAAwB;OACxB,YAAY,WAAW;OACxB;MACD,QAAQ;OACN;OACA;OACA,sBAAsB,EAAE;OACzB;MACF,CAAC;;;;;AAOV,OAAM,gBAAgB,QAAQ;AAC9B,eAAc,QAAQ;AACtB,mBAAkB,QAAQ;AAE1B,QAAO;EAAE;EAAS;EAAQ,UAAU,CAAC,GAAG,SAAS;EAAE;;;;;;;AAQrD,SAAS,oBAAoB,KAA6B;AACxD,QAAO,sBAAsB"}
@@ -1 +1 @@
1
- {"version":3,"file":"parse.js","names":[],"sources":["../../src/translation/parse.ts"],"sourcesContent":["import { Updates, TranslateFlags } from '../types/index.js';\nimport fs from 'fs';\nimport { logger } from '../console/logger.js';\nimport loadJSON from '../fs/loadJSON.js';\nimport { createDictionaryUpdates } from '../react/parse/createDictionaryUpdates.js';\nimport { createInlineUpdates } from '../react/parse/createInlineUpdates.js';\nimport { createPythonInlineUpdates } from '../python/parse/createPythonInlineUpdates.js';\nimport createESBuildConfig from '../react/config/createESBuildConfig.js';\nimport chalk from 'chalk';\nimport type { ParsingConfigOptions, GTParsingFlags } from '../types/parsing.js';\nimport { exitSync } from '../console/logging.js';\nimport { InlineLibrary, isPythonLibrary } from '../types/libraries.js';\n\n/**\n * Searches for gt-react or gt-next dictionary files and creates updates for them,\n * as well as inline updates for <T> tags and useGT()/getGT() calls\n *\n * @param options - The options object\n * @param sourceDictionary - The source dictionary file path\n * @param pkg - The package name\n * @returns An object containing the updates and errors\n */\nexport async function createUpdates(\n options: TranslateFlags,\n src: string[] | undefined,\n sourceDictionary: string | undefined,\n pkg: InlineLibrary,\n validate: boolean,\n parsingFlags: GTParsingFlags,\n parsingOptions: ParsingConfigOptions\n): Promise<{ updates: Updates; errors: string[]; warnings: string[] }> {\n let updates: Updates = [];\n let errors: string[] = [];\n let warnings: string[] = [];\n\n // Parse dictionary with esbuildConfig\n if (\n sourceDictionary &&\n fs.existsSync(sourceDictionary) &&\n fs.statSync(sourceDictionary).isFile()\n ) {\n if (sourceDictionary.endsWith('.json')) {\n updates = [\n ...updates,\n ...(await createDictionaryUpdates(sourceDictionary, errors, warnings)),\n ];\n } else {\n let esbuildConfig;\n if (options.jsconfig) {\n const jsconfig = loadJSON(options.jsconfig);\n if (!jsconfig) {\n logger.error(\n `Failed to resolve jsconfig.json or tsconfig.json at provided filepath: \"${options.jsconfig}\"`\n );\n exitSync(1);\n }\n esbuildConfig = createESBuildConfig(jsconfig);\n } else {\n esbuildConfig = createESBuildConfig({});\n }\n updates = [\n ...updates,\n ...(await createDictionaryUpdates(\n sourceDictionary,\n errors,\n warnings,\n esbuildConfig\n )),\n ];\n }\n }\n // Scan through project for translatable content\n const {\n updates: newUpdates,\n errors: newErrors,\n warnings: newWarnings,\n } = isPythonLibrary(pkg)\n ? await createPythonInlineUpdates(src)\n : await createInlineUpdates(\n pkg,\n validate,\n src,\n parsingFlags,\n parsingOptions\n );\n\n errors = [...errors, ...newErrors];\n warnings = [...warnings, ...newWarnings];\n updates = [...updates, ...newUpdates];\n\n // Metadata addition and validation\n const idHashMap = new Map<string, string>();\n const hashlessIds = new Set<string>();\n const warnedHashlessDuplicateIds = new Set<string>();\n const duplicateIds = new Set<string>();\n\n const warnHashlessDuplicateId = (id: string) => {\n if (warnedHashlessDuplicateIds.has(id)) return;\n warnings.push(\n `Duplicate id ${chalk.blue(\n id\n )} includes at least one entry without a hash. Hashless duplicate IDs cannot be compared, and later entries may overwrite earlier entries.`\n );\n warnedHashlessDuplicateIds.add(id);\n };\n\n updates = updates.map((update) => {\n const { id, hash } = update.metadata;\n if (!id) return update;\n if (!hash) {\n if (hashlessIds.has(id) || idHashMap.has(id)) {\n warnHashlessDuplicateId(id);\n }\n hashlessIds.add(id);\n return update;\n }\n\n if (hashlessIds.has(id)) {\n warnHashlessDuplicateId(id);\n }\n\n const existingHash = idHashMap.get(id);\n if (existingHash !== undefined) {\n if (existingHash !== hash) {\n errors.push(\n `Hashes don't match on two components with the same id: ${chalk.blue(\n id\n )}. Check your ${chalk.green(\n '<T>'\n )} tags and dictionary entries and make sure you're not accidentally duplicating IDs.`\n );\n duplicateIds.add(id);\n }\n } else {\n idHashMap.set(id, hash);\n }\n return update;\n });\n\n // Filter out updates with duplicate IDs\n updates = updates.filter(\n (update) => !update.metadata.id || !duplicateIds.has(update.metadata.id)\n );\n return { updates, errors, warnings };\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAsBA,eAAsB,cACpB,SACA,KACA,kBACA,KACA,UACA,cACA,gBACqE;CACrE,IAAI,UAAmB,EAAE;CACzB,IAAI,SAAmB,EAAE;CACzB,IAAI,WAAqB,EAAE;AAG3B,KACE,oBACA,GAAG,WAAW,iBAAiB,IAC/B,GAAG,SAAS,iBAAiB,CAAC,QAAQ,CAEtC,KAAI,iBAAiB,SAAS,QAAQ,CACpC,WAAU,CACR,GAAG,SACH,GAAI,MAAM,wBAAwB,kBAAkB,QAAQ,SAAS,CACtE;MACI;EACL,IAAI;AACJ,MAAI,QAAQ,UAAU;GACpB,MAAM,WAAW,SAAS,QAAQ,SAAS;AAC3C,OAAI,CAAC,UAAU;AACb,WAAO,MACL,2EAA2E,QAAQ,SAAS,GAC7F;AACD,aAAS,EAAE;;AAEb,mBAAgB,oBAAoB,SAAS;QAE7C,iBAAgB,oBAAoB,EAAE,CAAC;AAEzC,YAAU,CACR,GAAG,SACH,GAAI,MAAM,wBACR,kBACA,QACA,UACA,cACD,CACF;;CAIL,MAAM,EACJ,SAAS,YACT,QAAQ,WACR,UAAU,gBACR,gBAAgB,IAAI,GACpB,MAAM,0BAA0B,IAAI,GACpC,MAAM,oBACJ,KACA,UACA,KACA,cACA,eACD;AAEL,UAAS,CAAC,GAAG,QAAQ,GAAG,UAAU;AAClC,YAAW,CAAC,GAAG,UAAU,GAAG,YAAY;AACxC,WAAU,CAAC,GAAG,SAAS,GAAG,WAAW;CAGrC,MAAM,4BAAY,IAAI,KAAqB;CAC3C,MAAM,8BAAc,IAAI,KAAa;CACrC,MAAM,6CAA6B,IAAI,KAAa;CACpD,MAAM,+BAAe,IAAI,KAAa;CAEtC,MAAM,2BAA2B,OAAe;AAC9C,MAAI,2BAA2B,IAAI,GAAG,CAAE;AACxC,WAAS,KACP,gBAAgB,MAAM,KACpB,GACD,CAAC,0IACH;AACD,6BAA2B,IAAI,GAAG;;AAGpC,WAAU,QAAQ,KAAK,WAAW;EAChC,MAAM,EAAE,IAAI,SAAS,OAAO;AAC5B,MAAI,CAAC,GAAI,QAAO;AAChB,MAAI,CAAC,MAAM;AACT,OAAI,YAAY,IAAI,GAAG,IAAI,UAAU,IAAI,GAAG,CAC1C,yBAAwB,GAAG;AAE7B,eAAY,IAAI,GAAG;AACnB,UAAO;;AAGT,MAAI,YAAY,IAAI,GAAG,CACrB,yBAAwB,GAAG;EAG7B,MAAM,eAAe,UAAU,IAAI,GAAG;AACtC,MAAI,iBAAiB,KAAA;OACf,iBAAiB,MAAM;AACzB,WAAO,KACL,0DAA0D,MAAM,KAC9D,GACD,CAAC,eAAe,MAAM,MACrB,MACD,CAAC,qFACH;AACD,iBAAa,IAAI,GAAG;;QAGtB,WAAU,IAAI,IAAI,KAAK;AAEzB,SAAO;GACP;AAGF,WAAU,QAAQ,QACf,WAAW,CAAC,OAAO,SAAS,MAAM,CAAC,aAAa,IAAI,OAAO,SAAS,GAAG,CACzE;AACD,QAAO;EAAE;EAAS;EAAQ;EAAU"}
1
+ {"version":3,"file":"parse.js","names":[],"sources":["../../src/translation/parse.ts"],"sourcesContent":["import { Updates, TranslateFlags } from '../types/index.js';\nimport fs from 'fs';\nimport { logger } from '../console/logger.js';\nimport loadJSON from '../fs/loadJSON.js';\nimport { createDictionaryUpdates } from '../react/parse/createDictionaryUpdates.js';\nimport { createInlineUpdates } from '../react/parse/createInlineUpdates.js';\nimport { createPythonInlineUpdates } from '../python/parse/createPythonInlineUpdates.js';\nimport createESBuildConfig from '../react/config/createESBuildConfig.js';\nimport chalk from 'chalk';\nimport type { ParsingConfigOptions, GTParsingFlags } from '../types/parsing.js';\nimport { exitSync } from '../console/logging.js';\nimport { InlineLibrary, isPythonLibrary } from '../types/libraries.js';\n\n/**\n * Searches for gt-react or gt-next dictionary files and creates updates for them,\n * as well as inline updates for <T> tags and useGT()/getGT() calls\n *\n * @param options - The options object\n * @param sourceDictionary - The source dictionary file path\n * @param pkg - The package name\n * @returns An object containing the updates and errors\n */\nexport async function createUpdates(\n options: TranslateFlags,\n src: string[] | undefined,\n sourceDictionary: string | undefined,\n pkg: InlineLibrary,\n validate: boolean,\n parsingFlags: GTParsingFlags,\n parsingOptions: ParsingConfigOptions\n): Promise<{ updates: Updates; errors: string[]; warnings: string[] }> {\n let updates: Updates = [];\n let errors: string[] = [];\n let warnings: string[] = [];\n\n // Parse dictionary with esbuildConfig\n if (\n sourceDictionary &&\n fs.existsSync(sourceDictionary) &&\n fs.statSync(sourceDictionary).isFile()\n ) {\n if (sourceDictionary.endsWith('.json')) {\n updates = [\n ...updates,\n ...(await createDictionaryUpdates(sourceDictionary, errors, warnings)),\n ];\n } else {\n let esbuildConfig;\n if (options.jsconfig) {\n const jsconfig = loadJSON(options.jsconfig);\n if (!jsconfig) {\n logger.error(\n `Failed to resolve jsconfig.json or tsconfig.json at provided filepath: \"${options.jsconfig}\"`\n );\n exitSync(1);\n }\n esbuildConfig = createESBuildConfig(jsconfig);\n } else {\n esbuildConfig = createESBuildConfig({});\n }\n updates = [\n ...updates,\n ...(await createDictionaryUpdates(\n sourceDictionary,\n errors,\n warnings,\n esbuildConfig\n )),\n ];\n }\n }\n // Scan through project for translatable content\n const {\n updates: newUpdates,\n errors: newErrors,\n warnings: newWarnings,\n } = isPythonLibrary(pkg)\n ? await createPythonInlineUpdates(src)\n : await createInlineUpdates(\n pkg,\n validate,\n src,\n parsingFlags,\n parsingOptions\n );\n\n errors = [...errors, ...newErrors];\n warnings = [...warnings, ...newWarnings];\n updates = [...updates, ...newUpdates];\n\n // Validate user-supplied IDs without using them as translation lookup keys.\n const idHashMap = new Map<string, string>();\n const hashlessIds = new Set<string>();\n const warnedHashlessDuplicateIds = new Set<string>();\n const duplicateIds = new Set<string>();\n\n const warnHashlessDuplicateId = (id: string) => {\n if (warnedHashlessDuplicateIds.has(id)) return;\n warnings.push(\n `Duplicate id ${chalk.blue(\n id\n )} includes at least one entry without a hash. Hashless duplicate IDs cannot be compared, and later entries may overwrite earlier entries.`\n );\n warnedHashlessDuplicateIds.add(id);\n };\n\n updates = updates.map((update) => {\n const { id, hash } = update.metadata;\n if (!id) return update;\n if (!hash) {\n if (hashlessIds.has(id) || idHashMap.has(id)) {\n warnHashlessDuplicateId(id);\n }\n hashlessIds.add(id);\n return update;\n }\n\n if (hashlessIds.has(id)) {\n warnHashlessDuplicateId(id);\n }\n\n const existingHash = idHashMap.get(id);\n if (existingHash !== undefined) {\n if (existingHash !== hash) {\n errors.push(\n `Hashes don't match on two components with the same id: ${chalk.blue(\n id\n )}. Check your ${chalk.green(\n '<T>'\n )} tags and dictionary entries and make sure you're not accidentally duplicating IDs.`\n );\n duplicateIds.add(id);\n }\n } else {\n idHashMap.set(id, hash);\n }\n return update;\n });\n\n updates = updates.filter(\n (update) => !update.metadata.id || !duplicateIds.has(update.metadata.id)\n );\n\n return { updates, errors, warnings };\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAsBA,eAAsB,cACpB,SACA,KACA,kBACA,KACA,UACA,cACA,gBACqE;CACrE,IAAI,UAAmB,EAAE;CACzB,IAAI,SAAmB,EAAE;CACzB,IAAI,WAAqB,EAAE;AAG3B,KACE,oBACA,GAAG,WAAW,iBAAiB,IAC/B,GAAG,SAAS,iBAAiB,CAAC,QAAQ,CAEtC,KAAI,iBAAiB,SAAS,QAAQ,CACpC,WAAU,CACR,GAAG,SACH,GAAI,MAAM,wBAAwB,kBAAkB,QAAQ,SAAS,CACtE;MACI;EACL,IAAI;AACJ,MAAI,QAAQ,UAAU;GACpB,MAAM,WAAW,SAAS,QAAQ,SAAS;AAC3C,OAAI,CAAC,UAAU;AACb,WAAO,MACL,2EAA2E,QAAQ,SAAS,GAC7F;AACD,aAAS,EAAE;;AAEb,mBAAgB,oBAAoB,SAAS;QAE7C,iBAAgB,oBAAoB,EAAE,CAAC;AAEzC,YAAU,CACR,GAAG,SACH,GAAI,MAAM,wBACR,kBACA,QACA,UACA,cACD,CACF;;CAIL,MAAM,EACJ,SAAS,YACT,QAAQ,WACR,UAAU,gBACR,gBAAgB,IAAI,GACpB,MAAM,0BAA0B,IAAI,GACpC,MAAM,oBACJ,KACA,UACA,KACA,cACA,eACD;AAEL,UAAS,CAAC,GAAG,QAAQ,GAAG,UAAU;AAClC,YAAW,CAAC,GAAG,UAAU,GAAG,YAAY;AACxC,WAAU,CAAC,GAAG,SAAS,GAAG,WAAW;CAGrC,MAAM,4BAAY,IAAI,KAAqB;CAC3C,MAAM,8BAAc,IAAI,KAAa;CACrC,MAAM,6CAA6B,IAAI,KAAa;CACpD,MAAM,+BAAe,IAAI,KAAa;CAEtC,MAAM,2BAA2B,OAAe;AAC9C,MAAI,2BAA2B,IAAI,GAAG,CAAE;AACxC,WAAS,KACP,gBAAgB,MAAM,KACpB,GACD,CAAC,0IACH;AACD,6BAA2B,IAAI,GAAG;;AAGpC,WAAU,QAAQ,KAAK,WAAW;EAChC,MAAM,EAAE,IAAI,SAAS,OAAO;AAC5B,MAAI,CAAC,GAAI,QAAO;AAChB,MAAI,CAAC,MAAM;AACT,OAAI,YAAY,IAAI,GAAG,IAAI,UAAU,IAAI,GAAG,CAC1C,yBAAwB,GAAG;AAE7B,eAAY,IAAI,GAAG;AACnB,UAAO;;AAGT,MAAI,YAAY,IAAI,GAAG,CACrB,yBAAwB,GAAG;EAG7B,MAAM,eAAe,UAAU,IAAI,GAAG;AACtC,MAAI,iBAAiB,KAAA;OACf,iBAAiB,MAAM;AACzB,WAAO,KACL,0DAA0D,MAAM,KAC9D,GACD,CAAC,eAAe,MAAM,MACrB,MACD,CAAC,qFACH;AACD,iBAAa,IAAI,GAAG;;QAGtB,WAAU,IAAI,IAAI,KAAK;AAEzB,SAAO;GACP;AAEF,WAAU,QAAQ,QACf,WAAW,CAAC,OAAO,SAAS,MAAM,CAAC,aAAa,IAAI,OAAO,SAAS,GAAG,CACzE;AAED,QAAO;EAAE;EAAS;EAAQ;EAAU"}
@@ -70,6 +70,7 @@ export type TranslateFlags = SharedFlags & {
70
70
  experimentalLocalizeStaticImports?: boolean;
71
71
  experimentalLocalizeRelativeAssets?: boolean;
72
72
  experimentalAddHeaderAnchorIds?: 'mintlify' | 'default';
73
+ omitConfigIds?: boolean;
73
74
  excludeStaticUrls?: string[];
74
75
  excludeStaticImports?: string[];
75
76
  docsImportRewrites?: Array<{
@@ -200,6 +201,7 @@ export type Settings = {
200
201
  stageTranslations: boolean;
201
202
  requiresReview?: boolean;
202
203
  publish?: boolean;
204
+ omitConfigIds?: boolean;
203
205
  _versionId?: string;
204
206
  _branchId?: string;
205
207
  version?: string;
@@ -33,6 +33,7 @@ export type BaseParsingFlags = Record<string, unknown>;
33
33
  * @property {boolean | { jsx?: boolean; strings?: boolean }} autoderive - Whether to enable autoderive. A plain boolean enables/disables both JSX and strings. An object enables selectively.
34
34
  * @property {boolean} includeSourceCodeContext - Include surrounding source code lines as context for translations.
35
35
  * @property {boolean} enableAutoJsxInjection - Whether to enable auto-jsx injection for the internal <_T> and <_Var> components.
36
+ * @property {boolean} legacyGtReactImportSource - Whether compiler-injected gt-react imports should use gt-react/browser.
36
37
  */
37
38
  export type GTParsingFlags = BaseParsingFlags & {
38
39
  autoderive: boolean | {
@@ -41,6 +42,7 @@ export type GTParsingFlags = BaseParsingFlags & {
41
42
  };
42
43
  includeSourceCodeContext: boolean;
43
44
  enableAutoJsxInjection: boolean;
45
+ legacyGtReactImportSource: boolean;
44
46
  };
45
47
  /**
46
48
  * Resolves the autoderive config value into separate jsx and strings flags.
@@ -1 +1 @@
1
- {"version":3,"file":"parsing.js","names":[],"sources":["../../src/types/parsing.ts"],"sourcesContent":["import type { SupportedFileExtension } from './index.js';\n\n/**\n * For monorepo projects, checking for extra exports fields in resolved internal packages.\n * For instance, an exported path may be labeled as 'browser' or 'module' or 'default'.\n * These can resolve to different files in the compiled package. This helps us know\n * which files to check when we do resolution.\n *\n * @property conditionNames - The condition names to check for in the resolved package.\n *\n * @example\n * {\n * conditionNames: ['development', 'browser', 'module', 'import', 'require', 'default']\n * }\n */\nexport type ParsingConfigOptions = {\n conditionNames: string[];\n};\n\n/**\n * Base parsing flags for all files.\n * Currently no supported properties\n *\n * Future ideas for flags:\n * - flag for extraction of file name\n * - flag for extraction of last modified timestamp\n * - flag for extraction of git history\n */\nexport type BaseParsingFlags = Record<string, unknown>;\n\n/**\n * Flags for parsing content. Not to be confused with ParsingConfig which helps us enable/disable\n * parsing features depending on the function being parsed. Parsing flags is for users to override\n * some of these defaults or enable/disable other features.\n *\n * @property {boolean | { jsx?: boolean; strings?: boolean }} autoderive - Whether to enable autoderive. A plain boolean enables/disables both JSX and strings. An object enables selectively.\n * @property {boolean} includeSourceCodeContext - Include surrounding source code lines as context for translations.\n * @property {boolean} enableAutoJsxInjection - Whether to enable auto-jsx injection for the internal <_T> and <_Var> components.\n */\nexport type GTParsingFlags = BaseParsingFlags & {\n autoderive: boolean | { jsx?: boolean; strings?: boolean };\n includeSourceCodeContext: boolean;\n enableAutoJsxInjection: boolean;\n};\n\n/**\n * Resolves the autoderive config value into separate jsx and strings flags.\n * - `true` enables both (backward compatible)\n * - `false` disables both (backward compatible)\n * - `{ jsx?: boolean; strings?: boolean }` enables selectively (missing keys default to false)\n */\nexport function resolveAutoderive(\n value: boolean | { jsx?: boolean; strings?: boolean } | undefined\n): { jsx: boolean; strings: boolean } {\n if (value === undefined || typeof value === 'boolean') {\n return { jsx: !!value, strings: !!value };\n }\n return { jsx: value.jsx ?? false, strings: value.strings ?? false };\n}\n\n/**\n * Flags for parsing content with each filetype having its own flags\n * This is really a helper type that helps us map across filetypes\n */\nexport type ParseFlagsByFileType = {\n [K in SupportedFileExtension]?: BaseParsingFlags;\n};\n"],"mappings":";;;;;;;AAmDA,SAAgB,kBACd,OACoC;AACpC,KAAI,UAAU,KAAA,KAAa,OAAO,UAAU,UAC1C,QAAO;EAAE,KAAK,CAAC,CAAC;EAAO,SAAS,CAAC,CAAC;EAAO;AAE3C,QAAO;EAAE,KAAK,MAAM,OAAO;EAAO,SAAS,MAAM,WAAW;EAAO"}
1
+ {"version":3,"file":"parsing.js","names":[],"sources":["../../src/types/parsing.ts"],"sourcesContent":["import type { SupportedFileExtension } from './index.js';\n\n/**\n * For monorepo projects, checking for extra exports fields in resolved internal packages.\n * For instance, an exported path may be labeled as 'browser' or 'module' or 'default'.\n * These can resolve to different files in the compiled package. This helps us know\n * which files to check when we do resolution.\n *\n * @property conditionNames - The condition names to check for in the resolved package.\n *\n * @example\n * {\n * conditionNames: ['development', 'browser', 'module', 'import', 'require', 'default']\n * }\n */\nexport type ParsingConfigOptions = {\n conditionNames: string[];\n};\n\n/**\n * Base parsing flags for all files.\n * Currently no supported properties\n *\n * Future ideas for flags:\n * - flag for extraction of file name\n * - flag for extraction of last modified timestamp\n * - flag for extraction of git history\n */\nexport type BaseParsingFlags = Record<string, unknown>;\n\n/**\n * Flags for parsing content. Not to be confused with ParsingConfig which helps us enable/disable\n * parsing features depending on the function being parsed. Parsing flags is for users to override\n * some of these defaults or enable/disable other features.\n *\n * @property {boolean | { jsx?: boolean; strings?: boolean }} autoderive - Whether to enable autoderive. A plain boolean enables/disables both JSX and strings. An object enables selectively.\n * @property {boolean} includeSourceCodeContext - Include surrounding source code lines as context for translations.\n * @property {boolean} enableAutoJsxInjection - Whether to enable auto-jsx injection for the internal <_T> and <_Var> components.\n * @property {boolean} legacyGtReactImportSource - Whether compiler-injected gt-react imports should use gt-react/browser.\n */\nexport type GTParsingFlags = BaseParsingFlags & {\n autoderive: boolean | { jsx?: boolean; strings?: boolean };\n includeSourceCodeContext: boolean;\n enableAutoJsxInjection: boolean;\n legacyGtReactImportSource: boolean;\n};\n\n/**\n * Resolves the autoderive config value into separate jsx and strings flags.\n * - `true` enables both (backward compatible)\n * - `false` disables both (backward compatible)\n * - `{ jsx?: boolean; strings?: boolean }` enables selectively (missing keys default to false)\n */\nexport function resolveAutoderive(\n value: boolean | { jsx?: boolean; strings?: boolean } | undefined\n): { jsx: boolean; strings: boolean } {\n if (value === undefined || typeof value === 'boolean') {\n return { jsx: !!value, strings: !!value };\n }\n return { jsx: value.jsx ?? false, strings: value.strings ?? false };\n}\n\n/**\n * Flags for parsing content with each filetype having its own flags\n * This is really a helper type that helps us map across filetypes\n */\nexport type ParseFlagsByFileType = {\n [K in SupportedFileExtension]?: BaseParsingFlags;\n};\n"],"mappings":";;;;;;;AAqDA,SAAgB,kBACd,OACoC;AACpC,KAAI,UAAU,KAAA,KAAa,OAAO,UAAU,UAC1C,QAAO;EAAE,KAAK,CAAC,CAAC;EAAO,SAAS,CAAC,CAAC;EAAO;AAE3C,QAAO;EAAE,KAAK,MAAM,OAAO;EAAO,SAAS,MAAM,WAAW;EAAO"}
@@ -1,4 +1,4 @@
1
- import { API_VERSION } from "generaltranslation";
1
+ import { API_VERSION } from "generaltranslation/internal";
2
2
  //#region src/utils/fetch.ts
3
3
  /**
4
4
  * @internal
@@ -1 +1 @@
1
- {"version":3,"file":"fetch.js","names":[],"sources":["../../src/utils/fetch.ts"],"sourcesContent":["import { API_VERSION } from 'generaltranslation';\n\n/**\n * @internal\n *\n * Makes an API request to the General Translation API.\n *\n * Encapsulates URL construction, headers, and JSON parsing.\n */\nexport default async function apiRequest(\n baseUrl: string,\n endpoint: string,\n options?: {\n body?: unknown;\n method?: 'GET' | 'POST' | 'DELETE';\n }\n): Promise<Response> {\n const method = options?.method ?? 'POST';\n\n const requestInit: RequestInit = {\n method,\n headers: {\n 'Content-Type': 'application/json',\n 'gt-api-version': API_VERSION,\n },\n };\n\n if (options?.body !== undefined) {\n requestInit.body = JSON.stringify(options.body);\n }\n\n return fetch(`${baseUrl}${endpoint}`, requestInit);\n}\n"],"mappings":";;;;;;;;;AASA,eAA8B,WAC5B,SACA,UACA,SAImB;CAGnB,MAAM,cAA2B;EAC/B,QAHa,SAAS,UAAU;EAIhC,SAAS;GACP,gBAAgB;GAChB,kBAAkB;GACnB;EACF;AAED,KAAI,SAAS,SAAS,KAAA,EACpB,aAAY,OAAO,KAAK,UAAU,QAAQ,KAAK;AAGjD,QAAO,MAAM,GAAG,UAAU,YAAY,YAAY"}
1
+ {"version":3,"file":"fetch.js","names":[],"sources":["../../src/utils/fetch.ts"],"sourcesContent":["import { API_VERSION } from 'generaltranslation/internal';\n\n/**\n * @internal\n *\n * Makes an API request to the General Translation API.\n *\n * Encapsulates URL construction, headers, and JSON parsing.\n */\nexport default async function apiRequest(\n baseUrl: string,\n endpoint: string,\n options?: {\n body?: unknown;\n method?: 'GET' | 'POST' | 'DELETE';\n }\n): Promise<Response> {\n const method = options?.method ?? 'POST';\n\n const requestInit: RequestInit = {\n method,\n headers: {\n 'Content-Type': 'application/json',\n 'gt-api-version': API_VERSION,\n },\n };\n\n if (options?.body !== undefined) {\n requestInit.body = JSON.stringify(options.body);\n }\n\n return fetch(`${baseUrl}${endpoint}`, requestInit);\n}\n"],"mappings":";;;;;;;;;AASA,eAA8B,WAC5B,SACA,UACA,SAImB;CAGnB,MAAM,cAA2B;EAC/B,QAHa,SAAS,UAAU;EAIhC,SAAS;GACP,gBAAgB;GAChB,kBAAkB;GACnB;EACF;AAED,KAAI,SAAS,SAAS,KAAA,EACpB,aAAY,OAAO,KAAK,UAAU,QAAQ,KAAK;AAGjD,QAAO,MAAM,GAAG,UAAU,YAAY,YAAY"}