meno-core 1.0.53 → 1.1.0

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 (415) hide show
  1. package/.claude/settings.local.json +1 -3
  2. package/bin/cli.ts +66 -261
  3. package/build-astro.ts +150 -128
  4. package/dist/bin/cli.js +42 -185
  5. package/dist/bin/cli.js.map +2 -2
  6. package/dist/chunks/chunk-2AR55GYH.js +42 -0
  7. package/dist/chunks/chunk-2AR55GYH.js.map +7 -0
  8. package/dist/chunks/{chunk-JGWFTO6P.js → chunk-2IIQK7T3.js} +2624 -1389
  9. package/dist/chunks/chunk-2IIQK7T3.js.map +7 -0
  10. package/dist/chunks/chunk-4ZRU52J2.js +169 -0
  11. package/dist/chunks/chunk-4ZRU52J2.js.map +7 -0
  12. package/dist/chunks/{chunk-UB44F4Z2.js → chunk-5X4HCN7J.js} +5 -7
  13. package/dist/chunks/chunk-5X4HCN7J.js.map +7 -0
  14. package/dist/chunks/{chunk-WQFG7PAH.js → chunk-7CCVOL5M.js} +15 -19
  15. package/dist/chunks/chunk-7CCVOL5M.js.map +7 -0
  16. package/dist/chunks/{chunk-YBLHKYFF.js → chunk-AR7LHIFY.js} +8 -2
  17. package/dist/chunks/chunk-AR7LHIFY.js.map +7 -0
  18. package/dist/chunks/{chunk-O3NAGJP4.js → chunk-NUP7H7D3.js} +135 -41
  19. package/dist/chunks/chunk-NUP7H7D3.js.map +7 -0
  20. package/dist/chunks/{chunk-X754AHS5.js → chunk-QWTQZHG3.js} +194 -90
  21. package/dist/chunks/chunk-QWTQZHG3.js.map +7 -0
  22. package/dist/chunks/{chunk-H3GJ4H2U.js → chunk-XTKNX4FW.js} +216 -87
  23. package/dist/chunks/chunk-XTKNX4FW.js.map +7 -0
  24. package/dist/chunks/{fs-JGINUXGL.js → fs-G3ANWEFP.js} +2 -2
  25. package/dist/lib/client/index.js +1003 -475
  26. package/dist/lib/client/index.js.map +3 -3
  27. package/dist/lib/server/index.js +14393 -6371
  28. package/dist/lib/server/index.js.map +4 -4
  29. package/dist/lib/shared/index.js +342 -101
  30. package/dist/lib/shared/index.js.map +4 -4
  31. package/dist/lib/shared/richtext/index.js +1 -1
  32. package/dist/lib/test-utils/index.js +64 -80
  33. package/dist/lib/test-utils/index.js.map +2 -2
  34. package/entries/client-router.tsx +10 -8
  35. package/lib/client/ClientInitializer.ts +8 -8
  36. package/lib/client/ErrorBoundary.test.tsx +246 -186
  37. package/lib/client/ErrorBoundary.tsx +183 -132
  38. package/lib/client/componentRegistry.test.ts +96 -108
  39. package/lib/client/componentRegistry.ts +1 -3
  40. package/lib/client/contexts/ThemeContext.tsx +3 -2
  41. package/lib/client/core/ComponentBuilder.test.ts +663 -560
  42. package/lib/client/core/ComponentBuilder.ts +427 -155
  43. package/lib/client/core/ComponentRenderer.test.tsx +2 -4
  44. package/lib/client/core/ComponentRenderer.tsx +46 -33
  45. package/lib/client/core/builders/embedBuilder.ts +242 -54
  46. package/lib/client/core/builders/linkBuilder.ts +72 -45
  47. package/lib/client/core/builders/linkNodeBuilder.ts +79 -54
  48. package/lib/client/core/builders/listBuilder.ts +155 -89
  49. package/lib/client/core/builders/localeListBuilder.ts +97 -62
  50. package/lib/client/core/builders/types.ts +5 -5
  51. package/lib/client/core/cmsTemplateProcessor.ts +8 -9
  52. package/lib/client/elementRegistry.ts +3 -3
  53. package/lib/client/fontFamiliesService.test.ts +2 -10
  54. package/lib/client/fontFamiliesService.ts +3 -3
  55. package/lib/client/hmr/HMRManager.tsx +47 -30
  56. package/lib/client/hmrCssReload.ts +49 -14
  57. package/lib/client/hmrWebSocket.ts +14 -19
  58. package/lib/client/hooks/useColorVariables.test.ts +21 -21
  59. package/lib/client/hooks/useColorVariables.ts +23 -18
  60. package/lib/client/hooks/usePropertyAutocomplete.ts +4 -6
  61. package/lib/client/hooks/useVariables.ts +6 -4
  62. package/lib/client/hydration/HydrationUtils.test.ts +24 -25
  63. package/lib/client/hydration/HydrationUtils.ts +3 -4
  64. package/lib/client/i18nConfigService.test.ts +2 -7
  65. package/lib/client/i18nConfigService.ts +2 -2
  66. package/lib/client/meno-filter/MenoFilter.test.ts +47 -49
  67. package/lib/client/meno-filter/MenoFilter.ts +14 -15
  68. package/lib/client/meno-filter/bindings.ts +18 -43
  69. package/lib/client/meno-filter/init.ts +4 -4
  70. package/lib/client/meno-filter/renderer.ts +30 -32
  71. package/lib/client/meno-filter/script.generated.ts +1 -3
  72. package/lib/client/meno-filter/ui.ts +4 -6
  73. package/lib/client/meno-filter/updates.ts +18 -23
  74. package/lib/client/meno-filter/utils.ts +1 -1
  75. package/lib/client/navigation.test.ts +174 -178
  76. package/lib/client/navigation.ts +0 -1
  77. package/lib/client/responsiveStyleResolver.knownTokens.test.ts +71 -0
  78. package/lib/client/responsiveStyleResolver.test.ts +234 -232
  79. package/lib/client/responsiveStyleResolver.ts +74 -20
  80. package/lib/client/routing/RouteLoader.test.ts +24 -25
  81. package/lib/client/routing/RouteLoader.ts +27 -35
  82. package/lib/client/routing/Router.tsx +210 -153
  83. package/lib/client/scripts/ScriptExecutor.test.ts +157 -158
  84. package/lib/client/scripts/ScriptExecutor.ts +18 -36
  85. package/lib/client/services/PrefetchService.test.ts +3 -3
  86. package/lib/client/services/PrefetchService.ts +23 -29
  87. package/lib/client/styleProcessor.test.ts +9 -9
  88. package/lib/client/styleProcessor.ts +24 -15
  89. package/lib/client/styles/StyleInjector.test.ts +122 -115
  90. package/lib/client/styles/StyleInjector.ts +10 -7
  91. package/lib/client/styles/UtilityClassCollector.ts +62 -28
  92. package/lib/client/styles/cspNonce.test.ts +2 -5
  93. package/lib/client/templateEngine.test.ts +554 -488
  94. package/lib/client/templateEngine.ts +203 -73
  95. package/lib/client/theme.test.ts +1 -1
  96. package/lib/client/theme.ts +0 -1
  97. package/lib/client/utils/toast.ts +0 -1
  98. package/lib/server/__integration__/api-routes.test.ts +8 -4
  99. package/lib/server/__integration__/cms-integration.test.ts +1 -4
  100. package/lib/server/__integration__/server-lifecycle.test.ts +4 -5
  101. package/lib/server/__integration__/ssr-rendering.test.ts +47 -37
  102. package/lib/server/__integration__/static-assets.test.ts +3 -3
  103. package/lib/server/__integration__/test-helpers.ts +87 -74
  104. package/lib/server/ab/generateFunctions.ts +12 -10
  105. package/lib/server/astro/cmsPageEmitter.ts +26 -42
  106. package/lib/server/astro/componentEmitter.ts +35 -43
  107. package/lib/server/astro/cssCollector.ts +10 -26
  108. package/lib/server/astro/nodeToAstro.test.ts +1754 -34
  109. package/lib/server/astro/nodeToAstro.ts +232 -216
  110. package/lib/server/astro/normalizeOrphanTemplateProps.test.ts +115 -119
  111. package/lib/server/astro/normalizeOrphanTemplateProps.ts +11 -18
  112. package/lib/server/astro/pageEmitter.ts +9 -13
  113. package/lib/server/astro/tailwindMapper.test.ts +10 -37
  114. package/lib/server/astro/tailwindMapper.ts +33 -40
  115. package/lib/server/astro/templateTransformer.ts +17 -20
  116. package/lib/server/createServer.ts +7 -19
  117. package/lib/server/cssGenerator.test.ts +35 -44
  118. package/lib/server/cssGenerator.ts +8 -19
  119. package/lib/server/fileWatcher.test.ts +164 -13
  120. package/lib/server/fileWatcher.ts +209 -124
  121. package/lib/server/index.ts +14 -17
  122. package/lib/server/jsonLoader.test.ts +39 -2
  123. package/lib/server/jsonLoader.ts +39 -34
  124. package/lib/server/middleware/cors.test.ts +21 -21
  125. package/lib/server/middleware/cors.ts +28 -4
  126. package/lib/server/middleware/errorHandler.test.ts +7 -5
  127. package/lib/server/middleware/errorHandler.ts +3 -8
  128. package/lib/server/middleware/index.ts +0 -1
  129. package/lib/server/middleware/logger.test.ts +10 -8
  130. package/lib/server/middleware/logger.ts +17 -29
  131. package/lib/server/migrateTemplates.ts +3 -3
  132. package/lib/server/pageCache.test.ts +76 -77
  133. package/lib/server/pageCache.ts +0 -1
  134. package/lib/server/projectContext.ts +5 -4
  135. package/lib/server/providers/fileSystemCMSProvider.test.ts +142 -99
  136. package/lib/server/providers/fileSystemCMSProvider.ts +62 -38
  137. package/lib/server/routes/api/cms.test.ts +26 -14
  138. package/lib/server/routes/api/cms.ts +9 -14
  139. package/lib/server/routes/api/colors.test.ts +2 -2
  140. package/lib/server/routes/api/components.ts +31 -35
  141. package/lib/server/routes/api/config.ts +3 -4
  142. package/lib/server/routes/api/core-routes.ts +49 -76
  143. package/lib/server/routes/api/enums.test.ts +2 -2
  144. package/lib/server/routes/api/functions.ts +9 -17
  145. package/lib/server/routes/api/index.ts +3 -6
  146. package/lib/server/routes/api/pages.ts +8 -11
  147. package/lib/server/routes/api/shared.test.ts +1 -1
  148. package/lib/server/routes/api/shared.ts +12 -9
  149. package/lib/server/routes/api/variables.test.ts +3 -5
  150. package/lib/server/routes/api/variables.ts +1 -1
  151. package/lib/server/routes/index.ts +25 -28
  152. package/lib/server/routes/pages.ts +35 -31
  153. package/lib/server/routes/static.ts +17 -6
  154. package/lib/server/runtime/bundler.ts +98 -61
  155. package/lib/server/runtime/fs.ts +16 -26
  156. package/lib/server/runtime/httpServer.ts +8 -12
  157. package/lib/server/services/ColorService.test.ts +3 -3
  158. package/lib/server/services/ColorService.ts +37 -29
  159. package/lib/server/services/EnumService.test.ts +4 -8
  160. package/lib/server/services/EnumService.ts +11 -3
  161. package/lib/server/services/VariableService.test.ts +8 -12
  162. package/lib/server/services/VariableService.ts +11 -3
  163. package/lib/server/services/cmsService.test.ts +158 -120
  164. package/lib/server/services/cmsService.ts +36 -146
  165. package/lib/server/services/componentService.test.ts +125 -45
  166. package/lib/server/services/componentService.ts +70 -46
  167. package/lib/server/services/configService.test.ts +22 -45
  168. package/lib/server/services/configService.ts +50 -27
  169. package/lib/server/services/fileWatcherService.ts +42 -8
  170. package/lib/server/services/index.ts +0 -1
  171. package/lib/server/services/pageService.test.ts +8 -10
  172. package/lib/server/services/pageService.ts +32 -18
  173. package/lib/server/ssr/attributeBuilder.ts +18 -8
  174. package/lib/server/ssr/buildErrorOverlay.ts +11 -12
  175. package/lib/server/ssr/clientDataInjector.ts +7 -21
  176. package/lib/server/ssr/cmsSSRProcessor.ts +4 -8
  177. package/lib/server/ssr/cssCollector.ts +1 -1
  178. package/lib/server/ssr/errorOverlay.test.ts +1 -1
  179. package/lib/server/ssr/errorOverlay.ts +3 -9
  180. package/lib/server/ssr/htmlGenerator.nonce.test.ts +9 -14
  181. package/lib/server/ssr/htmlGenerator.test.ts +120 -44
  182. package/lib/server/ssr/htmlGenerator.ts +126 -91
  183. package/lib/server/ssr/imageMetadata.test.ts +3 -1
  184. package/lib/server/ssr/imageMetadata.ts +27 -21
  185. package/lib/server/ssr/jsCollector.test.ts +8 -18
  186. package/lib/server/ssr/jsCollector.ts +3 -8
  187. package/lib/server/ssr/liveReloadIntegration.test.ts +76 -36
  188. package/lib/server/ssr/metaTagGenerator.ts +2 -2
  189. package/lib/server/ssr/ssrRenderer.branches.test.ts +1103 -0
  190. package/lib/server/ssr/ssrRenderer.test.ts +316 -256
  191. package/lib/server/ssr/ssrRenderer.ts +795 -243
  192. package/lib/server/ssrRenderer.test.ts +1048 -954
  193. package/lib/server/utils/jsonLineMapper.test.ts +28 -28
  194. package/lib/server/utils/jsonLineMapper.ts +7 -7
  195. package/lib/server/validateStyleCoverage.ts +18 -21
  196. package/lib/server/websocketManager.ts +28 -19
  197. package/lib/shared/attributeNodeUtils.test.ts +15 -15
  198. package/lib/shared/attributeNodeUtils.ts +5 -12
  199. package/lib/shared/breakpoints.test.ts +5 -5
  200. package/lib/shared/breakpoints.ts +4 -11
  201. package/lib/shared/cmsQuery.test.ts +81 -0
  202. package/lib/shared/cmsQuery.ts +92 -0
  203. package/lib/shared/cmsQueryParser.test.ts +50 -42
  204. package/lib/shared/cmsQueryParser.ts +60 -38
  205. package/lib/shared/colorConversions.ts +9 -9
  206. package/lib/shared/colorVariableUtils.test.ts +27 -5
  207. package/lib/shared/colorVariableUtils.ts +21 -12
  208. package/lib/shared/componentRefs.ts +1 -5
  209. package/lib/shared/constants.test.ts +3 -3
  210. package/lib/shared/constants.ts +8 -8
  211. package/lib/shared/cssGeneration.test.ts +285 -144
  212. package/lib/shared/cssGeneration.ts +217 -531
  213. package/lib/shared/cssNamedColors.ts +152 -30
  214. package/lib/shared/cssProperties.test.ts +69 -70
  215. package/lib/shared/cssProperties.ts +298 -114
  216. package/lib/shared/elementClassName.test.ts +109 -109
  217. package/lib/shared/elementClassName.ts +3 -3
  218. package/lib/shared/elementUtils.ts +12 -16
  219. package/lib/shared/errorLogger.test.ts +12 -12
  220. package/lib/shared/errorLogger.ts +2 -10
  221. package/lib/shared/errors.test.ts +2 -13
  222. package/lib/shared/errors.ts +2 -8
  223. package/lib/shared/expressionEvaluator.test.ts +145 -0
  224. package/lib/shared/expressionEvaluator.ts +52 -24
  225. package/lib/shared/fontLoader.test.ts +32 -18
  226. package/lib/shared/fontLoader.ts +2 -2
  227. package/lib/shared/friendlyError.ts +2 -3
  228. package/lib/shared/gradientUtils.test.ts +3 -7
  229. package/lib/shared/gradientUtils.ts +17 -14
  230. package/lib/shared/hrefRefs.test.ts +2 -2
  231. package/lib/shared/hrefRefs.ts +2 -10
  232. package/lib/shared/i18n.test.ts +4 -4
  233. package/lib/shared/i18n.ts +18 -38
  234. package/lib/shared/index.ts +27 -0
  235. package/lib/shared/inlineSvgStyleRules.ts +14 -13
  236. package/lib/shared/interactiveStyleMappings.test.ts +32 -54
  237. package/lib/shared/interactiveStyleMappings.ts +11 -24
  238. package/lib/shared/interactiveStyles.test.ts +165 -188
  239. package/lib/shared/interfaces/contentProvider.ts +1 -1
  240. package/lib/shared/itemTemplateUtils.test.ts +11 -17
  241. package/lib/shared/itemTemplateUtils.ts +27 -39
  242. package/lib/shared/jsonRepair.ts +16 -10
  243. package/lib/shared/libraryLoader.test.ts +21 -55
  244. package/lib/shared/libraryLoader.ts +7 -22
  245. package/lib/shared/linkUtils.ts +1 -1
  246. package/lib/shared/logger.test.ts +66 -0
  247. package/lib/shared/logger.ts +94 -0
  248. package/lib/shared/markdown.ts +25 -0
  249. package/lib/shared/netlifyLocale404.test.ts +179 -0
  250. package/lib/shared/netlifyLocale404.ts +110 -0
  251. package/lib/shared/nodeUtils.test.ts +28 -16
  252. package/lib/shared/nodeUtils.ts +76 -23
  253. package/lib/shared/pathArrayUtils.test.ts +1 -2
  254. package/lib/shared/pathArrayUtils.ts +1 -1
  255. package/lib/shared/pathSecurity.ts +2 -2
  256. package/lib/shared/pathUtils.test.ts +4 -6
  257. package/lib/shared/pathUtils.ts +42 -49
  258. package/lib/shared/paths/Path.test.ts +2 -2
  259. package/lib/shared/paths/Path.ts +0 -1
  260. package/lib/shared/paths/PathConverter.test.ts +1 -1
  261. package/lib/shared/paths/PathConverter.ts +17 -20
  262. package/lib/shared/paths/PathUtils.ts +13 -13
  263. package/lib/shared/paths/PathValidator.test.ts +2 -15
  264. package/lib/shared/paths/PathValidator.ts +12 -10
  265. package/lib/shared/paths/index.ts +1 -2
  266. package/lib/shared/permissions.test.ts +168 -0
  267. package/lib/shared/permissions.ts +162 -0
  268. package/lib/shared/propResolver.test.ts +240 -244
  269. package/lib/shared/propResolver.ts +15 -26
  270. package/lib/shared/pxToRem.test.ts +7 -6
  271. package/lib/shared/pxToRem.ts +2 -5
  272. package/lib/shared/registry/BaseNodeTypeRegistry.test.ts +12 -6
  273. package/lib/shared/registry/ClientRegistry.ts +0 -2
  274. package/lib/shared/registry/ComponentRegistry.test.ts +46 -32
  275. package/lib/shared/registry/ComponentRegistry.ts +12 -9
  276. package/lib/shared/registry/NodeTypeDefinition.ts +16 -9
  277. package/lib/shared/registry/RegistryManager.ts +1 -2
  278. package/lib/shared/registry/SSRRegistry.ts +0 -2
  279. package/lib/shared/registry/createNodeType.ts +7 -9
  280. package/lib/shared/registry/defineNodeType.ts +2 -6
  281. package/lib/shared/registry/fieldPresets.ts +3 -1
  282. package/lib/shared/registry/index.ts +0 -1
  283. package/lib/shared/registry/nodeTypes/ComponentInstanceNodeType.ts +14 -15
  284. package/lib/shared/registry/nodeTypes/CustomNodeType.ts +103 -0
  285. package/lib/shared/registry/nodeTypes/EmbedNodeType.ts +18 -11
  286. package/lib/shared/registry/nodeTypes/HtmlNodeType.ts +48 -19
  287. package/lib/shared/registry/nodeTypes/IslandNodeType.ts +129 -0
  288. package/lib/shared/registry/nodeTypes/LinkNodeType.ts +21 -19
  289. package/lib/shared/registry/nodeTypes/ListNodeType.ts +117 -77
  290. package/lib/shared/registry/nodeTypes/LocaleListNodeType.ts +27 -21
  291. package/lib/shared/registry/nodeTypes/MarkdownNodeType.ts +78 -0
  292. package/lib/shared/registry/nodeTypes/SlotMarkerType.ts +12 -8
  293. package/lib/shared/registry/nodeTypes/index.ts +26 -3
  294. package/lib/shared/responsiveScaling.test.ts +16 -34
  295. package/lib/shared/responsiveScaling.ts +61 -42
  296. package/lib/shared/responsiveStyleUtils.test.ts +0 -1
  297. package/lib/shared/responsiveStyleUtils.ts +11 -13
  298. package/lib/shared/richtext/htmlToTiptap.test.ts +139 -130
  299. package/lib/shared/richtext/htmlToTiptap.ts +2 -4
  300. package/lib/shared/richtext/tiptapToHtml.test.ts +5 -6
  301. package/lib/shared/richtext/types.ts +1 -8
  302. package/lib/shared/slugTranslator.test.ts +13 -13
  303. package/lib/shared/slugTranslator.ts +12 -16
  304. package/lib/shared/slugify.ts +9 -15
  305. package/lib/shared/styleNodeUtils.test.ts +8 -8
  306. package/lib/shared/styleNodeUtils.ts +18 -20
  307. package/lib/shared/styleUtils.test.ts +87 -61
  308. package/lib/shared/styleUtils.ts +5 -6
  309. package/lib/shared/themeDefaults.test.ts +11 -14
  310. package/lib/shared/themeDefaults.ts +3 -4
  311. package/lib/shared/tree/PathBuilder.test.ts +63 -145
  312. package/lib/shared/tree/PathBuilder.ts +59 -47
  313. package/lib/shared/treePathUtils.test.ts +51 -12
  314. package/lib/shared/treePathUtils.ts +91 -60
  315. package/lib/shared/types/api.ts +105 -8
  316. package/lib/shared/types/cms.test.ts +34 -0
  317. package/lib/shared/types/cms.ts +90 -34
  318. package/lib/shared/types/comment.ts +49 -16
  319. package/lib/shared/types/components.ts +51 -25
  320. package/lib/shared/types/errors.test.ts +1 -6
  321. package/lib/shared/types/errors.ts +3 -7
  322. package/lib/shared/types/experiments.ts +28 -28
  323. package/lib/shared/types/index.ts +25 -2
  324. package/lib/shared/types/permissions.ts +139 -0
  325. package/lib/shared/types/styles.ts +0 -1
  326. package/lib/shared/types/variables.test.ts +4 -13
  327. package/lib/shared/types/variables.ts +51 -30
  328. package/lib/shared/types.ts +1 -2
  329. package/lib/shared/utilityClassConfig.ts +751 -321
  330. package/lib/shared/utilityClassMapper.durability.test.ts +117 -0
  331. package/lib/shared/utilityClassMapper.test.ts +433 -95
  332. package/lib/shared/utilityClassMapper.ts +322 -249
  333. package/lib/shared/utilityClassNames.test.ts +38 -0
  334. package/lib/shared/utilityClassNames.ts +458 -0
  335. package/lib/shared/utils.test.ts +2 -10
  336. package/lib/shared/utils.ts +19 -10
  337. package/lib/shared/validation/cmsValidators.ts +2 -1
  338. package/lib/shared/validation/commentValidators.test.ts +53 -0
  339. package/lib/shared/validation/commentValidators.ts +12 -1
  340. package/lib/shared/validation/index.ts +1 -0
  341. package/lib/shared/validation/permissionsValidators.test.ts +49 -0
  342. package/lib/shared/validation/permissionsValidators.ts +49 -0
  343. package/lib/shared/validation/propValidator.test.ts +19 -21
  344. package/lib/shared/validation/propValidator.ts +13 -18
  345. package/lib/shared/validation/schemas.test.ts +64 -32
  346. package/lib/shared/validation/schemas.ts +616 -345
  347. package/lib/shared/validation/validators.test.ts +3 -8
  348. package/lib/shared/validation/validators.ts +89 -68
  349. package/lib/shared/viewportUnits.integration.test.ts +14 -10
  350. package/lib/shared/viewportUnits.test.ts +24 -23
  351. package/lib/shared/viewportUnits.ts +12 -5
  352. package/lib/test-utils/dom-setup.ts +1 -1
  353. package/lib/test-utils/factories/ConsoleMockFactory.ts +10 -14
  354. package/lib/test-utils/factories/DomMockFactory.ts +17 -23
  355. package/lib/test-utils/factories/EventMockFactory.ts +7 -13
  356. package/lib/test-utils/factories/FetchMockFactory.ts +39 -57
  357. package/lib/test-utils/factories/ServerMockFactory.ts +6 -10
  358. package/lib/test-utils/factories/StoreMockFactory.ts +18 -29
  359. package/lib/test-utils/fixtures.ts +45 -45
  360. package/lib/test-utils/helpers/asyncHelpers.test.ts +15 -18
  361. package/lib/test-utils/helpers/asyncHelpers.ts +11 -20
  362. package/lib/test-utils/helpers.ts +1 -5
  363. package/lib/test-utils/index.ts +0 -4
  364. package/lib/test-utils/mockFactories.ts +13 -19
  365. package/lib/test-utils/mocks.ts +6 -4
  366. package/package.json +3 -5
  367. package/scripts/build-for-publish.mjs +2 -4
  368. package/scripts/build-meno-filter.ts +4 -7
  369. package/tsconfig.json +1 -0
  370. package/vite.config.ts +4 -4
  371. package/build-next.ts +0 -1361
  372. package/build-static.test.ts +0 -424
  373. package/build-static.ts +0 -1074
  374. package/dist/build-static.js +0 -36
  375. package/dist/chunks/chunk-2MHDV5BF.js +0 -251
  376. package/dist/chunks/chunk-2MHDV5BF.js.map +0 -7
  377. package/dist/chunks/chunk-AZQYF6KE.js +0 -559
  378. package/dist/chunks/chunk-AZQYF6KE.js.map +0 -7
  379. package/dist/chunks/chunk-GZHGVVW3.js +0 -322
  380. package/dist/chunks/chunk-GZHGVVW3.js.map +0 -7
  381. package/dist/chunks/chunk-H3GJ4H2U.js.map +0 -7
  382. package/dist/chunks/chunk-I7YIGZXT.js +0 -467
  383. package/dist/chunks/chunk-I7YIGZXT.js.map +0 -7
  384. package/dist/chunks/chunk-IGYR22T6.js +0 -6192
  385. package/dist/chunks/chunk-IGYR22T6.js.map +0 -7
  386. package/dist/chunks/chunk-JGP5A3Y5.js +0 -1136
  387. package/dist/chunks/chunk-JGP5A3Y5.js.map +0 -7
  388. package/dist/chunks/chunk-JGWFTO6P.js.map +0 -7
  389. package/dist/chunks/chunk-O3NAGJP4.js.map +0 -7
  390. package/dist/chunks/chunk-QB2LNO4W.js +0 -77
  391. package/dist/chunks/chunk-QB2LNO4W.js.map +0 -7
  392. package/dist/chunks/chunk-R6XHAFBF.js +0 -3821
  393. package/dist/chunks/chunk-R6XHAFBF.js.map +0 -7
  394. package/dist/chunks/chunk-UB44F4Z2.js.map +0 -7
  395. package/dist/chunks/chunk-WQFG7PAH.js.map +0 -7
  396. package/dist/chunks/chunk-X754AHS5.js.map +0 -7
  397. package/dist/chunks/chunk-YBLHKYFF.js.map +0 -7
  398. package/dist/chunks/configService-R3OGU2UD.js +0 -13
  399. package/dist/chunks/configService-R3OGU2UD.js.map +0 -7
  400. package/dist/chunks/constants-STK2YBIW.js +0 -46
  401. package/dist/chunks/constants-STK2YBIW.js.map +0 -7
  402. package/dist/chunks/fs-JGINUXGL.js.map +0 -7
  403. package/dist/entries/server-router.js +0 -67
  404. package/dist/entries/server-router.js.map +0 -7
  405. package/entries/server-router.tsx +0 -81
  406. package/lib/server/providers/fileSystemPageProvider.ts +0 -160
  407. package/lib/server/webflow/buildWebflow.ts +0 -635
  408. package/lib/server/webflow/index.ts +0 -23
  409. package/lib/server/webflow/nodeToWebflow.test.ts +0 -3170
  410. package/lib/server/webflow/nodeToWebflow.ts +0 -2435
  411. package/lib/server/webflow/styleMapper.test.ts +0 -389
  412. package/lib/server/webflow/styleMapper.ts +0 -695
  413. package/lib/server/webflow/templateWrapper.ts +0 -49
  414. package/lib/server/webflow/types.ts +0 -396
  415. /package/dist/{build-static.js.map → chunks/fs-G3ANWEFP.js.map} +0 -0
@@ -3,20 +3,20 @@
3
3
  * Tests for generating unique CSS class names for elements in pages and components
4
4
  */
5
5
 
6
- import { test, expect, describe } from "bun:test";
6
+ import { test, expect, describe } from 'bun:test';
7
7
  import {
8
8
  generateElementClassName,
9
9
  isElementClassName,
10
10
  parseElementClassName,
11
11
  type ElementClassContext,
12
- } from "./elementClassName";
12
+ } from './elementClassName';
13
13
 
14
- describe("generateElementClassName", () => {
15
- describe("Page elements", () => {
16
- test("should generate page class with p_ prefix", () => {
14
+ describe('generateElementClassName', () => {
15
+ describe('Page elements', () => {
16
+ test('should generate page class with p_ prefix', () => {
17
17
  const ctx: ElementClassContext = {
18
- fileType: "page",
19
- fileName: "about",
18
+ fileType: 'page',
19
+ fileName: 'about',
20
20
  path: [0],
21
21
  };
22
22
 
@@ -25,10 +25,10 @@ describe("generateElementClassName", () => {
25
25
  expect(className).toMatch(/^p_about_/);
26
26
  });
27
27
 
28
- test("should generate consistent hash for same path", () => {
28
+ test('should generate consistent hash for same path', () => {
29
29
  const ctx: ElementClassContext = {
30
- fileType: "page",
31
- fileName: "about",
30
+ fileType: 'page',
31
+ fileName: 'about',
32
32
  path: [0, 1, 2],
33
33
  };
34
34
 
@@ -38,16 +38,16 @@ describe("generateElementClassName", () => {
38
38
  expect(className1).toBe(className2);
39
39
  });
40
40
 
41
- test("should generate different hashes for different paths", () => {
41
+ test('should generate different hashes for different paths', () => {
42
42
  // Use significantly different paths to avoid hash collisions
43
43
  const ctx1: ElementClassContext = {
44
- fileType: "page",
45
- fileName: "about",
44
+ fileType: 'page',
45
+ fileName: 'about',
46
46
  path: [0],
47
47
  };
48
48
  const ctx2: ElementClassContext = {
49
- fileType: "page",
50
- fileName: "about",
49
+ fileType: 'page',
50
+ fileName: 'about',
51
51
  path: [0, 1, 2, 3],
52
52
  };
53
53
 
@@ -57,36 +57,36 @@ describe("generateElementClassName", () => {
57
57
  expect(className1).not.toBe(className2);
58
58
  });
59
59
 
60
- test("should use label when provided", () => {
60
+ test('should use label when provided', () => {
61
61
  const ctx: ElementClassContext = {
62
- fileType: "page",
63
- fileName: "about",
64
- label: "header",
62
+ fileType: 'page',
63
+ fileName: 'about',
64
+ label: 'header',
65
65
  path: [0],
66
66
  };
67
67
 
68
68
  const className = generateElementClassName(ctx);
69
69
 
70
- expect(className).toBe("p_about_header");
70
+ expect(className).toBe('p_about_header');
71
71
  });
72
72
 
73
- test("should sanitize label", () => {
73
+ test('should sanitize label', () => {
74
74
  const ctx: ElementClassContext = {
75
- fileType: "page",
76
- fileName: "about",
77
- label: "My Header Component",
75
+ fileType: 'page',
76
+ fileName: 'about',
77
+ label: 'My Header Component',
78
78
  path: [0],
79
79
  };
80
80
 
81
81
  const className = generateElementClassName(ctx);
82
82
 
83
- expect(className).toBe("p_about_my_header_component");
83
+ expect(className).toBe('p_about_my_header_component');
84
84
  });
85
85
 
86
- test("should handle index page path", () => {
86
+ test('should handle index page path', () => {
87
87
  const ctx: ElementClassContext = {
88
- fileType: "page",
89
- fileName: "index",
88
+ fileType: 'page',
89
+ fileName: 'index',
90
90
  path: [0],
91
91
  };
92
92
 
@@ -95,10 +95,10 @@ describe("generateElementClassName", () => {
95
95
  expect(className).toMatch(/^p_index_/);
96
96
  });
97
97
 
98
- test("should handle nested page paths", () => {
98
+ test('should handle nested page paths', () => {
99
99
  const ctx: ElementClassContext = {
100
- fileType: "page",
101
- fileName: "blog_post",
100
+ fileType: 'page',
101
+ fileName: 'blog_post',
102
102
  path: [0, 1, 2],
103
103
  };
104
104
 
@@ -108,11 +108,11 @@ describe("generateElementClassName", () => {
108
108
  });
109
109
  });
110
110
 
111
- describe("Component elements", () => {
112
- test("should generate component class with c_ prefix", () => {
111
+ describe('Component elements', () => {
112
+ test('should generate component class with c_ prefix', () => {
113
113
  const ctx: ElementClassContext = {
114
- fileType: "component",
115
- fileName: "Navigation",
114
+ fileType: 'component',
115
+ fileName: 'Navigation',
116
116
  path: [0],
117
117
  };
118
118
 
@@ -121,23 +121,23 @@ describe("generateElementClassName", () => {
121
121
  expect(className).toMatch(/^c_navigation_/);
122
122
  });
123
123
 
124
- test("should use label for named elements", () => {
124
+ test('should use label for named elements', () => {
125
125
  const ctx: ElementClassContext = {
126
- fileType: "component",
127
- fileName: "Navigation",
128
- label: "hamburger",
126
+ fileType: 'component',
127
+ fileName: 'Navigation',
128
+ label: 'hamburger',
129
129
  path: [0],
130
130
  };
131
131
 
132
132
  const className = generateElementClassName(ctx);
133
133
 
134
- expect(className).toBe("c_navigation_hamburger");
134
+ expect(className).toBe('c_navigation_hamburger');
135
135
  });
136
136
 
137
- test("should generate consistent hash for same component path", () => {
137
+ test('should generate consistent hash for same component path', () => {
138
138
  const ctx: ElementClassContext = {
139
- fileType: "component",
140
- fileName: "Card",
139
+ fileType: 'component',
140
+ fileName: 'Card',
141
141
  path: [0, 0],
142
142
  };
143
143
 
@@ -147,15 +147,15 @@ describe("generateElementClassName", () => {
147
147
  expect(className1).toBe(className2);
148
148
  });
149
149
 
150
- test("should generate different hash for different component paths", () => {
150
+ test('should generate different hash for different component paths', () => {
151
151
  const ctx1: ElementClassContext = {
152
- fileType: "component",
153
- fileName: "Card",
152
+ fileType: 'component',
153
+ fileName: 'Card',
154
154
  path: [0],
155
155
  };
156
156
  const ctx2: ElementClassContext = {
157
- fileType: "component",
158
- fileName: "Card",
157
+ fileType: 'component',
158
+ fileName: 'Card',
159
159
  path: [0, 0],
160
160
  };
161
161
 
@@ -165,23 +165,23 @@ describe("generateElementClassName", () => {
165
165
  expect(className1).not.toBe(className2);
166
166
  });
167
167
 
168
- test("should generate different hashes for sibling paths (only last index differs)", () => {
168
+ test('should generate different hashes for sibling paths (only last index differs)', () => {
169
169
  // Regression: a 5-char hash truncated from the high-order digits
170
170
  // collapsed to one value when only the final path index changed,
171
171
  // making every set of siblings share a class in the Webflow export.
172
- const base = ["Layout", [0, 0, 1, 0, 0]] as const;
172
+ const base = ['Layout', [0, 0, 1, 0, 0]] as const;
173
173
  const siblings = [0, 1, 2, 3, 4].map((i) =>
174
174
  generateElementClassName({
175
- fileType: "component",
175
+ fileType: 'component',
176
176
  fileName: base[0],
177
177
  path: [...base[1], i],
178
- })
178
+ }),
179
179
  );
180
180
  expect(new Set(siblings).size).toBe(siblings.length);
181
181
  });
182
182
  });
183
183
 
184
- describe("Component-relative paths", () => {
184
+ describe('Component-relative paths', () => {
185
185
  /**
186
186
  * When a component is placed on a page at path [0, 2, 1],
187
187
  * its internal elements should use relative paths from the component root.
@@ -189,17 +189,17 @@ describe("generateElementClassName", () => {
189
189
  * This ensures the same class is generated regardless of where the component
190
190
  * is placed on the page.
191
191
  */
192
- test("should generate same class for component elements regardless of page position", () => {
192
+ test('should generate same class for component elements regardless of page position', () => {
193
193
  // Component element at path [0] relative to component root
194
194
  const ctx1: ElementClassContext = {
195
- fileType: "component",
196
- fileName: "Card",
195
+ fileType: 'component',
196
+ fileName: 'Card',
197
197
  path: [0], // Relative path within component
198
198
  };
199
199
 
200
200
  const ctx2: ElementClassContext = {
201
- fileType: "component",
202
- fileName: "Card",
201
+ fileType: 'component',
202
+ fileName: 'Card',
203
203
  path: [0], // Same relative path
204
204
  };
205
205
 
@@ -211,16 +211,16 @@ describe("generateElementClassName", () => {
211
211
  expect(className1).toBe(className2);
212
212
  });
213
213
 
214
- test("should generate unique classes for different component names with same path", () => {
214
+ test('should generate unique classes for different component names with same path', () => {
215
215
  const ctx1: ElementClassContext = {
216
- fileType: "component",
217
- fileName: "Card",
216
+ fileType: 'component',
217
+ fileName: 'Card',
218
218
  path: [0],
219
219
  };
220
220
 
221
221
  const ctx2: ElementClassContext = {
222
- fileType: "component",
223
- fileName: "Button",
222
+ fileType: 'component',
223
+ fileName: 'Button',
224
224
  path: [0],
225
225
  };
226
226
 
@@ -233,11 +233,11 @@ describe("generateElementClassName", () => {
233
233
  });
234
234
  });
235
235
 
236
- describe("Edge cases", () => {
237
- test("should handle empty path array", () => {
236
+ describe('Edge cases', () => {
237
+ test('should handle empty path array', () => {
238
238
  const ctx: ElementClassContext = {
239
- fileType: "page",
240
- fileName: "about",
239
+ fileType: 'page',
240
+ fileName: 'about',
241
241
  path: [],
242
242
  };
243
243
 
@@ -246,10 +246,10 @@ describe("generateElementClassName", () => {
246
246
  expect(className).toMatch(/^p_about_/);
247
247
  });
248
248
 
249
- test("should handle deeply nested paths", () => {
249
+ test('should handle deeply nested paths', () => {
250
250
  const ctx: ElementClassContext = {
251
- fileType: "page",
252
- fileName: "index",
251
+ fileType: 'page',
252
+ fileName: 'index',
253
253
  path: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9],
254
254
  };
255
255
 
@@ -258,77 +258,77 @@ describe("generateElementClassName", () => {
258
258
  expect(className).toMatch(/^p_index_/);
259
259
  });
260
260
 
261
- test("should handle special characters in fileName", () => {
261
+ test('should handle special characters in fileName', () => {
262
262
  const ctx: ElementClassContext = {
263
- fileType: "page",
264
- fileName: "My Page (v2)",
263
+ fileType: 'page',
264
+ fileName: 'My Page (v2)',
265
265
  path: [0],
266
266
  };
267
267
 
268
268
  const className = generateElementClassName(ctx);
269
269
 
270
270
  // Should sanitize special characters
271
- expect(className).not.toContain("(");
272
- expect(className).not.toContain(")");
273
- expect(className).not.toContain(" ");
271
+ expect(className).not.toContain('(');
272
+ expect(className).not.toContain(')');
273
+ expect(className).not.toContain(' ');
274
274
  });
275
275
  });
276
276
  });
277
277
 
278
- describe("isElementClassName", () => {
279
- test("should return true for valid page class", () => {
280
- expect(isElementClassName("p_about_header")).toBe(true);
281
- expect(isElementClassName("p_index_a42e3")).toBe(true);
278
+ describe('isElementClassName', () => {
279
+ test('should return true for valid page class', () => {
280
+ expect(isElementClassName('p_about_header')).toBe(true);
281
+ expect(isElementClassName('p_index_a42e3')).toBe(true);
282
282
  });
283
283
 
284
- test("should return true for valid component class", () => {
285
- expect(isElementClassName("c_navigation_hamburger")).toBe(true);
286
- expect(isElementClassName("c_card_b12f4")).toBe(true);
284
+ test('should return true for valid component class', () => {
285
+ expect(isElementClassName('c_navigation_hamburger')).toBe(true);
286
+ expect(isElementClassName('c_card_b12f4')).toBe(true);
287
287
  });
288
288
 
289
- test("should return false for invalid classes", () => {
290
- expect(isElementClassName("about_header")).toBe(false); // Missing prefix
291
- expect(isElementClassName("p_about")).toBe(false); // Missing element name
292
- expect(isElementClassName("x_about_header")).toBe(false); // Wrong prefix
293
- expect(isElementClassName("flex")).toBe(false); // Utility class
294
- expect(isElementClassName("p-10px")).toBe(false); // Utility class
289
+ test('should return false for invalid classes', () => {
290
+ expect(isElementClassName('about_header')).toBe(false); // Missing prefix
291
+ expect(isElementClassName('p_about')).toBe(false); // Missing element name
292
+ expect(isElementClassName('x_about_header')).toBe(false); // Wrong prefix
293
+ expect(isElementClassName('flex')).toBe(false); // Utility class
294
+ expect(isElementClassName('p-[10px]')).toBe(false); // Utility class
295
295
  });
296
296
  });
297
297
 
298
- describe("parseElementClassName", () => {
299
- test("should parse page class correctly", () => {
300
- const result = parseElementClassName("p_about_header");
298
+ describe('parseElementClassName', () => {
299
+ test('should parse page class correctly', () => {
300
+ const result = parseElementClassName('p_about_header');
301
301
 
302
302
  expect(result).toEqual({
303
- fileType: "page",
304
- fileName: "about",
305
- elementName: "header",
303
+ fileType: 'page',
304
+ fileName: 'about',
305
+ elementName: 'header',
306
306
  });
307
307
  });
308
308
 
309
- test("should parse component class correctly", () => {
310
- const result = parseElementClassName("c_navigation_hamburger");
309
+ test('should parse component class correctly', () => {
310
+ const result = parseElementClassName('c_navigation_hamburger');
311
311
 
312
312
  expect(result).toEqual({
313
- fileType: "component",
314
- fileName: "navigation",
315
- elementName: "hamburger",
313
+ fileType: 'component',
314
+ fileName: 'navigation',
315
+ elementName: 'hamburger',
316
316
  });
317
317
  });
318
318
 
319
- test("should parse class with hash correctly", () => {
320
- const result = parseElementClassName("p_index_a42e3");
319
+ test('should parse class with hash correctly', () => {
320
+ const result = parseElementClassName('p_index_a42e3');
321
321
 
322
322
  expect(result).toEqual({
323
- fileType: "page",
324
- fileName: "index",
325
- elementName: "a42e3",
323
+ fileType: 'page',
324
+ fileName: 'index',
325
+ elementName: 'a42e3',
326
326
  });
327
327
  });
328
328
 
329
- test("should return null for invalid classes", () => {
330
- expect(parseElementClassName("about_header")).toBeNull();
331
- expect(parseElementClassName("p_about")).toBeNull();
332
- expect(parseElementClassName("flex")).toBeNull();
329
+ test('should return null for invalid classes', () => {
330
+ expect(parseElementClassName('about_header')).toBeNull();
331
+ expect(parseElementClassName('p_about')).toBeNull();
332
+ expect(parseElementClassName('flex')).toBeNull();
333
333
  });
334
334
  });
@@ -93,14 +93,14 @@ export function isElementClassName(className: string): boolean {
93
93
  * Returns null if not a valid element class name
94
94
  */
95
95
  export function parseElementClassName(
96
- className: string
96
+ className: string,
97
97
  ): { fileType: 'component' | 'page'; fileName: string; elementName: string } | null {
98
98
  const match = className.match(/^([cp])_([a-z0-9_-]+)_([a-z0-9_-]+)$/);
99
99
  if (!match) return null;
100
100
 
101
101
  return {
102
102
  fileType: match[1] === 'c' ? 'component' : 'page',
103
- fileName: match[2],
104
- elementName: match[3],
103
+ fileName: match[2] ?? '',
104
+ elementName: match[3] ?? '',
105
105
  };
106
106
  }
@@ -5,7 +5,7 @@
5
5
 
6
6
  /**
7
7
  * Find an element with data-element-path attribute by traversing up the DOM tree
8
- *
8
+ *
9
9
  * @param element - Starting element to search from
10
10
  * @returns Element with data-element-path attribute, or null if not found
11
11
  */
@@ -25,41 +25,41 @@ export function findElementWithPath(element: HTMLElement | null): HTMLElement |
25
25
  * The component root is the topmost element (walking up) that:
26
26
  * 1. Has data-element-path (is selectable in the tree)
27
27
  * 2. Has data-parent-component matching the starting element's component
28
- *
28
+ *
29
29
  * @param element - Starting element (should have data-parent-component attribute)
30
30
  * @returns Component instance root element, or null if not found
31
31
  */
32
32
  export function findComponentInstanceRoot(element: HTMLElement): HTMLElement | null {
33
33
  const componentName = element.getAttribute('data-parent-component');
34
34
  if (!componentName) return null;
35
-
35
+
36
36
  let current: HTMLElement | null = element;
37
37
  let componentRoot: HTMLElement | null = null;
38
-
38
+
39
39
  // Walk up the DOM tree
40
40
  while (current) {
41
41
  const currentComponentName = current.getAttribute('data-parent-component');
42
42
  const hasPath = current.hasAttribute('data-element-path');
43
-
43
+
44
44
  // If this element has the same component name and has a path, remember it
45
45
  // We want the LAST (topmost) one we encounter while still in the component
46
46
  if (currentComponentName === componentName && hasPath) {
47
47
  componentRoot = current;
48
48
  }
49
-
49
+
50
50
  // Stop if we've moved to a different component
51
51
  if (currentComponentName && currentComponentName !== componentName) {
52
52
  break;
53
53
  }
54
-
54
+
55
55
  // If we've exited the component (no data-parent-component) and we found a root, stop
56
56
  if (!currentComponentName && componentRoot) {
57
57
  break;
58
58
  }
59
-
59
+
60
60
  current = current.parentElement;
61
61
  }
62
-
62
+
63
63
  return componentRoot;
64
64
  }
65
65
 
@@ -67,13 +67,13 @@ export function findComponentInstanceRoot(element: HTMLElement): HTMLElement | n
67
67
  * Alternative implementation: Find component root by walking up until we find
68
68
  * an element without data-parent-component (the component root)
69
69
  * This is used by elementHighlighter.ts
70
- *
70
+ *
71
71
  * @param element - Starting element
72
72
  * @returns Component instance root element, or null if not found
73
73
  */
74
74
  export function findComponentInstanceRootByParent(element: HTMLElement): HTMLElement | null {
75
75
  let current: HTMLElement | null = element;
76
-
76
+
77
77
  // Walk up until we find an element without data-parent-component (the component root)
78
78
  while (current) {
79
79
  if (!current.hasAttribute('data-parent-component')) {
@@ -81,10 +81,6 @@ export function findComponentInstanceRootByParent(element: HTMLElement): HTMLEle
81
81
  }
82
82
  current = current.parentElement;
83
83
  }
84
-
84
+
85
85
  return null;
86
86
  }
87
-
88
-
89
-
90
-
@@ -19,47 +19,47 @@ describe('logRuntimeError', () => {
19
19
  });
20
20
 
21
21
  test('calls custom handler when set', () => {
22
- const handler = mock((entry: ErrorLogEntry) => {});
22
+ const handler = mock((_entry: ErrorLogEntry) => {});
23
23
  setErrorHandler(handler);
24
24
 
25
25
  logRuntimeError('test.location', new Error('test'));
26
26
 
27
27
  expect(handler).toHaveBeenCalledTimes(1);
28
- const entry = (handler.mock.calls as [ErrorLogEntry][])[0][0];
28
+ const entry = (handler.mock.calls as [ErrorLogEntry][])[0]![0];
29
29
  expect(entry.location).toBe('test.location');
30
30
  expect(entry.category).toBe('runtime');
31
31
  expect(entry.error).toBeInstanceOf(Error);
32
32
  });
33
33
 
34
34
  test('includes context in handler call', () => {
35
- const handler = mock((entry: ErrorLogEntry) => {});
35
+ const handler = mock((_entry: ErrorLogEntry) => {});
36
36
  setErrorHandler(handler);
37
37
 
38
38
  logRuntimeError('test.location', new Error('test'), { extra: 'data' });
39
39
 
40
- const entry = (handler.mock.calls as [ErrorLogEntry][])[0][0];
40
+ const entry = (handler.mock.calls as [ErrorLogEntry][])[0]![0];
41
41
  expect(entry.context).toEqual({ extra: 'data' });
42
42
  });
43
43
 
44
44
  test('includes timestamp in entry', () => {
45
- const handler = mock((entry: ErrorLogEntry) => {});
45
+ const handler = mock((_entry: ErrorLogEntry) => {});
46
46
  setErrorHandler(handler);
47
47
  const beforeTime = Date.now();
48
48
 
49
49
  logRuntimeError('test.location', new Error('test'));
50
50
 
51
- const entry = (handler.mock.calls as [ErrorLogEntry][])[0][0];
51
+ const entry = (handler.mock.calls as [ErrorLogEntry][])[0]![0];
52
52
  expect(entry.timestamp).toBeGreaterThanOrEqual(beforeTime);
53
53
  expect(entry.timestamp).toBeLessThanOrEqual(Date.now());
54
54
  });
55
55
 
56
56
  test('handles string errors', () => {
57
- const handler = mock((entry: ErrorLogEntry) => {});
57
+ const handler = mock((_entry: ErrorLogEntry) => {});
58
58
  setErrorHandler(handler);
59
59
 
60
60
  logRuntimeError('test.location', 'string error');
61
61
 
62
- const entry = (handler.mock.calls as [ErrorLogEntry][])[0][0];
62
+ const entry = (handler.mock.calls as [ErrorLogEntry][])[0]![0];
63
63
  expect(entry.error).toBe('string error');
64
64
  });
65
65
 
@@ -76,24 +76,24 @@ describe('logNetworkError', () => {
76
76
  });
77
77
 
78
78
  test('calls custom handler with network category', () => {
79
- const handler = mock((entry: ErrorLogEntry) => {});
79
+ const handler = mock((_entry: ErrorLogEntry) => {});
80
80
  setErrorHandler(handler);
81
81
 
82
82
  logNetworkError('api.fetch', new Error('network failed'));
83
83
 
84
84
  expect(handler).toHaveBeenCalledTimes(1);
85
- const entry = (handler.mock.calls as [ErrorLogEntry][])[0][0];
85
+ const entry = (handler.mock.calls as [ErrorLogEntry][])[0]![0];
86
86
  expect(entry.location).toBe('api.fetch');
87
87
  expect(entry.category).toBe('network');
88
88
  });
89
89
 
90
90
  test('includes context in handler call', () => {
91
- const handler = mock((entry: ErrorLogEntry) => {});
91
+ const handler = mock((_entry: ErrorLogEntry) => {});
92
92
  setErrorHandler(handler);
93
93
 
94
94
  logNetworkError('api.fetch', new Error('test'), { endpoint: '/api/test' });
95
95
 
96
- const entry = (handler.mock.calls as [ErrorLogEntry][])[0][0];
96
+ const entry = (handler.mock.calls as [ErrorLogEntry][])[0]![0];
97
97
  expect(entry.context).toEqual({ endpoint: '/api/test' });
98
98
  });
99
99
  });
@@ -40,11 +40,7 @@ function isDevelopment(): boolean {
40
40
  * Log runtime error with context
41
41
  * Use for graceful degradation scenarios where error is handled but should be visible
42
42
  */
43
- export function logRuntimeError(
44
- location: string,
45
- error: unknown,
46
- context?: Record<string, unknown>
47
- ): void {
43
+ export function logRuntimeError(location: string, error: unknown, context?: Record<string, unknown>): void {
48
44
  const entry: ErrorLogEntry = {
49
45
  location,
50
46
  category: 'runtime',
@@ -66,11 +62,7 @@ export function logRuntimeError(
66
62
  /**
67
63
  * Log network/API error
68
64
  */
69
- export function logNetworkError(
70
- location: string,
71
- error: unknown,
72
- context?: Record<string, unknown>
73
- ): void {
65
+ export function logNetworkError(location: string, error: unknown, context?: Record<string, unknown>): void {
74
66
  const entry: ErrorLogEntry = {
75
67
  location,
76
68
  category: 'network',
@@ -27,23 +27,12 @@ describe('createError', () => {
27
27
 
28
28
  test('creates error with cause', () => {
29
29
  const cause = new Error('Original error');
30
- const error = createError(
31
- 'internal',
32
- 'WRAPPED',
33
- 'Wrapped message',
34
- undefined,
35
- cause
36
- );
30
+ const error = createError('internal', 'WRAPPED', 'Wrapped message', undefined, cause);
37
31
  expect(error.cause).toBe(cause);
38
32
  });
39
33
 
40
34
  test('creates error for each category', () => {
41
- const categories = [
42
- 'validation',
43
- 'runtime',
44
- 'network',
45
- 'internal',
46
- ] as const;
35
+ const categories = ['validation', 'runtime', 'network', 'internal'] as const;
47
36
  for (const category of categories) {
48
37
  const error = createError(category, 'CODE', 'message');
49
38
  expect(error.category).toBe(category);