@maizzle/framework 6.0.0-rc.9 → 6.0.1

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 (624) hide show
  1. package/README.md +3 -3
  2. package/bin/maizzle.mjs +1 -1
  3. package/dist/build.d.ts +38 -0
  4. package/dist/build.d.ts.map +1 -0
  5. package/dist/build.js +234 -0
  6. package/dist/build.js.map +1 -0
  7. package/dist/components/Body.vue +32 -3
  8. package/dist/components/Button.vue +91 -62
  9. package/dist/components/CodeBlock.vue +6 -4
  10. package/dist/components/CodeInline.vue +77 -6
  11. package/dist/components/Column.vue +67 -31
  12. package/dist/components/Container.vue +73 -12
  13. package/dist/components/Font.vue +96 -0
  14. package/dist/components/Head.vue +1 -1
  15. package/dist/components/Heading.vue +1 -1
  16. package/dist/components/Hr.vue +33 -0
  17. package/dist/components/Html.vue +36 -3
  18. package/dist/components/Img.vue +332 -0
  19. package/dist/components/Layout.vue +73 -21
  20. package/dist/components/Link.vue +1 -1
  21. package/dist/components/Markdown.vue +51 -24
  22. package/dist/components/MarkdownLayout.vue +39 -0
  23. package/dist/components/NotPlaintext.vue +14 -0
  24. package/dist/components/Outlook.vue +38 -11
  25. package/dist/components/OutlookBg.vue +241 -0
  26. package/dist/components/Plaintext.vue +14 -0
  27. package/dist/components/Preheader.vue +35 -10
  28. package/dist/components/QrCode.vue +157 -0
  29. package/dist/components/Raw.vue +28 -0
  30. package/dist/components/Row.vue +115 -22
  31. package/dist/components/Section.vue +65 -26
  32. package/dist/components/Spacer.vue +35 -29
  33. package/dist/components/Tailwind.vue +45 -0
  34. package/dist/components/Text.vue +3 -3
  35. package/dist/components/Vml.vue +207 -94
  36. package/dist/components/utils.d.ts +53 -0
  37. package/dist/components/utils.d.ts.map +1 -0
  38. package/dist/components/utils.js +80 -0
  39. package/dist/components/utils.js.map +1 -0
  40. package/dist/components/utils.ts +102 -0
  41. package/dist/composables/defineConfig.d.ts +13 -0
  42. package/dist/composables/defineConfig.d.ts.map +1 -0
  43. package/dist/composables/{defineConfig.mjs → defineConfig.js} +7 -9
  44. package/dist/composables/defineConfig.js.map +1 -0
  45. package/dist/composables/renderContext.d.ts +37 -0
  46. package/dist/composables/renderContext.d.ts.map +1 -0
  47. package/dist/composables/renderContext.js +6 -0
  48. package/dist/composables/renderContext.js.map +1 -0
  49. package/dist/composables/useBaseUrl.d.ts +19 -0
  50. package/dist/composables/useBaseUrl.d.ts.map +1 -0
  51. package/dist/composables/useBaseUrl.js +26 -0
  52. package/dist/composables/useBaseUrl.js.map +1 -0
  53. package/dist/composables/useConfig.d.ts +16 -0
  54. package/dist/composables/useConfig.d.ts.map +1 -0
  55. package/dist/composables/useConfig.js +19 -0
  56. package/dist/composables/useConfig.js.map +1 -0
  57. package/dist/composables/useCurrentTemplate.d.ts +31 -0
  58. package/dist/composables/useCurrentTemplate.d.ts.map +1 -0
  59. package/dist/composables/useCurrentTemplate.js +42 -0
  60. package/dist/composables/useCurrentTemplate.js.map +1 -0
  61. package/dist/composables/{useDoctype.d.mts → useDoctype.d.ts} +1 -1
  62. package/dist/composables/useDoctype.d.ts.map +1 -0
  63. package/dist/composables/{useDoctype.mjs → useDoctype.js} +3 -4
  64. package/dist/composables/useDoctype.js.map +1 -0
  65. package/dist/composables/{useEvent.d.mts → useEvent.d.ts} +3 -3
  66. package/dist/composables/useEvent.d.ts.map +1 -0
  67. package/dist/composables/{useEvent.mjs → useEvent.js} +4 -5
  68. package/dist/composables/useEvent.js.map +1 -0
  69. package/dist/composables/useFont.d.ts +50 -0
  70. package/dist/composables/useFont.d.ts.map +1 -0
  71. package/dist/composables/useFont.js +92 -0
  72. package/dist/composables/useFont.js.map +1 -0
  73. package/dist/composables/useOutlookFallback.d.ts +21 -0
  74. package/dist/composables/useOutlookFallback.d.ts.map +1 -0
  75. package/dist/composables/useOutlookFallback.js +29 -0
  76. package/dist/composables/useOutlookFallback.js.map +1 -0
  77. package/dist/composables/useOutputPath.d.ts +17 -0
  78. package/dist/composables/useOutputPath.d.ts.map +1 -0
  79. package/dist/composables/useOutputPath.js +23 -0
  80. package/dist/composables/useOutputPath.js.map +1 -0
  81. package/dist/composables/{usePlaintext.d.mts → usePlaintext.d.ts} +3 -1
  82. package/dist/composables/usePlaintext.d.ts.map +1 -0
  83. package/dist/composables/{usePlaintext.mjs → usePlaintext.js} +4 -4
  84. package/dist/composables/usePlaintext.js.map +1 -0
  85. package/dist/composables/usePreheader.d.ts +25 -0
  86. package/dist/composables/usePreheader.d.ts.map +1 -0
  87. package/dist/composables/usePreheader.js +28 -0
  88. package/dist/composables/usePreheader.js.map +1 -0
  89. package/dist/composables/useTransformers.d.ts +34 -0
  90. package/dist/composables/useTransformers.d.ts.map +1 -0
  91. package/dist/composables/useTransformers.js +48 -0
  92. package/dist/composables/useTransformers.js.map +1 -0
  93. package/dist/composables/useUrlQuery.d.ts +19 -0
  94. package/dist/composables/useUrlQuery.d.ts.map +1 -0
  95. package/dist/composables/useUrlQuery.js +26 -0
  96. package/dist/composables/useUrlQuery.js.map +1 -0
  97. package/dist/config/{defaults.d.mts → defaults.d.ts} +2 -2
  98. package/dist/config/defaults.d.ts.map +1 -0
  99. package/dist/config/{defaults.mjs → defaults.js} +10 -6
  100. package/dist/config/defaults.js.map +1 -0
  101. package/dist/config/index.d.ts +33 -0
  102. package/dist/config/index.d.ts.map +1 -0
  103. package/dist/config/index.js +136 -0
  104. package/dist/config/index.js.map +1 -0
  105. package/dist/events/{index.d.mts → index.d.ts} +35 -12
  106. package/dist/events/index.d.ts.map +1 -0
  107. package/dist/events/{index.mjs → index.js} +31 -13
  108. package/dist/events/index.js.map +1 -0
  109. package/dist/index.d.ts +41 -0
  110. package/dist/index.js +40 -0
  111. package/dist/{plaintext.d.mts → plaintext.d.ts} +1 -1
  112. package/dist/plaintext.d.ts.map +1 -0
  113. package/dist/{plaintext.mjs → plaintext.js} +4 -5
  114. package/dist/plaintext.js.map +1 -0
  115. package/dist/{plugin.d.mts → plugin.d.ts} +2 -2
  116. package/dist/plugin.d.ts.map +1 -0
  117. package/dist/{plugin.mjs → plugin.js} +8 -9
  118. package/dist/plugin.js.map +1 -0
  119. package/dist/plugins/postcss/{mergeMediaQueries.d.mts → mergeMediaQueries.d.ts} +2 -2
  120. package/dist/plugins/postcss/mergeMediaQueries.d.ts.map +1 -0
  121. package/dist/plugins/postcss/{mergeMediaQueries.mjs → mergeMediaQueries.js} +2 -3
  122. package/dist/plugins/postcss/mergeMediaQueries.js.map +1 -0
  123. package/dist/plugins/postcss/{pruneVars.d.mts → pruneVars.d.ts} +1 -1
  124. package/dist/plugins/postcss/pruneVars.d.ts.map +1 -0
  125. package/dist/plugins/postcss/{pruneVars.mjs → pruneVars.js} +2 -2
  126. package/dist/plugins/postcss/pruneVars.js.map +1 -0
  127. package/dist/plugins/postcss/quoteFontFamilies.d.ts +13 -0
  128. package/dist/plugins/postcss/quoteFontFamilies.d.ts.map +1 -0
  129. package/dist/plugins/postcss/quoteFontFamilies.js +84 -0
  130. package/dist/plugins/postcss/quoteFontFamilies.js.map +1 -0
  131. package/dist/plugins/postcss/{removeDeclarations.d.mts → removeDeclarations.d.ts} +1 -1
  132. package/dist/plugins/postcss/removeDeclarations.d.ts.map +1 -0
  133. package/dist/plugins/postcss/{removeDeclarations.mjs → removeDeclarations.js} +2 -2
  134. package/dist/plugins/postcss/removeDeclarations.js.map +1 -0
  135. package/dist/plugins/postcss/resolveMaizzleImports.d.ts +16 -0
  136. package/dist/plugins/postcss/resolveMaizzleImports.d.ts.map +1 -0
  137. package/dist/plugins/postcss/resolveMaizzleImports.js +39 -0
  138. package/dist/plugins/postcss/resolveMaizzleImports.js.map +1 -0
  139. package/dist/plugins/postcss/resolveProps.d.ts +8 -0
  140. package/dist/plugins/postcss/resolveProps.d.ts.map +1 -0
  141. package/dist/plugins/postcss/resolveProps.js +155 -0
  142. package/dist/plugins/postcss/resolveProps.js.map +1 -0
  143. package/dist/plugins/postcss/{tailwindCleanup.d.mts → tailwindCleanup.d.ts} +2 -2
  144. package/dist/plugins/postcss/tailwindCleanup.d.ts.map +1 -0
  145. package/dist/plugins/postcss/{tailwindCleanup.mjs → tailwindCleanup.js} +5 -3
  146. package/dist/plugins/postcss/tailwindCleanup.js.map +1 -0
  147. package/dist/prepare.d.ts +17 -0
  148. package/dist/prepare.d.ts.map +1 -0
  149. package/dist/prepare.js +44 -0
  150. package/dist/prepare.js.map +1 -0
  151. package/dist/render/active.d.ts +8 -0
  152. package/dist/render/active.d.ts.map +1 -0
  153. package/dist/render/active.js +12 -0
  154. package/dist/render/active.js.map +1 -0
  155. package/dist/render/buildTemplate.d.ts +49 -0
  156. package/dist/render/buildTemplate.d.ts.map +1 -0
  157. package/dist/render/buildTemplate.js +141 -0
  158. package/dist/render/buildTemplate.js.map +1 -0
  159. package/dist/render/{createRenderer.d.mts → createRenderer.d.ts} +14 -6
  160. package/dist/render/createRenderer.d.ts.map +1 -0
  161. package/dist/render/createRenderer.js +468 -0
  162. package/dist/render/createRenderer.js.map +1 -0
  163. package/dist/render/index.d.ts +18 -0
  164. package/dist/render/index.d.ts.map +1 -0
  165. package/dist/render/index.js +59 -0
  166. package/dist/render/index.js.map +1 -0
  167. package/dist/render/injectFonts.d.ts +15 -0
  168. package/dist/render/injectFonts.d.ts.map +1 -0
  169. package/dist/render/injectFonts.js +45 -0
  170. package/dist/render/injectFonts.js.map +1 -0
  171. package/dist/render/parallel/buildWorker.d.ts +31 -0
  172. package/dist/render/parallel/buildWorker.d.ts.map +1 -0
  173. package/dist/render/parallel/buildWorker.js +66 -0
  174. package/dist/render/parallel/buildWorker.js.map +1 -0
  175. package/dist/render/parallel/worker.mjs +28 -0
  176. package/dist/render/plugins/codeBlockExtract.d.ts +14 -0
  177. package/dist/render/plugins/codeBlockExtract.d.ts.map +1 -0
  178. package/dist/render/plugins/codeBlockExtract.js +38 -0
  179. package/dist/render/plugins/codeBlockExtract.js.map +1 -0
  180. package/dist/render/plugins/markdownExtract.d.ts +12 -0
  181. package/dist/render/plugins/markdownExtract.d.ts.map +1 -0
  182. package/dist/render/plugins/markdownExtract.js +49 -0
  183. package/dist/render/plugins/markdownExtract.js.map +1 -0
  184. package/dist/render/plugins/rawExtract.d.ts +14 -0
  185. package/dist/render/plugins/rawExtract.d.ts.map +1 -0
  186. package/dist/render/plugins/rawExtract.js +34 -0
  187. package/dist/render/plugins/rawExtract.js.map +1 -0
  188. package/dist/render/plugins/rowSourceLocation.d.ts +18 -0
  189. package/dist/render/plugins/rowSourceLocation.d.ts.map +1 -0
  190. package/dist/render/plugins/rowSourceLocation.js +45 -0
  191. package/dist/render/plugins/rowSourceLocation.js.map +1 -0
  192. package/dist/{serve.d.mts → serve.d.ts} +5 -3
  193. package/dist/serve.d.ts.map +1 -0
  194. package/dist/{serve.mjs → serve.js} +248 -119
  195. package/dist/serve.js.map +1 -0
  196. package/dist/server/compatibility.d.ts +59 -0
  197. package/dist/server/compatibility.d.ts.map +1 -0
  198. package/dist/server/compatibility.js +959 -0
  199. package/dist/server/compatibility.js.map +1 -0
  200. package/dist/server/{email.d.mts → email.d.ts} +2 -2
  201. package/dist/server/email.d.ts.map +1 -0
  202. package/dist/server/{email.mjs → email.js} +2 -3
  203. package/dist/server/email.js.map +1 -0
  204. package/dist/server/linter.d.ts +20 -0
  205. package/dist/server/linter.d.ts.map +1 -0
  206. package/dist/server/linter.js +345 -0
  207. package/dist/server/linter.js.map +1 -0
  208. package/dist/server/sfc-utils.d.ts +21 -0
  209. package/dist/server/sfc-utils.d.ts.map +1 -0
  210. package/dist/server/sfc-utils.js +198 -0
  211. package/dist/server/sfc-utils.js.map +1 -0
  212. package/dist/server/ui/.vite/deps/@lucide_vue.js +44967 -0
  213. package/dist/server/ui/.vite/deps/@lucide_vue.js.map +1 -0
  214. package/dist/server/ui/.vite/deps/@vueuse_core.js +8155 -0
  215. package/dist/server/ui/.vite/deps/@vueuse_core.js.map +1 -0
  216. package/dist/server/ui/.vite/deps/@vueuse_shared.js +1859 -0
  217. package/dist/server/ui/.vite/deps/@vueuse_shared.js.map +1 -0
  218. package/dist/server/ui/.vite/deps/_metadata.json +78 -0
  219. package/dist/server/ui/.vite/deps/chunk-EAsCxrDo.js +14 -0
  220. package/dist/server/ui/.vite/deps/class-variance-authority.js +57 -0
  221. package/dist/server/ui/.vite/deps/class-variance-authority.js.map +1 -0
  222. package/dist/server/ui/.vite/deps/clsx.js +18 -0
  223. package/dist/server/ui/.vite/deps/clsx.js.map +1 -0
  224. package/dist/server/ui/.vite/deps/culori.js +4312 -0
  225. package/dist/server/ui/.vite/deps/culori.js.map +1 -0
  226. package/dist/server/ui/.vite/deps/package.json +3 -0
  227. package/dist/server/ui/.vite/deps/reka-ui.js +44464 -0
  228. package/dist/server/ui/.vite/deps/reka-ui.js.map +1 -0
  229. package/dist/server/ui/.vite/deps/tailwind-merge.js +3458 -0
  230. package/dist/server/ui/.vite/deps/tailwind-merge.js.map +1 -0
  231. package/dist/server/ui/.vite/deps/vue-router.js +6383 -0
  232. package/dist/server/ui/.vite/deps/vue-router.js.map +1 -0
  233. package/dist/server/ui/.vite/deps/vue.js +2 -0
  234. package/dist/server/ui/.vite/deps/vue.runtime.esm-bundler-N1X0OxKs.js +8800 -0
  235. package/dist/server/ui/.vite/deps/vue.runtime.esm-bundler-N1X0OxKs.js.map +1 -0
  236. package/dist/server/ui/App.vue +106 -66
  237. package/dist/server/ui/components/SidebarClose.vue +12 -0
  238. package/dist/server/ui/components/ui/checkbox/Checkbox.vue +1 -1
  239. package/dist/server/ui/components/ui/command/Command.vue +5 -1
  240. package/dist/server/ui/components/ui/command/CommandInput.vue +2 -2
  241. package/dist/server/ui/components/ui/dialog/DialogContent.vue +1 -1
  242. package/dist/server/ui/components/ui/dialog/DialogScrollContent.vue +1 -1
  243. package/dist/server/ui/components/ui/dropdown-menu/DropdownMenuCheckboxItem.vue +1 -1
  244. package/dist/server/ui/components/ui/dropdown-menu/DropdownMenuRadioItem.vue +1 -1
  245. package/dist/server/ui/components/ui/dropdown-menu/DropdownMenuSubTrigger.vue +1 -1
  246. package/dist/server/ui/components/ui/input/Input.vue +1 -1
  247. package/dist/server/ui/components/ui/sheet/SheetContent.vue +1 -1
  248. package/dist/server/ui/components/ui/sidebar/SidebarTrigger.vue +2 -2
  249. package/dist/server/ui/components/ui/tags-input/TagsInputInput.vue +1 -1
  250. package/dist/server/ui/components/ui/tags-input/TagsInputItemDelete.vue +1 -1
  251. package/dist/server/ui/lib/emulated-dark-mode.ts +146 -0
  252. package/dist/server/ui/main.css +25 -0
  253. package/dist/server/ui/pages/Home.vue +1 -1
  254. package/dist/server/ui/pages/Preview.vue +377 -186
  255. package/dist/server/ui/vite-env.d.ts +1 -0
  256. package/dist/tests/render/_helpers.d.ts +6 -0
  257. package/dist/tests/render/_helpers.d.ts.map +1 -0
  258. package/dist/tests/render/_helpers.js +16 -0
  259. package/dist/tests/render/_helpers.js.map +1 -0
  260. package/dist/transformers/addAttributes.d.ts +42 -0
  261. package/dist/transformers/addAttributes.d.ts.map +1 -0
  262. package/dist/transformers/{addAttributes.mjs → addAttributes.js} +40 -24
  263. package/dist/transformers/addAttributes.js.map +1 -0
  264. package/dist/transformers/attributeToStyle.d.ts +38 -0
  265. package/dist/transformers/attributeToStyle.d.ts.map +1 -0
  266. package/dist/transformers/attributeToStyle.js +94 -0
  267. package/dist/transformers/attributeToStyle.js.map +1 -0
  268. package/dist/transformers/base.d.ts +71 -0
  269. package/dist/transformers/base.d.ts.map +1 -0
  270. package/dist/transformers/{base.mjs → base.js} +65 -40
  271. package/dist/transformers/base.js.map +1 -0
  272. package/dist/transformers/columnWidth.d.ts +31 -0
  273. package/dist/transformers/columnWidth.d.ts.map +1 -0
  274. package/dist/transformers/columnWidth.js +527 -0
  275. package/dist/transformers/columnWidth.js.map +1 -0
  276. package/dist/transformers/entities.d.ts +37 -0
  277. package/dist/transformers/entities.d.ts.map +1 -0
  278. package/dist/transformers/entities.js +74 -0
  279. package/dist/transformers/entities.js.map +1 -0
  280. package/dist/transformers/filters/{defaults.d.mts → defaults.d.ts} +1 -1
  281. package/dist/transformers/filters/defaults.d.ts.map +1 -0
  282. package/dist/transformers/filters/{defaults.mjs → defaults.js} +2 -2
  283. package/dist/transformers/filters/defaults.js.map +1 -0
  284. package/dist/transformers/filters/index.d.ts +43 -0
  285. package/dist/transformers/filters/index.d.ts.map +1 -0
  286. package/dist/transformers/filters/index.js +89 -0
  287. package/dist/transformers/filters/index.js.map +1 -0
  288. package/dist/transformers/format.d.ts +22 -0
  289. package/dist/transformers/format.d.ts.map +1 -0
  290. package/dist/transformers/format.js +30 -0
  291. package/dist/transformers/format.js.map +1 -0
  292. package/dist/transformers/imgWidth.d.ts +20 -0
  293. package/dist/transformers/imgWidth.d.ts.map +1 -0
  294. package/dist/transformers/imgWidth.js +76 -0
  295. package/dist/transformers/imgWidth.js.map +1 -0
  296. package/dist/transformers/{index.d.mts → index.d.ts} +4 -3
  297. package/dist/transformers/index.d.ts.map +1 -0
  298. package/dist/transformers/index.js +163 -0
  299. package/dist/transformers/index.js.map +1 -0
  300. package/dist/transformers/inlineCss.d.ts +85 -0
  301. package/dist/transformers/inlineCss.d.ts.map +1 -0
  302. package/dist/transformers/inlineCss.js +112 -0
  303. package/dist/transformers/inlineCss.js.map +1 -0
  304. package/dist/transformers/inlineLink.d.ts +35 -0
  305. package/dist/transformers/inlineLink.d.ts.map +1 -0
  306. package/dist/transformers/{inlineLink.mjs → inlineLink.js} +35 -11
  307. package/dist/transformers/inlineLink.js.map +1 -0
  308. package/dist/transformers/minify.d.ts +21 -0
  309. package/dist/transformers/minify.d.ts.map +1 -0
  310. package/dist/transformers/minify.js +25 -0
  311. package/dist/transformers/minify.js.map +1 -0
  312. package/dist/transformers/minifyCodeInline.d.ts +29 -0
  313. package/dist/transformers/minifyCodeInline.d.ts.map +1 -0
  314. package/dist/transformers/minifyCodeInline.js +36 -0
  315. package/dist/transformers/minifyCodeInline.js.map +1 -0
  316. package/dist/transformers/msoPlaceholders.d.ts +33 -0
  317. package/dist/transformers/msoPlaceholders.d.ts.map +1 -0
  318. package/dist/transformers/msoPlaceholders.js +114 -0
  319. package/dist/transformers/msoPlaceholders.js.map +1 -0
  320. package/dist/transformers/purgeCss.d.ts +43 -0
  321. package/dist/transformers/purgeCss.d.ts.map +1 -0
  322. package/dist/transformers/purgeCss.js +207 -0
  323. package/dist/transformers/purgeCss.js.map +1 -0
  324. package/dist/transformers/removeAttributes.d.ts +54 -0
  325. package/dist/transformers/removeAttributes.d.ts.map +1 -0
  326. package/dist/transformers/removeAttributes.js +72 -0
  327. package/dist/transformers/removeAttributes.js.map +1 -0
  328. package/dist/transformers/{replaceStrings.d.mts → replaceStrings.d.ts} +2 -2
  329. package/dist/transformers/replaceStrings.d.ts.map +1 -0
  330. package/dist/transformers/{replaceStrings.mjs → replaceStrings.js} +2 -2
  331. package/dist/transformers/replaceStrings.js.map +1 -0
  332. package/dist/transformers/safeSelectors.d.ts +37 -0
  333. package/dist/transformers/safeSelectors.d.ts.map +1 -0
  334. package/dist/transformers/{safeClassNames.mjs → safeSelectors.js} +40 -10
  335. package/dist/transformers/safeSelectors.js.map +1 -0
  336. package/dist/transformers/shorthandCss.d.ts +47 -0
  337. package/dist/transformers/shorthandCss.d.ts.map +1 -0
  338. package/dist/transformers/shorthandCss.js +92 -0
  339. package/dist/transformers/shorthandCss.js.map +1 -0
  340. package/dist/transformers/sixHex.d.ts +25 -0
  341. package/dist/transformers/sixHex.d.ts.map +1 -0
  342. package/dist/transformers/sixHex.js +42 -0
  343. package/dist/transformers/sixHex.js.map +1 -0
  344. package/dist/transformers/tailwindComponent.d.ts +16 -0
  345. package/dist/transformers/tailwindComponent.d.ts.map +1 -0
  346. package/dist/transformers/tailwindComponent.js +101 -0
  347. package/dist/transformers/tailwindComponent.js.map +1 -0
  348. package/dist/transformers/{tailwindcss.d.mts → tailwindcss.d.ts} +2 -2
  349. package/dist/transformers/tailwindcss.d.ts.map +1 -0
  350. package/dist/transformers/{tailwindcss.mjs → tailwindcss.js} +33 -74
  351. package/dist/transformers/tailwindcss.js.map +1 -0
  352. package/dist/transformers/urlQuery.d.ts +36 -0
  353. package/dist/transformers/urlQuery.d.ts.map +1 -0
  354. package/dist/transformers/urlQuery.js +77 -0
  355. package/dist/transformers/urlQuery.js.map +1 -0
  356. package/dist/types/{config.d.mts → config.d.ts} +231 -46
  357. package/dist/types/config.d.ts.map +1 -0
  358. package/dist/types/config.js +1 -0
  359. package/dist/types/index.d.ts +2 -0
  360. package/dist/types/index.js +1 -0
  361. package/dist/utils/ast/index.d.ts +4 -0
  362. package/dist/utils/ast/index.js +4 -0
  363. package/dist/utils/ast/{parser.d.mts → parser.d.ts} +1 -1
  364. package/dist/utils/ast/parser.d.ts.map +1 -0
  365. package/dist/utils/ast/{parser.mjs → parser.js} +2 -3
  366. package/dist/utils/ast/parser.js.map +1 -0
  367. package/dist/utils/ast/{serializer.d.mts → serializer.d.ts} +1 -1
  368. package/dist/utils/ast/serializer.d.ts.map +1 -0
  369. package/dist/utils/ast/serializer.js +46 -0
  370. package/dist/utils/ast/serializer.js.map +1 -0
  371. package/dist/utils/ast/{walker.d.mts → walker.d.ts} +1 -1
  372. package/dist/utils/ast/walker.d.ts.map +1 -0
  373. package/dist/utils/ast/{walker.mjs → walker.js} +2 -2
  374. package/dist/utils/ast/walker.js.map +1 -0
  375. package/dist/utils/cloneConfig.d.ts +13 -0
  376. package/dist/utils/cloneConfig.d.ts.map +1 -0
  377. package/dist/utils/cloneConfig.js +21 -0
  378. package/dist/utils/cloneConfig.js.map +1 -0
  379. package/dist/utils/compileTailwindCss.d.ts +16 -0
  380. package/dist/utils/compileTailwindCss.d.ts.map +1 -0
  381. package/dist/utils/compileTailwindCss.js +55 -0
  382. package/dist/utils/compileTailwindCss.js.map +1 -0
  383. package/dist/utils/componentSources.d.ts +50 -0
  384. package/dist/utils/componentSources.d.ts.map +1 -0
  385. package/dist/utils/componentSources.js +50 -0
  386. package/dist/utils/componentSources.js.map +1 -0
  387. package/dist/utils/cssBox.d.ts +42 -0
  388. package/dist/utils/cssBox.d.ts.map +1 -0
  389. package/dist/utils/cssBox.js +151 -0
  390. package/dist/utils/cssBox.js.map +1 -0
  391. package/dist/utils/decodeStyleEntities.d.ts +15 -0
  392. package/dist/utils/decodeStyleEntities.d.ts.map +1 -0
  393. package/dist/utils/decodeStyleEntities.js +18 -0
  394. package/dist/utils/decodeStyleEntities.js.map +1 -0
  395. package/dist/utils/{detect.d.mts → detect.d.ts} +1 -1
  396. package/dist/utils/detect.d.ts.map +1 -0
  397. package/dist/utils/{detect.mjs → detect.js} +2 -3
  398. package/dist/utils/detect.js.map +1 -0
  399. package/dist/utils/output-markers.d.ts +29 -0
  400. package/dist/utils/output-markers.d.ts.map +1 -0
  401. package/dist/utils/output-markers.js +68 -0
  402. package/dist/utils/output-markers.js.map +1 -0
  403. package/dist/utils/{url.d.mts → url.d.ts} +1 -1
  404. package/dist/utils/url.d.ts.map +1 -0
  405. package/dist/utils/{url.mjs → url.js} +2 -3
  406. package/dist/utils/url.js.map +1 -0
  407. package/dist/utils/watchPaths.d.ts +11 -0
  408. package/dist/utils/watchPaths.d.ts.map +1 -0
  409. package/dist/utils/watchPaths.js +19 -0
  410. package/dist/utils/watchPaths.js.map +1 -0
  411. package/node_modules/@clack/core/CHANGELOG.md +44 -0
  412. package/node_modules/@clack/core/dist/index.d.mts +125 -5
  413. package/node_modules/@clack/core/dist/index.mjs +972 -11
  414. package/node_modules/@clack/core/package.json +6 -2
  415. package/node_modules/@clack/prompts/CHANGELOG.md +70 -0
  416. package/node_modules/@clack/prompts/README.md +129 -3
  417. package/node_modules/@clack/prompts/dist/index.d.mts +567 -33
  418. package/node_modules/@clack/prompts/dist/index.mjs +1378 -133
  419. package/node_modules/@clack/prompts/package.json +7 -4
  420. package/node_modules/fast-string-truncated-width/dist/index.js +36 -96
  421. package/node_modules/fast-string-truncated-width/dist/types.d.ts +0 -3
  422. package/node_modules/fast-string-truncated-width/dist/utils.d.ts +3 -3
  423. package/node_modules/fast-string-truncated-width/dist/utils.js +14 -9
  424. package/node_modules/fast-string-truncated-width/package.json +1 -1
  425. package/node_modules/fast-string-truncated-width/readme.md +2 -3
  426. package/node_modules/fast-string-width/package.json +2 -2
  427. package/node_modules/fast-string-width/readme.md +0 -3
  428. package/node_modules/fast-wrap-ansi/lib/main.js +4 -2
  429. package/node_modules/fast-wrap-ansi/package.json +11 -11
  430. package/node_modules/maizzle/README.md +24 -0
  431. package/node_modules/maizzle/dist/commands/make/component.mjs +1 -1
  432. package/node_modules/maizzle/dist/commands/make/config.mjs +8 -7
  433. package/node_modules/maizzle/dist/commands/make/layout.mjs +3 -3
  434. package/node_modules/maizzle/dist/commands/make/scaffold.mjs +1 -1
  435. package/node_modules/maizzle/dist/commands/make/stubs/Layout.vue +146 -0
  436. package/node_modules/maizzle/dist/commands/make/stubs/component.vue +2 -4
  437. package/node_modules/maizzle/dist/commands/make/stubs/config.ts +1 -5
  438. package/node_modules/maizzle/dist/commands/make/template.mjs +1 -1
  439. package/node_modules/maizzle/dist/commands/new.mjs +46 -135
  440. package/node_modules/maizzle/dist/index.d.mts +1 -0
  441. package/node_modules/maizzle/dist/index.mjs +30 -7
  442. package/node_modules/maizzle/package.json +5 -4
  443. package/node_modules/nypm/dist/cli.mjs +28 -5
  444. package/node_modules/nypm/dist/index.d.mts +0 -8
  445. package/node_modules/nypm/dist/index.mjs +27 -4
  446. package/node_modules/nypm/package.json +12 -12
  447. package/node_modules/tinyexec/README.md +9 -1
  448. package/node_modules/tinyexec/dist/main.d.mts +22 -7
  449. package/node_modules/tinyexec/dist/main.mjs +189 -491
  450. package/node_modules/tinyexec/package.json +14 -16
  451. package/package.json +38 -31
  452. package/dist/_virtual/_rolldown/runtime.mjs +0 -32
  453. package/dist/build.d.mts +0 -19
  454. package/dist/build.d.mts.map +0 -1
  455. package/dist/build.mjs +0 -141
  456. package/dist/build.mjs.map +0 -1
  457. package/dist/components/Divider.vue +0 -133
  458. package/dist/components/Image.vue +0 -70
  459. package/dist/components/Overlap.vue +0 -80
  460. package/dist/components/utils.d.mts +0 -5
  461. package/dist/components/utils.d.mts.map +0 -1
  462. package/dist/components/utils.mjs +0 -9
  463. package/dist/components/utils.mjs.map +0 -1
  464. package/dist/composables/defineConfig.d.mts +0 -14
  465. package/dist/composables/defineConfig.d.mts.map +0 -1
  466. package/dist/composables/defineConfig.mjs.map +0 -1
  467. package/dist/composables/renderContext.d.mts +0 -24
  468. package/dist/composables/renderContext.d.mts.map +0 -1
  469. package/dist/composables/renderContext.mjs +0 -6
  470. package/dist/composables/renderContext.mjs.map +0 -1
  471. package/dist/composables/useConfig.d.mts +0 -9
  472. package/dist/composables/useConfig.d.mts.map +0 -1
  473. package/dist/composables/useConfig.mjs +0 -13
  474. package/dist/composables/useConfig.mjs.map +0 -1
  475. package/dist/composables/useDoctype.d.mts.map +0 -1
  476. package/dist/composables/useDoctype.mjs.map +0 -1
  477. package/dist/composables/useEvent.d.mts.map +0 -1
  478. package/dist/composables/useEvent.mjs.map +0 -1
  479. package/dist/composables/usePlaintext.d.mts.map +0 -1
  480. package/dist/composables/usePlaintext.mjs.map +0 -1
  481. package/dist/composables/usePreviewText.d.mts +0 -24
  482. package/dist/composables/usePreviewText.d.mts.map +0 -1
  483. package/dist/composables/usePreviewText.mjs +0 -29
  484. package/dist/composables/usePreviewText.mjs.map +0 -1
  485. package/dist/config/defaults.d.mts.map +0 -1
  486. package/dist/config/defaults.mjs.map +0 -1
  487. package/dist/config/index.d.mts +0 -15
  488. package/dist/config/index.d.mts.map +0 -1
  489. package/dist/config/index.mjs +0 -71
  490. package/dist/config/index.mjs.map +0 -1
  491. package/dist/events/index.d.mts.map +0 -1
  492. package/dist/events/index.mjs.map +0 -1
  493. package/dist/index.d.mts +0 -31
  494. package/dist/index.mjs +0 -31
  495. package/dist/node_modules/picomatch/index.mjs +0 -13
  496. package/dist/node_modules/picomatch/index.mjs.map +0 -1
  497. package/dist/node_modules/picomatch/lib/constants.mjs +0 -174
  498. package/dist/node_modules/picomatch/lib/constants.mjs.map +0 -1
  499. package/dist/node_modules/picomatch/lib/parse.mjs +0 -1067
  500. package/dist/node_modules/picomatch/lib/parse.mjs.map +0 -1
  501. package/dist/node_modules/picomatch/lib/picomatch.mjs +0 -304
  502. package/dist/node_modules/picomatch/lib/picomatch.mjs.map +0 -1
  503. package/dist/node_modules/picomatch/lib/scan.mjs +0 -296
  504. package/dist/node_modules/picomatch/lib/scan.mjs.map +0 -1
  505. package/dist/node_modules/picomatch/lib/utils.mjs +0 -53
  506. package/dist/node_modules/picomatch/lib/utils.mjs.map +0 -1
  507. package/dist/plaintext.d.mts.map +0 -1
  508. package/dist/plaintext.mjs.map +0 -1
  509. package/dist/plugin.d.mts.map +0 -1
  510. package/dist/plugin.mjs.map +0 -1
  511. package/dist/plugins/postcss/mergeMediaQueries.d.mts.map +0 -1
  512. package/dist/plugins/postcss/mergeMediaQueries.mjs.map +0 -1
  513. package/dist/plugins/postcss/pruneVars.d.mts.map +0 -1
  514. package/dist/plugins/postcss/pruneVars.mjs.map +0 -1
  515. package/dist/plugins/postcss/removeDeclarations.d.mts.map +0 -1
  516. package/dist/plugins/postcss/removeDeclarations.mjs.map +0 -1
  517. package/dist/plugins/postcss/tailwindCleanup.d.mts.map +0 -1
  518. package/dist/plugins/postcss/tailwindCleanup.mjs.map +0 -1
  519. package/dist/render/createRenderer.d.mts.map +0 -1
  520. package/dist/render/createRenderer.mjs +0 -286
  521. package/dist/render/createRenderer.mjs.map +0 -1
  522. package/dist/render/index.d.mts +0 -26
  523. package/dist/render/index.d.mts.map +0 -1
  524. package/dist/render/index.mjs +0 -46
  525. package/dist/render/index.mjs.map +0 -1
  526. package/dist/serve.d.mts.map +0 -1
  527. package/dist/serve.mjs.map +0 -1
  528. package/dist/server/compatibility.d.mts +0 -5
  529. package/dist/server/compatibility.d.mts.map +0 -1
  530. package/dist/server/compatibility.mjs +0 -97
  531. package/dist/server/compatibility.mjs.map +0 -1
  532. package/dist/server/email.d.mts.map +0 -1
  533. package/dist/server/email.mjs.map +0 -1
  534. package/dist/server/linter.d.mts +0 -5
  535. package/dist/server/linter.d.mts.map +0 -1
  536. package/dist/server/linter.mjs +0 -189
  537. package/dist/server/linter.mjs.map +0 -1
  538. package/dist/transformers/addAttributes.d.mts +0 -32
  539. package/dist/transformers/addAttributes.d.mts.map +0 -1
  540. package/dist/transformers/addAttributes.mjs.map +0 -1
  541. package/dist/transformers/attributeToStyle.d.mts +0 -25
  542. package/dist/transformers/attributeToStyle.d.mts.map +0 -1
  543. package/dist/transformers/attributeToStyle.mjs +0 -80
  544. package/dist/transformers/attributeToStyle.mjs.map +0 -1
  545. package/dist/transformers/base.d.mts +0 -8
  546. package/dist/transformers/base.d.mts.map +0 -1
  547. package/dist/transformers/base.mjs.map +0 -1
  548. package/dist/transformers/entities.d.mts +0 -8
  549. package/dist/transformers/entities.d.mts.map +0 -1
  550. package/dist/transformers/entities.mjs +0 -41
  551. package/dist/transformers/entities.mjs.map +0 -1
  552. package/dist/transformers/filters/defaults.d.mts.map +0 -1
  553. package/dist/transformers/filters/defaults.mjs.map +0 -1
  554. package/dist/transformers/filters/index.d.mts +0 -22
  555. package/dist/transformers/filters/index.d.mts.map +0 -1
  556. package/dist/transformers/filters/index.mjs +0 -67
  557. package/dist/transformers/filters/index.mjs.map +0 -1
  558. package/dist/transformers/format.d.mts +0 -15
  559. package/dist/transformers/format.d.mts.map +0 -1
  560. package/dist/transformers/format.mjs +0 -26
  561. package/dist/transformers/format.mjs.map +0 -1
  562. package/dist/transformers/index.d.mts.map +0 -1
  563. package/dist/transformers/index.mjs +0 -81
  564. package/dist/transformers/index.mjs.map +0 -1
  565. package/dist/transformers/inlineCSS.d.mts +0 -17
  566. package/dist/transformers/inlineCSS.d.mts.map +0 -1
  567. package/dist/transformers/inlineCSS.mjs +0 -70
  568. package/dist/transformers/inlineCSS.mjs.map +0 -1
  569. package/dist/transformers/inlineLink.d.mts +0 -14
  570. package/dist/transformers/inlineLink.d.mts.map +0 -1
  571. package/dist/transformers/inlineLink.mjs.map +0 -1
  572. package/dist/transformers/minify.d.mts +0 -17
  573. package/dist/transformers/minify.d.mts.map +0 -1
  574. package/dist/transformers/minify.mjs +0 -24
  575. package/dist/transformers/minify.mjs.map +0 -1
  576. package/dist/transformers/purgeCSS.d.mts +0 -23
  577. package/dist/transformers/purgeCSS.d.mts.map +0 -1
  578. package/dist/transformers/purgeCSS.mjs +0 -132
  579. package/dist/transformers/purgeCSS.mjs.map +0 -1
  580. package/dist/transformers/removeAttributes.d.mts +0 -31
  581. package/dist/transformers/removeAttributes.d.mts.map +0 -1
  582. package/dist/transformers/removeAttributes.mjs +0 -63
  583. package/dist/transformers/removeAttributes.mjs.map +0 -1
  584. package/dist/transformers/replaceStrings.d.mts.map +0 -1
  585. package/dist/transformers/replaceStrings.mjs.map +0 -1
  586. package/dist/transformers/safeClassNames.d.mts +0 -22
  587. package/dist/transformers/safeClassNames.d.mts.map +0 -1
  588. package/dist/transformers/safeClassNames.mjs.map +0 -1
  589. package/dist/transformers/shorthandCSS.d.mts +0 -24
  590. package/dist/transformers/shorthandCSS.d.mts.map +0 -1
  591. package/dist/transformers/shorthandCSS.mjs +0 -48
  592. package/dist/transformers/shorthandCSS.mjs.map +0 -1
  593. package/dist/transformers/sixHex.d.mts +0 -16
  594. package/dist/transformers/sixHex.d.mts.map +0 -1
  595. package/dist/transformers/sixHex.mjs +0 -30
  596. package/dist/transformers/sixHex.mjs.map +0 -1
  597. package/dist/transformers/tailwindcss.d.mts.map +0 -1
  598. package/dist/transformers/tailwindcss.mjs.map +0 -1
  599. package/dist/transformers/urlQuery.d.mts +0 -24
  600. package/dist/transformers/urlQuery.d.mts.map +0 -1
  601. package/dist/transformers/urlQuery.mjs +0 -65
  602. package/dist/transformers/urlQuery.mjs.map +0 -1
  603. package/dist/types/config.d.mts.map +0 -1
  604. package/dist/types/config.mjs +0 -1
  605. package/dist/types/index.d.mts +0 -2
  606. package/dist/types/index.mjs +0 -1
  607. package/dist/utils/ast/index.d.mts +0 -4
  608. package/dist/utils/ast/index.mjs +0 -5
  609. package/dist/utils/ast/parser.d.mts.map +0 -1
  610. package/dist/utils/ast/parser.mjs.map +0 -1
  611. package/dist/utils/ast/serializer.d.mts.map +0 -1
  612. package/dist/utils/ast/serializer.mjs +0 -37
  613. package/dist/utils/ast/serializer.mjs.map +0 -1
  614. package/dist/utils/ast/walker.d.mts.map +0 -1
  615. package/dist/utils/ast/walker.mjs.map +0 -1
  616. package/dist/utils/detect.d.mts.map +0 -1
  617. package/dist/utils/detect.mjs.map +0 -1
  618. package/dist/utils/url.d.mts.map +0 -1
  619. package/dist/utils/url.mjs.map +0 -1
  620. package/node_modules/@clack/core/dist/index.mjs.map +0 -1
  621. package/node_modules/@clack/prompts/dist/index.mjs.map +0 -1
  622. package/node_modules/fast-wrap-ansi/lib/main.js.map +0 -1
  623. package/node_modules/maizzle/dist/commands/make/stubs/layout.vue +0 -39
  624. package/node_modules/tinyexec/dist/LICENSES.txt +0 -83
@@ -0,0 +1,114 @@
1
+ import { walk } from "../utils/ast/walker.js";
2
+ import "../utils/ast/index.js";
3
+ import { horizontalBorderPx } from "../utils/cssBox.js";
4
+ import safeParser from "postcss-safe-parser";
5
+ //#region src/transformers/msoPlaceholders.ts
6
+ const RE_MAX_WIDTH = /(?:^|;\s*)max-width:\s*([^;]+)/i;
7
+ const RE_WIDTH = /(?:^|;\s*)width:\s*([^;]+)/i;
8
+ const RE_PERCENT = /^[\d.]+%$/;
9
+ function resolveWidth(value) {
10
+ const trimmed = value.trim();
11
+ if (RE_PERCENT.test(trimmed)) return trimmed;
12
+ const m = trimmed.match(/^([\d.]+)(px|rem|em|pt)?$/i);
13
+ if (!m) return null;
14
+ const n = parseFloat(m[1]);
15
+ const unit = (m[2] || "px").toLowerCase();
16
+ return `${Math.round(n * (unit === "rem" || unit === "em" ? 16 : unit === "pt" ? 1.333 : 1))}px`;
17
+ }
18
+ /**
19
+ * Resolve all `__MAIZZLE_MSO*__` placeholders inside MSO conditional comments
20
+ * by reading inlined style + `data-*` markers on the paired elements.
21
+ *
22
+ * Two placeholder families:
23
+ *
24
+ * MSOW (`__MAIZZLE_MSOW_{id}__`) — emitted by `<Container>` and `<Section>`.
25
+ * Source element is marked with `data-maizzle-msow-id`. Reads inlined
26
+ * `max-width:` (falls back to `width:`) and normalizes to px. Falls
27
+ * back to `data-maizzle-msow-fallback` (default `600px`) when the
28
+ * value can't be parsed.
29
+ *
30
+ * MSOTDSTYLE (`__MAIZZLE_MSOTDSTYLE_{id}__`) — emitted by `<Container>` and
31
+ * `<Section>`'s MSO `<td>`. Source element is marked with
32
+ * `data-maizzle-mso-td-id`. Extracts from the inlined style:
33
+ * - `background-color` (always, when present) so Word paints the cell.
34
+ * - `padding*` (only when no horizontal border on the element, since
35
+ * Word drops div padding without a border and a copy would
36
+ * double-pad with one).
37
+ * Appends the `data-maizzle-mso-style` value (the user's `msoStyle`
38
+ * prop) last so it wins on duplicates. Empty input resolves to ''
39
+ * so the placeholder collapses cleanly.
40
+ *
41
+ * Single collect-walk + single substitute-walk: the same Container div
42
+ * carries both marker kinds, so one element visit fills both maps.
43
+ */
44
+ function msoPlaceholders(dom) {
45
+ const widths = /* @__PURE__ */ new Map();
46
+ const tdStyles = /* @__PURE__ */ new Map();
47
+ walk(dom, (node) => {
48
+ const a = node.attribs;
49
+ if (!a) return;
50
+ const msowId = a["data-maizzle-msow-id"];
51
+ const tdId = a["data-maizzle-mso-td-id"];
52
+ if (!msowId && !tdId) return;
53
+ const style = a.style ?? "";
54
+ if (msowId) {
55
+ delete a["data-maizzle-msow-id"];
56
+ const fallback = a["data-maizzle-msow-fallback"] ?? "600px";
57
+ delete a["data-maizzle-msow-fallback"];
58
+ const raw = style.match(RE_MAX_WIDTH)?.[1] ?? style.match(RE_WIDTH)?.[1];
59
+ const resolved = raw ? resolveWidth(raw) : null;
60
+ widths.set(msowId, resolved ?? fallback);
61
+ }
62
+ if (tdId) {
63
+ delete a["data-maizzle-mso-td-id"];
64
+ const msoStyle = (a["data-maizzle-mso-style"] ?? "").trim().replace(/;\s*$/, "");
65
+ delete a["data-maizzle-mso-style"];
66
+ /**
67
+ * Build the MSO td's inline style from three sources, in CSS priority order
68
+ * (earlier = lower, later wins on dupes):
69
+ *
70
+ * 1. `background-color` (always, when present) — Word paints the cell
71
+ * under any padding area or inline-block gap, not just the div.
72
+ *
73
+ * 2. `padding*` (hoisted only when no horizontal border) — Word drops
74
+ * div padding without a stabilizing border, so the td has to
75
+ * carry it. With a border, Word renders div padding and a td
76
+ * copy would double-pad.
77
+ *
78
+ * 3. The user's `mso-style` prop — last so it overrides anything the
79
+ * auto-hoist computed.
80
+ */
81
+ const parts = [];
82
+ if (style) {
83
+ const root = safeParser(style);
84
+ let bgDecl;
85
+ root.walkDecls("background-color", (d) => {
86
+ bgDecl = `background-color: ${d.value}${d.important ? " !important" : ""}`;
87
+ });
88
+ if (bgDecl) parts.push(bgDecl);
89
+ if (horizontalBorderPx(root) === 0) root.walkDecls((d) => {
90
+ if (/^padding(-|$)/.test(d.prop)) parts.push(`${d.prop}: ${d.value}${d.important ? " !important" : ""}`);
91
+ });
92
+ }
93
+ if (msoStyle) parts.push(msoStyle);
94
+ tdStyles.set(tdId, parts.length ? ` style="${parts.join("; ")}"` : "");
95
+ }
96
+ });
97
+ if (widths.size === 0 && tdStyles.size === 0) return dom;
98
+ walk(dom, (node) => {
99
+ if (node.type !== "comment") return;
100
+ let data = node.data;
101
+ if (!data) return;
102
+ const hasMsow = widths.size > 0 && data.includes("__MAIZZLE_MSOW_");
103
+ const hasTd = tdStyles.size > 0 && data.includes("__MAIZZLE_MSOTDSTYLE_");
104
+ if (!hasMsow && !hasTd) return;
105
+ if (hasMsow) for (const [id, val] of widths) data = data.replaceAll(`__MAIZZLE_MSOW_${id}__`, val);
106
+ if (hasTd) for (const [id, val] of tdStyles) data = data.replaceAll(`__MAIZZLE_MSOTDSTYLE_${id}__`, val);
107
+ node.data = data;
108
+ });
109
+ return dom;
110
+ }
111
+ //#endregion
112
+ export { msoPlaceholders };
113
+
114
+ //# sourceMappingURL=msoPlaceholders.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"msoPlaceholders.js","names":["el"],"sources":["../../src/transformers/msoPlaceholders.ts"],"sourcesContent":["import safeParser from 'postcss-safe-parser'\nimport { walk } from '../utils/ast/index.ts'\nimport { horizontalBorderPx } from '../utils/cssBox.ts'\nimport type { ChildNode, Element } from 'domhandler'\n\nconst RE_MAX_WIDTH = /(?:^|;\\s*)max-width:\\s*([^;]+)/i\nconst RE_WIDTH = /(?:^|;\\s*)width:\\s*([^;]+)/i\nconst RE_PERCENT = /^[\\d.]+%$/\n\nfunction resolveWidth(value: string): string | null {\n const trimmed = value.trim()\n if (RE_PERCENT.test(trimmed)) return trimmed\n const m = trimmed.match(/^([\\d.]+)(px|rem|em|pt)?$/i)\n if (!m) return null\n const n = parseFloat(m[1])\n const unit = (m[2] || 'px').toLowerCase()\n const factor = unit === 'rem' || unit === 'em' ? 16 : unit === 'pt' ? 1.333 : 1\n return `${Math.round(n * factor)}px`\n}\n\n/**\n * Resolve all `__MAIZZLE_MSO*__` placeholders inside MSO conditional comments\n * by reading inlined style + `data-*` markers on the paired elements.\n *\n * Two placeholder families:\n *\n * MSOW (`__MAIZZLE_MSOW_{id}__`) — emitted by `<Container>` and `<Section>`.\n * Source element is marked with `data-maizzle-msow-id`. Reads inlined\n * `max-width:` (falls back to `width:`) and normalizes to px. Falls\n * back to `data-maizzle-msow-fallback` (default `600px`) when the\n * value can't be parsed.\n *\n * MSOTDSTYLE (`__MAIZZLE_MSOTDSTYLE_{id}__`) — emitted by `<Container>` and\n * `<Section>`'s MSO `<td>`. Source element is marked with\n * `data-maizzle-mso-td-id`. Extracts from the inlined style:\n * - `background-color` (always, when present) so Word paints the cell.\n * - `padding*` (only when no horizontal border on the element, since\n * Word drops div padding without a border and a copy would\n * double-pad with one).\n * Appends the `data-maizzle-mso-style` value (the user's `msoStyle`\n * prop) last so it wins on duplicates. Empty input resolves to ''\n * so the placeholder collapses cleanly.\n *\n * Single collect-walk + single substitute-walk: the same Container div\n * carries both marker kinds, so one element visit fills both maps.\n */\nexport function msoPlaceholders(dom: ChildNode[]): ChildNode[] {\n const widths = new Map<string, string>()\n const tdStyles = new Map<string, string>()\n\n walk(dom, (node) => {\n const el = node as Element\n const a = el.attribs\n if (!a) return\n\n const msowId = a['data-maizzle-msow-id']\n const tdId = a['data-maizzle-mso-td-id']\n if (!msowId && !tdId) return\n\n const style = a.style ?? ''\n\n if (msowId) {\n delete a['data-maizzle-msow-id']\n const fallback = a['data-maizzle-msow-fallback'] ?? '600px'\n delete a['data-maizzle-msow-fallback']\n const raw = style.match(RE_MAX_WIDTH)?.[1] ?? style.match(RE_WIDTH)?.[1]\n const resolved = raw ? resolveWidth(raw) : null\n widths.set(msowId, resolved ?? fallback)\n }\n\n if (tdId) {\n delete a['data-maizzle-mso-td-id']\n const msoStyle = (a['data-maizzle-mso-style'] ?? '').trim().replace(/;\\s*$/, '')\n delete a['data-maizzle-mso-style']\n\n /**\n * Build the MSO td's inline style from three sources, in CSS priority order\n * (earlier = lower, later wins on dupes):\n *\n * 1. `background-color` (always, when present) — Word paints the cell\n * under any padding area or inline-block gap, not just the div.\n *\n * 2. `padding*` (hoisted only when no horizontal border) — Word drops\n * div padding without a stabilizing border, so the td has to\n * carry it. With a border, Word renders div padding and a td\n * copy would double-pad.\n *\n * 3. The user's `mso-style` prop — last so it overrides anything the\n * auto-hoist computed.\n */\n const parts: string[] = []\n if (style) {\n const root = safeParser(style)\n\n let bgDecl: string | undefined\n root.walkDecls('background-color', (d) => {\n bgDecl = `background-color: ${d.value}${d.important ? ' !important' : ''}`\n })\n if (bgDecl) parts.push(bgDecl)\n\n if (horizontalBorderPx(root) === 0) {\n root.walkDecls((d) => {\n if (/^padding(-|$)/.test(d.prop)) {\n parts.push(`${d.prop}: ${d.value}${d.important ? ' !important' : ''}`)\n }\n })\n }\n }\n if (msoStyle) parts.push(msoStyle)\n\n tdStyles.set(tdId, parts.length ? ` style=\"${parts.join('; ')}\"` : '')\n }\n })\n\n if (widths.size === 0 && tdStyles.size === 0) return dom\n\n walk(dom, (node) => {\n if (node.type !== 'comment') return\n let data = (node as any).data as string\n if (!data) return\n const hasMsow = widths.size > 0 && data.includes('__MAIZZLE_MSOW_')\n const hasTd = tdStyles.size > 0 && data.includes('__MAIZZLE_MSOTDSTYLE_')\n if (!hasMsow && !hasTd) return\n\n if (hasMsow) {\n for (const [id, val] of widths) {\n data = data.replaceAll(`__MAIZZLE_MSOW_${id}__`, val)\n }\n }\n if (hasTd) {\n for (const [id, val] of tdStyles) {\n data = data.replaceAll(`__MAIZZLE_MSOTDSTYLE_${id}__`, val)\n }\n }\n ;(node as any).data = data\n })\n\n return dom\n}\n"],"mappings":";;;;;AAKA,MAAM,eAAe;AACrB,MAAM,WAAW;AACjB,MAAM,aAAa;AAEnB,SAAS,aAAa,OAA8B;CAClD,MAAM,UAAU,MAAM,KAAK;CAC3B,IAAI,WAAW,KAAK,OAAO,GAAG,OAAO;CACrC,MAAM,IAAI,QAAQ,MAAM,4BAA4B;CACpD,IAAI,CAAC,GAAG,OAAO;CACf,MAAM,IAAI,WAAW,EAAE,EAAE;CACzB,MAAM,QAAQ,EAAE,MAAM,KAAA,CAAM,YAAY;CAExC,OAAO,GAAG,KAAK,MAAM,KADN,SAAS,SAAS,SAAS,OAAO,KAAK,SAAS,OAAO,QAAQ,EAC/C,EAAE;AACnC;;;;;;;;;;;;;;;;;;;;;;;;;;;AA4BA,SAAgB,gBAAgB,KAA+B;CAC7D,MAAM,yBAAS,IAAI,IAAoB;CACvC,MAAM,2BAAW,IAAI,IAAoB;CAEzC,KAAK,MAAM,SAAS;EAElB,MAAM,IAAIA,KAAG;EACb,IAAI,CAAC,GAAG;EAER,MAAM,SAAS,EAAE;EACjB,MAAM,OAAO,EAAE;EACf,IAAI,CAAC,UAAU,CAAC,MAAM;EAEtB,MAAM,QAAQ,EAAE,SAAS;EAEzB,IAAI,QAAQ;GACV,OAAO,EAAE;GACT,MAAM,WAAW,EAAE,iCAAiC;GACpD,OAAO,EAAE;GACT,MAAM,MAAM,MAAM,MAAM,YAAY,CAAC,GAAG,MAAM,MAAM,MAAM,QAAQ,CAAC,GAAG;GACtE,MAAM,WAAW,MAAM,aAAa,GAAG,IAAI;GAC3C,OAAO,IAAI,QAAQ,YAAY,QAAQ;EACzC;EAEA,IAAI,MAAM;GACR,OAAO,EAAE;GACT,MAAM,YAAY,EAAE,6BAA6B,GAAA,CAAI,KAAK,CAAC,CAAC,QAAQ,SAAS,EAAE;GAC/E,OAAO,EAAE;;;;;;;;;;;;;;;;GAiBT,MAAM,QAAkB,CAAC;GACzB,IAAI,OAAO;IACT,MAAM,OAAO,WAAW,KAAK;IAE7B,IAAI;IACJ,KAAK,UAAU,qBAAqB,MAAM;KACxC,SAAS,qBAAqB,EAAE,QAAQ,EAAE,YAAY,gBAAgB;IACxE,CAAC;IACD,IAAI,QAAQ,MAAM,KAAK,MAAM;IAE7B,IAAI,mBAAmB,IAAI,MAAM,GAC/B,KAAK,WAAW,MAAM;KACpB,IAAI,gBAAgB,KAAK,EAAE,IAAI,GAC7B,MAAM,KAAK,GAAG,EAAE,KAAK,IAAI,EAAE,QAAQ,EAAE,YAAY,gBAAgB,IAAI;IAEzE,CAAC;GAEL;GACA,IAAI,UAAU,MAAM,KAAK,QAAQ;GAEjC,SAAS,IAAI,MAAM,MAAM,SAAS,WAAW,MAAM,KAAK,IAAI,EAAE,KAAK,EAAE;EACvE;CACF,CAAC;CAED,IAAI,OAAO,SAAS,KAAK,SAAS,SAAS,GAAG,OAAO;CAErD,KAAK,MAAM,SAAS;EAClB,IAAI,KAAK,SAAS,WAAW;EAC7B,IAAI,OAAQ,KAAa;EACzB,IAAI,CAAC,MAAM;EACX,MAAM,UAAU,OAAO,OAAO,KAAK,KAAK,SAAS,iBAAiB;EAClE,MAAM,QAAQ,SAAS,OAAO,KAAK,KAAK,SAAS,uBAAuB;EACxE,IAAI,CAAC,WAAW,CAAC,OAAO;EAExB,IAAI,SACF,KAAK,MAAM,CAAC,IAAI,QAAQ,QACtB,OAAO,KAAK,WAAW,kBAAkB,GAAG,KAAK,GAAG;EAGxD,IAAI,OACF,KAAK,MAAM,CAAC,IAAI,QAAQ,UACtB,OAAO,KAAK,WAAW,wBAAwB,GAAG,KAAK,GAAG;EAG7D,KAAc,OAAO;CACxB,CAAC;CAED,OAAO;AACT"}
@@ -0,0 +1,43 @@
1
+ import { ChildNode } from "domhandler";
2
+ import { Opts } from "email-comb";
3
+
4
+ //#region src/transformers/purgeCss.d.ts
5
+ /**
6
+ * Options for the `purgeCss` transformer.
7
+ */
8
+ interface PurgeCssOptions extends Partial<Omit<Opts, 'whitelist'>> {
9
+ /**
10
+ * Selectors to preserve regardless of whether they're matched in the
11
+ * markup. Appended to Maizzle's built-in safelist (Gmail, Apple Mail,
12
+ * Outlook.com hooks, etc). Mapped to email-comb's `whitelist` option.
13
+ */
14
+ safelist?: string[];
15
+ }
16
+ /**
17
+ * Remove unused CSS from an HTML string.
18
+ *
19
+ * Uses `email-comb` together with a DOM-aware deep-purge step to strip
20
+ * CSS selectors and class/id references that are not matched anywhere
21
+ * in the document body.
22
+ *
23
+ * @param html HTML string to transform.
24
+ * @param options Email-comb options plus a Maizzle `safelist`.
25
+ * @returns The transformed HTML string.
26
+ *
27
+ * @example
28
+ * import { purgeCss } from '@maizzle/framework'
29
+ *
30
+ * const out = purgeCss('<style>.a{}.b{}</style><p class="a">x</p>', {
31
+ * safelist: ['.keep'],
32
+ * })
33
+ */
34
+ declare function purgeCss(html: string, options?: PurgeCssOptions): string;
35
+ /**
36
+ * DOM-form of {@link purgeCss} used by the internal transformer
37
+ * pipeline. Takes a parsed DOM, returns a parsed DOM — avoids redundant
38
+ * serialize/parse round-trips when chained with other transformers.
39
+ */
40
+ declare function purgeCssDom(dom: ChildNode[], options?: PurgeCssOptions): ChildNode[];
41
+ //#endregion
42
+ export { PurgeCssOptions, purgeCss, purgeCssDom };
43
+ //# sourceMappingURL=purgeCss.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"purgeCss.d.ts","names":[],"sources":["../../src/transformers/purgeCss.ts"],"mappings":";;;;;;AAsCA;UAAiB,eAAA,SAAwB,OAAA,CAAQ,IAAA,CAAK,IAAA;;;;;;EAMpD,QAAA;AAAA;;;;;AAAQ;AAqBV;;;;;;;;AAAoE;AASpE;;;;iBATgB,QAAA,CAAS,IAAA,UAAc,OAAA,GAAS,eAAoB;;;;;;iBASpD,WAAA,CAAY,GAAA,EAAK,SAAA,IAAa,OAAA,GAAS,eAAA,GAAuB,SAAA"}
@@ -0,0 +1,207 @@
1
+ import { parse } from "../utils/ast/parser.js";
2
+ import { walk } from "../utils/ast/walker.js";
3
+ import { serialize } from "../utils/ast/serializer.js";
4
+ import "../utils/ast/index.js";
5
+ import { defu as defu$1 } from "defu";
6
+ import safeParser from "postcss-safe-parser";
7
+ import { selectAll } from "css-select";
8
+ import { comb } from "email-comb";
9
+ //#region src/transformers/purgeCss.ts
10
+ const DEFAULT_SAFELIST = [
11
+ "*body*",
12
+ ".gmail*",
13
+ ".apple*",
14
+ ".ios*",
15
+ ".ox-*",
16
+ ".outlook*",
17
+ "[data-ogs*",
18
+ ".bloop_container",
19
+ ".Singleton",
20
+ ".unused",
21
+ ".moz-text-html",
22
+ ".mail-detail-content",
23
+ "*edo*",
24
+ "#*",
25
+ ".\\&*",
26
+ ".lang*"
27
+ ];
28
+ const DEFAULT_OPTIONS = {
29
+ backend: [{
30
+ heads: "{{",
31
+ tails: "}}"
32
+ }, {
33
+ heads: "{%",
34
+ tails: "%}"
35
+ }],
36
+ whitelist: [...DEFAULT_SAFELIST]
37
+ };
38
+ /**
39
+ * Remove unused CSS from an HTML string.
40
+ *
41
+ * Uses `email-comb` together with a DOM-aware deep-purge step to strip
42
+ * CSS selectors and class/id references that are not matched anywhere
43
+ * in the document body.
44
+ *
45
+ * @param html HTML string to transform.
46
+ * @param options Email-comb options plus a Maizzle `safelist`.
47
+ * @returns The transformed HTML string.
48
+ *
49
+ * @example
50
+ * import { purgeCss } from '@maizzle/framework'
51
+ *
52
+ * const out = purgeCss('<style>.a{}.b{}</style><p class="a">x</p>', {
53
+ * safelist: ['.keep'],
54
+ * })
55
+ */
56
+ function purgeCss(html, options = {}) {
57
+ return serialize(purgeCssDom(parse(html), options));
58
+ }
59
+ /**
60
+ * DOM-form of {@link purgeCss} used by the internal transformer
61
+ * pipeline. Takes a parsed DOM, returns a parsed DOM — avoids redundant
62
+ * serialize/parse round-trips when chained with other transformers.
63
+ */
64
+ function purgeCssDom(dom, options = {}) {
65
+ const userSafelist = Array.isArray(options.safelist) ? options.safelist : [];
66
+ const { safelist: _discard, ...restUserOptions } = options;
67
+ /**
68
+ * Merge user options on top of defaults. defu merges objects deeply;
69
+ * for arrays it appends user values. We want the user safelist
70
+ * appended to the default safelist, so we build whitelist
71
+ * manually.
72
+ */
73
+ const combOptions = defu$1({
74
+ ...restUserOptions,
75
+ whitelist: [...DEFAULT_SAFELIST, ...userSafelist]
76
+ }, DEFAULT_OPTIONS);
77
+ /**
78
+ * Deep purge first: DOM-aware selector removal via PostCSS + css-select.
79
+ * Runs before email-comb so that email-comb can clean up orphaned
80
+ * classes in HTML attributes left behind by removed CSS rules.
81
+ */
82
+ const safelist = [...DEFAULT_SAFELIST, ...userSafelist];
83
+ dom = deepPurge(dom, safelist);
84
+ /**
85
+ * Shield embed style tags from email-comb. Comb has no skip option,
86
+ * so it strips CSS comments and drops class refs it can't match
87
+ * against visible CSS. Swap each embed tag's body for a unique
88
+ * stub rule (`.maizzle-keep-N{}`) so comb keeps the tag, then
89
+ * whitelist that stub plus every selector from the original
90
+ * CSS so comb leaves matching refs alone elsewhere — and
91
+ * finally restore the original CSS once comb has run.
92
+ */
93
+ const stash = [];
94
+ const extraWhitelist = [];
95
+ walk(dom, (node) => {
96
+ const el = node;
97
+ if (el.name !== "style" || !el.attribs) return;
98
+ if (!("embed" in el.attribs) && !("data-embed" in el.attribs) && !("amp-custom" in el.attribs)) return;
99
+ const textNode = el.children?.find((c) => c.type === "text");
100
+ if (!textNode?.data) return;
101
+ const token = `.maizzle-keep-${stash.length}`;
102
+ extraWhitelist.push(token);
103
+ for (const m of textNode.data.matchAll(/(?<![\w-])[.#][a-zA-Z_][\w-]*/g)) extraWhitelist.push(m[0]);
104
+ stash.push({
105
+ token,
106
+ original: textNode.data,
107
+ textNode
108
+ });
109
+ textNode.data = `${token}{}`;
110
+ });
111
+ if (extraWhitelist.length) combOptions.whitelist = [...combOptions.whitelist ?? [], ...extraWhitelist];
112
+ const { result } = comb(serialize(dom), combOptions);
113
+ /**
114
+ * Comb returns a fresh string, so we work off the post-parse tree:
115
+ * find each embed style tag whose body still starts with the stub
116
+ * token we planted earlier and swap the original CSS back in.
117
+ */
118
+ let purgedDom = parse(result);
119
+ if (stash.length) walk(purgedDom, (node) => {
120
+ const el = node;
121
+ if (el.name !== "style" || !el.attribs) return;
122
+ if (!("embed" in el.attribs) && !("data-embed" in el.attribs) && !("amp-custom" in el.attribs)) return;
123
+ const textNode = el.children?.find((c) => c.type === "text");
124
+ if (!textNode?.data) return;
125
+ const trimmed = textNode.data.trim();
126
+ const match = stash.find((s) => trimmed === `${s.token}{}` || trimmed.startsWith(`${s.token}{`));
127
+ if (match) textNode.data = match.original;
128
+ });
129
+ /**
130
+ * Clean up data-embed/embed attributes — no longer needed after purging.
131
+ * `amp-custom` stays as-is (it's the user-authored AMP4Email attr).
132
+ */
133
+ walk(purgedDom, (node) => {
134
+ const el = node;
135
+ if (el.name === "style" && el.attribs) {
136
+ delete el.attribs["data-embed"];
137
+ delete el.attribs.embed;
138
+ }
139
+ });
140
+ return purgedDom;
141
+ }
142
+ /**
143
+ * Deep purge: uses PostCSS to parse CSS in non-embedded style tags,
144
+ * then checks each selector against the DOM with css-select.
145
+ * Removes rules where no selector matches any element.
146
+ */
147
+ function isSafelisted(selector, safelist) {
148
+ return safelist.some((pattern) => {
149
+ if (pattern.startsWith("*") && pattern.endsWith("*")) return selector.includes(pattern.slice(1, -1));
150
+ if (pattern.endsWith("*")) return selector.startsWith(pattern.slice(0, -1));
151
+ if (pattern.startsWith("*")) return selector.endsWith(pattern.slice(1));
152
+ return selector === pattern;
153
+ });
154
+ }
155
+ function deepPurge(dom, safelist) {
156
+ walk(dom, (node) => {
157
+ const el = node;
158
+ if (el.name !== "style" || !el.attribs) return;
159
+ if ("data-embed" in el.attribs || "embed" in el.attribs || "amp-custom" in el.attribs) return;
160
+ const textNode = el.children?.find((c) => c.type === "text");
161
+ if (!textNode?.data?.trim()) return;
162
+ const root = safeParser(textNode.data);
163
+ root.walkRules((rule) => {
164
+ /**
165
+ * Skip rules inside @media or other at-rules — those may target
166
+ * states we can't match statically (hover, responsive, etc.).
167
+ */
168
+ if (rule.parent?.type === "atrule") return;
169
+ const selectors = rule.selectors ?? [rule.selector];
170
+ const matched = selectors.filter((sel) => {
171
+ if (isSafelisted(sel, safelist)) return true;
172
+ /**
173
+ * Skip pseudo-classes/elements that can't be matched statically.
174
+ * Functional pseudos like :not(), :is(), :where(), :has() are
175
+ * matchable by css-select, so we only skip dynamic/state
176
+ * ones.
177
+ */
178
+ if (/::[\w-]/.test(sel)) return true;
179
+ if (/(?<!:):(?!not\b|is\b|where\b|has\b)[\w-]/.test(sel.replace(/\\./g, ""))) return true;
180
+ try {
181
+ return selectAll(sel, dom).length > 0;
182
+ } catch {
183
+ return true;
184
+ }
185
+ });
186
+ if (matched.length === 0) rule.remove();
187
+ else if (matched.length < selectors.length) rule.selectors = matched;
188
+ });
189
+ root.walkAtRules((atRule) => {
190
+ if (atRule.nodes?.length === 0) atRule.remove();
191
+ });
192
+ const purgedCss = root.toString();
193
+ if (purgedCss.trim()) textNode.data = purgedCss;
194
+ else {
195
+ const parent = el.parent;
196
+ if (parent && "children" in parent) {
197
+ const idx = parent.children.indexOf(el);
198
+ if (idx !== -1) parent.children.splice(idx, 1);
199
+ }
200
+ }
201
+ });
202
+ return dom;
203
+ }
204
+ //#endregion
205
+ export { purgeCss, purgeCssDom };
206
+
207
+ //# sourceMappingURL=purgeCss.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"purgeCss.js","names":["merge"],"sources":["../../src/transformers/purgeCss.ts"],"sourcesContent":["import { comb } from 'email-comb'\nimport { defu as merge } from 'defu'\nimport safeParser from 'postcss-safe-parser'\nimport { selectAll } from 'css-select'\nimport type { ChildNode, Element } from 'domhandler'\nimport type { Opts as CombOptions } from 'email-comb'\nimport { parse, serialize, walk } from '../utils/ast/index.ts'\n\nconst DEFAULT_SAFELIST: string[] = [\n '*body*', // Gmail\n '.gmail*', // Gmail\n '.apple*', // Apple Mail\n '.ios*', // Mail on iOS\n '.ox-*', // Open-Xchange\n '.outlook*', // Outlook.com\n '[data-ogs*', // Outlook.com\n '.bloop_container', // Airmail\n '.Singleton', // Apple Mail 10\n '.unused', // Notes 8\n '.moz-text-html', // Thunderbird\n '.mail-detail-content', // Comcast, Libero webmail\n '*edo*', // Edison (all)\n '#*', // Freenet uses #msgBody\n '.\\\\&*', // Yahoo Mail wraps content in a class literally named \"&\"\n '.lang*', // Fenced code blocks\n]\n\nconst DEFAULT_OPTIONS = {\n backend: [\n { heads: '{{', tails: '}}' },\n { heads: '{%', tails: '%}' },\n ],\n whitelist: [...DEFAULT_SAFELIST],\n}\n\n/**\n * Options for the `purgeCss` transformer.\n */\nexport interface PurgeCssOptions extends Partial<Omit<CombOptions, 'whitelist'>> {\n /**\n * Selectors to preserve regardless of whether they're matched in the\n * markup. Appended to Maizzle's built-in safelist (Gmail, Apple Mail,\n * Outlook.com hooks, etc). Mapped to email-comb's `whitelist` option.\n */\n safelist?: string[]\n}\n\n/**\n * Remove unused CSS from an HTML string.\n *\n * Uses `email-comb` together with a DOM-aware deep-purge step to strip\n * CSS selectors and class/id references that are not matched anywhere\n * in the document body.\n *\n * @param html HTML string to transform.\n * @param options Email-comb options plus a Maizzle `safelist`.\n * @returns The transformed HTML string.\n *\n * @example\n * import { purgeCss } from '@maizzle/framework'\n *\n * const out = purgeCss('<style>.a{}.b{}</style><p class=\"a\">x</p>', {\n * safelist: ['.keep'],\n * })\n */\nexport function purgeCss(html: string, options: PurgeCssOptions = {}): string {\n return serialize(purgeCssDom(parse(html), options))\n}\n\n/**\n * DOM-form of {@link purgeCss} used by the internal transformer\n * pipeline. Takes a parsed DOM, returns a parsed DOM — avoids redundant\n * serialize/parse round-trips when chained with other transformers.\n */\nexport function purgeCssDom(dom: ChildNode[], options: PurgeCssOptions = {}): ChildNode[] {\n const userSafelist = Array.isArray(options.safelist) ? options.safelist : []\n\n const { safelist: _discard, ...restUserOptions } = options\n\n /**\n * Merge user options on top of defaults. defu merges objects deeply;\n * for arrays it appends user values. We want the user safelist\n * appended to the default safelist, so we build whitelist\n * manually.\n */\n const combOptions = merge(\n { ...restUserOptions, whitelist: [...DEFAULT_SAFELIST, ...userSafelist] },\n DEFAULT_OPTIONS,\n )\n\n /**\n * Deep purge first: DOM-aware selector removal via PostCSS + css-select.\n * Runs before email-comb so that email-comb can clean up orphaned\n * classes in HTML attributes left behind by removed CSS rules.\n */\n const safelist = [...DEFAULT_SAFELIST, ...userSafelist]\n dom = deepPurge(dom, safelist)\n\n /**\n * Shield embed style tags from email-comb. Comb has no skip option,\n * so it strips CSS comments and drops class refs it can't match\n * against visible CSS. Swap each embed tag's body for a unique\n * stub rule (`.maizzle-keep-N{}`) so comb keeps the tag, then\n * whitelist that stub plus every selector from the original\n * CSS so comb leaves matching refs alone elsewhere — and\n * finally restore the original CSS once comb has run.\n */\n const stash: { token: string; original: string; textNode: any }[] = []\n const extraWhitelist: string[] = []\n walk(dom, (node) => {\n const el = node as Element\n if (el.name !== 'style' || !el.attribs) return\n if (!('embed' in el.attribs) && !('data-embed' in el.attribs) && !('amp-custom' in el.attribs)) return\n const textNode = el.children?.find((c: any) => c.type === 'text') as any\n if (!textNode?.data) return\n const idx = stash.length\n const token = `.maizzle-keep-${idx}`\n extraWhitelist.push(token)\n for (const m of textNode.data.matchAll(/(?<![\\w-])[.#][a-zA-Z_][\\w-]*/g)) {\n extraWhitelist.push(m[0])\n }\n stash.push({ token, original: textNode.data, textNode })\n textNode.data = `${token}{}`\n })\n\n if (extraWhitelist.length) {\n combOptions.whitelist = [...(combOptions.whitelist as string[] ?? []), ...extraWhitelist]\n }\n\n const { result } = comb(serialize(dom), combOptions)\n\n /**\n * Comb returns a fresh string, so we work off the post-parse tree:\n * find each embed style tag whose body still starts with the stub\n * token we planted earlier and swap the original CSS back in.\n */\n let purgedDom = parse(result)\n\n if (stash.length) {\n walk(purgedDom, (node) => {\n const el = node as Element\n if (el.name !== 'style' || !el.attribs) return\n if (!('embed' in el.attribs) && !('data-embed' in el.attribs) && !('amp-custom' in el.attribs)) return\n const textNode = el.children?.find((c: any) => c.type === 'text') as any\n if (!textNode?.data) return\n const trimmed = textNode.data.trim()\n const match = stash.find(s => trimmed === `${s.token}{}` || trimmed.startsWith(`${s.token}{`))\n if (match) textNode.data = match.original\n })\n }\n\n /**\n * Clean up data-embed/embed attributes — no longer needed after purging.\n * `amp-custom` stays as-is (it's the user-authored AMP4Email attr).\n */\n walk(purgedDom, (node) => {\n const el = node as Element\n if (el.name === 'style' && el.attribs) {\n delete el.attribs['data-embed']\n delete el.attribs.embed\n }\n })\n\n return purgedDom\n}\n\n/**\n * Deep purge: uses PostCSS to parse CSS in non-embedded style tags,\n * then checks each selector against the DOM with css-select.\n * Removes rules where no selector matches any element.\n */\nfunction isSafelisted(selector: string, safelist: string[]): boolean {\n return safelist.some((pattern) => {\n if (pattern.startsWith('*') && pattern.endsWith('*')) {\n return selector.includes(pattern.slice(1, -1))\n }\n if (pattern.endsWith('*')) {\n return selector.startsWith(pattern.slice(0, -1))\n }\n if (pattern.startsWith('*')) {\n return selector.endsWith(pattern.slice(1))\n }\n return selector === pattern\n })\n}\n\nfunction deepPurge(dom: ChildNode[], safelist: string[]): ChildNode[] {\n walk(dom, (node) => {\n const el = node as Element\n\n if (el.name !== 'style' || !el.attribs) return\n if ('data-embed' in el.attribs || 'embed' in el.attribs || 'amp-custom' in el.attribs) return\n\n const textNode = el.children?.find((c: any) => c.type === 'text') as any\n if (!textNode?.data?.trim()) return\n\n const root = safeParser(textNode.data)\n\n root.walkRules((rule) => {\n /**\n * Skip rules inside @media or other at-rules — those may target\n * states we can't match statically (hover, responsive, etc.).\n */\n if (rule.parent?.type === 'atrule') return\n\n const selectors = rule.selectors ?? [rule.selector]\n const matched = selectors.filter((sel) => {\n // Keep safelisted selectors\n if (isSafelisted(sel, safelist)) return true\n\n /**\n * Skip pseudo-classes/elements that can't be matched statically.\n * Functional pseudos like :not(), :is(), :where(), :has() are\n * matchable by css-select, so we only skip dynamic/state\n * ones.\n */\n if (/::[\\w-]/.test(sel)) return true\n if (/(?<!:):(?!not\\b|is\\b|where\\b|has\\b)[\\w-]/.test(sel.replace(/\\\\./g, ''))) return true\n\n try {\n return selectAll(sel, dom).length > 0\n } catch {\n // If css-select can't parse the selector, keep it\n return true\n }\n })\n\n if (matched.length === 0) {\n rule.remove()\n } else if (matched.length < selectors.length) {\n rule.selectors = matched\n }\n })\n\n // Remove empty at-rules\n root.walkAtRules((atRule) => {\n if (atRule.nodes?.length === 0) {\n atRule.remove()\n }\n })\n\n const purgedCss = root.toString()\n\n if (purgedCss.trim()) {\n textNode.data = purgedCss\n } else {\n // Remove the style tag entirely if empty\n const parent = el.parent\n if (parent && 'children' in parent) {\n const idx = parent.children.indexOf(el as any)\n if (idx !== -1) parent.children.splice(idx, 1)\n }\n }\n })\n\n return dom\n}\n"],"mappings":";;;;;;;;;AAQA,MAAM,mBAA6B;CACjC;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;AACF;AAEA,MAAM,kBAAkB;CACtB,SAAS,CACP;EAAE,OAAO;EAAM,OAAO;CAAK,GAC3B;EAAE,OAAO;EAAM,OAAO;CAAK,CAC7B;CACA,WAAW,CAAC,GAAG,gBAAgB;AACjC;;;;;;;;;;;;;;;;;;;AAgCA,SAAgB,SAAS,MAAc,UAA2B,CAAC,GAAW;CAC5E,OAAO,UAAU,YAAY,MAAM,IAAI,GAAG,OAAO,CAAC;AACpD;;;;;;AAOA,SAAgB,YAAY,KAAkB,UAA2B,CAAC,GAAgB;CACxF,MAAM,eAAe,MAAM,QAAQ,QAAQ,QAAQ,IAAI,QAAQ,WAAW,CAAC;CAE3E,MAAM,EAAE,UAAU,UAAU,GAAG,oBAAoB;;;;;;;CAQnD,MAAM,cAAcA,OAClB;EAAE,GAAG;EAAiB,WAAW,CAAC,GAAG,kBAAkB,GAAG,YAAY;CAAE,GACxE,eACF;;;;;;CAOA,MAAM,WAAW,CAAC,GAAG,kBAAkB,GAAG,YAAY;CACtD,MAAM,UAAU,KAAK,QAAQ;;;;;;;;;;CAW7B,MAAM,QAA8D,CAAC;CACrE,MAAM,iBAA2B,CAAC;CAClC,KAAK,MAAM,SAAS;EAClB,MAAM,KAAK;EACX,IAAI,GAAG,SAAS,WAAW,CAAC,GAAG,SAAS;EACxC,IAAI,EAAE,WAAW,GAAG,YAAY,EAAE,gBAAgB,GAAG,YAAY,EAAE,gBAAgB,GAAG,UAAU;EAChG,MAAM,WAAW,GAAG,UAAU,MAAM,MAAW,EAAE,SAAS,MAAM;EAChE,IAAI,CAAC,UAAU,MAAM;EAErB,MAAM,QAAQ,iBADF,MAAM;EAElB,eAAe,KAAK,KAAK;EACzB,KAAK,MAAM,KAAK,SAAS,KAAK,SAAS,gCAAgC,GACrE,eAAe,KAAK,EAAE,EAAE;EAE1B,MAAM,KAAK;GAAE;GAAO,UAAU,SAAS;GAAM;EAAS,CAAC;EACvD,SAAS,OAAO,GAAG,MAAM;CAC3B,CAAC;CAED,IAAI,eAAe,QACjB,YAAY,YAAY,CAAC,GAAI,YAAY,aAAyB,CAAC,GAAI,GAAG,cAAc;CAG1F,MAAM,EAAE,WAAW,KAAK,UAAU,GAAG,GAAG,WAAW;;;;;;CAOnD,IAAI,YAAY,MAAM,MAAM;CAE5B,IAAI,MAAM,QACR,KAAK,YAAY,SAAS;EACxB,MAAM,KAAK;EACX,IAAI,GAAG,SAAS,WAAW,CAAC,GAAG,SAAS;EACxC,IAAI,EAAE,WAAW,GAAG,YAAY,EAAE,gBAAgB,GAAG,YAAY,EAAE,gBAAgB,GAAG,UAAU;EAChG,MAAM,WAAW,GAAG,UAAU,MAAM,MAAW,EAAE,SAAS,MAAM;EAChE,IAAI,CAAC,UAAU,MAAM;EACrB,MAAM,UAAU,SAAS,KAAK,KAAK;EACnC,MAAM,QAAQ,MAAM,MAAK,MAAK,YAAY,GAAG,EAAE,MAAM,OAAO,QAAQ,WAAW,GAAG,EAAE,MAAM,EAAE,CAAC;EAC7F,IAAI,OAAO,SAAS,OAAO,MAAM;CACnC,CAAC;;;;;CAOH,KAAK,YAAY,SAAS;EACxB,MAAM,KAAK;EACX,IAAI,GAAG,SAAS,WAAW,GAAG,SAAS;GACrC,OAAO,GAAG,QAAQ;GAClB,OAAO,GAAG,QAAQ;EACpB;CACF,CAAC;CAED,OAAO;AACT;;;;;;AAOA,SAAS,aAAa,UAAkB,UAA6B;CACnE,OAAO,SAAS,MAAM,YAAY;EAChC,IAAI,QAAQ,WAAW,GAAG,KAAK,QAAQ,SAAS,GAAG,GACjD,OAAO,SAAS,SAAS,QAAQ,MAAM,GAAG,EAAE,CAAC;EAE/C,IAAI,QAAQ,SAAS,GAAG,GACtB,OAAO,SAAS,WAAW,QAAQ,MAAM,GAAG,EAAE,CAAC;EAEjD,IAAI,QAAQ,WAAW,GAAG,GACxB,OAAO,SAAS,SAAS,QAAQ,MAAM,CAAC,CAAC;EAE3C,OAAO,aAAa;CACtB,CAAC;AACH;AAEA,SAAS,UAAU,KAAkB,UAAiC;CACpE,KAAK,MAAM,SAAS;EAClB,MAAM,KAAK;EAEX,IAAI,GAAG,SAAS,WAAW,CAAC,GAAG,SAAS;EACxC,IAAI,gBAAgB,GAAG,WAAW,WAAW,GAAG,WAAW,gBAAgB,GAAG,SAAS;EAEvF,MAAM,WAAW,GAAG,UAAU,MAAM,MAAW,EAAE,SAAS,MAAM;EAChE,IAAI,CAAC,UAAU,MAAM,KAAK,GAAG;EAE7B,MAAM,OAAO,WAAW,SAAS,IAAI;EAErC,KAAK,WAAW,SAAS;;;;;GAKvB,IAAI,KAAK,QAAQ,SAAS,UAAU;GAEpC,MAAM,YAAY,KAAK,aAAa,CAAC,KAAK,QAAQ;GAClD,MAAM,UAAU,UAAU,QAAQ,QAAQ;IAExC,IAAI,aAAa,KAAK,QAAQ,GAAG,OAAO;;;;;;;IAQxC,IAAI,UAAU,KAAK,GAAG,GAAG,OAAO;IAChC,IAAI,2CAA2C,KAAK,IAAI,QAAQ,QAAQ,EAAE,CAAC,GAAG,OAAO;IAErF,IAAI;KACF,OAAO,UAAU,KAAK,GAAG,CAAC,CAAC,SAAS;IACtC,QAAQ;KAEN,OAAO;IACT;GACF,CAAC;GAED,IAAI,QAAQ,WAAW,GACrB,KAAK,OAAO;QACP,IAAI,QAAQ,SAAS,UAAU,QACpC,KAAK,YAAY;EAErB,CAAC;EAGD,KAAK,aAAa,WAAW;GAC3B,IAAI,OAAO,OAAO,WAAW,GAC3B,OAAO,OAAO;EAElB,CAAC;EAED,MAAM,YAAY,KAAK,SAAS;EAEhC,IAAI,UAAU,KAAK,GACjB,SAAS,OAAO;OACX;GAEL,MAAM,SAAS,GAAG;GAClB,IAAI,UAAU,cAAc,QAAQ;IAClC,MAAM,MAAM,OAAO,SAAS,QAAQ,EAAS;IAC7C,IAAI,QAAQ,IAAI,OAAO,SAAS,OAAO,KAAK,CAAC;GAC/C;EACF;CACF,CAAC;CAED,OAAO;AACT"}
@@ -0,0 +1,54 @@
1
+ import { ChildNode } from "domhandler";
2
+
3
+ //#region src/transformers/removeAttributes.d.ts
4
+ /**
5
+ * Single attribute-removal rule.
6
+ */
7
+ interface RemoveAttributeRule {
8
+ /** Attribute name to match. */
9
+ name: string;
10
+ /**
11
+ * Match condition for the attribute's value:
12
+ * - `string` — remove when the value matches exactly.
13
+ * - `RegExp` — remove when the value matches the regex.
14
+ * - `boolean` / omitted — remove when the value is empty.
15
+ */
16
+ value?: string | RegExp | boolean;
17
+ }
18
+ /**
19
+ * Entry passed to {@link removeAttributes}. A bare string targets the named
20
+ * attribute and removes it when its value is empty.
21
+ */
22
+ type RemoveAttributeOption = string | RemoveAttributeRule;
23
+ /**
24
+ * Remove HTML attributes from elements.
25
+ *
26
+ * Empty `style` and `class` attributes are always stripped, regardless of
27
+ * what you pass. Your entries are appended to those defaults.
28
+ *
29
+ * - `'data-src'` — remove when the value is empty.
30
+ * - `{ name: 'id', value: 'test' }` — remove when the value matches exactly.
31
+ * - `{ name: 'data-id', value: /\d/ }` — remove when the value matches the regex.
32
+ *
33
+ * @param html HTML string to transform.
34
+ * @param attributes Additional attribute-removal rules to apply on top of the defaults.
35
+ * @returns The transformed HTML string.
36
+ *
37
+ * @example
38
+ * import { removeAttributes } from '@maizzle/framework'
39
+ *
40
+ * const out = removeAttributes('<p style="" data-x="">x</p>', [
41
+ * 'data-x',
42
+ * { name: 'role', value: 'none' },
43
+ * ])
44
+ */
45
+ declare function removeAttributes(html: string, attributes?: RemoveAttributeOption[]): string;
46
+ /**
47
+ * DOM-form of {@link removeAttributes} used by the internal transformer
48
+ * pipeline. Takes a parsed DOM, returns a parsed DOM — avoids redundant
49
+ * serialize/parse round-trips when chained with other transformers.
50
+ */
51
+ declare function removeAttributesDom(dom: ChildNode[], attributes?: RemoveAttributeOption[]): ChildNode[];
52
+ //#endregion
53
+ export { RemoveAttributeOption, RemoveAttributeRule, removeAttributes, removeAttributesDom };
54
+ //# sourceMappingURL=removeAttributes.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"removeAttributes.d.ts","names":[],"sources":["../../src/transformers/removeAttributes.ts"],"mappings":";;;;;AAMA;UAAiB,mBAAA;;EAEf,IAAA;EAAA;;;;AAOuB;AAOzB;EAPE,KAAA,YAAiB,MAAM;AAAA;;AAOuC;AAwBhE;;KAxBY,qBAAA,YAAiC,mBAAmB;;;;;;AAwBuB;AASvF;;;;;;;;;;;;;;AAA0G;;iBAT1F,gBAAA,CAAiB,IAAA,UAAc,UAAA,GAAY,qBAAqB;;;;;;iBAShE,mBAAA,CAAoB,GAAA,EAAK,SAAA,IAAa,UAAA,GAAY,qBAAA,KAA+B,SAAA"}
@@ -0,0 +1,72 @@
1
+ import { parse } from "../utils/ast/parser.js";
2
+ import { walk } from "../utils/ast/walker.js";
3
+ import { serialize } from "../utils/ast/serializer.js";
4
+ import "../utils/ast/index.js";
5
+ //#region src/transformers/removeAttributes.ts
6
+ /**
7
+ * Remove HTML attributes from elements.
8
+ *
9
+ * Empty `style` and `class` attributes are always stripped, regardless of
10
+ * what you pass. Your entries are appended to those defaults.
11
+ *
12
+ * - `'data-src'` — remove when the value is empty.
13
+ * - `{ name: 'id', value: 'test' }` — remove when the value matches exactly.
14
+ * - `{ name: 'data-id', value: /\d/ }` — remove when the value matches the regex.
15
+ *
16
+ * @param html HTML string to transform.
17
+ * @param attributes Additional attribute-removal rules to apply on top of the defaults.
18
+ * @returns The transformed HTML string.
19
+ *
20
+ * @example
21
+ * import { removeAttributes } from '@maizzle/framework'
22
+ *
23
+ * const out = removeAttributes('<p style="" data-x="">x</p>', [
24
+ * 'data-x',
25
+ * { name: 'role', value: 'none' },
26
+ * ])
27
+ */
28
+ function removeAttributes(html, attributes = []) {
29
+ return serialize(removeAttributesDom(parse(html), attributes));
30
+ }
31
+ /**
32
+ * DOM-form of {@link removeAttributes} used by the internal transformer
33
+ * pipeline. Takes a parsed DOM, returns a parsed DOM — avoids redundant
34
+ * serialize/parse round-trips when chained with other transformers.
35
+ */
36
+ function removeAttributesDom(dom, attributes = []) {
37
+ const attributesToRemove = [
38
+ "style",
39
+ "class",
40
+ ...attributes
41
+ ];
42
+ walk(dom, (node) => {
43
+ const el = node;
44
+ if (!el.attribs) return;
45
+ for (const attr of attributesToRemove) {
46
+ let attrName;
47
+ let attrValue;
48
+ if (typeof attr === "string") {
49
+ attrName = attr;
50
+ attrValue = true;
51
+ } else {
52
+ attrName = attr.name;
53
+ attrValue = attr.value;
54
+ }
55
+ const currentValue = el.attribs[attrName];
56
+ if (currentValue === void 0) continue;
57
+ let shouldRemove = false;
58
+ if (typeof attrValue === "boolean") shouldRemove = currentValue === "" || currentValue === true;
59
+ else if (typeof attrValue === "string") shouldRemove = currentValue === attrValue;
60
+ else if (attrValue instanceof RegExp) {
61
+ attrValue.lastIndex = 0;
62
+ shouldRemove = attrValue.test(currentValue);
63
+ } else shouldRemove = currentValue === "";
64
+ if (shouldRemove) delete el.attribs[attrName];
65
+ }
66
+ });
67
+ return dom;
68
+ }
69
+ //#endregion
70
+ export { removeAttributes, removeAttributesDom };
71
+
72
+ //# sourceMappingURL=removeAttributes.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"removeAttributes.js","names":[],"sources":["../../src/transformers/removeAttributes.ts"],"sourcesContent":["import type { ChildNode, Element } from 'domhandler'\nimport { parse, serialize, walk } from '../utils/ast/index.ts'\n\n/**\n * Single attribute-removal rule.\n */\nexport interface RemoveAttributeRule {\n /** Attribute name to match. */\n name: string\n /**\n * Match condition for the attribute's value:\n * - `string` — remove when the value matches exactly.\n * - `RegExp` — remove when the value matches the regex.\n * - `boolean` / omitted — remove when the value is empty.\n */\n value?: string | RegExp | boolean\n}\n\n/**\n * Entry passed to {@link removeAttributes}. A bare string targets the named\n * attribute and removes it when its value is empty.\n */\nexport type RemoveAttributeOption = string | RemoveAttributeRule\n\n/**\n * Remove HTML attributes from elements.\n *\n * Empty `style` and `class` attributes are always stripped, regardless of\n * what you pass. Your entries are appended to those defaults.\n *\n * - `'data-src'` — remove when the value is empty.\n * - `{ name: 'id', value: 'test' }` — remove when the value matches exactly.\n * - `{ name: 'data-id', value: /\\d/ }` — remove when the value matches the regex.\n *\n * @param html HTML string to transform.\n * @param attributes Additional attribute-removal rules to apply on top of the defaults.\n * @returns The transformed HTML string.\n *\n * @example\n * import { removeAttributes } from '@maizzle/framework'\n *\n * const out = removeAttributes('<p style=\"\" data-x=\"\">x</p>', [\n * 'data-x',\n * { name: 'role', value: 'none' },\n * ])\n */\nexport function removeAttributes(html: string, attributes: RemoveAttributeOption[] = []): string {\n return serialize(removeAttributesDom(parse(html), attributes))\n}\n\n/**\n * DOM-form of {@link removeAttributes} used by the internal transformer\n * pipeline. Takes a parsed DOM, returns a parsed DOM — avoids redundant\n * serialize/parse round-trips when chained with other transformers.\n */\nexport function removeAttributesDom(dom: ChildNode[], attributes: RemoveAttributeOption[] = []): ChildNode[] {\n // Empty style/class are always stripped; user entries are appended.\n const attributesToRemove: RemoveAttributeOption[] = ['style', 'class', ...attributes]\n\n walk(dom, (node) => {\n const el = node as Element\n if (!el.attribs) return\n\n for (const attr of attributesToRemove) {\n let attrName: string\n let attrValue: string | RegExp | boolean | undefined\n\n if (typeof attr === 'string') {\n attrName = attr\n attrValue = true // Remove when value is empty (boolean true or empty string)\n } else {\n attrName = attr.name\n attrValue = attr.value\n }\n\n const currentValue = el.attribs[attrName]\n\n // Skip if attribute doesn't exist\n if (currentValue === undefined) continue\n\n let shouldRemove = false\n\n if (typeof attrValue === 'boolean') {\n // Remove if value is empty (boolean true is treated as no-value attribute)\n shouldRemove = currentValue === '' || (currentValue as unknown) === true\n } else if (typeof attrValue === 'string') {\n // Remove if value matches exactly\n shouldRemove = currentValue === attrValue\n } else if (attrValue instanceof RegExp) {\n // Remove if value matches regex. Reset lastIndex first: a user-supplied\n // /g or /y regex is stateful across .test() calls, so reusing it over\n // many elements would otherwise match only every other one.\n attrValue.lastIndex = 0\n shouldRemove = attrValue.test(currentValue)\n } else {\n // Default: remove if empty\n shouldRemove = currentValue === ''\n }\n\n if (shouldRemove) {\n delete el.attribs[attrName]\n }\n }\n })\n\n return dom\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;AA8CA,SAAgB,iBAAiB,MAAc,aAAsC,CAAC,GAAW;CAC/F,OAAO,UAAU,oBAAoB,MAAM,IAAI,GAAG,UAAU,CAAC;AAC/D;;;;;;AAOA,SAAgB,oBAAoB,KAAkB,aAAsC,CAAC,GAAgB;CAE3G,MAAM,qBAA8C;EAAC;EAAS;EAAS,GAAG;CAAU;CAEpF,KAAK,MAAM,SAAS;EAClB,MAAM,KAAK;EACX,IAAI,CAAC,GAAG,SAAS;EAEjB,KAAK,MAAM,QAAQ,oBAAoB;GACrC,IAAI;GACJ,IAAI;GAEJ,IAAI,OAAO,SAAS,UAAU;IAC5B,WAAW;IACX,YAAY;GACd,OAAO;IACL,WAAW,KAAK;IAChB,YAAY,KAAK;GACnB;GAEA,MAAM,eAAe,GAAG,QAAQ;GAGhC,IAAI,iBAAiB,KAAA,GAAW;GAEhC,IAAI,eAAe;GAEnB,IAAI,OAAO,cAAc,WAEvB,eAAe,iBAAiB,MAAO,iBAA6B;QAC/D,IAAI,OAAO,cAAc,UAE9B,eAAe,iBAAiB;QAC3B,IAAI,qBAAqB,QAAQ;IAItC,UAAU,YAAY;IACtB,eAAe,UAAU,KAAK,YAAY;GAC5C,OAEE,eAAe,iBAAiB;GAGlC,IAAI,cACF,OAAO,GAAG,QAAQ;EAEtB;CACF,CAAC;CAED,OAAO;AACT"}
@@ -1,4 +1,4 @@
1
- import { MaizzleConfig } from "../types/config.mjs";
1
+ import { MaizzleConfig } from "../types/config.js";
2
2
 
3
3
  //#region src/transformers/replaceStrings.d.ts
4
4
  /**
@@ -13,4 +13,4 @@ import { MaizzleConfig } from "../types/config.mjs";
13
13
  declare function replaceStrings(html: string, config?: MaizzleConfig): string;
14
14
  //#endregion
15
15
  export { replaceStrings };
16
- //# sourceMappingURL=replaceStrings.d.mts.map
16
+ //# sourceMappingURL=replaceStrings.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"replaceStrings.d.ts","names":[],"sources":["../../src/transformers/replaceStrings.ts"],"mappings":";;;;;AAWA;;;;;;;iBAAgB,cAAA,CAAe,IAAA,UAAc,MAAA,GAAQ,aAAkB"}
@@ -13,7 +13,7 @@ function replaceStrings(html, config = {}) {
13
13
  if (!replacements || Object.keys(replacements).length === 0) return html;
14
14
  return Object.entries(replacements).reduce((result, [pattern, replacement]) => result.replace(new RegExp(pattern, "gi"), replacement), html);
15
15
  }
16
-
17
16
  //#endregion
18
17
  export { replaceStrings };
19
- //# sourceMappingURL=replaceStrings.mjs.map
18
+
19
+ //# sourceMappingURL=replaceStrings.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"replaceStrings.js","names":[],"sources":["../../src/transformers/replaceStrings.ts"],"sourcesContent":["import type { MaizzleConfig } from '../types/config.ts'\n\n/**\n * Replace strings transformer.\n *\n * Replaces strings in the HTML using the key-value pairs defined in\n * `config.replaceStrings`. Each key is treated as a regular expression\n * pattern (case-insensitive, global), and the value is the replacement.\n *\n * Character classes must be escaped in keys, e.g. `\\\\s` for `\\s`.\n */\nexport function replaceStrings(html: string, config: MaizzleConfig = {}): string {\n const replacements = config.replaceStrings\n\n if (!replacements || Object.keys(replacements).length === 0) return html\n\n return Object.entries(replacements).reduce(\n (result, [pattern, replacement]) => result.replace(new RegExp(pattern, 'gi'), replacement),\n html,\n )\n}\n"],"mappings":";;;;;;;;;;AAWA,SAAgB,eAAe,MAAc,SAAwB,CAAC,GAAW;CAC/E,MAAM,eAAe,OAAO;CAE5B,IAAI,CAAC,gBAAgB,OAAO,KAAK,YAAY,CAAC,CAAC,WAAW,GAAG,OAAO;CAEpE,OAAO,OAAO,QAAQ,YAAY,CAAC,CAAC,QACjC,QAAQ,CAAC,SAAS,iBAAiB,OAAO,QAAQ,IAAI,OAAO,SAAS,IAAI,GAAG,WAAW,GACzF,IACF;AACF"}
@@ -0,0 +1,37 @@
1
+ import { CssConfig } from "../types/config.js";
2
+ import { ChildNode } from "domhandler";
3
+
4
+ //#region src/transformers/safeSelectors.d.ts
5
+ /**
6
+ * Safe selectors transformer.
7
+ *
8
+ * Replaces unsafe characters (`:`, `/`, `[`, `]`, etc.) in:
9
+ * - CSS selectors inside `<style>` tags
10
+ * - HTML `class` attributes
11
+ *
12
+ * This makes Tailwind utility classes like `sm:text-base` safe for
13
+ * email clients that cannot handle escaped characters in class names.
14
+ *
15
+ * Enabled by default. Disable by setting `css.safe` to `false`.
16
+ * Customize replacements by passing a `Record<string, string>` — user
17
+ * values are merged on top of the defaults.
18
+ *
19
+ * @param html HTML string to transform.
20
+ * @param config CSS config (see {@link CssConfig}).
21
+ * @returns The transformed HTML string.
22
+ *
23
+ * @example
24
+ * import { safeSelectors } from '@maizzle/framework'
25
+ *
26
+ * const out = safeSelectors('<div class="sm:text-base"></div>')
27
+ */
28
+ declare function safeSelectors(html: string, config?: CssConfig): string;
29
+ /**
30
+ * DOM-form of {@link safeSelectors} used by the internal transformer pipeline.
31
+ * Takes a parsed DOM, returns a parsed DOM — avoids redundant
32
+ * serialize/parse round-trips when chained with other transformers.
33
+ */
34
+ declare function safeSelectorsDom(dom: ChildNode[], config?: CssConfig): ChildNode[];
35
+ //#endregion
36
+ export { safeSelectors, safeSelectorsDom };
37
+ //# sourceMappingURL=safeSelectors.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"safeSelectors.d.ts","names":[],"sources":["../../src/transformers/safeSelectors.ts"],"mappings":";;;;;;AA2HA;;;;;;;;AAAkE;AASlE;;;;;;;;;;;;iBATgB,aAAA,CAAc,IAAA,UAAc,MAAA,GAAQ,SAAc;;AASmB;;;;iBAArE,gBAAA,CAAiB,GAAA,EAAK,SAAA,IAAa,MAAA,GAAQ,SAAA,GAAiB,SAAA"}