@hanzogui/static 8.3.0 → 8.3.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (377) hide show
  1. package/dist/cjs/check-dep-versions.js +438 -0
  2. package/dist/cjs/check-dep-versions.js.map +1 -0
  3. package/dist/cjs/checkDeps.js +343 -0
  4. package/dist/cjs/checkDeps.js.map +1 -0
  5. package/dist/cjs/constants.js +13 -0
  6. package/dist/cjs/constants.js.map +1 -0
  7. package/dist/cjs/exports.js +27 -0
  8. package/dist/cjs/exports.js.map +1 -0
  9. package/dist/cjs/extractor/accessSafe.js +17 -0
  10. package/dist/cjs/extractor/accessSafe.js.map +1 -0
  11. package/dist/cjs/extractor/babelParse.js +27 -0
  12. package/dist/cjs/extractor/babelParse.js.map +1 -0
  13. package/dist/cjs/extractor/buildClassName.js +65 -0
  14. package/dist/cjs/extractor/buildClassName.js.map +1 -0
  15. package/dist/cjs/extractor/bundle.js +257 -0
  16. package/dist/cjs/extractor/bundle.js.map +1 -0
  17. package/dist/cjs/extractor/bundleConfig.js +794 -0
  18. package/dist/cjs/extractor/bundleConfig.js.map +1 -0
  19. package/dist/cjs/extractor/concatClassName.js +101 -0
  20. package/dist/cjs/extractor/concatClassName.js.map +1 -0
  21. package/dist/cjs/extractor/createEvaluator.js +56 -0
  22. package/dist/cjs/extractor/createEvaluator.js.map +1 -0
  23. package/dist/cjs/extractor/createExtractor.js +2285 -0
  24. package/dist/cjs/extractor/createExtractor.js.map +1 -0
  25. package/dist/cjs/extractor/createLogger.js +34 -0
  26. package/dist/cjs/extractor/createLogger.js.map +1 -0
  27. package/dist/cjs/extractor/detectModuleFormat.js +41 -0
  28. package/dist/cjs/extractor/detectModuleFormat.js.map +1 -0
  29. package/dist/cjs/extractor/ensureImportingConcat.js +23 -0
  30. package/dist/cjs/extractor/ensureImportingConcat.js.map +1 -0
  31. package/dist/cjs/extractor/errors.js +7 -0
  32. package/dist/cjs/extractor/errors.js.map +1 -0
  33. package/dist/cjs/extractor/esbuildAliasPlugin.js +43 -0
  34. package/dist/cjs/extractor/esbuildAliasPlugin.js.map +1 -0
  35. package/dist/cjs/extractor/esbuildTsconfigPaths.js +68 -0
  36. package/dist/cjs/extractor/esbuildTsconfigPaths.js.map +1 -0
  37. package/dist/cjs/extractor/evaluateAstNode.js +107 -0
  38. package/dist/cjs/extractor/evaluateAstNode.js.map +1 -0
  39. package/dist/cjs/extractor/extractHelpers.js +183 -0
  40. package/dist/cjs/extractor/extractHelpers.js.map +1 -0
  41. package/dist/cjs/extractor/extractMediaStyle.js +143 -0
  42. package/dist/cjs/extractor/extractMediaStyle.js.map +1 -0
  43. package/dist/cjs/extractor/extractToClassNames.js +541 -0
  44. package/dist/cjs/extractor/extractToClassNames.js.map +1 -0
  45. package/dist/cjs/extractor/extractToNative.js +404 -0
  46. package/dist/cjs/extractor/extractToNative.js.map +1 -0
  47. package/dist/cjs/extractor/extractablePath.js +89 -0
  48. package/dist/cjs/extractor/extractablePath.js.map +1 -0
  49. package/dist/cjs/extractor/findTopmostFunction.js +17 -0
  50. package/dist/cjs/extractor/findTopmostFunction.js.map +1 -0
  51. package/dist/cjs/extractor/generatedUid.js +35 -0
  52. package/dist/cjs/extractor/generatedUid.js.map +1 -0
  53. package/dist/cjs/extractor/getGuiConfigPathFromOptionsConfig.js +21 -0
  54. package/dist/cjs/extractor/getGuiConfigPathFromOptionsConfig.js.map +1 -0
  55. package/dist/cjs/extractor/getPrefixLogs.js +9 -0
  56. package/dist/cjs/extractor/getPrefixLogs.js.map +1 -0
  57. package/dist/cjs/extractor/getPropValueFromAttributes.js +75 -0
  58. package/dist/cjs/extractor/getPropValueFromAttributes.js.map +1 -0
  59. package/dist/cjs/extractor/getSourceModule.js +81 -0
  60. package/dist/cjs/extractor/getSourceModule.js.map +1 -0
  61. package/dist/cjs/extractor/getStaticBindingsForScope.js +212 -0
  62. package/dist/cjs/extractor/getStaticBindingsForScope.js.map +1 -0
  63. package/dist/cjs/extractor/hasTopLevelAwait.js +29 -0
  64. package/dist/cjs/extractor/hasTopLevelAwait.js.map +1 -0
  65. package/dist/cjs/extractor/hoistClassNames.js +47 -0
  66. package/dist/cjs/extractor/hoistClassNames.js.map +1 -0
  67. package/dist/cjs/extractor/literalToAst.js +83 -0
  68. package/dist/cjs/extractor/literalToAst.js.map +1 -0
  69. package/dist/cjs/extractor/loadFile.js +24 -0
  70. package/dist/cjs/extractor/loadFile.js.map +1 -0
  71. package/dist/cjs/extractor/loadGui.js +414 -0
  72. package/dist/cjs/extractor/loadGui.js.map +1 -0
  73. package/dist/cjs/extractor/logLines.js +20 -0
  74. package/dist/cjs/extractor/logLines.js.map +1 -0
  75. package/dist/cjs/extractor/normalizeTernaries.js +60 -0
  76. package/dist/cjs/extractor/normalizeTernaries.js.map +1 -0
  77. package/dist/cjs/extractor/propsToFontFamilyCache.js +20 -0
  78. package/dist/cjs/extractor/propsToFontFamilyCache.js.map +1 -0
  79. package/dist/cjs/extractor/regenerateConfig.js +151 -0
  80. package/dist/cjs/extractor/regenerateConfig.js.map +1 -0
  81. package/dist/cjs/extractor/removeUnusedHooks.js +84 -0
  82. package/dist/cjs/extractor/removeUnusedHooks.js.map +1 -0
  83. package/dist/cjs/extractor/timer.js +30 -0
  84. package/dist/cjs/extractor/timer.js.map +1 -0
  85. package/dist/cjs/extractor/validHTMLAttributes.js +56 -0
  86. package/dist/cjs/extractor/validHTMLAttributes.js.map +1 -0
  87. package/dist/cjs/extractor/watchGuiConfig.js +56 -0
  88. package/dist/cjs/extractor/watchGuiConfig.js.map +1 -0
  89. package/dist/cjs/getPragmaOptions.js +52 -0
  90. package/dist/cjs/getPragmaOptions.js.map +1 -0
  91. package/dist/cjs/helpers/memoize.js +24 -0
  92. package/dist/cjs/helpers/memoize.js.map +1 -0
  93. package/dist/cjs/helpers/nativeEntry.js +87 -0
  94. package/dist/cjs/helpers/nativeEntry.js.map +1 -0
  95. package/dist/cjs/helpers/requireGuiCore.js +25 -0
  96. package/dist/cjs/helpers/requireGuiCore.js.map +1 -0
  97. package/dist/cjs/here.js +8 -0
  98. package/dist/cjs/here.js.map +1 -0
  99. package/dist/cjs/index.js +8 -0
  100. package/dist/cjs/index.js.map +1 -0
  101. package/dist/cjs/package.json +1 -0
  102. package/dist/cjs/registerRequire.js +263 -0
  103. package/dist/cjs/registerRequire.js.map +1 -0
  104. package/dist/cjs/server.js +41 -0
  105. package/dist/cjs/server.js.map +1 -0
  106. package/dist/cjs/setup.js +2 -0
  107. package/dist/cjs/setup.js.map +1 -0
  108. package/dist/cjs/types.js +3 -0
  109. package/dist/cjs/types.js.map +1 -0
  110. package/dist/cjs/worker.js +95 -0
  111. package/dist/cjs/worker.js.map +1 -0
  112. package/dist/esm/check-dep-versions.js +433 -0
  113. package/dist/esm/check-dep-versions.js.map +1 -0
  114. package/dist/esm/checkDeps.js +339 -0
  115. package/dist/esm/checkDeps.js.map +1 -0
  116. package/dist/esm/constants.js +9 -0
  117. package/dist/esm/constants.js.map +1 -0
  118. package/dist/esm/exports.js +18 -0
  119. package/dist/esm/exports.js.map +1 -0
  120. package/dist/esm/extractor/accessSafe.js +13 -0
  121. package/dist/esm/extractor/accessSafe.js.map +1 -0
  122. package/dist/esm/extractor/babelParse.js +22 -0
  123. package/dist/esm/extractor/babelParse.js.map +1 -0
  124. package/dist/esm/extractor/buildClassName.js +59 -0
  125. package/dist/esm/extractor/buildClassName.js.map +1 -0
  126. package/dist/esm/extractor/bundle.js +252 -0
  127. package/dist/esm/extractor/bundle.js.map +1 -0
  128. package/dist/esm/extractor/bundleConfig.js +781 -0
  129. package/dist/esm/extractor/bundleConfig.js.map +1 -0
  130. package/dist/esm/extractor/concatClassName.js +98 -0
  131. package/dist/esm/extractor/concatClassName.js.map +1 -0
  132. package/dist/esm/extractor/createEvaluator.js +51 -0
  133. package/dist/esm/extractor/createEvaluator.js.map +1 -0
  134. package/dist/esm/extractor/createExtractor.js +2281 -0
  135. package/dist/esm/extractor/createExtractor.js.map +1 -0
  136. package/dist/esm/extractor/createLogger.js +31 -0
  137. package/dist/esm/extractor/createLogger.js.map +1 -0
  138. package/dist/esm/extractor/detectModuleFormat.js +37 -0
  139. package/dist/esm/extractor/detectModuleFormat.js.map +1 -0
  140. package/dist/esm/extractor/ensureImportingConcat.js +19 -0
  141. package/dist/esm/extractor/ensureImportingConcat.js.map +1 -0
  142. package/dist/esm/extractor/errors.js +3 -0
  143. package/dist/esm/extractor/errors.js.map +1 -0
  144. package/dist/esm/extractor/esbuildAliasPlugin.js +39 -0
  145. package/dist/esm/extractor/esbuildAliasPlugin.js.map +1 -0
  146. package/dist/esm/extractor/esbuildTsconfigPaths.js +63 -0
  147. package/dist/esm/extractor/esbuildTsconfigPaths.js.map +1 -0
  148. package/dist/esm/extractor/evaluateAstNode.js +103 -0
  149. package/dist/esm/extractor/evaluateAstNode.js.map +1 -0
  150. package/dist/esm/extractor/extractHelpers.js +166 -0
  151. package/dist/esm/extractor/extractHelpers.js.map +1 -0
  152. package/dist/esm/extractor/extractMediaStyle.js +138 -0
  153. package/dist/esm/extractor/extractMediaStyle.js.map +1 -0
  154. package/dist/esm/extractor/extractToClassNames.js +537 -0
  155. package/dist/esm/extractor/extractToClassNames.js.map +1 -0
  156. package/dist/esm/extractor/extractToNative.js +398 -0
  157. package/dist/esm/extractor/extractToNative.js.map +1 -0
  158. package/dist/esm/extractor/extractablePath.js +84 -0
  159. package/dist/esm/extractor/extractablePath.js.map +1 -0
  160. package/dist/esm/extractor/findTopmostFunction.js +14 -0
  161. package/dist/esm/extractor/findTopmostFunction.js.map +1 -0
  162. package/dist/esm/extractor/generatedUid.js +31 -0
  163. package/dist/esm/extractor/generatedUid.js.map +1 -0
  164. package/dist/esm/extractor/getGuiConfigPathFromOptionsConfig.js +18 -0
  165. package/dist/esm/extractor/getGuiConfigPathFromOptionsConfig.js.map +1 -0
  166. package/dist/esm/extractor/getPrefixLogs.js +6 -0
  167. package/dist/esm/extractor/getPrefixLogs.js.map +1 -0
  168. package/dist/esm/extractor/getPropValueFromAttributes.js +71 -0
  169. package/dist/esm/extractor/getPropValueFromAttributes.js.map +1 -0
  170. package/dist/esm/extractor/getSourceModule.js +77 -0
  171. package/dist/esm/extractor/getSourceModule.js.map +1 -0
  172. package/dist/esm/extractor/getStaticBindingsForScope.js +207 -0
  173. package/dist/esm/extractor/getStaticBindingsForScope.js.map +1 -0
  174. package/dist/esm/extractor/hasTopLevelAwait.js +25 -0
  175. package/dist/esm/extractor/hasTopLevelAwait.js.map +1 -0
  176. package/dist/esm/extractor/hoistClassNames.js +43 -0
  177. package/dist/esm/extractor/hoistClassNames.js.map +1 -0
  178. package/dist/esm/extractor/literalToAst.js +78 -0
  179. package/dist/esm/extractor/literalToAst.js.map +1 -0
  180. package/dist/esm/extractor/loadFile.js +22 -0
  181. package/dist/esm/extractor/loadFile.js.map +1 -0
  182. package/dist/esm/extractor/loadGui.js +402 -0
  183. package/dist/esm/extractor/loadGui.js.map +1 -0
  184. package/dist/esm/extractor/logLines.js +16 -0
  185. package/dist/esm/extractor/logLines.js.map +1 -0
  186. package/dist/esm/extractor/normalizeTernaries.js +56 -0
  187. package/dist/esm/extractor/normalizeTernaries.js.map +1 -0
  188. package/dist/esm/extractor/propsToFontFamilyCache.js +15 -0
  189. package/dist/esm/extractor/propsToFontFamilyCache.js.map +1 -0
  190. package/dist/esm/extractor/regenerateConfig.js +145 -0
  191. package/dist/esm/extractor/regenerateConfig.js.map +1 -0
  192. package/dist/esm/extractor/removeUnusedHooks.js +80 -0
  193. package/dist/esm/extractor/removeUnusedHooks.js.map +1 -0
  194. package/dist/esm/extractor/timer.js +26 -0
  195. package/dist/esm/extractor/timer.js.map +1 -0
  196. package/dist/esm/extractor/validHTMLAttributes.js +53 -0
  197. package/dist/esm/extractor/validHTMLAttributes.js.map +1 -0
  198. package/dist/esm/extractor/watchGuiConfig.js +53 -0
  199. package/dist/esm/extractor/watchGuiConfig.js.map +1 -0
  200. package/dist/esm/getPragmaOptions.js +49 -0
  201. package/dist/esm/getPragmaOptions.js.map +1 -0
  202. package/dist/esm/helpers/memoize.js +21 -0
  203. package/dist/esm/helpers/memoize.js.map +1 -0
  204. package/dist/esm/helpers/nativeEntry.js +82 -0
  205. package/dist/esm/helpers/nativeEntry.js.map +1 -0
  206. package/dist/esm/helpers/requireGuiCore.js +22 -0
  207. package/dist/esm/helpers/requireGuiCore.js.map +1 -0
  208. package/dist/esm/here.js +7 -0
  209. package/dist/esm/here.js.map +1 -0
  210. package/dist/esm/index.js +5 -0
  211. package/dist/esm/index.js.map +1 -0
  212. package/dist/esm/registerRequire.js +256 -0
  213. package/dist/esm/registerRequire.js.map +1 -0
  214. package/dist/esm/server.js +37 -0
  215. package/dist/esm/server.js.map +1 -0
  216. package/dist/esm/setup.js +2 -0
  217. package/dist/esm/setup.js.map +1 -0
  218. package/dist/esm/types.js +2 -0
  219. package/dist/esm/types.js.map +1 -0
  220. package/dist/esm/worker.js +92 -0
  221. package/dist/esm/worker.js.map +1 -0
  222. package/package.json +77 -56
  223. package/src/check-dep-versions.ts +2 -1
  224. package/src/checkDeps.ts +1 -1
  225. package/src/exports.ts +17 -17
  226. package/src/extractor/babelParse.ts +2 -11
  227. package/src/extractor/buildClassName.ts +1 -1
  228. package/src/extractor/bundle.ts +13 -9
  229. package/src/extractor/bundleConfig.ts +25 -21
  230. package/src/extractor/createEvaluator.ts +3 -3
  231. package/src/extractor/createExtractor.ts +59 -77
  232. package/src/extractor/createLogger.ts +2 -2
  233. package/src/extractor/esbuildTsconfigPaths.ts +55 -120
  234. package/src/extractor/evaluateAstNode.ts +2 -2
  235. package/src/extractor/extractHelpers.ts +3 -3
  236. package/src/extractor/extractMediaStyle.ts +3 -3
  237. package/src/extractor/extractToClassNames.ts +12 -12
  238. package/src/extractor/extractToNative.ts +20 -22
  239. package/src/extractor/findTopmostFunction.ts +5 -13
  240. package/src/extractor/getGuiConfigPathFromOptionsConfig.ts +1 -1
  241. package/src/extractor/getPrefixLogs.ts +1 -1
  242. package/src/extractor/getPropValueFromAttributes.ts +2 -2
  243. package/src/extractor/getStaticBindingsForScope.ts +6 -6
  244. package/src/extractor/hasTopLevelAwait.ts +1 -1
  245. package/src/extractor/literalToAst.ts +2 -2
  246. package/src/extractor/loadFile.ts +6 -1
  247. package/src/extractor/loadGui.ts +16 -12
  248. package/src/extractor/normalizeTernaries.ts +3 -3
  249. package/src/extractor/regenerateConfig.ts +10 -6
  250. package/src/extractor/watchGuiConfig.ts +7 -3
  251. package/src/helpers/nativeEntry.ts +92 -0
  252. package/src/helpers/requireGuiCore.ts +8 -3
  253. package/src/here.cjs.ts +6 -0
  254. package/src/here.ts +8 -0
  255. package/src/index.ts +2 -2
  256. package/src/registerRequire.ts +30 -14
  257. package/src/server.ts +1 -1
  258. package/src/types.ts +1 -1
  259. package/src/worker.ts +7 -7
  260. package/types/check-dep-versions.d.ts.map +1 -1
  261. package/types/constants.d.ts +1 -1
  262. package/types/constants.d.ts.map +1 -1
  263. package/types/exports.d.ts +17 -17
  264. package/types/exports.d.ts.map +1 -1
  265. package/types/extractor/babelParse.d.ts.map +1 -1
  266. package/types/extractor/buildClassName.d.ts +1 -1
  267. package/types/extractor/buildClassName.d.ts.map +1 -1
  268. package/types/extractor/bundle.d.ts +66 -66
  269. package/types/extractor/bundle.d.ts.map +1 -1
  270. package/types/extractor/bundleConfig.d.ts +2 -2
  271. package/types/extractor/bundleConfig.d.ts.map +1 -1
  272. package/types/extractor/createEvaluator.d.ts +1 -1
  273. package/types/extractor/createEvaluator.d.ts.map +1 -1
  274. package/types/extractor/createExtractor.d.ts +4 -4
  275. package/types/extractor/createExtractor.d.ts.map +1 -1
  276. package/types/extractor/createLogger.d.ts +1 -1
  277. package/types/extractor/createLogger.d.ts.map +1 -1
  278. package/types/extractor/esbuildAliasPlugin.d.ts.map +1 -1
  279. package/types/extractor/esbuildTsconfigPaths.d.ts +4 -9
  280. package/types/extractor/esbuildTsconfigPaths.d.ts.map +1 -1
  281. package/types/extractor/extractHelpers.d.ts +1 -1
  282. package/types/extractor/extractHelpers.d.ts.map +1 -1
  283. package/types/extractor/extractMediaStyle.d.ts +2 -3
  284. package/types/extractor/extractMediaStyle.d.ts.map +1 -1
  285. package/types/extractor/extractToClassNames.d.ts +2 -2
  286. package/types/extractor/extractToClassNames.d.ts.map +1 -1
  287. package/types/extractor/extractToNative.d.ts +4 -4
  288. package/types/extractor/extractToNative.d.ts.map +1 -1
  289. package/types/extractor/findTopmostFunction.d.ts +1 -1
  290. package/types/extractor/findTopmostFunction.d.ts.map +1 -1
  291. package/types/extractor/getGuiConfigPathFromOptionsConfig.d.ts +1 -1
  292. package/types/extractor/getGuiConfigPathFromOptionsConfig.d.ts.map +1 -1
  293. package/types/extractor/getPrefixLogs.d.ts +1 -1
  294. package/types/extractor/getPrefixLogs.d.ts.map +1 -1
  295. package/types/extractor/loadFile.d.ts +1 -0
  296. package/types/extractor/loadGui.d.ts +1 -1
  297. package/types/extractor/loadGui.d.ts.map +1 -1
  298. package/types/extractor/logLines.d.ts.map +1 -1
  299. package/types/extractor/normalizeTernaries.d.ts +1 -1
  300. package/types/extractor/normalizeTernaries.d.ts.map +1 -1
  301. package/types/extractor/regenerateConfig.d.ts +1 -1
  302. package/types/extractor/regenerateConfig.d.ts.map +1 -1
  303. package/types/extractor/timer.d.ts.map +1 -1
  304. package/types/extractor/validHTMLAttributes.d.ts.map +1 -1
  305. package/types/extractor/watchGuiConfig.d.ts.map +1 -1
  306. package/types/getPragmaOptions.d.ts +1 -1
  307. package/types/helpers/memoize.d.ts +1 -1
  308. package/types/helpers/memoize.d.ts.map +1 -1
  309. package/types/helpers/nativeEntry.d.ts +16 -0
  310. package/types/helpers/nativeEntry.d.ts.map +1 -0
  311. package/types/helpers/requireGuiCore.d.ts +1 -1
  312. package/types/helpers/requireGuiCore.d.ts.map +1 -1
  313. package/types/here.d.ts +3 -0
  314. package/types/here.d.ts.map +1 -0
  315. package/types/index.d.ts +2 -2
  316. package/types/index.d.ts.map +1 -1
  317. package/types/registerRequire.d.ts +1 -1
  318. package/types/registerRequire.d.ts.map +1 -1
  319. package/types/server.d.ts +1 -1
  320. package/types/server.d.ts.map +1 -1
  321. package/types/types.d.ts +1 -1
  322. package/types/types.d.ts.map +1 -1
  323. package/types/worker.d.ts +4 -4
  324. package/types/worker.d.ts.map +1 -1
  325. package/dist/check-dep-versions.cjs +0 -372
  326. package/dist/checkDeps.cjs +0 -271
  327. package/dist/constants.cjs +0 -51
  328. package/dist/exports.cjs +0 -49
  329. package/dist/extractor/accessSafe.cjs +0 -48
  330. package/dist/extractor/babelParse.cjs +0 -56
  331. package/dist/extractor/buildClassName.cjs +0 -86
  332. package/dist/extractor/bundle.cjs +0 -234
  333. package/dist/extractor/bundleConfig.cjs +0 -729
  334. package/dist/extractor/concatClassName.cjs +0 -121
  335. package/dist/extractor/createEvaluator.cjs +0 -88
  336. package/dist/extractor/createExtractor.cjs +0 -1935
  337. package/dist/extractor/createLogger.cjs +0 -50
  338. package/dist/extractor/detectModuleFormat.cjs +0 -55
  339. package/dist/extractor/ensureImportingConcat.cjs +0 -54
  340. package/dist/extractor/errors.cjs +0 -28
  341. package/dist/extractor/esbuildAliasPlugin.cjs +0 -56
  342. package/dist/extractor/esbuildTsconfigPaths.cjs +0 -126
  343. package/dist/extractor/evaluateAstNode.cjs +0 -128
  344. package/dist/extractor/extractHelpers.cjs +0 -182
  345. package/dist/extractor/extractMediaStyle.cjs +0 -169
  346. package/dist/extractor/extractToClassNames.cjs +0 -476
  347. package/dist/extractor/extractToNative.cjs +0 -369
  348. package/dist/extractor/extractablePath.cjs +0 -51
  349. package/dist/extractor/findTopmostFunction.cjs +0 -43
  350. package/dist/extractor/generatedUid.cjs +0 -58
  351. package/dist/extractor/getGuiConfigPathFromOptionsConfig.cjs +0 -41
  352. package/dist/extractor/getPrefixLogs.cjs +0 -31
  353. package/dist/extractor/getPropValueFromAttributes.cjs +0 -85
  354. package/dist/extractor/getSourceModule.cjs +0 -100
  355. package/dist/extractor/getStaticBindingsForScope.cjs +0 -213
  356. package/dist/extractor/hasTopLevelAwait.cjs +0 -62
  357. package/dist/extractor/hoistClassNames.cjs +0 -76
  358. package/dist/extractor/literalToAst.cjs +0 -109
  359. package/dist/extractor/loadFile.cjs +0 -17
  360. package/dist/extractor/loadGui.cjs +0 -373
  361. package/dist/extractor/logLines.cjs +0 -43
  362. package/dist/extractor/normalizeTernaries.cjs +0 -95
  363. package/dist/extractor/propsToFontFamilyCache.cjs +0 -42
  364. package/dist/extractor/regenerateConfig.cjs +0 -178
  365. package/dist/extractor/removeUnusedHooks.cjs +0 -108
  366. package/dist/extractor/timer.cjs +0 -52
  367. package/dist/extractor/validHTMLAttributes.cjs +0 -79
  368. package/dist/extractor/watchGuiConfig.cjs +0 -70
  369. package/dist/getPragmaOptions.cjs +0 -73
  370. package/dist/helpers/memoize.cjs +0 -45
  371. package/dist/helpers/requireGuiCore.cjs +0 -40
  372. package/dist/index.cjs +0 -42
  373. package/dist/registerRequire.cjs +0 -209
  374. package/dist/server.cjs +0 -82
  375. package/dist/setup.cjs +0 -0
  376. package/dist/types.cjs +0 -18
  377. package/dist/worker.cjs +0 -111
@@ -0,0 +1,2285 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createExtractor = createExtractor;
4
+ const tslib_1 = require("tslib");
5
+ const traverse_1 = tslib_1.__importDefault(require("@babel/traverse"));
6
+ const t = tslib_1.__importStar(require("@babel/types"));
7
+ const cli_color_1 = require("@hanzogui/cli-color");
8
+ const reactNativeWebInternals = tslib_1.__importStar(require("@hanzogui/react-native-web-internals"));
9
+ const web_1 = require("@hanzogui/web");
10
+ const node_fs_1 = require("node:fs");
11
+ const node_path_1 = require("node:path");
12
+ const constants_ts_1 = require("../constants.js");
13
+ const requireGuiCore_ts_1 = require("../helpers/requireGuiCore.js");
14
+ const registerRequire_ts_1 = require("../registerRequire.js");
15
+ const createEvaluator_ts_1 = require("./createEvaluator.js");
16
+ const extractablePath_ts_1 = require("./extractablePath.js");
17
+ const evaluateAstNode_ts_1 = require("./evaluateAstNode.js");
18
+ const extractHelpers_ts_1 = require("./extractHelpers.js");
19
+ const findTopmostFunction_ts_1 = require("./findTopmostFunction.js");
20
+ const getStaticBindingsForScope_ts_1 = require("./getStaticBindingsForScope.js");
21
+ const literalToAst_ts_1 = require("./literalToAst.js");
22
+ const loadGui_ts_1 = require("./loadGui.js");
23
+ const logLines_ts_1 = require("./logLines.js");
24
+ const normalizeTernaries_ts_1 = require("./normalizeTernaries.js");
25
+ const propsToFontFamilyCache_ts_1 = require("./propsToFontFamilyCache.js");
26
+ const timer_ts_1 = require("./timer.js");
27
+ const validHTMLAttributes_ts_1 = require("./validHTMLAttributes.js");
28
+ const errors_ts_1 = require("./errors.js");
29
+ const esbuildTsconfigPaths_ts_1 = require("./esbuildTsconfigPaths.js");
30
+ // The core of a platform, loaded with the extractor's own require in place so
31
+ // the react-native its native emit asks for is the one this process can run.
32
+ const loadGuiCore = (platform) => {
33
+ const { unregister } = (0, registerRequire_ts_1.registerRequire)(platform);
34
+ try {
35
+ return (0, requireGuiCore_ts_1.requireGuiCore)(platform);
36
+ }
37
+ finally {
38
+ unregister();
39
+ }
40
+ };
41
+ const UNTOUCHED_PROPS = {
42
+ key: true,
43
+ style: true,
44
+ className: true,
45
+ };
46
+ // Platform variants that can't be resolved at compile time on native builds.
47
+ // Defined at module level (not inside the loop) to avoid repeated Set allocations during compilation.
48
+ // (requires runtime Platform.OS + Platform.isTV checks via react-native-tvos)
49
+ const nativeOnlyPlatforms = new Set(['android', 'ios', 'tv', 'androidtv', 'tvos']);
50
+ const createTernary = (x) => x;
51
+ let hasLoggedBaseInfo = false;
52
+ function isFullyDisabled(props) {
53
+ return props.disableExtraction && props.disableDebugAttr;
54
+ }
55
+ // Walk up JSX ancestors looking for one that declares `group="<groupName>"` together
56
+ // with the `untilMeasured` prop. Used to deopt children whose styles depend on a
57
+ // parent that the runtime measures before emitting child styles (can't be modeled
58
+ // in static CSS).
59
+ function hasUntilMeasuredAncestor(path, groupName) {
60
+ let current = path.parentPath;
61
+ while (current) {
62
+ if (current.isJSXElement()) {
63
+ const opening = current.node.openingElement;
64
+ let foundGroup = false;
65
+ let foundUntilMeasured = false;
66
+ for (const attr of opening.attributes) {
67
+ if (!t.isJSXAttribute(attr))
68
+ continue;
69
+ if (!t.isJSXIdentifier(attr.name))
70
+ continue;
71
+ const aName = attr.name.name;
72
+ if (aName === 'group') {
73
+ // only literal string equality counts — dynamic group= is left to runtime
74
+ if (t.isStringLiteral(attr.value) && attr.value.value === groupName) {
75
+ foundGroup = true;
76
+ }
77
+ else if (t.isJSXExpressionContainer(attr.value) &&
78
+ t.isStringLiteral(attr.value.expression) &&
79
+ attr.value.expression.value === groupName) {
80
+ foundGroup = true;
81
+ }
82
+ }
83
+ else if (aName === 'untilMeasured') {
84
+ foundUntilMeasured = true;
85
+ }
86
+ }
87
+ if (foundGroup && foundUntilMeasured)
88
+ return true;
89
+ }
90
+ current = current.parentPath;
91
+ }
92
+ return false;
93
+ }
94
+ function createExtractor({ logger = console, platform = 'web' } = { logger: console }) {
95
+ const INLINE_EXTRACTABLE = {
96
+ ref: 'ref',
97
+ key: 'key',
98
+ ...(platform === 'web' && {
99
+ onPress: 'onClick',
100
+ onHoverIn: 'onMouseEnter',
101
+ onHoverOut: 'onMouseLeave',
102
+ onPressIn: 'onMouseDown',
103
+ onPressOut: 'onMouseUp',
104
+ }),
105
+ ...(platform === 'native' && {
106
+ // native view props that should pass through without preventing flattening
107
+ testID: 'testID',
108
+ nativeID: 'nativeID',
109
+ accessibilityLabel: 'accessibilityLabel',
110
+ accessibilityHint: 'accessibilityHint',
111
+ accessibilityRole: 'accessibilityRole',
112
+ accessibilityState: 'accessibilityState',
113
+ accessibilityValue: 'accessibilityValue',
114
+ accessibilityActions: 'accessibilityActions',
115
+ accessibilityLabelledBy: 'accessibilityLabelledBy',
116
+ accessibilityLiveRegion: 'accessibilityLiveRegion',
117
+ accessibilityElementsHidden: 'accessibilityElementsHidden',
118
+ accessibilityViewIsModal: 'accessibilityViewIsModal',
119
+ importantForAccessibility: 'importantForAccessibility',
120
+ collapsable: 'collapsable',
121
+ needsOffscreenAlphaCompositing: 'needsOffscreenAlphaCompositing',
122
+ removeClippedSubviews: 'removeClippedSubviews',
123
+ renderToHardwareTextureAndroid: 'renderToHardwareTextureAndroid',
124
+ shouldRasterizeIOS: 'shouldRasterizeIOS',
125
+ hitSlop: 'hitSlop',
126
+ pointerEvents: 'pointerEvents',
127
+ }),
128
+ };
129
+ const componentState = {
130
+ focus: false,
131
+ focusVisible: false,
132
+ focusWithin: false,
133
+ hover: false,
134
+ unmounted: true,
135
+ press: false,
136
+ pressIn: false,
137
+ disabled: false,
138
+ };
139
+ const styleProps = {
140
+ resolveValues: platform === 'native' ? 'value' : 'variable',
141
+ noClass: false,
142
+ isAnimated: false,
143
+ };
144
+ const shouldAddDebugProp =
145
+ // really basic disable this for next.js because it messes with ssr
146
+ !process.env.npm_package_dependencies_next &&
147
+ platform !== 'native' &&
148
+ process.env.IDENTIFY_TAGS !== 'false' &&
149
+ (process.env.NODE_ENV === 'development' || process.env.IDENTIFY_TAGS);
150
+ let projectInfo = null;
151
+ // cache of dynamically discovered styled components, keyed by absolute file path
152
+ // persists across files within the same worker/extractor instance
153
+ const dynamicComponentCache = new Map();
154
+ const dynamicLoadingInProgress = new Set();
155
+ function resolveImportPath(fromFile, importPath) {
156
+ const dir = (0, node_path_1.dirname)(fromFile);
157
+ if (importPath.startsWith('.')) {
158
+ return (0, esbuildTsconfigPaths_ts_1.probe)((0, node_path_1.resolve)(dir, importPath));
159
+ }
160
+ // tsconfig path alias (e.g. ~/foo, @/bar) into project source, never into node_modules
161
+ const file = (0, esbuildTsconfigPaths_ts_1.resolveAlias)(importPath, dir);
162
+ return file && !file.includes('node_modules') ? file : null;
163
+ }
164
+ const styledCheckCache = new Map();
165
+ function mightHaveStyledComponents(filePath) {
166
+ const cached = styledCheckCache.get(filePath);
167
+ if (cached !== undefined)
168
+ return cached;
169
+ try {
170
+ const content = (0, node_fs_1.readFileSync)(filePath, 'utf-8');
171
+ const result = content.includes('styled(');
172
+ styledCheckCache.set(filePath, result);
173
+ return result;
174
+ }
175
+ catch {
176
+ styledCheckCache.set(filePath, false);
177
+ return false;
178
+ }
179
+ }
180
+ // we load hanzogui delayed because we need to set some global/env stuff before importing
181
+ // otherwise we'd import `rnw` and cause it to evaluate react-native-web which causes errors
182
+ function loadSync(props) {
183
+ if (isFullyDisabled(props)) {
184
+ return null;
185
+ }
186
+ return (projectInfo || (projectInfo = (0, loadGui_ts_1.loadGuiSync)(props)));
187
+ }
188
+ async function load(props) {
189
+ if (isFullyDisabled(props)) {
190
+ return null;
191
+ }
192
+ return (projectInfo || (projectInfo = await (0, loadGui_ts_1.loadGui)(props)));
193
+ }
194
+ return {
195
+ options: {
196
+ logger,
197
+ },
198
+ cleanupBeforeExit: getStaticBindingsForScope_ts_1.cleanupBeforeExit,
199
+ loadGui: load,
200
+ loadGuiSync: loadSync,
201
+ getGui() {
202
+ return projectInfo?.hanzoguiConfig;
203
+ },
204
+ parseSync: (f, props) => {
205
+ globalThis.expo || (globalThis.expo = {}); // expo-modules-core checks this and avoids loading "native" modules if exists
206
+ const projectInfo = loadSync(props);
207
+ return parseWithConfig(projectInfo || {}, f, props);
208
+ },
209
+ parse: async (f, props) => {
210
+ globalThis.expo || (globalThis.expo = {}); // expo-modules-core checks this and avoids loading "native" modules if exists
211
+ const projectInfo = await load(props);
212
+ return parseWithConfig(projectInfo || {}, f, props);
213
+ },
214
+ };
215
+ function parseWithConfig({ components, hanzoguiConfig }, fileOrPath, options) {
216
+ const { config = 'hanzogui.config.ts', importsWhitelist = ['constants.js'], evaluateVars = true, sourcePath = '', onExtractTag, onStyledDefinitionRule, getFlattenedNode, disable, disableExtraction, disableExtractVariables, disableDebugAttr, enableDynamicEvaluation = false, includeExtensions = ['.ts', '.tsx', '.jsx'], extractStyledDefinitions = false, prefixLogs, excludeProps, platform, ...restProps } = options;
217
+ // invalidate dynamic cache for this file on re-parse (HMR)
218
+ if (sourcePath && dynamicComponentCache.has(sourcePath)) {
219
+ dynamicComponentCache.delete(sourcePath);
220
+ styledCheckCache.delete(sourcePath);
221
+ }
222
+ if (sourcePath.includes('.hanzogui-dynamic-eval')) {
223
+ return null;
224
+ }
225
+ const { normalizeStyle, getSplitStyles, mediaQueryConfig, propMapper, proxyThemeVariables, getDefaultProps, pseudoDescriptors, } = loadGuiCore(platform);
226
+ let shouldPrintDebug = options.shouldPrintDebug || false;
227
+ if (disable === true || (Array.isArray(disable) && disable.includes(sourcePath))) {
228
+ return null;
229
+ }
230
+ if (!isFullyDisabled(options)) {
231
+ if (!components) {
232
+ throw new Error(`Must provide components`);
233
+ }
234
+ }
235
+ // includeExtensions describes the app's OWN source, where the author picks
236
+ // the extension. An installed package ships whatever its build emits —
237
+ // .mjs, .js — and it already passed the package allowlist to get here, so
238
+ // holding it to ['.ts', '.tsx', '.jsx'] rejected every design-system file
239
+ // the allowlist had just admitted.
240
+ if (sourcePath &&
241
+ includeExtensions &&
242
+ !(0, extractablePath_ts_1.installedPackageOf)(sourcePath) &&
243
+ !includeExtensions.some((ext) => sourcePath.endsWith(ext))) {
244
+ if (shouldPrintDebug) {
245
+ logger.info(`Ignoring file due to includeExtensions: ${sourcePath}, includeExtensions: ${includeExtensions.join(', ')}`);
246
+ }
247
+ return null;
248
+ }
249
+ function isValidStyleKey(name, staticConfig) {
250
+ if (!projectInfo) {
251
+ throw new Error(`Gui extractor not loaded yet`);
252
+ }
253
+ if (platform === 'native' && name[0] === '$' && mediaQueryConfig[name.slice(1)]) {
254
+ return false;
255
+ }
256
+ // Check for $theme-, $platform-, $group- prefixed keys
257
+ if (name[0] === '$') {
258
+ const mediaName = name.slice(1);
259
+ if (mediaName.startsWith('theme-') ||
260
+ mediaName.startsWith('platform-') ||
261
+ mediaName.startsWith('group-')) {
262
+ return true;
263
+ }
264
+ if (mediaQueryConfig[mediaName]) {
265
+ return true;
266
+ }
267
+ }
268
+ return !!(staticConfig.validStyles?.[name] ||
269
+ pseudoDescriptors[name] ||
270
+ // don't disable variants or else you lose many things flattening
271
+ staticConfig.variants?.[name] ||
272
+ projectInfo?.hanzoguiConfig?.shorthands[name]);
273
+ }
274
+ function getGroupPseudo(name) {
275
+ const [_, groupName, a, b, c] = name.split('-');
276
+ if (!groupName)
277
+ return;
278
+ const m2 = a && b ? `${a}-${b}` : '';
279
+ const media = (m2 && mediaQueryConfig[m2] && m2) || (a && mediaQueryConfig[a] && a);
280
+ return media
281
+ ? media === m2
282
+ ? c
283
+ : b
284
+ ? `${b}${c ? `-${c}` : ''}`
285
+ : undefined
286
+ : a
287
+ ? `${a}${b ? `-${b}` : ''}${c ? `-${c}` : ''}`
288
+ : undefined;
289
+ }
290
+ /**
291
+ * Step 1: Determine if importing any statically extractable components
292
+ */
293
+ const isTargetingHTML = platform === 'web';
294
+ const ogDebug = shouldPrintDebug;
295
+ const tm = (0, timer_ts_1.timer)();
296
+ const propsWithFileInfo = {
297
+ ...options,
298
+ sourcePath,
299
+ allLoadedComponents: components ? [...components] : [],
300
+ };
301
+ if (!hasLoggedBaseInfo) {
302
+ hasLoggedBaseInfo = true;
303
+ if (shouldPrintDebug) {
304
+ logger.info([
305
+ 'loaded components:',
306
+ propsWithFileInfo.allLoadedComponents
307
+ .map((comp) => Object.keys(comp.nameToInfo).join(', '))
308
+ .join(', '),
309
+ ].join(' '));
310
+ }
311
+ if (process.env.DEBUG?.startsWith('hanzogui')) {
312
+ logger.info([
313
+ 'loaded:',
314
+ propsWithFileInfo.allLoadedComponents.map((x) => x.moduleName),
315
+ ].join('\n'));
316
+ }
317
+ }
318
+ tm.mark('load-hanzogui', !!shouldPrintDebug);
319
+ if (!isFullyDisabled(options)) {
320
+ if (!hanzoguiConfig?.themes) {
321
+ console.error(`⛔️ Error: Missing "themes" in your hanzogui.config file:
322
+
323
+ You may not need the compiler! Remember you can run Gui with no configuration at all.
324
+
325
+ You may have not "export default" your config (you can also "export const config").
326
+
327
+ Or this may be due to duplicated dependency versions:
328
+ - try out https://github.com/bmish/check-dependency-version-consistency to see if there are mis-matches.
329
+ - or search your lockfile for mis-matches.
330
+ `);
331
+ console.info(` Got config:`, hanzoguiConfig);
332
+ process.exit(0);
333
+ }
334
+ }
335
+ const firstThemeName = Object.keys(hanzoguiConfig?.themes || {})[0];
336
+ const firstTheme = hanzoguiConfig?.themes[firstThemeName] || {};
337
+ if (!firstTheme || typeof firstTheme !== 'object') {
338
+ const err = `Missing theme ${firstThemeName}, an error occurred when importing your config`;
339
+ console.info(err, `Got config:`, hanzoguiConfig);
340
+ console.info(`Looking for theme:`, firstThemeName);
341
+ throw new Error(err);
342
+ }
343
+ const proxiedTheme = proxyThemeVariables(firstTheme);
344
+ const themeAccessListeners = new Set();
345
+ const defaultTheme = new Proxy(proxiedTheme, {
346
+ get(target, key) {
347
+ if (Reflect.has(target, key)) {
348
+ themeAccessListeners.forEach((cb) => cb(String(key)));
349
+ }
350
+ return Reflect.get(target, key);
351
+ },
352
+ });
353
+ const body = fileOrPath.type === 'Program' ? fileOrPath.get('body') : fileOrPath.program.body;
354
+ if (!isFullyDisabled(options)) {
355
+ if (Object.keys(components || []).length === 0) {
356
+ console.warn(`Warning: Gui didn't find any valid components (DEBUG=hanzogui for more)`);
357
+ if (process.env.DEBUG === 'hanzogui') {
358
+ console.info(`components`, Object.keys(components || []), components);
359
+ }
360
+ }
361
+ }
362
+ if (shouldPrintDebug === 'verbose') {
363
+ logger.info(`allLoadedComponent modules ${propsWithFileInfo.allLoadedComponents
364
+ .map((k) => k.moduleName)
365
+ .join(', ')}`);
366
+ logger.info(`valid import paths: ${JSON.stringify((0, extractHelpers_ts_1.getValidComponentsPaths)(propsWithFileInfo))}`);
367
+ }
368
+ let doesUseValidImport = false;
369
+ let hasImportedTheme = false;
370
+ const importDeclarations = [];
371
+ for (const bodyPath of body) {
372
+ if (bodyPath.type !== 'ImportDeclaration')
373
+ continue;
374
+ const node = ('node' in bodyPath ? bodyPath.node : bodyPath);
375
+ const moduleName = node.source.value;
376
+ // if importing valid module
377
+ const valid = (0, extractHelpers_ts_1.isValidImport)(propsWithFileInfo, moduleName);
378
+ if (valid) {
379
+ importDeclarations.push(node);
380
+ }
381
+ if (shouldPrintDebug === 'verbose') {
382
+ logger.info(` - import via ${moduleName} ${valid}`);
383
+ }
384
+ if (extractStyledDefinitions && enableDynamicEvaluation) {
385
+ // check all imports for `styled`, not just valid packages
386
+ // styled( is basically guaranteed to be hanzogui regardless of source
387
+ if (node.specifiers.some((specifier) => specifier.local.name === 'styled')) {
388
+ doesUseValidImport = true;
389
+ // don't break - need to collect all import declarations for the styled() handler
390
+ }
391
+ }
392
+ if (valid) {
393
+ const names = node.specifiers.map((specifier) => specifier.local.name);
394
+ const isValidComponent = names.some((name) => Boolean((0, extractHelpers_ts_1.isValidImport)(propsWithFileInfo, moduleName, name)));
395
+ if (shouldPrintDebug === 'verbose') {
396
+ logger.info(` - import ${isValidComponent ? '✅' : '⇣'} - ${names.join(', ')} via package '${moduleName}' - (valid: ${JSON.stringify((0, extractHelpers_ts_1.getValidComponentsPaths)(propsWithFileInfo))})`);
397
+ }
398
+ if (isValidComponent) {
399
+ doesUseValidImport = true;
400
+ if (!(extractStyledDefinitions && enableDynamicEvaluation))
401
+ break;
402
+ }
403
+ }
404
+ }
405
+ if (shouldPrintDebug) {
406
+ logger.info(`${JSON.stringify({ doesUseValidImport, hasImportedTheme }, null, 2)}\n`);
407
+ }
408
+ if (!doesUseValidImport &&
409
+ extractStyledDefinitions &&
410
+ enableDynamicEvaluation &&
411
+ sourcePath) {
412
+ // check if any local import is in the dynamic cache or has styled components
413
+ for (const bodyPath of body) {
414
+ if (bodyPath.type !== 'ImportDeclaration')
415
+ continue;
416
+ const node = ('node' in bodyPath ? bodyPath.node : bodyPath);
417
+ const moduleName = node.source.value;
418
+ const resolved = resolveImportPath(sourcePath, moduleName);
419
+ if (!resolved)
420
+ continue;
421
+ if (dynamicComponentCache.has(resolved)) {
422
+ doesUseValidImport = true;
423
+ break;
424
+ }
425
+ if (mightHaveStyledComponents(resolved)) {
426
+ doesUseValidImport = true;
427
+ break;
428
+ }
429
+ }
430
+ }
431
+ if (!doesUseValidImport) {
432
+ return null;
433
+ }
434
+ function getValidImportedComponent(componentName) {
435
+ const importDeclaration = importDeclarations.find((dec) => dec.specifiers.some((spec) => spec.local.name === componentName));
436
+ if (!importDeclaration) {
437
+ return null;
438
+ }
439
+ return (0, extractHelpers_ts_1.getValidImport)(propsWithFileInfo, importDeclaration.source.value, componentName);
440
+ }
441
+ tm.mark('import-check', !!shouldPrintDebug);
442
+ let couldntParse = false;
443
+ const modifiedComponents = new Set();
444
+ // only keeping a cache around per-file, reset it if it changes
445
+ const bindingCache = {};
446
+ const callTraverse = (a) => {
447
+ return fileOrPath.type === 'File' ? (0, traverse_1.default)(fileOrPath, a) : fileOrPath.traverse(a);
448
+ };
449
+ const shouldDisableExtraction = disableExtraction === true ||
450
+ (Array.isArray(disableExtraction) && disableExtraction.includes(sourcePath));
451
+ /**
452
+ * Step 2: Statically extract from JSX < /> nodes
453
+ */
454
+ let programPath = null;
455
+ const res = {
456
+ styled: 0,
457
+ flattened: 0,
458
+ optimized: 0,
459
+ modified: 0,
460
+ found: 0,
461
+ };
462
+ const version = `${Math.random()}`;
463
+ callTraverse({
464
+ Program: {
465
+ enter(path) {
466
+ programPath = path;
467
+ },
468
+ },
469
+ // styled() calls
470
+ CallExpression(path) {
471
+ if (disable || shouldDisableExtraction || extractStyledDefinitions === false) {
472
+ return;
473
+ }
474
+ if (!t.isIdentifier(path.node.callee) || path.node.callee.name !== 'styled') {
475
+ return;
476
+ }
477
+ const variableName = t.isVariableDeclarator(path.parent) && t.isIdentifier(path.parent.id)
478
+ ? path.parent.id.name
479
+ : 'unknown';
480
+ if (shouldPrintDebug) {
481
+ logger.info(` [styled] Found styled(${variableName})`);
482
+ }
483
+ const parentNode = path.node.arguments[0];
484
+ if (!t.isIdentifier(parentNode)) {
485
+ return;
486
+ }
487
+ const parentName = parentNode.name;
488
+ const definition = path.node.arguments[1];
489
+ if (!parentName || !definition || !t.isObjectExpression(definition)) {
490
+ return;
491
+ }
492
+ // look up by parent first (e.g. View in `styled(View, {...})`), then by self
493
+ let Component = getValidImportedComponent(parentName) || getValidImportedComponent(variableName);
494
+ if (!Component) {
495
+ if (!enableDynamicEvaluation) {
496
+ return;
497
+ }
498
+ try {
499
+ if (shouldPrintDebug) {
500
+ logger.info(`Unknown component: ${variableName} = styled(${parentName}) attempting dynamic load: ${sourcePath}`);
501
+ }
502
+ const out = (0, loadGui_ts_1.loadGuiSync)({
503
+ forceExports: true,
504
+ components: [sourcePath],
505
+ cacheKey: version,
506
+ });
507
+ if (!out?.components) {
508
+ if (shouldPrintDebug) {
509
+ logger.info(`Couldn't load, got ${out}`);
510
+ }
511
+ return;
512
+ }
513
+ propsWithFileInfo.allLoadedComponents = [
514
+ ...propsWithFileInfo.allLoadedComponents,
515
+ ...out.components,
516
+ ];
517
+ Component = out.components.flatMap((x) => x.nameToInfo[variableName] ?? [])[0];
518
+ if (!out.cached) {
519
+ const foundNames = out.components
520
+ ?.map((x) => Object.keys(x.nameToInfo).join(', '))
521
+ .join(', ')
522
+ .trim();
523
+ if (foundNames) {
524
+ (0, cli_color_1.colorLog)(cli_color_1.Color.FgYellow, ` | Gui found dynamic components: ${foundNames}`);
525
+ }
526
+ }
527
+ }
528
+ catch (err) {
529
+ if (shouldPrintDebug) {
530
+ logger.info(`skip optimize styled(${variableName}), unable to pre-process (DEBUG=hanzogui for more)`);
531
+ }
532
+ }
533
+ }
534
+ if (!Component) {
535
+ if (shouldPrintDebug) {
536
+ logger.info(` No component found`);
537
+ }
538
+ /**
539
+ * We could/should still extract CSS just limited to validStyleProps
540
+ */
541
+ return;
542
+ }
543
+ const componentSkipProps = new Set([
544
+ ...(Component.staticConfig.inlineWhenUnflattened || []),
545
+ ...(Component.staticConfig.inlineProps || []),
546
+ // for now skip variants, will return to them
547
+ 'variants',
548
+ 'defaultVariants',
549
+ // skip fontFamily its basically a "variant", important for theme use to be value always
550
+ 'fontFamily',
551
+ 'name',
552
+ 'focusStyle',
553
+ 'focusVisibleStyle',
554
+ 'focusWithinStyle',
555
+ 'disabledStyle',
556
+ 'hoverStyle',
557
+ 'pressStyle',
558
+ ]);
559
+ // for now dont parse variants, spreads, etc
560
+ const skipped = new Set();
561
+ const styles = {};
562
+ const staticDefaultProps = {};
563
+ // Generate scope object at this level
564
+ const staticNamespace = (0, getStaticBindingsForScope_ts_1.getStaticBindingsForScope)(path.scope, importsWhitelist, sourcePath, bindingCache, shouldPrintDebug);
565
+ const attemptEval = !evaluateVars
566
+ ? evaluateAstNode_ts_1.evaluateAstNode
567
+ : (0, createEvaluator_ts_1.createEvaluator)({
568
+ props: propsWithFileInfo,
569
+ staticNamespace,
570
+ sourcePath,
571
+ shouldPrintDebug,
572
+ });
573
+ const attemptEvalSafe = (0, createEvaluator_ts_1.createSafeEvaluator)(attemptEval);
574
+ for (const property of definition.properties) {
575
+ if (t.isObjectProperty(property) &&
576
+ (t.isIdentifier(property.key) || t.isStringLiteral(property.key))) {
577
+ const key = t.isIdentifier(property.key)
578
+ ? property.key.name
579
+ : property.key.value;
580
+ const defaultPropValue = attemptEvalSafe(property.value);
581
+ if (defaultPropValue !== constants_ts_1.FAILED_EVAL) {
582
+ staticDefaultProps[key] = defaultPropValue;
583
+ }
584
+ }
585
+ if (!t.isObjectProperty(property) ||
586
+ !t.isIdentifier(property.key) ||
587
+ !isValidStyleKey(property.key.name, Component.staticConfig) ||
588
+ // TODO make pseudos and variants work
589
+ // skip pseudos
590
+ pseudoDescriptors[property.key.name] ||
591
+ // skip variants
592
+ Component.staticConfig.variants?.[property.key.name] ||
593
+ componentSkipProps.has(property.key.name)) {
594
+ skipped.add(property);
595
+ continue;
596
+ }
597
+ // attempt eval
598
+ const out = attemptEvalSafe(property.value);
599
+ if (out === constants_ts_1.FAILED_EVAL) {
600
+ skipped.add(property);
601
+ }
602
+ else {
603
+ styles[property.key.name] = out;
604
+ }
605
+ }
606
+ const out = getSplitStyles(styles, Component.staticConfig, defaultTheme, '', componentState, styleProps, undefined, undefined, undefined, undefined, false, shouldPrintDebug);
607
+ const classNames = {
608
+ ...out.classNames,
609
+ };
610
+ // // add in the style object as classnames
611
+ // const atomics = getPropsAtomic(out.style)
612
+ // for (const atomic of atomics) {
613
+ // out.rulesToInsert = out.rulesToInsert || []
614
+ // out.rulesToInsert.push(atomic)
615
+ // classNames[atomic.property] = atomic.identifier
616
+ // }
617
+ if (shouldPrintDebug) {
618
+ logger.info([
619
+ `Extracted styled(${variableName})\n`,
620
+ JSON.stringify(styles, null, 2),
621
+ '\n classNames:',
622
+ JSON.stringify(classNames, null, 2),
623
+ '\n rulesToInsert:',
624
+ out.rulesToInsert,
625
+ ].join(' '));
626
+ }
627
+ // don't replace definition values with class name strings -
628
+ // the runtime needs real values for animations, context, and group styles.
629
+ // we only emit the CSS rules so they're available if the runtime uses classNames.
630
+ if (out.rulesToInsert) {
631
+ for (const key in out.rulesToInsert) {
632
+ const styleObject = out.rulesToInsert[key];
633
+ onStyledDefinitionRule?.(styleObject[web_1.StyleObjectIdentifier], styleObject[web_1.StyleObjectRules]);
634
+ }
635
+ }
636
+ res.styled++;
637
+ // register so JSX handler can find this component (same-file and cross-file)
638
+ if (extractStyledDefinitions && enableDynamicEvaluation && Component) {
639
+ const dynamicStaticConfig = {
640
+ ...Component.staticConfig,
641
+ defaultProps: {
642
+ ...Component.staticConfig.defaultProps,
643
+ ...staticDefaultProps,
644
+ },
645
+ };
646
+ // add to allLoadedComponents with '' so getValidComponent matches when moduleName is ''
647
+ // (same-file styled components have '' as moduleName in JSX handler)
648
+ propsWithFileInfo.allLoadedComponents.push({
649
+ moduleName: '',
650
+ nameToInfo: { [variableName]: { staticConfig: dynamicStaticConfig } },
651
+ });
652
+ // also cache by file path so other files importing from this path can find it
653
+ if (sourcePath) {
654
+ let existing = dynamicComponentCache.get(sourcePath);
655
+ if (!existing) {
656
+ existing = { moduleName: sourcePath, nameToInfo: {} };
657
+ dynamicComponentCache.set(sourcePath, existing);
658
+ }
659
+ existing.nameToInfo[variableName] = { staticConfig: dynamicStaticConfig };
660
+ }
661
+ }
662
+ if (shouldPrintDebug) {
663
+ logger.info(`Extracted styled(${variableName})`);
664
+ }
665
+ },
666
+ JSXElement(traversePath) {
667
+ tm.mark('jsx-element', !!shouldPrintDebug);
668
+ const node = traversePath.node.openingElement;
669
+ const ogAttributes = node.attributes.map((attr) => ({ ...attr }));
670
+ const componentName = (0, extractHelpers_ts_1.findComponentName)(traversePath.scope);
671
+ const closingElement = traversePath.node.closingElement;
672
+ // skip non-identifier opening elements (member expressions, etc.)
673
+ if ((closingElement && t.isJSXMemberExpression(closingElement?.name)) ||
674
+ !t.isJSXIdentifier(node.name)) {
675
+ if (shouldPrintDebug) {
676
+ logger.info(` skip non-identifier element`);
677
+ }
678
+ return;
679
+ }
680
+ // validate its a proper import from hanzogui (or internally inside hanzogui)
681
+ const binding = traversePath.scope.getBinding(node.name.name);
682
+ let moduleName = '';
683
+ let dynamicComponent = null;
684
+ if (binding) {
685
+ if (t.isImportDeclaration(binding.path.parent)) {
686
+ moduleName = binding.path.parent.source.value;
687
+ if (!(0, extractHelpers_ts_1.isValidImport)(propsWithFileInfo, moduleName, binding.identifier.name)) {
688
+ // fallback: try dynamic component cache for local imports (relative or tsconfig alias)
689
+ if (enableDynamicEvaluation && sourcePath) {
690
+ const resolved = resolveImportPath(sourcePath, moduleName);
691
+ if (resolved) {
692
+ // check cache first
693
+ const cached = dynamicComponentCache.get(resolved);
694
+ if (cached?.nameToInfo[binding.identifier.name]) {
695
+ dynamicComponent = cached.nameToInfo[binding.identifier.name];
696
+ }
697
+ else if (!dynamicLoadingInProgress.has(resolved) &&
698
+ mightHaveStyledComponents(resolved)) {
699
+ // proactively load the file
700
+ dynamicLoadingInProgress.add(resolved);
701
+ try {
702
+ const out = (0, loadGui_ts_1.loadGuiSync)({
703
+ forceExports: true,
704
+ components: [resolved],
705
+ });
706
+ if (out?.components) {
707
+ for (const comp of out.components) {
708
+ // merge into cache
709
+ let existing = dynamicComponentCache.get(resolved);
710
+ if (!existing) {
711
+ existing = { moduleName: resolved, nameToInfo: {} };
712
+ dynamicComponentCache.set(resolved, existing);
713
+ }
714
+ Object.assign(existing.nameToInfo, comp.nameToInfo);
715
+ // also add to allLoadedComponents so getValidComponent works
716
+ propsWithFileInfo.allLoadedComponents.push({
717
+ moduleName: resolved,
718
+ nameToInfo: comp.nameToInfo,
719
+ });
720
+ }
721
+ const cachedNow = dynamicComponentCache.get(resolved);
722
+ if (cachedNow?.nameToInfo[binding.identifier.name]) {
723
+ dynamicComponent = cachedNow.nameToInfo[binding.identifier.name];
724
+ }
725
+ }
726
+ }
727
+ catch (err) {
728
+ if (shouldPrintDebug) {
729
+ logger.info(` - Failed to dynamically load ${resolved}: ${err}`);
730
+ }
731
+ }
732
+ finally {
733
+ dynamicLoadingInProgress.delete(resolved);
734
+ }
735
+ }
736
+ }
737
+ }
738
+ if (!dynamicComponent) {
739
+ if (shouldPrintDebug) {
740
+ logger.info(` - Binding in component ${componentName} not valid import: "${binding.identifier.name}" isn't in ${moduleName}\n`);
741
+ }
742
+ return;
743
+ }
744
+ }
745
+ }
746
+ }
747
+ const component = dynamicComponent ||
748
+ (0, extractHelpers_ts_1.getValidComponent)(propsWithFileInfo, moduleName, node.name.name);
749
+ if (!component || !component.staticConfig) {
750
+ if (shouldPrintDebug) {
751
+ logger.info(`\n - No Gui conf for: ${node.name.name}\n`);
752
+ }
753
+ return;
754
+ }
755
+ const originalNodeName = node.name.name;
756
+ // found a valid tag
757
+ res.found++;
758
+ const filePath = `./${(0, node_path_1.relative)(process.cwd(), sourcePath)}`;
759
+ const lineNumbers = node.loc
760
+ ? node.loc.start.line +
761
+ (node.loc.start.line !== node.loc.end.line ? `-${node.loc.end.line}` : '')
762
+ : '';
763
+ const codePosition = `${filePath}:${lineNumbers}`;
764
+ // debug just one
765
+ const debugPropValue = node.attributes
766
+ .filter((n) => t.isJSXAttribute(n) && t.isJSXIdentifier(n.name) && n.name.name === 'debug')
767
+ // @ts-ignore
768
+ .map((n) => {
769
+ if (n.value === null)
770
+ return true;
771
+ if (t.isStringLiteral(n.value))
772
+ return n.value.value;
773
+ return false;
774
+ })[0];
775
+ if (debugPropValue) {
776
+ shouldPrintDebug = debugPropValue;
777
+ }
778
+ if (shouldPrintDebug) {
779
+ logger.info(`\x1b[33m\x1b[0m ` + `${componentName} | ${codePosition} -------------------`);
780
+ // prettier-ignore
781
+ logger.info([
782
+ '\x1b[1m',
783
+ '\x1b[32m',
784
+ `<${originalNodeName} />`,
785
+ disableDebugAttr ? '' : '🐛',
786
+ ].join(' '));
787
+ }
788
+ // add data-* debug attributes
789
+ if (platform !== 'native') {
790
+ if (shouldAddDebugProp && !disableDebugAttr) {
791
+ res.modified++;
792
+ node.attributes.unshift(t.jsxAttribute(t.jsxIdentifier('data-is'), t.stringLiteral(node.name.name)));
793
+ if (componentName) {
794
+ node.attributes.unshift(t.jsxAttribute(t.jsxIdentifier('data-in'), t.stringLiteral(componentName)));
795
+ }
796
+ node.attributes.unshift(t.jsxAttribute(t.jsxIdentifier('data-at'), t.stringLiteral(`${(0, node_path_1.basename)(filePath)}:${lineNumbers}`)));
797
+ }
798
+ }
799
+ if (shouldDisableExtraction) {
800
+ if (shouldPrintDebug === 'verbose') {
801
+ logger.info(` ❌ Extraction disabled: ${JSON.stringify(disableExtraction)}\n`);
802
+ }
803
+ return;
804
+ }
805
+ try {
806
+ const { staticConfig } = component;
807
+ const defaultProps = {
808
+ ...getDefaultProps(staticConfig),
809
+ };
810
+ const variants = staticConfig.variants || {};
811
+ const isTextView = staticConfig.isText || false;
812
+ const validStyles = staticConfig?.validStyles ?? {};
813
+ // find render="a" render="main" etc dom indicators
814
+ let tagName = defaultProps.render ?? (isTextView ? 'span' : 'div');
815
+ traversePath
816
+ .get('openingElement')
817
+ .get('attributes')
818
+ .forEach((path) => {
819
+ const attr = path.node;
820
+ if (t.isJSXSpreadAttribute(attr))
821
+ return;
822
+ if (attr.name.name !== 'render')
823
+ return;
824
+ const val = attr.value;
825
+ if (!t.isStringLiteral(val))
826
+ return;
827
+ tagName = val.value;
828
+ });
829
+ if (shouldPrintDebug === 'verbose') {
830
+ console.info(` Start tag ${tagName}`);
831
+ }
832
+ const flatNodeName = getFlattenedNode?.({ isTextView, tag: tagName });
833
+ const inlineProps = new Set([
834
+ // adding some always inline props
835
+ ...(restProps.inlineProps || []),
836
+ ...(staticConfig.inlineProps || []),
837
+ ]);
838
+ const canFlattenTransition = isTargetingHTML &&
839
+ hanzoguiConfig?.animations.outputStyle === 'css' &&
840
+ !hanzoguiConfig.animationDrivers;
841
+ const deoptProps = new Set([
842
+ // css-only transitions lower to ordinary css; every runtime driver
843
+ // needs the component preserved so it can respond to prop changes.
844
+ 'animation',
845
+ ...(canFlattenTransition ? [] : ['transition']),
846
+ 'animateOnly',
847
+ 'animatePresence',
848
+ 'disableOptimization',
849
+ ...(!isTargetingHTML
850
+ ? [
851
+ // native has no css pseudo selectors; these are runtime-only on
852
+ // rn (event listeners + style merge in createComponent), and if
853
+ // we let them flatten into the stylesheet they get written
854
+ // under a literal key that rn treats as an unknown style prop.
855
+ // hover is intentionally excluded: it is no-op on native and
856
+ // should be dropped rather than preserved as runtime work.
857
+ 'pressStyle',
858
+ 'focusStyle',
859
+ 'focusVisibleStyle',
860
+ 'focusWithinStyle',
861
+ 'disabledStyle',
862
+ ]
863
+ : []),
864
+ // when using a non-CSS driver, de-opt on enterStyle/exitStyle
865
+ ...(hanzoguiConfig?.animations.isReactNative
866
+ ? ['enterStyle', 'exitStyle']
867
+ : []),
868
+ ]);
869
+ const inlineWhenUnflattened = new Set(staticConfig.inlineWhenUnflattened || []);
870
+ // Generate scope object at this level
871
+ const staticNamespace = (0, getStaticBindingsForScope_ts_1.getStaticBindingsForScope)(traversePath.scope, importsWhitelist, sourcePath, bindingCache, shouldPrintDebug);
872
+ const attemptEval = !evaluateVars
873
+ ? evaluateAstNode_ts_1.evaluateAstNode
874
+ : (0, createEvaluator_ts_1.createEvaluator)({
875
+ props: propsWithFileInfo,
876
+ staticNamespace,
877
+ sourcePath,
878
+ traversePath,
879
+ shouldPrintDebug,
880
+ });
881
+ const attemptEvalSafe = (0, createEvaluator_ts_1.createSafeEvaluator)(attemptEval);
882
+ if (shouldPrintDebug) {
883
+ logger.info(` staticNamespace ${Object.keys(staticNamespace).join(', ')}`);
884
+ }
885
+ //
886
+ // SPREADS SETUP
887
+ //
888
+ if (couldntParse) {
889
+ return;
890
+ }
891
+ tm.mark('jsx-element-flattened', !!shouldPrintDebug);
892
+ let attrs = [];
893
+ let shouldDeopt = false;
894
+ const inlined = new Map();
895
+ const variantValues = new Map();
896
+ let hasSetOptimized = false;
897
+ const inlineWhenUnflattenedOGVals = {};
898
+ // RUN first pass
899
+ // normalize all conditionals so we can evaluate away easier later
900
+ // at the same time lets normalize shorthand media queries into spreads:
901
+ // that way we can parse them with the same logic later on
902
+ //
903
+ // {...media.sm && { color: x ? 'red' : 'blue' }}
904
+ // => {...media.sm && x && { color: 'red' }}
905
+ // => {...media.sm && !x && { color: 'blue' }}
906
+ //
907
+ // $sm={{ color: 'red' }}
908
+ // => {...media.sm && { color: 'red' }}
909
+ //
910
+ // $sm={{ color: x ? 'red' : 'blue' }}
911
+ // => {...media.sm && x && { color: 'red' }}
912
+ // => {...media.sm && !x && { color: 'blue' }}
913
+ const propMapperStyleState = {
914
+ staticConfig,
915
+ usedKeys: {},
916
+ classNames: {},
917
+ style: {},
918
+ theme: defaultTheme,
919
+ viewProps: defaultProps,
920
+ conf: hanzoguiConfig,
921
+ props: defaultProps,
922
+ componentState,
923
+ styleProps: {
924
+ ...styleProps,
925
+ resolveValues: 'auto',
926
+ },
927
+ debug: shouldPrintDebug,
928
+ };
929
+ attrs = traversePath
930
+ .get('openingElement')
931
+ .get('attributes')
932
+ .flatMap((path) => {
933
+ // avoid work
934
+ if (shouldDeopt) {
935
+ return;
936
+ }
937
+ try {
938
+ const res = evaluateAttribute(path);
939
+ if (!res) {
940
+ path.remove();
941
+ }
942
+ return res;
943
+ }
944
+ catch (err) {
945
+ if (shouldPrintDebug) {
946
+ logger.info([
947
+ 'Recoverable error extracting attribute',
948
+ err.message,
949
+ shouldPrintDebug === 'verbose' ? err.stack : '',
950
+ ].join(' '));
951
+ if (shouldPrintDebug === 'verbose') {
952
+ logger.info(`node ${path.node?.type}`);
953
+ }
954
+ }
955
+ // dont flatten if we run into error
956
+ inlined.set(`${Math.random()}`, 'spread');
957
+ return {
958
+ type: 'attr',
959
+ value: path.node,
960
+ };
961
+ }
962
+ })
963
+ .flat(4)
964
+ .filter(extractHelpers_ts_1.isPresent);
965
+ if (shouldPrintDebug) {
966
+ logger.info([' - attrs (before):\n', (0, logLines_ts_1.logLines)(attrs.map(extractHelpers_ts_1.attrStr).join(', '))].join(' '));
967
+ }
968
+ // START function evaluateAttribute
969
+ function evaluateAttribute(path) {
970
+ const attribute = path.node;
971
+ const attr = { type: 'attr', value: attribute };
972
+ // ...spreads
973
+ if (t.isJSXSpreadAttribute(attribute)) {
974
+ const arg = attribute.argument;
975
+ const conditional = t.isConditionalExpression(arg)
976
+ ? // <YStack {...isSmall ? { color: 'red } : { color: 'blue }}
977
+ [arg.test, arg.consequent, arg.alternate]
978
+ : t.isLogicalExpression(arg) && arg.operator === '&&'
979
+ ? // <YStack {...isSmall && { color: 'red }}
980
+ [arg.left, arg.right, null]
981
+ : null;
982
+ if (conditional) {
983
+ const [test, alt, cons] = conditional;
984
+ if (!test)
985
+ throw new Error(`no test`);
986
+ if ([alt, cons].some((side) => side && !isStaticObject(side))) {
987
+ if (shouldPrintDebug) {
988
+ logger.info(`not extractable ${alt} ${cons}`);
989
+ }
990
+ return attr;
991
+ }
992
+ // split into individual ternaries per object property
993
+ return [
994
+ ...(flattenNestedTernaries(test, alt) || []),
995
+ ...((cons &&
996
+ flattenNestedTernaries(t.unaryExpression('!', test), cons)) ||
997
+ []),
998
+ ].map((ternary) => ({
999
+ type: 'ternary',
1000
+ value: ternary,
1001
+ }));
1002
+ }
1003
+ }
1004
+ // END ...spreads
1005
+ // directly keep these
1006
+ // couldn't evaluate spread, undefined name, or name is not string
1007
+ if (t.isJSXSpreadAttribute(attribute) ||
1008
+ !attribute.name ||
1009
+ typeof attribute.name.name !== 'string') {
1010
+ if (shouldPrintDebug) {
1011
+ logger.info(' ! inlining, spread attr');
1012
+ }
1013
+ inlined.set(`${Math.random()}`, 'spread');
1014
+ return attr;
1015
+ }
1016
+ const name = attribute.name.name;
1017
+ // in hanzogui style is handled at the end of the style loop so its not as simple as just
1018
+ // adding this as a "style" property
1019
+ // its not used often when using hanzogui so not optimizing it for now
1020
+ if (name === 'style') {
1021
+ shouldDeopt = true;
1022
+ return null;
1023
+ }
1024
+ if (excludeProps?.has(name)) {
1025
+ if (shouldPrintDebug) {
1026
+ logger.info([' excluding prop', name].join(' '));
1027
+ }
1028
+ return null;
1029
+ }
1030
+ if (inlineProps.has(name)) {
1031
+ inlined.set(name, name);
1032
+ if (shouldPrintDebug) {
1033
+ logger.info([' ! inlining, inline prop', name].join(' '));
1034
+ }
1035
+ return attr;
1036
+ }
1037
+ // pass className, key, and style props through untouched
1038
+ if (UNTOUCHED_PROPS[name]) {
1039
+ return attr;
1040
+ }
1041
+ if (INLINE_EXTRACTABLE[name]) {
1042
+ inlined.set(name, INLINE_EXTRACTABLE[name]);
1043
+ return attr;
1044
+ }
1045
+ if (name.startsWith('data-') ||
1046
+ name.startsWith('aria-') ||
1047
+ validHTMLAttributes_ts_1.validHTMLAttributes[name]) {
1048
+ return attr;
1049
+ }
1050
+ // de-opt on enterStyle={expression}
1051
+ if ((name === 'enterStyle' || name === 'exitStyle') &&
1052
+ t.isJSXExpressionContainer(attribute?.value)) {
1053
+ shouldDeopt = true;
1054
+ return attr;
1055
+ }
1056
+ // shorthand media queries
1057
+ if (name[0] === '$' && t.isJSXExpressionContainer(attribute?.value)) {
1058
+ const shortname = name.slice(1);
1059
+ if (mediaQueryConfig[shortname]) {
1060
+ const expression = attribute.value.expression;
1061
+ if (!t.isJSXEmptyExpression(expression)) {
1062
+ const ternaries = flattenNestedTernaries(t.stringLiteral(shortname), expression, {
1063
+ inlineMediaQuery: shortname,
1064
+ });
1065
+ if (ternaries) {
1066
+ return ternaries.map((value) => ({
1067
+ type: 'ternary',
1068
+ value,
1069
+ }));
1070
+ }
1071
+ }
1072
+ }
1073
+ }
1074
+ const [value, valuePath] = (() => {
1075
+ if (t.isJSXExpressionContainer(attribute?.value)) {
1076
+ return [attribute.value.expression, path.get('value')];
1077
+ }
1078
+ return [attribute.value, path.get('value')];
1079
+ })();
1080
+ // these props have runtime-only meaning on native. decide from the
1081
+ // original jsx attr, before getSplitStyles has a chance to drop
1082
+ // native-dead work like hoverStyle from its static output.
1083
+ if (deoptProps.has(name) ||
1084
+ (platform === 'native' &&
1085
+ name[0] === '$' &&
1086
+ (name.startsWith('$theme-') ||
1087
+ (name.startsWith('$group-') && getGroupPseudo(name) !== 'hover')))) {
1088
+ inlined.set(name, true);
1089
+ return attr;
1090
+ }
1091
+ const remove = () => {
1092
+ Array.isArray(valuePath)
1093
+ ? valuePath.map((p) => p.remove())
1094
+ : valuePath.remove();
1095
+ };
1096
+ if (name === 'ref') {
1097
+ if (shouldPrintDebug) {
1098
+ logger.info([' ! inlining, ref', name].join(' '));
1099
+ }
1100
+ inlined.set('ref', 'ref');
1101
+ return attr;
1102
+ }
1103
+ if (name === 'render') {
1104
+ // Only optimize string literal render props
1105
+ // JSX elements and functions should deopt
1106
+ if (!value || value.type !== 'StringLiteral') {
1107
+ if (shouldPrintDebug) {
1108
+ logger.info(` ! deopt on render prop (not a string literal)`);
1109
+ }
1110
+ shouldDeopt = true;
1111
+ }
1112
+ return {
1113
+ type: 'attr',
1114
+ value: path.node,
1115
+ };
1116
+ }
1117
+ // native shouldn't extract variables
1118
+ if (disableExtractVariables === true) {
1119
+ if (value) {
1120
+ if (value.type === 'StringLiteral' && value.value[0] === '$') {
1121
+ if (shouldPrintDebug) {
1122
+ logger.info([
1123
+ ` ! inlining, native disable extract: ${name} =`,
1124
+ value.value,
1125
+ ].join(' '));
1126
+ }
1127
+ inlined.set(name, true);
1128
+ return attr;
1129
+ }
1130
+ }
1131
+ }
1132
+ if (name === 'theme') {
1133
+ inlined.set('theme', attr.value);
1134
+ return attr;
1135
+ }
1136
+ // static `group="<literal>"` is handled at compile-time in
1137
+ // extractToClassNames (emits container CSS + adds `t_group_<name>`
1138
+ // className), so we drop the JSX attribute here without bailing
1139
+ // flattening. dynamic `group={expr}` falls through to runtime.
1140
+ if (isTargetingHTML && name === 'group' && t.isStringLiteral(value)) {
1141
+ return [];
1142
+ }
1143
+ // if value can be evaluated, extract it and filter it out
1144
+ const styleValue = attemptEvalSafe(value);
1145
+ // media-like blocks with nested $-keys (eg $theme-dark={{ $sm: {…} }})
1146
+ // can't resolve to static CSS in one pass — keep them on the runtime path
1147
+ if (name[0] === '$' &&
1148
+ (name.startsWith('$theme-') || name.startsWith('$group-')) &&
1149
+ styleValue &&
1150
+ typeof styleValue === 'object' &&
1151
+ Object.keys(styleValue).some((k) => k[0] === '$')) {
1152
+ if (shouldPrintDebug) {
1153
+ logger.info(` ! nested media-like key inside ${name}, deopt to runtime`);
1154
+ }
1155
+ inlined.set(name, true);
1156
+ return attr;
1157
+ }
1158
+ // never flatten if a prop isn't a valid static attribute
1159
+ // only post prop-mapping
1160
+ if (!variants[name] && !isValidStyleKey(name, staticConfig)) {
1161
+ let out = null;
1162
+ // for now passing empty props {}, a bit odd, need to at least document
1163
+ // for now we don't expose custom components so just noting behavior
1164
+ propMapper(name, styleValue, propMapperStyleState, false, (key, val) => {
1165
+ out || (out = {});
1166
+ out[key] = val;
1167
+ });
1168
+ if (out) {
1169
+ if (isTargetingHTML) {
1170
+ // translate to DOM-compat
1171
+ out = reactNativeWebInternals.createDOMProps(isTextView ? 'span' : 'div', out);
1172
+ // remove className - we dont use rnw styling
1173
+ delete out.className;
1174
+ // remove style - rnw createDOMProps unconditionally emits a
1175
+ // (possibly empty) style key, but we passed it a single
1176
+ // non-style prop. Leaving it in causes Object.keys(out) to
1177
+ // iterate twice and emit the original JSXAttribute twice
1178
+ // (e.g. duplicate testID), breaking the DOM output.
1179
+ delete out.style;
1180
+ }
1181
+ }
1182
+ let didInline = false;
1183
+ const attributes = Object.keys(out).map((key) => {
1184
+ const val = out[key];
1185
+ const isStyle = isValidStyleKey(key, staticConfig);
1186
+ if (isStyle) {
1187
+ return {
1188
+ type: 'style',
1189
+ value: { [key]: styleValue },
1190
+ name: key,
1191
+ attr: path.node,
1192
+ };
1193
+ }
1194
+ if (validHTMLAttributes_ts_1.validHTMLAttributes[key] ||
1195
+ key.startsWith('aria-') ||
1196
+ key.startsWith('data-') ||
1197
+ // this is debug stuff added by vite / new jsx transform
1198
+ key === '__source' ||
1199
+ key === '__self') {
1200
+ if (styleValue === constants_ts_1.FAILED_EVAL &&
1201
+ key !== name &&
1202
+ t.isJSXAttribute(attr.value)) {
1203
+ // createDOMProps renamed the prop (e.g. testID -> data-testid).
1204
+ // preserve the original expression value but use the new
1205
+ // attribute name. restricted to FAILED_EVAL because the
1206
+ // later `case 'attr'` rename pass only runs on
1207
+ // statically-evaluable values; for static values that pass
1208
+ // intentionally preserves some prop names (e.g. focusable
1209
+ // in v2) instead of doing the createDOMProps rename.
1210
+ return {
1211
+ type: 'attr',
1212
+ value: t.jsxAttribute(t.jsxIdentifier(key), attr.value.value),
1213
+ };
1214
+ }
1215
+ return attr;
1216
+ }
1217
+ if (shouldPrintDebug) {
1218
+ logger.info(' ! inlining, non-static ' + key);
1219
+ }
1220
+ didInline = true;
1221
+ inlined.set(key, val);
1222
+ return val;
1223
+ });
1224
+ // weird logic whats going on here
1225
+ if (didInline) {
1226
+ if (shouldPrintDebug) {
1227
+ logger.info(` bailing flattening due to attributes ${attributes.map((x) => x.toString())}`);
1228
+ }
1229
+ // bail
1230
+ return attr;
1231
+ }
1232
+ // return evaluated attributes
1233
+ return attributes;
1234
+ }
1235
+ // FAILED = dynamic or ternary, keep going
1236
+ if (styleValue !== constants_ts_1.FAILED_EVAL) {
1237
+ if (inlineWhenUnflattened.has(name)) {
1238
+ // preserve original value for restoration
1239
+ inlineWhenUnflattenedOGVals[name] = { styleValue, attr };
1240
+ }
1241
+ if (isValidStyleKey(name, staticConfig)) {
1242
+ // $theme- / $group- styles extract through the atomic-CSS pipeline
1243
+ // (extractToClassNames → createMediaStyle), so they fall through to
1244
+ // the normal style return below. The one case we still bail is
1245
+ // $group-<name>-* when an ancestor element declares `group="<name>"`
1246
+ // together with `untilMeasured` — the runtime measures the parent
1247
+ // and only then emits child styles, which can't be modeled in CSS.
1248
+ // $platform- can be flattened if the platform matches.
1249
+ if (name[0] === '$') {
1250
+ if (name.startsWith('$group-')) {
1251
+ const groupName = name.slice('$group-'.length).split('-')[0];
1252
+ if (groupName && hasUntilMeasuredAncestor(path, groupName)) {
1253
+ if (shouldPrintDebug) {
1254
+ logger.info(` ! group="${groupName}" ancestor has untilMeasured, not flattening: ${name}`);
1255
+ }
1256
+ inlined.set(name, true);
1257
+ return attr;
1258
+ }
1259
+ }
1260
+ // $platform-web, $platform-native, $platform-ios, $platform-android, $platform-tv, $platform-androidtv, $platform-tvos
1261
+ if (name.startsWith('$platform-')) {
1262
+ const platformName = name.slice(10); // remove '$platform-'
1263
+ const isMatchingPlatform = platformName === platform ||
1264
+ (platformName === 'native' && platform === 'native') ||
1265
+ (platformName === 'web' && platform === 'web');
1266
+ if (isMatchingPlatform && typeof styleValue === 'object') {
1267
+ // Flatten the inner styles directly
1268
+ if (shouldPrintDebug) {
1269
+ logger.info(` flattening $platform-${platformName}: ${JSON.stringify(styleValue)}`);
1270
+ }
1271
+ return Object.entries(styleValue).map(([key, val]) => ({
1272
+ type: 'style',
1273
+ value: { [key]: val },
1274
+ name: key,
1275
+ attr: path.node,
1276
+ }));
1277
+ }
1278
+ else {
1279
+ // On native builds, sub-platform variants (android, ios, tv, androidtv, tvos)
1280
+ // can't be resolved at compile time - leave for runtime evaluation
1281
+ if (platform === 'native' &&
1282
+ nativeOnlyPlatforms.has(platformName)) {
1283
+ if (shouldPrintDebug) {
1284
+ logger.info(` ! keeping platform-specific style for runtime evaluation: ${name}`);
1285
+ }
1286
+ inlined.set(name, true);
1287
+ return attr;
1288
+ }
1289
+ // Platform doesn't match, skip these styles entirely
1290
+ if (shouldPrintDebug) {
1291
+ logger.info(` ! skipping non-matching platform style: ${name}`);
1292
+ }
1293
+ return [];
1294
+ }
1295
+ }
1296
+ }
1297
+ if (shouldPrintDebug) {
1298
+ logger.info(` style: ${name} = ${JSON.stringify(styleValue)}`);
1299
+ }
1300
+ if (!(name in defaultProps)) {
1301
+ if (!hasSetOptimized) {
1302
+ res.optimized++;
1303
+ hasSetOptimized = true;
1304
+ }
1305
+ }
1306
+ return {
1307
+ type: 'style',
1308
+ value: { [name]: styleValue },
1309
+ name,
1310
+ attr: path.node,
1311
+ };
1312
+ }
1313
+ if (variants[name]) {
1314
+ variantValues.set(name, styleValue);
1315
+ }
1316
+ inlined.set(name, true);
1317
+ return attr;
1318
+ }
1319
+ // ternaries!
1320
+ // binary ternary, we can eventually make this smarter but step 1
1321
+ // basically for the common use case of:
1322
+ // opacity={(conditional ? 0 : 1) * scale}
1323
+ if (t.isBinaryExpression(value)) {
1324
+ if (shouldPrintDebug) {
1325
+ logger.info(` binary expression ${name} = ${value}`);
1326
+ }
1327
+ const { operator, left, right } = value;
1328
+ // if one side is a ternary, and the other side is evaluatable, we can maybe extract
1329
+ const lVal = attemptEvalSafe(left);
1330
+ const rVal = attemptEvalSafe(right);
1331
+ if (shouldPrintDebug) {
1332
+ logger.info(` evalBinaryExpression lVal ${String(lVal)}, rVal ${String(rVal)}`);
1333
+ }
1334
+ if (lVal !== constants_ts_1.FAILED_EVAL && t.isConditionalExpression(right)) {
1335
+ const ternary = addBinaryConditional(operator, left, right);
1336
+ if (ternary)
1337
+ return ternary;
1338
+ }
1339
+ if (rVal !== constants_ts_1.FAILED_EVAL && t.isConditionalExpression(left)) {
1340
+ const ternary = addBinaryConditional(operator, right, left);
1341
+ if (ternary)
1342
+ return ternary;
1343
+ }
1344
+ if (shouldPrintDebug) {
1345
+ logger.info(` evalBinaryExpression cant extract`);
1346
+ }
1347
+ inlined.set(name, true);
1348
+ return attr;
1349
+ }
1350
+ const staticConditional = getStaticConditional(value);
1351
+ if (staticConditional) {
1352
+ if (shouldPrintDebug === 'verbose') {
1353
+ logger.info(` static conditional ${name} ${value}`);
1354
+ }
1355
+ return { type: 'ternary', value: staticConditional };
1356
+ }
1357
+ const staticLogical = getStaticLogical(value);
1358
+ if (staticLogical) {
1359
+ if (shouldPrintDebug === 'verbose') {
1360
+ logger.info(` static ternary ${name} = ${value}`);
1361
+ }
1362
+ return { type: 'ternary', value: staticLogical };
1363
+ }
1364
+ // if we've made it this far, the prop stays inline
1365
+ inlined.set(name, true);
1366
+ if (shouldPrintDebug) {
1367
+ logger.info(` ! inline no match ${name} ${value}`);
1368
+ }
1369
+ //
1370
+ // RETURN ATTR
1371
+ //
1372
+ return attr;
1373
+ // attr helpers:
1374
+ function addBinaryConditional(operator, staticExpr, cond) {
1375
+ if (getStaticConditional(cond)) {
1376
+ const alt = attemptEval(t.binaryExpression(operator, staticExpr, cond.alternate));
1377
+ const cons = attemptEval(t.binaryExpression(operator, staticExpr, cond.consequent));
1378
+ if (shouldPrintDebug) {
1379
+ logger.info([' binaryConditional', cond.test, cons, alt].join(' '));
1380
+ }
1381
+ return {
1382
+ type: 'ternary',
1383
+ value: {
1384
+ test: cond.test,
1385
+ remove,
1386
+ alternate: { [name]: alt },
1387
+ consequent: { [name]: cons },
1388
+ },
1389
+ };
1390
+ }
1391
+ return null;
1392
+ }
1393
+ function getStaticConditional(value) {
1394
+ if (t.isConditionalExpression(value)) {
1395
+ try {
1396
+ const aVal = attemptEval(value.alternate);
1397
+ const cVal = attemptEval(value.consequent);
1398
+ if (shouldPrintDebug) {
1399
+ const type = value.test.type;
1400
+ logger.info([' static ternary', type, cVal, aVal].join(' '));
1401
+ }
1402
+ return {
1403
+ test: value.test,
1404
+ remove,
1405
+ consequent: { [name]: cVal },
1406
+ alternate: { [name]: aVal },
1407
+ };
1408
+ }
1409
+ catch (err) {
1410
+ if (shouldPrintDebug) {
1411
+ logger.info([' cant eval ternary', err.message].join(' '));
1412
+ }
1413
+ }
1414
+ }
1415
+ return null;
1416
+ }
1417
+ function getStaticLogical(value) {
1418
+ if (t.isLogicalExpression(value)) {
1419
+ if (value.operator === '&&') {
1420
+ try {
1421
+ const val = attemptEval(value.right);
1422
+ if (shouldPrintDebug) {
1423
+ logger.info([' staticLogical', value.left, name, val].join(' '));
1424
+ }
1425
+ return {
1426
+ test: value.left,
1427
+ remove,
1428
+ consequent: { [name]: val },
1429
+ alternate: null,
1430
+ };
1431
+ }
1432
+ catch (err) {
1433
+ if (shouldPrintDebug) {
1434
+ logger.info([' cant static eval logical', err].join(' '));
1435
+ }
1436
+ }
1437
+ }
1438
+ }
1439
+ return null;
1440
+ }
1441
+ } // END function evaluateAttribute
1442
+ function isStaticObject(obj) {
1443
+ return (t.isObjectExpression(obj) &&
1444
+ obj.properties.every((prop) => {
1445
+ if (!t.isObjectProperty(prop)) {
1446
+ // console.warn('not an object prop?', prop)
1447
+ return false;
1448
+ }
1449
+ const propName = prop.key['name'];
1450
+ if (!isValidStyleKey(propName, staticConfig) && propName !== 'render') {
1451
+ if (shouldPrintDebug) {
1452
+ logger.info([' not a valid style prop!', propName].join(' '));
1453
+ }
1454
+ return false;
1455
+ }
1456
+ return true;
1457
+ }));
1458
+ }
1459
+ // side = {
1460
+ // color: 'red',
1461
+ // background: x ? 'red' : 'green',
1462
+ // $gtSm: { color: 'green' }
1463
+ // }
1464
+ // => Ternary<test, { color: 'red' }, null>
1465
+ // => Ternary<test && x, { background: 'red' }, null>
1466
+ // => Ternary<test && !x, { background: 'green' }, null>
1467
+ // => Ternary<test && '$gtSm', { color: 'green' }, null>
1468
+ function flattenNestedTernaries(test, side, ternaryPartial = {}) {
1469
+ if (!side) {
1470
+ return null;
1471
+ }
1472
+ if (!isStaticObject(side)) {
1473
+ throw new Error('not extractable');
1474
+ }
1475
+ return side.properties.flatMap((property) => {
1476
+ if (!t.isObjectProperty(property)) {
1477
+ throw new Error('expected object property');
1478
+ }
1479
+ // this could be a recurse here if we want to get fancy
1480
+ if (t.isConditionalExpression(property.value)) {
1481
+ // merge up into the parent conditional, split into two
1482
+ const [truthy, falsy] = [
1483
+ t.objectExpression([
1484
+ t.objectProperty(property.key, property.value.consequent),
1485
+ ]),
1486
+ t.objectExpression([
1487
+ t.objectProperty(property.key, property.value.alternate),
1488
+ ]),
1489
+ ].map((x) => attemptEval(x));
1490
+ return [
1491
+ createTernary({
1492
+ remove() { },
1493
+ ...ternaryPartial,
1494
+ test: t.logicalExpression('&&', test, property.value.test),
1495
+ consequent: truthy,
1496
+ alternate: null,
1497
+ }),
1498
+ createTernary({
1499
+ ...ternaryPartial,
1500
+ test: t.logicalExpression('&&', test, t.unaryExpression('!', property.value.test)),
1501
+ consequent: falsy,
1502
+ alternate: null,
1503
+ remove() { },
1504
+ }),
1505
+ ];
1506
+ }
1507
+ const obj = t.objectExpression([
1508
+ t.objectProperty(property.key, property.value),
1509
+ ]);
1510
+ const consequent = attemptEval(obj);
1511
+ return createTernary({
1512
+ remove() { },
1513
+ ...ternaryPartial,
1514
+ test,
1515
+ consequent,
1516
+ alternate: null,
1517
+ });
1518
+ });
1519
+ }
1520
+ if (couldntParse || shouldDeopt) {
1521
+ if (shouldPrintDebug) {
1522
+ logger.info([` avoid optimizing:`, { couldntParse, shouldDeopt }].join(' '));
1523
+ }
1524
+ node.attributes = ogAttributes;
1525
+ return;
1526
+ }
1527
+ // before deopt, can still optimize
1528
+ const parentFn = (0, findTopmostFunction_ts_1.findTopmostFunction)(traversePath);
1529
+ if (parentFn) {
1530
+ modifiedComponents.add(parentFn);
1531
+ }
1532
+ // flatten logic!
1533
+ // fairly simple check to see if all children are text
1534
+ const hasSpread = attrs.some((x) => x.type === 'attr' && t.isJSXSpreadAttribute(x.value));
1535
+ const hasOnlyStringChildren = !hasSpread &&
1536
+ (node.selfClosing ||
1537
+ (traversePath.node.children &&
1538
+ traversePath.node.children.every((x) => x.type === 'JSXText')));
1539
+ let themeVal = inlined.get('theme');
1540
+ // on native we can't flatten when theme prop is set
1541
+ if (platform !== 'native') {
1542
+ inlined.delete('theme');
1543
+ }
1544
+ for (const [key] of inlined) {
1545
+ const isStaticObjectVariant = staticConfig.variants?.[key] && variantValues.has(key);
1546
+ if (INLINE_EXTRACTABLE[key] || isStaticObjectVariant) {
1547
+ inlined.delete(key);
1548
+ }
1549
+ }
1550
+ const canFlattenProps = inlined.size === 0;
1551
+ let shouldFlatten = Boolean(flatNodeName &&
1552
+ !shouldDeopt &&
1553
+ canFlattenProps &&
1554
+ !hasSpread &&
1555
+ !staticConfig.isStyledHOC &&
1556
+ !staticConfig.isHOC &&
1557
+ !staticConfig.isReactNative &&
1558
+ staticConfig.neverFlatten !== true &&
1559
+ (staticConfig.neverFlatten === 'jsx' ? hasOnlyStringChildren : true));
1560
+ if (shouldPrintDebug === 'verbose') {
1561
+ logger.info(` flatten? ${originalNodeName} -> ${flatNodeName} ${JSON.stringify({
1562
+ shouldFlatten,
1563
+ shouldDeopt,
1564
+ canFlattenProps,
1565
+ hasSpread,
1566
+ isStyledHOC: staticConfig.isStyledHOC,
1567
+ isHOC: staticConfig.isHOC,
1568
+ isReactNative: staticConfig.isReactNative,
1569
+ neverFlatten: staticConfig.neverFlatten,
1570
+ })}`);
1571
+ }
1572
+ const usedThemeKeys = new Set();
1573
+ // if it accesses any theme values during evaluation
1574
+ themeAccessListeners.add((key) => {
1575
+ if (disableExtractVariables) {
1576
+ usedThemeKeys.add(key);
1577
+ shouldFlatten = false;
1578
+ if (shouldPrintDebug === 'verbose') {
1579
+ logger.info([' ! accessing theme key, avoid flatten', key].join(' '));
1580
+ }
1581
+ }
1582
+ });
1583
+ if (!shouldFlatten) {
1584
+ if (shouldPrintDebug) {
1585
+ logger.info(`Deopting ${JSON.stringify({
1586
+ shouldFlatten,
1587
+ shouldDeopt,
1588
+ canFlattenProps,
1589
+ hasSpread,
1590
+ neverFlatten: staticConfig.neverFlatten,
1591
+ })}`);
1592
+ }
1593
+ node.attributes = ogAttributes;
1594
+ return;
1595
+ }
1596
+ // ensure the default styles are there
1597
+ let skipMap = false;
1598
+ const defaultStyleAttrs = Object.keys(defaultProps).flatMap((key) => {
1599
+ if (skipMap)
1600
+ return [];
1601
+ const value = defaultProps[key];
1602
+ if (key === 'theme' && !themeVal) {
1603
+ if (platform === 'native') {
1604
+ shouldFlatten = false;
1605
+ skipMap = true;
1606
+ inlined.set('theme', { value: t.stringLiteral(value) });
1607
+ }
1608
+ themeVal = { value: t.stringLiteral(value) };
1609
+ return [];
1610
+ }
1611
+ if (!isValidStyleKey(key, staticConfig)) {
1612
+ return [];
1613
+ }
1614
+ const name = hanzoguiConfig?.shorthands[key] || key;
1615
+ if (value === undefined) {
1616
+ logger.warn(`⚠️ Error evaluating default style for component, prop ${key} ${value}`);
1617
+ shouldDeopt = true;
1618
+ return;
1619
+ }
1620
+ if (name[0] === '$' && mediaQueryConfig[name.slice(1)]) {
1621
+ defaultProps[key] = undefined;
1622
+ return evaluateAttribute({
1623
+ node: t.jsxAttribute(t.jsxIdentifier(name), t.jsxExpressionContainer(t.objectExpression(Object.keys(value)
1624
+ .filter((k) => {
1625
+ return typeof value[k] !== 'undefined';
1626
+ })
1627
+ .map((k) => {
1628
+ return t.objectProperty(t.identifier(k), (0, literalToAst_ts_1.literalToAst)(value[k]));
1629
+ })))),
1630
+ });
1631
+ }
1632
+ const attr = {
1633
+ type: 'style',
1634
+ name,
1635
+ value: { [name]: value },
1636
+ };
1637
+ return attr;
1638
+ });
1639
+ if (!skipMap) {
1640
+ if (defaultStyleAttrs.length) {
1641
+ attrs = [...defaultStyleAttrs, ...attrs];
1642
+ }
1643
+ }
1644
+ // combine ternaries
1645
+ let ternaries = [];
1646
+ attrs = attrs
1647
+ .reduce((out, cur) => {
1648
+ const next = attrs[attrs.indexOf(cur) + 1];
1649
+ if (cur.type === 'ternary') {
1650
+ ternaries.push(cur.value);
1651
+ }
1652
+ if ((!next || next.type !== 'ternary') && ternaries.length) {
1653
+ // finish, process
1654
+ const normalized = (0, normalizeTernaries_ts_1.normalizeTernaries)(ternaries).map(({ alternate, consequent, ...rest }) => {
1655
+ return {
1656
+ type: 'ternary',
1657
+ value: {
1658
+ ...rest,
1659
+ alternate: alternate || null,
1660
+ consequent: consequent || null,
1661
+ },
1662
+ };
1663
+ });
1664
+ try {
1665
+ return [...out, ...normalized];
1666
+ }
1667
+ finally {
1668
+ if (shouldPrintDebug) {
1669
+ logger.info(` normalizeTernaries (${ternaries.length} => ${normalized.length})`);
1670
+ }
1671
+ ternaries = [];
1672
+ }
1673
+ }
1674
+ if (cur.type === 'ternary') {
1675
+ return out;
1676
+ }
1677
+ out.push(cur);
1678
+ return out;
1679
+ }, [])
1680
+ .flat();
1681
+ // wrap theme around children on flatten
1682
+ // account for shouldFlatten could change w the above block "if (disableExtractVariables)"
1683
+ if (themeVal) {
1684
+ if (!programPath) {
1685
+ console.warn(`No program path found, avoiding importing flattening / importing theme in ${sourcePath}`);
1686
+ }
1687
+ else {
1688
+ if (shouldPrintDebug) {
1689
+ logger.info([' - wrapping theme', themeVal].join(' '));
1690
+ }
1691
+ // remove theme attribute from flattened node
1692
+ attrs = attrs.filter((x) => !(x.type === 'attr' &&
1693
+ t.isJSXAttribute(x.value) &&
1694
+ x.value.name.name === 'theme'));
1695
+ // add import
1696
+ if (!hasImportedTheme) {
1697
+ hasImportedTheme = true;
1698
+ programPath.node.body.push(t.importDeclaration([t.importSpecifier(t.identifier('_GuiTheme'), t.identifier('Theme'))], t.stringLiteral('@hanzogui/web')));
1699
+ }
1700
+ traversePath.replaceWith(t.jsxElement(t.jsxOpeningElement(t.jsxIdentifier('_GuiTheme'), [
1701
+ t.jsxAttribute(t.jsxIdentifier('name'), themeVal.value),
1702
+ ]), t.jsxClosingElement(t.jsxIdentifier('_GuiTheme')), [traversePath.node]));
1703
+ }
1704
+ }
1705
+ if (shouldPrintDebug) {
1706
+ logger.info([' - attrs (flattened): \n', (0, logLines_ts_1.logLines)(attrs.map(extractHelpers_ts_1.attrStr).join(', '))].join(' '));
1707
+ }
1708
+ function mergeToEnd(obj, key, val) {
1709
+ if (key in obj) {
1710
+ delete obj[key];
1711
+ }
1712
+ obj[key] = val;
1713
+ }
1714
+ // preserves order
1715
+ function normalizeStyleWithoutVariants(style) {
1716
+ let res = {};
1717
+ for (const key in style) {
1718
+ if (staticConfig.variants && key in staticConfig.variants) {
1719
+ mergeToEnd(res, key, style[key]);
1720
+ }
1721
+ else {
1722
+ const expanded = normalizeStyle({ [key]: style[key] }, true);
1723
+ for (const key in expanded) {
1724
+ mergeToEnd(res, key, expanded[key]);
1725
+ }
1726
+ }
1727
+ }
1728
+ return res;
1729
+ }
1730
+ // evaluates all static attributes into a simple object
1731
+ let foundStaticProps = {};
1732
+ for (const key in attrs) {
1733
+ const cur = attrs[key];
1734
+ if (cur.type === 'style') {
1735
+ // remove variants because they are processed later, and can lead to invalid values here
1736
+ // see <Spacer flex /> where flex looks like a valid style, but is a variant
1737
+ const expanded = normalizeStyleWithoutVariants(cur.value);
1738
+ // preserve order
1739
+ for (const key in expanded) {
1740
+ mergeToEnd(foundStaticProps, key, expanded[key]);
1741
+ }
1742
+ continue;
1743
+ }
1744
+ if (cur.type === 'attr') {
1745
+ if (t.isJSXSpreadAttribute(cur.value)) {
1746
+ continue;
1747
+ }
1748
+ if (!t.isJSXIdentifier(cur.value.name)) {
1749
+ continue;
1750
+ }
1751
+ const key = cur.value.name.name;
1752
+ // undefined = boolean true
1753
+ const value = attemptEvalSafe(cur.value.value || t.booleanLiteral(true));
1754
+ if (value !== constants_ts_1.FAILED_EVAL) {
1755
+ mergeToEnd(foundStaticProps, key, value);
1756
+ }
1757
+ }
1758
+ }
1759
+ // must preserve exact order
1760
+ const completeProps = {};
1761
+ for (const key in defaultProps) {
1762
+ if (!(key in foundStaticProps)) {
1763
+ completeProps[key] = defaultProps[key];
1764
+ }
1765
+ }
1766
+ for (const key in foundStaticProps) {
1767
+ completeProps[key] = foundStaticProps[key];
1768
+ }
1769
+ // expand shorthands, de-opt variables
1770
+ attrs = attrs.reduce((acc, cur) => {
1771
+ if (!cur)
1772
+ return acc;
1773
+ if (cur.type === 'attr' && !t.isJSXSpreadAttribute(cur.value)) {
1774
+ if (shouldFlatten) {
1775
+ const name = cur.value.name.name;
1776
+ if (typeof name === 'string') {
1777
+ if (name === 'render') {
1778
+ // remove render=""
1779
+ return acc;
1780
+ }
1781
+ // if flattening, expand variants
1782
+ if (variants[name] && variantValues.has(name)) {
1783
+ const styleState = {
1784
+ ...propMapperStyleState,
1785
+ props: completeProps,
1786
+ };
1787
+ let out = {};
1788
+ propMapper(name, variantValues.get(name), styleState, false, (key, val) => {
1789
+ out[key] = val;
1790
+ });
1791
+ if (out && isTargetingHTML) {
1792
+ const cn = out.className;
1793
+ // translate to DOM-compat
1794
+ out = reactNativeWebInternals.createDOMProps(isTextView ? 'span' : 'div', out);
1795
+ // remove rnw className use ours
1796
+ out.className = cn;
1797
+ // see note in single-prop branch above; createDOMProps
1798
+ // also emits a stray style key here that would duplicate
1799
+ // emitted JSXAttributes downstream.
1800
+ delete out.style;
1801
+ }
1802
+ if (shouldPrintDebug) {
1803
+ logger.info([' - expanded variant', name, out].join(' '));
1804
+ }
1805
+ for (const key in out) {
1806
+ const value = out[key];
1807
+ if (isValidStyleKey(key, staticConfig)) {
1808
+ acc.push({
1809
+ type: 'style',
1810
+ value: { [key]: value },
1811
+ name: key,
1812
+ attr: cur.value,
1813
+ });
1814
+ }
1815
+ else {
1816
+ acc.push({
1817
+ type: 'attr',
1818
+ value: t.jsxAttribute(t.jsxIdentifier(key), t.jsxExpressionContainer(typeof value === 'string'
1819
+ ? t.stringLiteral(value)
1820
+ : (0, literalToAst_ts_1.literalToAst)(value))),
1821
+ });
1822
+ }
1823
+ }
1824
+ }
1825
+ }
1826
+ }
1827
+ }
1828
+ if (cur.type !== 'style') {
1829
+ acc.push(cur);
1830
+ return acc;
1831
+ }
1832
+ let key = Object.keys(cur.value)[0];
1833
+ const value = cur.value[key];
1834
+ const fullKey = hanzoguiConfig?.shorthands[key];
1835
+ // expand shorthands
1836
+ if (fullKey) {
1837
+ cur.value = { [fullKey]: value };
1838
+ key = fullKey;
1839
+ }
1840
+ // finally we have all styles + expansions, lets see if we need to skip
1841
+ // any and keep them as attrs
1842
+ if (disableExtractVariables) {
1843
+ if (value[0] === '$' &&
1844
+ (usedThemeKeys.has(key) || usedThemeKeys.has(fullKey))) {
1845
+ if (shouldPrintDebug) {
1846
+ logger.info([` keeping variable inline: ${key} =`, value].join(' '));
1847
+ }
1848
+ acc.push({
1849
+ type: 'attr',
1850
+ value: t.jsxAttribute(t.jsxIdentifier(key), t.jsxExpressionContainer(t.stringLiteral(value))),
1851
+ });
1852
+ return acc;
1853
+ }
1854
+ }
1855
+ acc.push(cur);
1856
+ return acc;
1857
+ }, []);
1858
+ tm.mark('jsx-element-expanded', !!shouldPrintDebug);
1859
+ if (shouldPrintDebug) {
1860
+ logger.info([' - attrs (expanded): \n', (0, logLines_ts_1.logLines)(attrs.map(extractHelpers_ts_1.attrStr).join(', '))].join(' '));
1861
+ }
1862
+ // merge styles, leave undefined values
1863
+ let prev = null;
1864
+ function mergeStyles(prev, next) {
1865
+ for (const key in next) {
1866
+ // merge pseudos
1867
+ if (pseudoDescriptors[key]) {
1868
+ prev[key] = prev[key] || {};
1869
+ Object.assign(prev[key], next[key]);
1870
+ }
1871
+ else {
1872
+ mergeToEnd(prev, key, next[key]);
1873
+ }
1874
+ }
1875
+ }
1876
+ // post process
1877
+ const getProps = (props, includeProps = false, debugName = '') => {
1878
+ if (!props) {
1879
+ if (shouldPrintDebug)
1880
+ logger.info([' getProps() no props'].join(' '));
1881
+ return {};
1882
+ }
1883
+ if (excludeProps?.size) {
1884
+ for (const key in props) {
1885
+ if (excludeProps.has(key)) {
1886
+ if (shouldPrintDebug)
1887
+ logger.info([' delete excluded', key].join(' '));
1888
+ delete props[key];
1889
+ }
1890
+ }
1891
+ }
1892
+ const before = process.env.IS_STATIC;
1893
+ process.env.IS_STATIC = 'is_static';
1894
+ try {
1895
+ // $group-* / $theme-* keys carry block-form style objects that
1896
+ // getSplitStyles drops in static mode (no parent group context,
1897
+ // no theme value to read). Pluck them out so the atomic-CSS
1898
+ // pipeline in extractToClassNames can emit @container / theme
1899
+ // rules for them directly.
1900
+ let extractedMediaLikeProps = null;
1901
+ let propsForSplit = props;
1902
+ for (const k in props) {
1903
+ if (k[0] === '$' &&
1904
+ (k.startsWith('$group-') || k.startsWith('$theme-'))) {
1905
+ if (propsForSplit === props) {
1906
+ propsForSplit = { ...props };
1907
+ }
1908
+ if (platform === 'native' &&
1909
+ k.startsWith('$group-') &&
1910
+ getGroupPseudo(k) === 'hover') {
1911
+ delete propsForSplit[k];
1912
+ continue;
1913
+ }
1914
+ extractedMediaLikeProps || (extractedMediaLikeProps = {});
1915
+ extractedMediaLikeProps[k] = propsForSplit[k];
1916
+ delete propsForSplit[k];
1917
+ }
1918
+ }
1919
+ const out = getSplitStyles(propsForSplit, staticConfig, defaultTheme, '', componentState, {
1920
+ ...styleProps,
1921
+ noClass: true,
1922
+ fallbackProps: completeProps,
1923
+ ...(platform === 'native' && {
1924
+ resolveValues: 'except-theme',
1925
+ }),
1926
+ }, undefined, undefined, undefined, undefined, false, debugPropValue || shouldPrintDebug);
1927
+ // resolve tokens inside the plucked blocks: they skipped the main
1928
+ // split, so values like "$color5" would flow raw into the emitted
1929
+ // CSS where browsers reject the declaration. run each block through
1930
+ // its own static split so tokens become var(--x) references.
1931
+ // (native never extracts these — it deopts below — so web only.)
1932
+ if (extractedMediaLikeProps && platform !== 'native') {
1933
+ for (const k in extractedMediaLikeProps) {
1934
+ const block = extractedMediaLikeProps[k];
1935
+ if (!block || typeof block !== 'object')
1936
+ continue;
1937
+ const blockOut = getSplitStyles(block, staticConfig, defaultTheme, '', componentState, {
1938
+ ...styleProps,
1939
+ noClass: true,
1940
+ fallbackProps: completeProps,
1941
+ }, undefined, undefined, undefined, undefined, false, debugPropValue || shouldPrintDebug);
1942
+ if (blockOut) {
1943
+ extractedMediaLikeProps[k] = {
1944
+ ...blockOut.style,
1945
+ ...blockOut.pseudos,
1946
+ };
1947
+ }
1948
+ }
1949
+ }
1950
+ let outProps = {
1951
+ ...(includeProps ? out.viewProps : {}),
1952
+ ...out.style,
1953
+ ...out.pseudos,
1954
+ ...extractedMediaLikeProps,
1955
+ };
1956
+ // check de-opt props again
1957
+ for (const key in outProps) {
1958
+ if (deoptProps.has(key)) {
1959
+ shouldFlatten = false;
1960
+ }
1961
+ // native has no atomic-CSS sink for theme- / group- pseudo
1962
+ // blocks; if they flatten they get serialized under the literal
1963
+ // `$theme-…` / `$group-…` key into the RN StyleSheet, where the
1964
+ // runtime's @container / theme-name matching never runs. de-opt
1965
+ // → preserve as inline prop so getSplitStyles handles them at
1966
+ // render time.
1967
+ if (platform === 'native' &&
1968
+ key[0] === '$' &&
1969
+ (key.startsWith('$theme-') ||
1970
+ (key.startsWith('$group-') && getGroupPseudo(key) !== 'hover'))) {
1971
+ shouldFlatten = false;
1972
+ }
1973
+ }
1974
+ if (shouldPrintDebug) {
1975
+ logger.info(`(${debugName})`);
1976
+ // prettier-ignore
1977
+ logger.info(`\n getProps (props in): ${(0, logLines_ts_1.logLines)((0, extractHelpers_ts_1.objToStr)(props))}`);
1978
+ // prettier-ignore
1979
+ logger.info(`\n getProps (outProps): ${(0, logLines_ts_1.logLines)((0, extractHelpers_ts_1.objToStr)(outProps))}`);
1980
+ }
1981
+ if (out.fontFamily) {
1982
+ (0, propsToFontFamilyCache_ts_1.setPropsToFontFamily)(outProps, out.fontFamily);
1983
+ if (shouldPrintDebug) {
1984
+ logger.info(`\n 💬 new font fam: ${out.fontFamily}`);
1985
+ }
1986
+ }
1987
+ return outProps;
1988
+ }
1989
+ catch (err) {
1990
+ logger.info(['error', err.message, err.stack].join(' '));
1991
+ return {};
1992
+ }
1993
+ finally {
1994
+ process.env.IS_STATIC = before;
1995
+ }
1996
+ };
1997
+ // add default props
1998
+ attrs.unshift({
1999
+ type: 'style',
2000
+ value: defaultProps,
2001
+ });
2002
+ attrs = attrs.reduce((acc, cur) => {
2003
+ if (cur.type === 'style') {
2004
+ const keys = Object.keys(cur.value || {});
2005
+ if (!keys.length) {
2006
+ return acc;
2007
+ }
2008
+ const key = keys[0];
2009
+ const value = cur.value[key];
2010
+ // Check if this is a media-like key ($theme-, $platform-, $group-, or $mediaQuery)
2011
+ const isMediaLikeKey = key[0] === '$' &&
2012
+ (key.startsWith('$theme-') ||
2013
+ key.startsWith('$platform-') ||
2014
+ key.startsWith('$group-') ||
2015
+ mediaQueryConfig[key.slice(1)]);
2016
+ const shouldKeepOriginalAttr =
2017
+ // !isStyleAndAttr[key] &&
2018
+ !shouldFlatten &&
2019
+ // de-opt if non-style
2020
+ !validStyles[key] &&
2021
+ !pseudoDescriptors[key] &&
2022
+ !isMediaLikeKey &&
2023
+ !(key.startsWith('data-') || key.startsWith('aria-'));
2024
+ if (shouldKeepOriginalAttr) {
2025
+ if (shouldPrintDebug) {
2026
+ logger.info([' - keeping as non-style', key].join(' '));
2027
+ }
2028
+ prev = cur;
2029
+ acc.push({
2030
+ type: 'attr',
2031
+ value: t.jsxAttribute(t.jsxIdentifier(key), t.jsxExpressionContainer(typeof value === 'string'
2032
+ ? t.stringLiteral(value)
2033
+ : (0, literalToAst_ts_1.literalToAst)(value))),
2034
+ });
2035
+ acc.push(cur);
2036
+ return acc;
2037
+ }
2038
+ if (prev?.type === 'style') {
2039
+ mergeStyles(prev.value, cur.value);
2040
+ return acc;
2041
+ }
2042
+ }
2043
+ if (cur.type === 'style') {
2044
+ prev = cur;
2045
+ }
2046
+ acc.push(cur);
2047
+ return acc;
2048
+ }, []);
2049
+ if (shouldPrintDebug) {
2050
+ logger.info([
2051
+ ' - attrs (combined 🔀): \n',
2052
+ (0, logLines_ts_1.logLines)(attrs.map(extractHelpers_ts_1.attrStr).join(', ')),
2053
+ ].join(' '));
2054
+ }
2055
+ let getStyleError = null;
2056
+ // fix up ternaries, combine final style values
2057
+ for (const attr of attrs) {
2058
+ try {
2059
+ if (shouldPrintDebug) {
2060
+ console.info(` Processing ${attr.type}:`);
2061
+ }
2062
+ switch (attr.type) {
2063
+ case 'ternary': {
2064
+ const a = getProps(attr.value.alternate, false, 'ternary.alternate');
2065
+ const c = getProps(attr.value.consequent, false, 'ternary.consequent');
2066
+ if (a)
2067
+ attr.value.alternate = a;
2068
+ if (c)
2069
+ attr.value.consequent = c;
2070
+ if (shouldPrintDebug)
2071
+ logger.info([' => tern ', (0, extractHelpers_ts_1.attrStr)(attr)].join(' '));
2072
+ continue;
2073
+ }
2074
+ case 'style': {
2075
+ // expand variants and such
2076
+ const styles = getProps(attr.value, false, 'style');
2077
+ if (styles) {
2078
+ // @ts-ignore
2079
+ attr.value = styles;
2080
+ }
2081
+ // prettier-ignore
2082
+ if (shouldPrintDebug)
2083
+ logger.info([' * styles (in)', (0, logLines_ts_1.logLines)((0, extractHelpers_ts_1.objToStr)(attr.value))].join(' '));
2084
+ // prettier-ignore
2085
+ if (shouldPrintDebug)
2086
+ logger.info([' * styles (out)', (0, logLines_ts_1.logLines)((0, extractHelpers_ts_1.objToStr)(styles))].join(' '));
2087
+ continue;
2088
+ }
2089
+ case 'attr': {
2090
+ if (shouldFlatten && t.isJSXAttribute(attr.value)) {
2091
+ // we know all attributes are static
2092
+ // this only does one at a time but it should really do the whole group together...
2093
+ // also awkward to be doing it using jsxAttributes...
2094
+ const key = attr.value.name.name;
2095
+ // dont process style/className can just stay attrs
2096
+ if (key === 'style' || key === 'className' || key === 'render') {
2097
+ continue;
2098
+ }
2099
+ // undefined = boolean true
2100
+ const value = attemptEvalSafe(attr.value.value || t.booleanLiteral(true));
2101
+ if (value !== constants_ts_1.FAILED_EVAL) {
2102
+ const outProps = getProps({ [key]: value }, true, `attr.${key}`);
2103
+ const outKey = Object.keys(outProps)[0];
2104
+ if (outKey) {
2105
+ const outVal = outProps[outKey];
2106
+ attr.value = t.jsxAttribute(t.jsxIdentifier(outKey), t.jsxExpressionContainer(typeof outVal === 'string'
2107
+ ? t.stringLiteral(outVal)
2108
+ : (0, literalToAst_ts_1.literalToAst)(outVal)));
2109
+ }
2110
+ }
2111
+ }
2112
+ }
2113
+ }
2114
+ }
2115
+ catch (err) {
2116
+ // any error de-opt
2117
+ getStyleError = err;
2118
+ }
2119
+ }
2120
+ if (shouldPrintDebug) {
2121
+ // prettier-ignore
2122
+ logger.info([
2123
+ ' - attrs (ternaries/combined):\n',
2124
+ (0, logLines_ts_1.logLines)(attrs.map(extractHelpers_ts_1.attrStr).join(', ')),
2125
+ ].join(' '));
2126
+ }
2127
+ tm.mark('jsx-element-styles', !!shouldPrintDebug);
2128
+ if (getStyleError) {
2129
+ logger.info([' ⚠️ postprocessing error, deopt', getStyleError].join(' '));
2130
+ node.attributes = ogAttributes;
2131
+ return null;
2132
+ }
2133
+ // final lazy extra loop:
2134
+ const existingStyleKeys = new Set();
2135
+ for (let i = attrs.length - 1; i >= 0; i--) {
2136
+ const attr = attrs[i];
2137
+ // if flattening map inline props to proper flattened names
2138
+ if (shouldFlatten) {
2139
+ if (attr.type === 'attr') {
2140
+ if (t.isJSXAttribute(attr.value)) {
2141
+ if (t.isJSXIdentifier(attr.value.name)) {
2142
+ const name = attr.value.name.name;
2143
+ if (INLINE_EXTRACTABLE[name]) {
2144
+ // map to HTML only name
2145
+ attr.value.name.name = INLINE_EXTRACTABLE[name];
2146
+ }
2147
+ }
2148
+ }
2149
+ }
2150
+ }
2151
+ // remove duplicate styles
2152
+ // so if you have:
2153
+ // style({ color: 'red' }), ...someProps, style({ color: 'green' })
2154
+ // this will mutate:
2155
+ // style({}), ...someProps, style({ color: 'green' })
2156
+ if (attr.type === 'style') {
2157
+ for (const key in attr.value) {
2158
+ if (existingStyleKeys.has(key)) {
2159
+ if (shouldPrintDebug) {
2160
+ logger.info([` >> delete existing ${key}`].join(' '));
2161
+ }
2162
+ delete attr.value[key];
2163
+ }
2164
+ else {
2165
+ existingStyleKeys.add(key);
2166
+ }
2167
+ }
2168
+ }
2169
+ }
2170
+ attrs = attrs.filter(Boolean);
2171
+ // inlineWhenUnflattened
2172
+ if (!shouldFlatten) {
2173
+ if (inlineWhenUnflattened.size) {
2174
+ for (const [index, attr] of attrs.entries()) {
2175
+ if (attr.type === 'style') {
2176
+ for (const key in attr.value) {
2177
+ if (!inlineWhenUnflattened.has(key))
2178
+ continue;
2179
+ const val = inlineWhenUnflattenedOGVals[key];
2180
+ if (val) {
2181
+ // delete the style
2182
+ delete attr.value[key];
2183
+ // and insert it before
2184
+ attrs.splice(index - 1, 0, val.attr);
2185
+ }
2186
+ else {
2187
+ // just delete it, it was added during expansion but should be left inline
2188
+ delete attr.value[key];
2189
+ }
2190
+ }
2191
+ }
2192
+ }
2193
+ }
2194
+ }
2195
+ // delete empty styles:
2196
+ attrs = attrs.filter((x) => {
2197
+ if (x.type === 'style' && Object.keys(x.value).length === 0) {
2198
+ return false;
2199
+ }
2200
+ return true;
2201
+ });
2202
+ const isNativeNotFlat = !shouldFlatten && platform === 'native';
2203
+ if (isNativeNotFlat) {
2204
+ if (shouldPrintDebug) {
2205
+ logger.info(`Disabled flattening except for simple cases on native for now: ${JSON.stringify({
2206
+ flatNode: flatNodeName,
2207
+ shouldDeopt,
2208
+ canFlattenProps,
2209
+ hasSpread,
2210
+ 'staticConfig.isStyledHOC': staticConfig.isStyledHOC,
2211
+ '!staticConfig.isHOC': !staticConfig.isHOC,
2212
+ 'staticConfig.isReactNative': staticConfig.isReactNative,
2213
+ 'staticConfig.neverFlatten': staticConfig.neverFlatten,
2214
+ }, null, 2)}`);
2215
+ }
2216
+ node.attributes = ogAttributes;
2217
+ return null;
2218
+ }
2219
+ if (shouldPrintDebug) {
2220
+ // prettier-ignore
2221
+ logger.info([
2222
+ ` - inlined props (${inlined.size}):`,
2223
+ shouldDeopt ? ' deopted' : '',
2224
+ hasSpread ? ' has spread' : '',
2225
+ staticConfig.neverFlatten ? 'neverFlatten' : '',
2226
+ ].join(' '));
2227
+ logger.info(` - attrs (end):\n ${(0, logLines_ts_1.logLines)(attrs.map(extractHelpers_ts_1.attrStr).join(', '))}`);
2228
+ }
2229
+ onExtractTag({
2230
+ parserProps: propsWithFileInfo,
2231
+ attrs,
2232
+ node,
2233
+ lineNumbers,
2234
+ filePath,
2235
+ config: hanzoguiConfig,
2236
+ flatNodeName,
2237
+ attemptEval,
2238
+ jsxPath: traversePath,
2239
+ originalNodeName,
2240
+ programPath: programPath,
2241
+ completeProps,
2242
+ staticConfig,
2243
+ });
2244
+ if (shouldFlatten) {
2245
+ if (shouldPrintDebug) {
2246
+ logger.info([' [✅] flattened', originalNodeName, flatNodeName].join(' '));
2247
+ }
2248
+ // Only rename if onExtractTag hasn't already renamed to a custom wrapper
2249
+ // @ts-ignore - check if already renamed by callback (e.g., to a styled wrapper)
2250
+ const currentName = node.name?.name;
2251
+ if (!currentName ||
2252
+ currentName === originalNodeName ||
2253
+ currentName.startsWith('__ReactNative')) {
2254
+ // @ts-ignore
2255
+ node.name.name = flatNodeName;
2256
+ if (closingElement) {
2257
+ // @ts-ignore
2258
+ closingElement.name.name = flatNodeName;
2259
+ }
2260
+ }
2261
+ res.flattened++;
2262
+ }
2263
+ }
2264
+ catch (err) {
2265
+ node.attributes = ogAttributes;
2266
+ if (!(err instanceof errors_ts_1.BailOptimizationError)) {
2267
+ console.error(`@hanzogui/static error, reverting optimization. In ${filePath} ${lineNumbers} on ${originalNodeName}: ${err.message}. For stack trace set environment GUI_DEBUG=1`);
2268
+ if (process.env.GUI_DEBUG === '1') {
2269
+ console.error(err.stack);
2270
+ }
2271
+ }
2272
+ }
2273
+ finally {
2274
+ if (debugPropValue) {
2275
+ shouldPrintDebug = ogDebug;
2276
+ }
2277
+ }
2278
+ },
2279
+ });
2280
+ tm.mark('jsx-done', !!shouldPrintDebug);
2281
+ tm.done(shouldPrintDebug === 'verbose');
2282
+ return res;
2283
+ }
2284
+ }
2285
+ //# sourceMappingURL=createExtractor.js.map