@maizzle/framework 6.0.0-rc.1 → 6.0.0-rc.11

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 (347) hide show
  1. package/bin/maizzle.mjs +1 -1
  2. package/dist/_virtual/_rolldown/runtime.mjs +32 -0
  3. package/dist/build.mjs +6 -3
  4. package/dist/build.mjs.map +1 -1
  5. package/dist/components/Body.vue +111 -0
  6. package/dist/components/Button.vue +68 -14
  7. package/dist/components/CodeBlock.vue +68 -0
  8. package/dist/components/CodeInline.vue +49 -0
  9. package/dist/components/Column.vue +78 -0
  10. package/dist/components/Container.vue +53 -0
  11. package/dist/components/Divider.vue +28 -0
  12. package/dist/components/Head.vue +30 -0
  13. package/dist/components/Heading.vue +28 -0
  14. package/dist/components/Html.vue +104 -0
  15. package/dist/components/Img.vue +70 -0
  16. package/dist/components/Layout.vue +93 -0
  17. package/dist/components/Link.vue +26 -0
  18. package/dist/components/Markdown.vue +89 -0
  19. package/dist/components/Outlook.vue +36 -0
  20. package/dist/components/Overlap.vue +84 -0
  21. package/dist/components/Preheader.vue +20 -0
  22. package/dist/components/Row.vue +91 -0
  23. package/dist/components/Section.vue +83 -0
  24. package/dist/components/Spacer.vue +50 -7
  25. package/dist/components/Text.vue +29 -0
  26. package/dist/components/Vml.vue +165 -13
  27. package/dist/composables/renderContext.d.mts +5 -0
  28. package/dist/composables/renderContext.d.mts.map +1 -1
  29. package/dist/composables/renderContext.mjs.map +1 -1
  30. package/dist/composables/usePreheader.d.mts +24 -0
  31. package/dist/composables/usePreheader.d.mts.map +1 -0
  32. package/dist/composables/usePreheader.mjs +29 -0
  33. package/dist/composables/usePreheader.mjs.map +1 -0
  34. package/dist/config/defaults.mjs +1 -3
  35. package/dist/config/defaults.mjs.map +1 -1
  36. package/dist/config/index.mjs +7 -0
  37. package/dist/config/index.mjs.map +1 -1
  38. package/dist/index.d.mts +4 -2
  39. package/dist/index.mjs +3 -1
  40. package/dist/node_modules/picomatch/index.mjs +13 -0
  41. package/dist/node_modules/picomatch/index.mjs.map +1 -0
  42. package/dist/node_modules/picomatch/lib/constants.mjs +174 -0
  43. package/dist/node_modules/picomatch/lib/constants.mjs.map +1 -0
  44. package/dist/node_modules/picomatch/lib/parse.mjs +1067 -0
  45. package/dist/node_modules/picomatch/lib/parse.mjs.map +1 -0
  46. package/dist/node_modules/picomatch/lib/picomatch.mjs +304 -0
  47. package/dist/node_modules/picomatch/lib/picomatch.mjs.map +1 -0
  48. package/dist/node_modules/picomatch/lib/scan.mjs +296 -0
  49. package/dist/node_modules/picomatch/lib/scan.mjs.map +1 -0
  50. package/dist/node_modules/picomatch/lib/utils.mjs +53 -0
  51. package/dist/node_modules/picomatch/lib/utils.mjs.map +1 -0
  52. package/dist/plugin.d.mts.map +1 -1
  53. package/dist/plugin.mjs +24 -7
  54. package/dist/plugin.mjs.map +1 -1
  55. package/dist/plugins/postcss/resolveProps.d.mts +8 -0
  56. package/dist/plugins/postcss/resolveProps.d.mts.map +1 -0
  57. package/dist/plugins/postcss/resolveProps.mjs +144 -0
  58. package/dist/plugins/postcss/resolveProps.mjs.map +1 -0
  59. package/dist/plugins/postcss/tailwindCleanup.d.mts.map +1 -1
  60. package/dist/plugins/postcss/tailwindCleanup.mjs +46 -13
  61. package/dist/plugins/postcss/tailwindCleanup.mjs.map +1 -1
  62. package/dist/render/createRenderer.d.mts +8 -3
  63. package/dist/render/createRenderer.d.mts.map +1 -1
  64. package/dist/render/createRenderer.mjs +146 -10
  65. package/dist/render/createRenderer.mjs.map +1 -1
  66. package/dist/render/index.mjs +6 -3
  67. package/dist/render/index.mjs.map +1 -1
  68. package/dist/serve.d.mts.map +1 -1
  69. package/dist/serve.mjs +157 -63
  70. package/dist/serve.mjs.map +1 -1
  71. package/dist/server/compatibility.d.mts +1 -2
  72. package/dist/server/compatibility.d.mts.map +1 -1
  73. package/dist/server/compatibility.mjs +30 -16
  74. package/dist/server/compatibility.mjs.map +1 -1
  75. package/dist/server/email.d.mts +17 -0
  76. package/dist/server/email.d.mts.map +1 -0
  77. package/dist/server/email.mjs +41 -0
  78. package/dist/server/email.mjs.map +1 -0
  79. package/dist/server/linter.d.mts +1 -2
  80. package/dist/server/linter.d.mts.map +1 -1
  81. package/dist/server/linter.mjs +60 -71
  82. package/dist/server/linter.mjs.map +1 -1
  83. package/dist/server/ui/App.vue +206 -70
  84. package/dist/server/ui/components/ui/checkbox/Checkbox.vue +35 -0
  85. package/dist/server/ui/components/ui/checkbox/index.ts +1 -0
  86. package/dist/server/ui/components/ui/command/CommandDialog.vue +1 -1
  87. package/dist/server/ui/components/ui/command/CommandInput.vue +19 -1
  88. package/dist/server/ui/components/ui/command/CommandItem.vue +1 -1
  89. package/dist/server/ui/components/ui/command/CommandList.vue +1 -1
  90. package/dist/server/ui/components/ui/command/CommandShortcut.vue +1 -1
  91. package/dist/server/ui/components/ui/dialog/DialogOverlay.vue +9 -1
  92. package/dist/server/ui/components/ui/dropdown-menu/DropdownMenuItem.vue +1 -1
  93. package/dist/server/ui/components/ui/scroll-area/ScrollBar.vue +1 -1
  94. package/dist/server/ui/components/ui/sheet/SheetContent.vue +1 -1
  95. package/dist/server/ui/components/ui/sheet/SheetOverlay.vue +9 -1
  96. package/dist/server/ui/components/ui/sidebar/Sidebar.vue +8 -1
  97. package/dist/server/ui/components/ui/sidebar/SidebarProvider.vue +1 -1
  98. package/dist/server/ui/components/ui/sidebar/SidebarTrigger.vue +5 -4
  99. package/dist/server/ui/components/ui/tags-input/TagsInput.vue +26 -0
  100. package/dist/server/ui/components/ui/tags-input/TagsInputInput.vue +17 -0
  101. package/dist/server/ui/components/ui/tags-input/TagsInputItem.vue +19 -0
  102. package/dist/server/ui/components/ui/tags-input/TagsInputItemDelete.vue +22 -0
  103. package/dist/server/ui/components/ui/tags-input/TagsInputItemText.vue +17 -0
  104. package/dist/server/ui/components/ui/tags-input/index.ts +5 -0
  105. package/dist/server/ui/components/ui/toggle/index.ts +3 -3
  106. package/dist/server/ui/components/ui/toggle-group/ToggleGroup.vue +1 -1
  107. package/dist/server/ui/components/ui/toggle-group/ToggleGroupItem.vue +2 -2
  108. package/dist/server/ui/main.css +20 -20
  109. package/dist/server/ui/pages/Home.vue +12 -5
  110. package/dist/server/ui/pages/Preview.vue +506 -216
  111. package/dist/transformers/entities.d.mts.map +1 -1
  112. package/dist/transformers/entities.mjs +3 -0
  113. package/dist/transformers/entities.mjs.map +1 -1
  114. package/dist/transformers/filters/defaults.d.mts +6 -0
  115. package/dist/transformers/filters/defaults.d.mts.map +1 -0
  116. package/dist/transformers/filters/defaults.mjs +78 -0
  117. package/dist/transformers/filters/defaults.mjs.map +1 -0
  118. package/dist/transformers/filters/index.d.mts +22 -0
  119. package/dist/transformers/filters/index.d.mts.map +1 -0
  120. package/dist/transformers/filters/index.mjs +67 -0
  121. package/dist/transformers/filters/index.mjs.map +1 -0
  122. package/dist/transformers/index.d.mts +11 -9
  123. package/dist/transformers/index.d.mts.map +1 -1
  124. package/dist/transformers/index.mjs +19 -11
  125. package/dist/transformers/index.mjs.map +1 -1
  126. package/dist/transformers/inlineCSS.d.mts +1 -14
  127. package/dist/transformers/inlineCSS.d.mts.map +1 -1
  128. package/dist/transformers/inlineCSS.mjs +32 -36
  129. package/dist/transformers/inlineCSS.mjs.map +1 -1
  130. package/dist/transformers/purgeCSS.d.mts.map +1 -1
  131. package/dist/transformers/purgeCSS.mjs +67 -1
  132. package/dist/transformers/purgeCSS.mjs.map +1 -1
  133. package/dist/transformers/sixHex.d.mts +16 -0
  134. package/dist/transformers/sixHex.d.mts.map +1 -0
  135. package/dist/transformers/sixHex.mjs +30 -0
  136. package/dist/transformers/sixHex.mjs.map +1 -0
  137. package/dist/transformers/tailwindcss.d.mts +6 -2
  138. package/dist/transformers/tailwindcss.d.mts.map +1 -1
  139. package/dist/transformers/tailwindcss.mjs +54 -30
  140. package/dist/transformers/tailwindcss.mjs.map +1 -1
  141. package/dist/types/config.d.mts +436 -23
  142. package/dist/types/config.d.mts.map +1 -1
  143. package/dist/types/index.d.mts +2 -2
  144. package/dist/utils/ast/serializer.d.mts +3 -2
  145. package/dist/utils/ast/serializer.d.mts.map +1 -1
  146. package/dist/utils/ast/serializer.mjs +24 -0
  147. package/dist/utils/ast/serializer.mjs.map +1 -1
  148. package/dist/utils/detect.d.mts +5 -0
  149. package/dist/utils/detect.d.mts.map +1 -0
  150. package/dist/utils/detect.mjs +11 -0
  151. package/dist/utils/detect.mjs.map +1 -0
  152. package/node_modules/@clack/core/CHANGELOG.md +87 -4
  153. package/node_modules/@clack/core/README.md +1 -1
  154. package/node_modules/@clack/core/dist/index.d.mts +186 -48
  155. package/node_modules/@clack/core/dist/index.mjs +10 -14
  156. package/node_modules/@clack/core/dist/index.mjs.map +1 -1
  157. package/node_modules/@clack/core/package.json +7 -9
  158. package/node_modules/@clack/prompts/CHANGELOG.md +171 -7
  159. package/node_modules/@clack/prompts/README.md +66 -3
  160. package/node_modules/@clack/prompts/dist/index.d.mts +302 -76
  161. package/node_modules/@clack/prompts/dist/index.mjs +134 -84
  162. package/node_modules/@clack/prompts/dist/index.mjs.map +1 -1
  163. package/node_modules/@clack/prompts/package.json +14 -10
  164. package/node_modules/citty/LICENSE +0 -15
  165. package/node_modules/citty/README.md +166 -69
  166. package/node_modules/citty/dist/index.d.mts +88 -56
  167. package/node_modules/citty/dist/index.mjs +399 -437
  168. package/node_modules/citty/package.json +28 -35
  169. package/node_modules/giget/README.md +59 -11
  170. package/node_modules/giget/dist/THIRD-PARTY-LICENSES.md +205 -0
  171. package/node_modules/giget/dist/_chunks/giget.mjs +508 -0
  172. package/node_modules/giget/dist/_chunks/libs/citty.mjs +269 -0
  173. package/node_modules/giget/dist/_chunks/libs/nypm.d.mts +1 -0
  174. package/node_modules/giget/dist/_chunks/libs/nypm.mjs +669 -0
  175. package/node_modules/giget/dist/_chunks/libs/tar.mjs +2931 -0
  176. package/node_modules/giget/dist/_chunks/rolldown-runtime.mjs +14 -0
  177. package/node_modules/giget/dist/cli.d.mts +1 -0
  178. package/node_modules/giget/dist/cli.mjs +89 -111
  179. package/node_modules/giget/dist/index.d.mts +46 -35
  180. package/node_modules/giget/dist/index.mjs +2 -22
  181. package/node_modules/giget/package.json +32 -45
  182. package/node_modules/maizzle/README.md +140 -0
  183. package/node_modules/maizzle/bin/maizzle.mjs +5 -0
  184. package/node_modules/maizzle/dist/commands/new.d.mts +7 -0
  185. package/node_modules/maizzle/dist/commands/new.mjs +253 -0
  186. package/node_modules/{@maizzle/cli → maizzle}/dist/index.d.mts +1 -1
  187. package/node_modules/maizzle/dist/index.mjs +44 -0
  188. package/node_modules/{commander → maizzle/node_modules/commander}/Readme.md +94 -67
  189. package/node_modules/{commander → maizzle/node_modules/commander}/lib/argument.js +5 -4
  190. package/node_modules/{commander → maizzle/node_modules/commander}/lib/command.js +154 -39
  191. package/node_modules/{commander → maizzle/node_modules/commander}/lib/help.js +77 -39
  192. package/node_modules/{commander → maizzle/node_modules/commander}/lib/option.js +16 -3
  193. package/node_modules/{commander → maizzle/node_modules/commander}/package-support.json +4 -1
  194. package/node_modules/{commander → maizzle/node_modules/commander}/package.json +8 -8
  195. package/node_modules/{commander → maizzle/node_modules/commander}/typings/index.d.ts +71 -3
  196. package/node_modules/{@maizzle/cli → maizzle}/package.json +14 -12
  197. package/node_modules/tinyexec/README.md +49 -3
  198. package/node_modules/tinyexec/dist/main.d.mts +25 -14
  199. package/node_modules/tinyexec/dist/main.mjs +148 -100
  200. package/node_modules/tinyexec/package.json +9 -8
  201. package/package.json +17 -13
  202. package/dist/server/ui/components/ui/resizable/ResizableHandle.vue +0 -30
  203. package/dist/server/ui/components/ui/resizable/ResizablePanel.vue +0 -21
  204. package/dist/server/ui/components/ui/resizable/ResizablePanelGroup.vue +0 -25
  205. package/dist/server/ui/components/ui/resizable/index.ts +0 -3
  206. package/node_modules/@clack/core/dist/index.cjs +0 -15
  207. package/node_modules/@clack/core/dist/index.cjs.map +0 -1
  208. package/node_modules/@clack/core/dist/index.d.cts +0 -211
  209. package/node_modules/@clack/core/dist/index.d.ts +0 -211
  210. package/node_modules/@clack/prompts/dist/index.cjs +0 -87
  211. package/node_modules/@clack/prompts/dist/index.cjs.map +0 -1
  212. package/node_modules/@clack/prompts/dist/index.d.cts +0 -165
  213. package/node_modules/@clack/prompts/dist/index.d.ts +0 -165
  214. package/node_modules/@maizzle/cli/README.md +0 -58
  215. package/node_modules/@maizzle/cli/dist/index.mjs +0 -42
  216. package/node_modules/citty/dist/index.cjs +0 -475
  217. package/node_modules/citty/dist/index.d.cts +0 -80
  218. package/node_modules/citty/dist/index.d.ts +0 -80
  219. package/node_modules/consola/LICENSE +0 -47
  220. package/node_modules/consola/README.md +0 -352
  221. package/node_modules/consola/basic.d.ts +0 -1
  222. package/node_modules/consola/browser.d.ts +0 -1
  223. package/node_modules/consola/core.d.ts +0 -1
  224. package/node_modules/consola/dist/basic.cjs +0 -32
  225. package/node_modules/consola/dist/basic.d.cts +0 -23
  226. package/node_modules/consola/dist/basic.d.mts +0 -21
  227. package/node_modules/consola/dist/basic.d.ts +0 -23
  228. package/node_modules/consola/dist/basic.mjs +0 -24
  229. package/node_modules/consola/dist/browser.cjs +0 -84
  230. package/node_modules/consola/dist/browser.d.cts +0 -23
  231. package/node_modules/consola/dist/browser.d.mts +0 -21
  232. package/node_modules/consola/dist/browser.d.ts +0 -23
  233. package/node_modules/consola/dist/browser.mjs +0 -76
  234. package/node_modules/consola/dist/chunks/prompt.cjs +0 -288
  235. package/node_modules/consola/dist/chunks/prompt.mjs +0 -280
  236. package/node_modules/consola/dist/core.cjs +0 -517
  237. package/node_modules/consola/dist/core.d.cts +0 -459
  238. package/node_modules/consola/dist/core.d.mts +0 -459
  239. package/node_modules/consola/dist/core.d.ts +0 -459
  240. package/node_modules/consola/dist/core.mjs +0 -512
  241. package/node_modules/consola/dist/index.cjs +0 -663
  242. package/node_modules/consola/dist/index.d.cts +0 -24
  243. package/node_modules/consola/dist/index.d.mts +0 -22
  244. package/node_modules/consola/dist/index.d.ts +0 -24
  245. package/node_modules/consola/dist/index.mjs +0 -651
  246. package/node_modules/consola/dist/shared/consola.DCGIlDNP.cjs +0 -75
  247. package/node_modules/consola/dist/shared/consola.DRwqZj3T.mjs +0 -72
  248. package/node_modules/consola/dist/shared/consola.DXBYu-KD.mjs +0 -288
  249. package/node_modules/consola/dist/shared/consola.DwRq1yyg.cjs +0 -312
  250. package/node_modules/consola/dist/utils.cjs +0 -64
  251. package/node_modules/consola/dist/utils.d.cts +0 -286
  252. package/node_modules/consola/dist/utils.d.mts +0 -286
  253. package/node_modules/consola/dist/utils.d.ts +0 -286
  254. package/node_modules/consola/dist/utils.mjs +0 -54
  255. package/node_modules/consola/lib/index.cjs +0 -10
  256. package/node_modules/consola/package.json +0 -136
  257. package/node_modules/consola/utils.d.ts +0 -1
  258. package/node_modules/create-maizzle/README.md +0 -86
  259. package/node_modules/create-maizzle/bin/create-maizzle.mjs +0 -4
  260. package/node_modules/create-maizzle/node_modules/@clack/core/CHANGELOG.md +0 -340
  261. package/node_modules/create-maizzle/node_modules/@clack/core/LICENSE +0 -9
  262. package/node_modules/create-maizzle/node_modules/@clack/core/README.md +0 -22
  263. package/node_modules/create-maizzle/node_modules/@clack/core/dist/index.d.mts +0 -349
  264. package/node_modules/create-maizzle/node_modules/@clack/core/dist/index.mjs +0 -11
  265. package/node_modules/create-maizzle/node_modules/@clack/core/dist/index.mjs.map +0 -1
  266. package/node_modules/create-maizzle/node_modules/@clack/core/package.json +0 -60
  267. package/node_modules/create-maizzle/node_modules/@clack/prompts/CHANGELOG.md +0 -576
  268. package/node_modules/create-maizzle/node_modules/@clack/prompts/LICENSE +0 -9
  269. package/node_modules/create-maizzle/node_modules/@clack/prompts/README.md +0 -270
  270. package/node_modules/create-maizzle/node_modules/@clack/prompts/dist/index.d.mts +0 -391
  271. package/node_modules/create-maizzle/node_modules/@clack/prompts/dist/index.mjs +0 -137
  272. package/node_modules/create-maizzle/node_modules/@clack/prompts/dist/index.mjs.map +0 -1
  273. package/node_modules/create-maizzle/node_modules/@clack/prompts/package.json +0 -65
  274. package/node_modules/create-maizzle/package.json +0 -47
  275. package/node_modules/create-maizzle/src/index.js +0 -242
  276. package/node_modules/defu/LICENSE +0 -21
  277. package/node_modules/defu/README.md +0 -171
  278. package/node_modules/defu/dist/defu.cjs +0 -77
  279. package/node_modules/defu/dist/defu.d.cts +0 -31
  280. package/node_modules/defu/dist/defu.d.mts +0 -29
  281. package/node_modules/defu/dist/defu.d.ts +0 -31
  282. package/node_modules/defu/dist/defu.mjs +0 -69
  283. package/node_modules/defu/lib/defu.cjs +0 -10
  284. package/node_modules/defu/lib/defu.d.cts +0 -12
  285. package/node_modules/defu/package.json +0 -48
  286. package/node_modules/giget/dist/shared/giget.OCaTp9b-.mjs +0 -468
  287. package/node_modules/node-fetch-native/LICENSE +0 -114
  288. package/node_modules/node-fetch-native/README.md +0 -225
  289. package/node_modules/node-fetch-native/dist/chunks/multipart-parser.cjs +0 -2
  290. package/node_modules/node-fetch-native/dist/chunks/multipart-parser.mjs +0 -2
  291. package/node_modules/node-fetch-native/dist/index.cjs +0 -1
  292. package/node_modules/node-fetch-native/dist/index.mjs +0 -1
  293. package/node_modules/node-fetch-native/dist/native.cjs +0 -1
  294. package/node_modules/node-fetch-native/dist/native.mjs +0 -1
  295. package/node_modules/node-fetch-native/dist/node.cjs +0 -19
  296. package/node_modules/node-fetch-native/dist/node.mjs +0 -19
  297. package/node_modules/node-fetch-native/dist/polyfill.cjs +0 -1
  298. package/node_modules/node-fetch-native/dist/polyfill.mjs +0 -1
  299. package/node_modules/node-fetch-native/dist/proxy-stub.cjs +0 -1
  300. package/node_modules/node-fetch-native/dist/proxy-stub.mjs +0 -1
  301. package/node_modules/node-fetch-native/dist/proxy.cjs +0 -58
  302. package/node_modules/node-fetch-native/dist/shared/node-fetch-native.DfbY2q-x.mjs +0 -1
  303. package/node_modules/node-fetch-native/dist/shared/node-fetch-native.DhEqb06g.cjs +0 -1
  304. package/node_modules/node-fetch-native/index.d.ts +0 -1
  305. package/node_modules/node-fetch-native/lib/empty.cjs +0 -0
  306. package/node_modules/node-fetch-native/lib/empty.mjs +0 -0
  307. package/node_modules/node-fetch-native/lib/index.cjs +0 -11
  308. package/node_modules/node-fetch-native/lib/index.d.cts +0 -10
  309. package/node_modules/node-fetch-native/lib/index.d.mts +0 -10
  310. package/node_modules/node-fetch-native/lib/index.d.ts +0 -10
  311. package/node_modules/node-fetch-native/lib/native.cjs +0 -11
  312. package/node_modules/node-fetch-native/lib/polyfill.d.cts +0 -1
  313. package/node_modules/node-fetch-native/lib/polyfill.d.mts +0 -1
  314. package/node_modules/node-fetch-native/lib/polyfill.d.ts +0 -1
  315. package/node_modules/node-fetch-native/lib/proxy.d.ts +0 -32
  316. package/node_modules/node-fetch-native/node.d.ts +0 -1
  317. package/node_modules/node-fetch-native/package.json +0 -138
  318. package/node_modules/node-fetch-native/polyfill.d.ts +0 -1
  319. package/node_modules/node-fetch-native/proxy.d.ts +0 -1
  320. package/node_modules/nypm/node_modules/citty/LICENSE +0 -21
  321. package/node_modules/nypm/node_modules/citty/README.md +0 -231
  322. package/node_modules/nypm/node_modules/citty/dist/index.d.mts +0 -112
  323. package/node_modules/nypm/node_modules/citty/dist/index.mjs +0 -425
  324. package/node_modules/nypm/node_modules/citty/package.json +0 -42
  325. /package/node_modules/{nypm/node_modules/citty → citty}/dist/THIRD-PARTY-LICENSES.md +0 -0
  326. /package/node_modules/{nypm/node_modules/citty → citty}/dist/_chunks/libs/scule.mjs +0 -0
  327. /package/node_modules/{@maizzle/cli → maizzle}/LICENSE +0 -0
  328. /package/node_modules/{@maizzle/cli → maizzle}/dist/commands/make/component.d.mts +0 -0
  329. /package/node_modules/{@maizzle/cli → maizzle}/dist/commands/make/component.mjs +0 -0
  330. /package/node_modules/{@maizzle/cli → maizzle}/dist/commands/make/config.d.mts +0 -0
  331. /package/node_modules/{@maizzle/cli → maizzle}/dist/commands/make/config.mjs +0 -0
  332. /package/node_modules/{@maizzle/cli → maizzle}/dist/commands/make/layout.d.mts +0 -0
  333. /package/node_modules/{@maizzle/cli → maizzle}/dist/commands/make/layout.mjs +0 -0
  334. /package/node_modules/{@maizzle/cli → maizzle}/dist/commands/make/scaffold.d.mts +0 -0
  335. /package/node_modules/{@maizzle/cli → maizzle}/dist/commands/make/scaffold.mjs +0 -0
  336. /package/node_modules/{@maizzle/cli → maizzle}/dist/commands/make/stubs/component.vue +0 -0
  337. /package/node_modules/{@maizzle/cli → maizzle}/dist/commands/make/stubs/config.ts +0 -0
  338. /package/node_modules/{@maizzle/cli → maizzle}/dist/commands/make/stubs/layout.vue +0 -0
  339. /package/node_modules/{@maizzle/cli → maizzle}/dist/commands/make/stubs/template.vue +0 -0
  340. /package/node_modules/{@maizzle/cli → maizzle}/dist/commands/make/template.d.mts +0 -0
  341. /package/node_modules/{@maizzle/cli → maizzle}/dist/commands/make/template.mjs +0 -0
  342. /package/node_modules/{commander → maizzle/node_modules/commander}/LICENSE +0 -0
  343. /package/node_modules/{commander → maizzle/node_modules/commander}/esm.mjs +0 -0
  344. /package/node_modules/{commander → maizzle/node_modules/commander}/index.js +0 -0
  345. /package/node_modules/{commander → maizzle/node_modules/commander}/lib/error.js +0 -0
  346. /package/node_modules/{commander → maizzle/node_modules/commander}/lib/suggestSimilar.js +0 -0
  347. /package/node_modules/{commander → maizzle/node_modules/commander}/typings/esm.d.mts +0 -0
@@ -1 +1 @@
1
- {"version":3,"file":"entities.d.mts","names":[],"sources":["../../src/transformers/entities.ts"],"mappings":";;;;iBA2BgB,QAAA,CAAS,GAAA,EAAK,SAAA,IAAa,MAAA,GAAQ,cAAA,GAAwB,SAAA"}
1
+ {"version":3,"file":"entities.d.mts","names":[],"sources":["../../src/transformers/entities.ts"],"mappings":";;;;iBA8BgB,QAAA,CAAS,GAAA,EAAK,SAAA,IAAa,MAAA,GAAQ,cAAA,GAAwB,SAAA"}
@@ -7,7 +7,10 @@ const DEFAULT_ENTITIES = {
7
7
  "‍": "‍",
8
8
  "‌": "‌",
9
9
  "\xA0": " ",
10
+ "­": "­",
10
11
  "​": "​",
12
+ " ": " ",
13
+ "͏": "͏",
11
14
  " ": " ",
12
15
  "\u2028": "&LineSeparator;",
13
16
  "\u2029": "&ParagraphSeparator;",
@@ -1 +1 @@
1
- {"version":3,"file":"entities.mjs","names":["merge"],"sources":["../../src/transformers/entities.ts"],"sourcesContent":["import { defu as merge } from 'defu'\nimport { walk } from '../utils/ast/index.ts'\nimport type { ChildNode } from 'domhandler'\nimport type { EntitiesConfig } from '../types/index.ts'\n\nconst DEFAULT_ENTITIES: Record<string, string> = {\n '\\u200D': '&zwj;',\n '\\u200C': '&zwnj;',\n '\\u00A0': '&nbsp;',\n '\\u200B': '&#8203;',\n '\\u2003': '&emsp;',\n '\\u2028': '&LineSeparator;',\n '\\u2029': '&ParagraphSeparator;',\n '\\u00B7': '&middot;',\n '\\u2013': '&ndash;',\n '\\u2014': '&mdash;',\n '\\u2018': '&lsquo;',\n '\\u2019': '&rsquo;',\n '\\u201C': '&ldquo;',\n '\\u201D': '&rdquo;',\n '\\u00AB': '&laquo;',\n '\\u00BB': '&raquo;',\n '\\u2022': '&bull;',\n '\\u2039': '&lsaquo;',\n '\\u203A': '&rsaquo;'\n}\n\nexport function entities(dom: ChildNode[], config: EntitiesConfig = true): ChildNode[] {\n if (!config) return dom\n\n const map = typeof config === 'object'\n ? merge(config as Record<string, string>, DEFAULT_ENTITIES)\n : DEFAULT_ENTITIES\n\n walk(dom, (node) => {\n if (node.type === 'text') {\n for (const [char, entity] of Object.entries(map)) {\n node.data = node.data.split(char).join(entity)\n }\n }\n })\n\n return dom\n}\n"],"mappings":";;;;;AAKA,MAAM,mBAA2C;CAC/C,KAAU;CACV,KAAU;CACV,QAAU;CACV,KAAU;CACV,KAAU;CACV,UAAU;CACV,UAAU;CACV,KAAU;CACV,KAAU;CACV,KAAU;CACV,KAAU;CACV,KAAU;CACV,KAAU;CACV,KAAU;CACV,KAAU;CACV,KAAU;CACV,KAAU;CACV,KAAU;CACV,KAAU;CACX;AAED,SAAgB,SAAS,KAAkB,SAAyB,MAAmB;AACrF,KAAI,CAAC,OAAQ,QAAO;CAEpB,MAAM,MAAM,OAAO,WAAW,WAC1BA,KAAM,QAAkC,iBAAiB,GACzD;AAEJ,MAAK,MAAM,SAAS;AAClB,MAAI,KAAK,SAAS,OAChB,MAAK,MAAM,CAAC,MAAM,WAAW,OAAO,QAAQ,IAAI,CAC9C,MAAK,OAAO,KAAK,KAAK,MAAM,KAAK,CAAC,KAAK,OAAO;GAGlD;AAEF,QAAO"}
1
+ {"version":3,"file":"entities.mjs","names":["merge"],"sources":["../../src/transformers/entities.ts"],"sourcesContent":["import { defu as merge } from 'defu'\nimport { walk } from '../utils/ast/index.ts'\nimport type { ChildNode } from 'domhandler'\nimport type { EntitiesConfig } from '../types/index.ts'\n\nconst DEFAULT_ENTITIES: Record<string, string> = {\n '\\u200D': '&zwj;',\n '\\u200C': '&zwnj;',\n '\\u00A0': '&nbsp;',\n '\\u00AD': '&shy;',\n '\\u200B': '&#8203;',\n '\\u2007': '&#8199;',\n '\\u034F': '&#847;',\n '\\u2003': '&emsp;',\n '\\u2028': '&LineSeparator;',\n '\\u2029': '&ParagraphSeparator;',\n '\\u00B7': '&middot;',\n '\\u2013': '&ndash;',\n '\\u2014': '&mdash;',\n '\\u2018': '&lsquo;',\n '\\u2019': '&rsquo;',\n '\\u201C': '&ldquo;',\n '\\u201D': '&rdquo;',\n '\\u00AB': '&laquo;',\n '\\u00BB': '&raquo;',\n '\\u2022': '&bull;',\n '\\u2039': '&lsaquo;',\n '\\u203A': '&rsaquo;'\n}\n\nexport function entities(dom: ChildNode[], config: EntitiesConfig = true): ChildNode[] {\n if (!config) return dom\n\n const map = typeof config === 'object'\n ? merge(config as Record<string, string>, DEFAULT_ENTITIES)\n : DEFAULT_ENTITIES\n\n walk(dom, (node) => {\n if (node.type === 'text') {\n for (const [char, entity] of Object.entries(map)) {\n node.data = node.data.split(char).join(entity)\n }\n }\n })\n\n return dom\n}\n"],"mappings":";;;;;AAKA,MAAM,mBAA2C;CAC/C,KAAU;CACV,KAAU;CACV,QAAU;CACV,KAAU;CACV,KAAU;CACV,KAAU;CACV,KAAU;CACV,KAAU;CACV,UAAU;CACV,UAAU;CACV,KAAU;CACV,KAAU;CACV,KAAU;CACV,KAAU;CACV,KAAU;CACV,KAAU;CACV,KAAU;CACV,KAAU;CACV,KAAU;CACV,KAAU;CACV,KAAU;CACV,KAAU;CACX;AAED,SAAgB,SAAS,KAAkB,SAAyB,MAAmB;AACrF,KAAI,CAAC,OAAQ,QAAO;CAEpB,MAAM,MAAM,OAAO,WAAW,WAC1BA,KAAM,QAAkC,iBAAiB,GACzD;AAEJ,MAAK,MAAM,SAAS;AAClB,MAAI,KAAK,SAAS,OAChB,MAAK,MAAM,CAAC,MAAM,WAAW,OAAO,QAAQ,IAAI,CAC9C,MAAK,OAAO,KAAK,KAAK,MAAM,KAAK,CAAC,KAAK,OAAO;GAGlD;AAEF,QAAO"}
@@ -0,0 +1,6 @@
1
+ //#region src/transformers/filters/defaults.d.ts
2
+ type FilterFunction = (str: string, value: string) => string;
3
+ declare const defaults: Record<string, FilterFunction>;
4
+ //#endregion
5
+ export { FilterFunction, defaults };
6
+ //# sourceMappingURL=defaults.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"defaults.d.mts","names":[],"sources":["../../../src/transformers/filters/defaults.ts"],"mappings":";KAAY,cAAA,IAAkB,GAAA,UAAa,KAAA;AAAA,cAgB9B,QAAA,EAAU,MAAA,SAAe,cAAA"}
@@ -0,0 +1,78 @@
1
+ //#region src/transformers/filters/defaults.ts
2
+ const escapeMap = {
3
+ "\"": "&#34;",
4
+ "&": "&amp;",
5
+ "'": "&#39;",
6
+ "<": "&lt;",
7
+ ">": "&gt;"
8
+ };
9
+ const escapeRegex = /["&'<>]/g;
10
+ function escapeHtml(str) {
11
+ return str.replace(escapeRegex, (ch) => escapeMap[ch]);
12
+ }
13
+ const defaults = {
14
+ append: (str, value) => str + value,
15
+ prepend: (str, value) => value + str,
16
+ uppercase: (str) => str.toUpperCase(),
17
+ lowercase: (str) => str.toLowerCase(),
18
+ capitalize: (str) => str.charAt(0).toUpperCase() + str.slice(1),
19
+ ceil: (str) => String(Math.ceil(Number.parseFloat(str))),
20
+ floor: (str) => String(Math.floor(Number.parseFloat(str))),
21
+ round: (str) => String(Math.round(Number.parseFloat(str))),
22
+ escape: (str) => escapeHtml(str),
23
+ "escape-once": (str) => {
24
+ return escapeHtml(str.replace(/&amp;/g, "&").replace(/&lt;/g, "<").replace(/&gt;/g, ">").replace(/&#34;/g, "\"").replace(/&quot;/g, "\"").replace(/&#39;/g, "'").replace(/&apos;/g, "'"));
25
+ },
26
+ lstrip: (str) => str.trimStart(),
27
+ rstrip: (str) => str.trimEnd(),
28
+ trim: (str) => str.trim(),
29
+ minus: (str, value) => String(Number.parseFloat(str) - Number.parseFloat(value)),
30
+ plus: (str, value) => String(Number.parseFloat(str) + Number.parseFloat(value)),
31
+ multiply: (str, value) => String(Number.parseFloat(str) * Number.parseFloat(value)),
32
+ times: (str, value) => String(Number.parseFloat(str) * Number.parseFloat(value)),
33
+ "divide-by": (str, value) => String(Number.parseFloat(str) / Number.parseFloat(value)),
34
+ divide: (str, value) => String(Number.parseFloat(str) / Number.parseFloat(value)),
35
+ modulo: (str, value) => String(Number.parseFloat(str) % Number.parseFloat(value)),
36
+ "newline-to-br": (str) => str.replace(/\n/g, "<br>"),
37
+ "strip-newlines": (str) => str.replace(/\n/g, ""),
38
+ remove: (str, value) => str.split(value).join(""),
39
+ "remove-first": (str, value) => {
40
+ const i = str.indexOf(value);
41
+ return i === -1 ? str : str.slice(0, i) + str.slice(i + value.length);
42
+ },
43
+ replace: (str, value) => {
44
+ const [search = "", replacement = ""] = value.split("|");
45
+ return str.split(search).join(replacement);
46
+ },
47
+ "replace-first": (str, value) => {
48
+ const [search = "", replacement = ""] = value.split("|");
49
+ const i = str.indexOf(search);
50
+ return i === -1 ? str : str.slice(0, i) + replacement + str.slice(i + search.length);
51
+ },
52
+ size: (str) => String(str.length),
53
+ slice: (str, value) => {
54
+ const args = value.split(",").map((s) => Number.parseInt(s.trim(), 10));
55
+ return str.slice(args[0], args[1]);
56
+ },
57
+ truncate: (str, value) => {
58
+ const commaIndex = value.indexOf(",");
59
+ const length = Number.parseInt(commaIndex === -1 ? value : value.slice(0, commaIndex), 10);
60
+ const ellipsis = commaIndex === -1 ? "..." : value.slice(commaIndex + 1);
61
+ if (str.length <= length) return str;
62
+ return str.slice(0, length) + ellipsis;
63
+ },
64
+ "truncate-words": (str, value) => {
65
+ const commaIndex = value.indexOf(",");
66
+ const count = Number.parseInt(commaIndex === -1 ? value : value.slice(0, commaIndex), 10);
67
+ const ellipsis = commaIndex === -1 ? "..." : value.slice(commaIndex + 1);
68
+ const words = str.split(/\s+/).filter(Boolean);
69
+ if (words.length <= count) return str;
70
+ return words.slice(0, count).join(" ") + ellipsis;
71
+ },
72
+ "url-decode": (str) => decodeURIComponent(str.replace(/\+/g, " ")),
73
+ "url-encode": (str) => encodeURIComponent(str)
74
+ };
75
+
76
+ //#endregion
77
+ export { defaults };
78
+ //# sourceMappingURL=defaults.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"defaults.mjs","names":[],"sources":["../../../src/transformers/filters/defaults.ts"],"sourcesContent":["export type FilterFunction = (str: string, value: string) => string\n\nconst escapeMap: Record<string, string> = {\n '\"': '&#34;',\n '&': '&amp;',\n \"'\": '&#39;',\n '<': '&lt;',\n '>': '&gt;',\n}\n\nconst escapeRegex = /[\"&'<>]/g\n\nfunction escapeHtml(str: string): string {\n return str.replace(escapeRegex, ch => escapeMap[ch])\n}\n\nexport const defaults: Record<string, FilterFunction> = {\n append: (str, value) => str + value,\n prepend: (str, value) => value + str,\n uppercase: str => str.toUpperCase(),\n lowercase: str => str.toLowerCase(),\n capitalize: str => str.charAt(0).toUpperCase() + str.slice(1),\n ceil: str => String(Math.ceil(Number.parseFloat(str))),\n floor: str => String(Math.floor(Number.parseFloat(str))),\n round: str => String(Math.round(Number.parseFloat(str))),\n escape: str => escapeHtml(str),\n 'escape-once': str => {\n const decoded = str\n .replace(/&amp;/g, '&')\n .replace(/&lt;/g, '<')\n .replace(/&gt;/g, '>')\n .replace(/&#34;/g, '\"')\n .replace(/&quot;/g, '\"')\n .replace(/&#39;/g, \"'\")\n .replace(/&apos;/g, \"'\")\n\n return escapeHtml(decoded)\n },\n lstrip: str => str.trimStart(),\n rstrip: str => str.trimEnd(),\n trim: str => str.trim(),\n minus: (str, value) => String(Number.parseFloat(str) - Number.parseFloat(value)),\n plus: (str, value) => String(Number.parseFloat(str) + Number.parseFloat(value)),\n multiply: (str, value) => String(Number.parseFloat(str) * Number.parseFloat(value)),\n times: (str, value) => String(Number.parseFloat(str) * Number.parseFloat(value)),\n 'divide-by': (str, value) => String(Number.parseFloat(str) / Number.parseFloat(value)),\n divide: (str, value) => String(Number.parseFloat(str) / Number.parseFloat(value)),\n modulo: (str, value) => String(Number.parseFloat(str) % Number.parseFloat(value)),\n 'newline-to-br': str => str.replace(/\\n/g, '<br>'),\n 'strip-newlines': str => str.replace(/\\n/g, ''),\n remove: (str, value) => str.split(value).join(''),\n 'remove-first': (str, value) => {\n const i = str.indexOf(value)\n return i === -1 ? str : str.slice(0, i) + str.slice(i + value.length)\n },\n replace: (str, value) => {\n const [search = '', replacement = ''] = value.split('|')\n return str.split(search).join(replacement)\n },\n 'replace-first': (str, value) => {\n const [search = '', replacement = ''] = value.split('|')\n const i = str.indexOf(search)\n return i === -1 ? str : str.slice(0, i) + replacement + str.slice(i + search.length)\n },\n size: str => String(str.length),\n slice: (str, value) => {\n const args = value.split(',').map(s => Number.parseInt(s.trim(), 10))\n return str.slice(args[0], args[1])\n },\n truncate: (str, value) => {\n const commaIndex = value.indexOf(',')\n const length = Number.parseInt(commaIndex === -1 ? value : value.slice(0, commaIndex), 10)\n const ellipsis = commaIndex === -1 ? '...' : value.slice(commaIndex + 1)\n\n if (str.length <= length) return str\n\n return str.slice(0, length) + ellipsis\n },\n 'truncate-words': (str, value) => {\n const commaIndex = value.indexOf(',')\n const count = Number.parseInt(commaIndex === -1 ? value : value.slice(0, commaIndex), 10)\n const ellipsis = commaIndex === -1 ? '...' : value.slice(commaIndex + 1)\n const words = str.split(/\\s+/).filter(Boolean)\n\n if (words.length <= count) return str\n\n return words.slice(0, count).join(' ') + ellipsis\n },\n 'url-decode': str => decodeURIComponent(str.replace(/\\+/g, ' ')),\n 'url-encode': str => encodeURIComponent(str),\n}\n"],"mappings":";AAEA,MAAM,YAAoC;CACxC,MAAK;CACL,KAAK;CACL,KAAK;CACL,KAAK;CACL,KAAK;CACN;AAED,MAAM,cAAc;AAEpB,SAAS,WAAW,KAAqB;AACvC,QAAO,IAAI,QAAQ,cAAa,OAAM,UAAU,IAAI;;AAGtD,MAAa,WAA2C;CACtD,SAAS,KAAK,UAAU,MAAM;CAC9B,UAAU,KAAK,UAAU,QAAQ;CACjC,YAAW,QAAO,IAAI,aAAa;CACnC,YAAW,QAAO,IAAI,aAAa;CACnC,aAAY,QAAO,IAAI,OAAO,EAAE,CAAC,aAAa,GAAG,IAAI,MAAM,EAAE;CAC7D,OAAM,QAAO,OAAO,KAAK,KAAK,OAAO,WAAW,IAAI,CAAC,CAAC;CACtD,QAAO,QAAO,OAAO,KAAK,MAAM,OAAO,WAAW,IAAI,CAAC,CAAC;CACxD,QAAO,QAAO,OAAO,KAAK,MAAM,OAAO,WAAW,IAAI,CAAC,CAAC;CACxD,SAAQ,QAAO,WAAW,IAAI;CAC9B,gBAAe,QAAO;AAUpB,SAAO,WATS,IACb,QAAQ,UAAU,IAAI,CACtB,QAAQ,SAAS,IAAI,CACrB,QAAQ,SAAS,IAAI,CACrB,QAAQ,UAAU,KAAI,CACtB,QAAQ,WAAW,KAAI,CACvB,QAAQ,UAAU,IAAI,CACtB,QAAQ,WAAW,IAAI,CAEA;;CAE5B,SAAQ,QAAO,IAAI,WAAW;CAC9B,SAAQ,QAAO,IAAI,SAAS;CAC5B,OAAM,QAAO,IAAI,MAAM;CACvB,QAAQ,KAAK,UAAU,OAAO,OAAO,WAAW,IAAI,GAAG,OAAO,WAAW,MAAM,CAAC;CAChF,OAAO,KAAK,UAAU,OAAO,OAAO,WAAW,IAAI,GAAG,OAAO,WAAW,MAAM,CAAC;CAC/E,WAAW,KAAK,UAAU,OAAO,OAAO,WAAW,IAAI,GAAG,OAAO,WAAW,MAAM,CAAC;CACnF,QAAQ,KAAK,UAAU,OAAO,OAAO,WAAW,IAAI,GAAG,OAAO,WAAW,MAAM,CAAC;CAChF,cAAc,KAAK,UAAU,OAAO,OAAO,WAAW,IAAI,GAAG,OAAO,WAAW,MAAM,CAAC;CACtF,SAAS,KAAK,UAAU,OAAO,OAAO,WAAW,IAAI,GAAG,OAAO,WAAW,MAAM,CAAC;CACjF,SAAS,KAAK,UAAU,OAAO,OAAO,WAAW,IAAI,GAAG,OAAO,WAAW,MAAM,CAAC;CACjF,kBAAiB,QAAO,IAAI,QAAQ,OAAO,OAAO;CAClD,mBAAkB,QAAO,IAAI,QAAQ,OAAO,GAAG;CAC/C,SAAS,KAAK,UAAU,IAAI,MAAM,MAAM,CAAC,KAAK,GAAG;CACjD,iBAAiB,KAAK,UAAU;EAC9B,MAAM,IAAI,IAAI,QAAQ,MAAM;AAC5B,SAAO,MAAM,KAAK,MAAM,IAAI,MAAM,GAAG,EAAE,GAAG,IAAI,MAAM,IAAI,MAAM,OAAO;;CAEvE,UAAU,KAAK,UAAU;EACvB,MAAM,CAAC,SAAS,IAAI,cAAc,MAAM,MAAM,MAAM,IAAI;AACxD,SAAO,IAAI,MAAM,OAAO,CAAC,KAAK,YAAY;;CAE5C,kBAAkB,KAAK,UAAU;EAC/B,MAAM,CAAC,SAAS,IAAI,cAAc,MAAM,MAAM,MAAM,IAAI;EACxD,MAAM,IAAI,IAAI,QAAQ,OAAO;AAC7B,SAAO,MAAM,KAAK,MAAM,IAAI,MAAM,GAAG,EAAE,GAAG,cAAc,IAAI,MAAM,IAAI,OAAO,OAAO;;CAEtF,OAAM,QAAO,OAAO,IAAI,OAAO;CAC/B,QAAQ,KAAK,UAAU;EACrB,MAAM,OAAO,MAAM,MAAM,IAAI,CAAC,KAAI,MAAK,OAAO,SAAS,EAAE,MAAM,EAAE,GAAG,CAAC;AACrE,SAAO,IAAI,MAAM,KAAK,IAAI,KAAK,GAAG;;CAEpC,WAAW,KAAK,UAAU;EACxB,MAAM,aAAa,MAAM,QAAQ,IAAI;EACrC,MAAM,SAAS,OAAO,SAAS,eAAe,KAAK,QAAQ,MAAM,MAAM,GAAG,WAAW,EAAE,GAAG;EAC1F,MAAM,WAAW,eAAe,KAAK,QAAQ,MAAM,MAAM,aAAa,EAAE;AAExE,MAAI,IAAI,UAAU,OAAQ,QAAO;AAEjC,SAAO,IAAI,MAAM,GAAG,OAAO,GAAG;;CAEhC,mBAAmB,KAAK,UAAU;EAChC,MAAM,aAAa,MAAM,QAAQ,IAAI;EACrC,MAAM,QAAQ,OAAO,SAAS,eAAe,KAAK,QAAQ,MAAM,MAAM,GAAG,WAAW,EAAE,GAAG;EACzF,MAAM,WAAW,eAAe,KAAK,QAAQ,MAAM,MAAM,aAAa,EAAE;EACxE,MAAM,QAAQ,IAAI,MAAM,MAAM,CAAC,OAAO,QAAQ;AAE9C,MAAI,MAAM,UAAU,MAAO,QAAO;AAElC,SAAO,MAAM,MAAM,GAAG,MAAM,CAAC,KAAK,IAAI,GAAG;;CAE3C,eAAc,QAAO,mBAAmB,IAAI,QAAQ,OAAO,IAAI,CAAC;CAChE,eAAc,QAAO,mBAAmB,IAAI;CAC7C"}
@@ -0,0 +1,22 @@
1
+ import { FilterFunction } from "./defaults.mjs";
2
+ import { ChildNode } from "domhandler";
3
+
4
+ //#region src/transformers/filters/index.d.ts
5
+ type FiltersConfig = false | Record<string, (str: string, value: string) => string>;
6
+ /**
7
+ * Filters transformer.
8
+ *
9
+ * Applies transformation functions to the content of elements that
10
+ * have matching filter attributes. Multiple filters on the same element
11
+ * are executed in the order the attributes are defined.
12
+ *
13
+ * Default filters include string manipulation (uppercase, lowercase, trim, etc.),
14
+ * math operations (plus, minus, multiply, etc.), and more.
15
+ *
16
+ * Custom filters can be added via config, and will be merged with defaults.
17
+ * Set config to `false` to disable all filters.
18
+ */
19
+ declare function filters(dom: ChildNode[], config?: FiltersConfig): ChildNode[];
20
+ //#endregion
21
+ export { type FilterFunction, FiltersConfig, filters };
22
+ //# sourceMappingURL=index.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.mts","names":[],"sources":["../../../src/transformers/filters/index.ts"],"mappings":";;;;KAMY,aAAA,WAAwB,MAAA,UAAgB,GAAA,UAAa,KAAA;;AAAjE;;;;;;;;;AA4BA;;;iBAAgB,OAAA,CAAQ,GAAA,EAAK,SAAA,IAAa,MAAA,GAAQ,aAAA,GAAqB,SAAA"}
@@ -0,0 +1,67 @@
1
+ import { parse } from "../../utils/ast/parser.mjs";
2
+ import { serialize } from "../../utils/ast/serializer.mjs";
3
+ import "../../utils/ast/index.mjs";
4
+ import { defaults } from "./defaults.mjs";
5
+ import { Text } from "domhandler";
6
+
7
+ //#region src/transformers/filters/index.ts
8
+ /**
9
+ * Process children before parents so nested filter elements work correctly.
10
+ */
11
+ function walkBottomUp(nodes, callback) {
12
+ for (const node of [...nodes]) {
13
+ if ("children" in node && node.children?.length) walkBottomUp(node.children, callback);
14
+ callback(node);
15
+ }
16
+ }
17
+ /**
18
+ * Filters transformer.
19
+ *
20
+ * Applies transformation functions to the content of elements that
21
+ * have matching filter attributes. Multiple filters on the same element
22
+ * are executed in the order the attributes are defined.
23
+ *
24
+ * Default filters include string manipulation (uppercase, lowercase, trim, etc.),
25
+ * math operations (plus, minus, multiply, etc.), and more.
26
+ *
27
+ * Custom filters can be added via config, and will be merged with defaults.
28
+ * Set config to `false` to disable all filters.
29
+ */
30
+ function filters(dom, config = {}) {
31
+ if (config === false) return dom;
32
+ const allFilters = {
33
+ ...defaults,
34
+ ...config
35
+ };
36
+ const filterNames = new Set(Object.keys(allFilters));
37
+ walkBottomUp(dom, (node) => {
38
+ const el = node;
39
+ if (!el.attribs) return;
40
+ const matched = [];
41
+ for (const attr of Object.keys(el.attribs)) if (filterNames.has(attr)) matched.push({
42
+ name: attr,
43
+ value: el.attribs[attr]
44
+ });
45
+ if (matched.length === 0) return;
46
+ let content = serialize(el.children);
47
+ for (const { name, value } of matched) {
48
+ content = allFilters[name](content, value);
49
+ delete el.attribs[name];
50
+ }
51
+ if (content === "") el.children = [];
52
+ else if (/<[a-z/!]/i.test(content)) {
53
+ const newChildren = parse(content);
54
+ for (const child of newChildren) child.parent = el;
55
+ el.children = newChildren;
56
+ } else {
57
+ const textNode = new Text(content);
58
+ textNode.parent = el;
59
+ el.children = [textNode];
60
+ }
61
+ });
62
+ return dom;
63
+ }
64
+
65
+ //#endregion
66
+ export { filters };
67
+ //# sourceMappingURL=index.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.mjs","names":[],"sources":["../../../src/transformers/filters/index.ts"],"sourcesContent":["import { Text } from 'domhandler'\nimport type { ChildNode, Element } from 'domhandler'\nimport { parse, serialize } from '../../utils/ast/index.ts'\nimport { defaults } from './defaults.ts'\n\nexport type { FilterFunction } from './defaults.ts'\nexport type FiltersConfig = false | Record<string, (str: string, value: string) => string>\n\n/**\n * Process children before parents so nested filter elements work correctly.\n */\nfunction walkBottomUp(nodes: ChildNode[], callback: (node: ChildNode) => void): void {\n for (const node of [...nodes]) {\n if ('children' in node && node.children?.length) {\n walkBottomUp(node.children as ChildNode[], callback)\n }\n\n callback(node)\n }\n}\n\n/**\n * Filters transformer.\n *\n * Applies transformation functions to the content of elements that\n * have matching filter attributes. Multiple filters on the same element\n * are executed in the order the attributes are defined.\n *\n * Default filters include string manipulation (uppercase, lowercase, trim, etc.),\n * math operations (plus, minus, multiply, etc.), and more.\n *\n * Custom filters can be added via config, and will be merged with defaults.\n * Set config to `false` to disable all filters.\n */\nexport function filters(dom: ChildNode[], config: FiltersConfig = {}): ChildNode[] {\n if (config === false) return dom\n\n const allFilters = { ...defaults, ...config }\n const filterNames = new Set(Object.keys(allFilters))\n\n walkBottomUp(dom, (node) => {\n const el = node as Element\n\n if (!el.attribs) return\n\n // Collect matching filter attributes in source order\n const matched: Array<{ name: string; value: string }> = []\n\n for (const attr of Object.keys(el.attribs)) {\n if (filterNames.has(attr)) {\n matched.push({ name: attr, value: el.attribs[attr] })\n }\n }\n\n if (matched.length === 0) return\n\n // Serialize children to get innerHTML\n let content = serialize(el.children as ChildNode[])\n\n // Apply each filter in attribute order\n for (const { name, value } of matched) {\n content = allFilters[name](content, value)\n delete el.attribs[name]\n }\n\n // Replace children with the filtered content\n if (content === '') {\n el.children = []\n } else if (/<[a-z/!]/i.test(content)) {\n // Result contains HTML elements — parse back to DOM\n const newChildren = parse(content)\n\n for (const child of newChildren) {\n child.parent = el as any\n }\n\n el.children = newChildren as ChildNode[]\n } else {\n // Text-only result — create a text node directly to preserve entity strings\n const textNode = new Text(content)\n textNode.parent = el as any\n el.children = [textNode]\n }\n })\n\n return dom\n}\n"],"mappings":";;;;;;;;;;AAWA,SAAS,aAAa,OAAoB,UAA2C;AACnF,MAAK,MAAM,QAAQ,CAAC,GAAG,MAAM,EAAE;AAC7B,MAAI,cAAc,QAAQ,KAAK,UAAU,OACvC,cAAa,KAAK,UAAyB,SAAS;AAGtD,WAAS,KAAK;;;;;;;;;;;;;;;;AAiBlB,SAAgB,QAAQ,KAAkB,SAAwB,EAAE,EAAe;AACjF,KAAI,WAAW,MAAO,QAAO;CAE7B,MAAM,aAAa;EAAE,GAAG;EAAU,GAAG;EAAQ;CAC7C,MAAM,cAAc,IAAI,IAAI,OAAO,KAAK,WAAW,CAAC;AAEpD,cAAa,MAAM,SAAS;EAC1B,MAAM,KAAK;AAEX,MAAI,CAAC,GAAG,QAAS;EAGjB,MAAM,UAAkD,EAAE;AAE1D,OAAK,MAAM,QAAQ,OAAO,KAAK,GAAG,QAAQ,CACxC,KAAI,YAAY,IAAI,KAAK,CACvB,SAAQ,KAAK;GAAE,MAAM;GAAM,OAAO,GAAG,QAAQ;GAAO,CAAC;AAIzD,MAAI,QAAQ,WAAW,EAAG;EAG1B,IAAI,UAAU,UAAU,GAAG,SAAwB;AAGnD,OAAK,MAAM,EAAE,MAAM,WAAW,SAAS;AACrC,aAAU,WAAW,MAAM,SAAS,MAAM;AAC1C,UAAO,GAAG,QAAQ;;AAIpB,MAAI,YAAY,GACd,IAAG,WAAW,EAAE;WACP,YAAY,KAAK,QAAQ,EAAE;GAEpC,MAAM,cAAc,MAAM,QAAQ;AAElC,QAAK,MAAM,SAAS,YAClB,OAAM,SAAS;AAGjB,MAAG,WAAW;SACT;GAEL,MAAM,WAAW,IAAI,KAAK,QAAQ;AAClC,YAAS,SAAS;AAClB,MAAG,WAAW,CAAC,SAAS;;GAE1B;AAEF,QAAO"}
@@ -19,17 +19,19 @@ import { MaizzleConfig } from "../types/config.mjs";
19
19
  * 4. CSS inliner
20
20
  * 5. Remove attributes
21
21
  * 6. Shorthand CSS
22
- * 7. Add attributes
23
- * 8. Base URL
24
- * 9. URL query
25
- * 10. Purge CSS (serializes/parses internally around email-comb)
26
- * 11. Entities
22
+ * 7. Six-digit HEX
23
+ * 8. Add attributes
24
+ * 9. Filters
25
+ * 10. Base URL
26
+ * 11. URL query
27
+ * 12. Purge CSS (serializes/parses internally around email-comb)
28
+ * 13. Entities
27
29
  * + Vue-generated comments stripped here (on serialized string)
28
- * 12. Replace strings
29
- * 13. Prettify
30
- * 14. Minify
30
+ * 14. Replace strings
31
+ * 15. Prettify
32
+ * 16. Minify
31
33
  */
32
- declare function runTransformers(html: string, config: MaizzleConfig, filePath?: string): Promise<string>;
34
+ declare function runTransformers(html: string, config: MaizzleConfig, filePath?: string, doctype?: string): Promise<string>;
33
35
  //#endregion
34
36
  export { runTransformers };
35
37
  //# sourceMappingURL=index.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.mts","names":[],"sources":["../../src/transformers/index.ts"],"mappings":";;;;;AA8CA;;;;;;;;;;;;;;;;;;;;;;;;;;iBAAsB,eAAA,CACpB,IAAA,UACA,MAAA,EAAQ,aAAA,EACR,QAAA,YACC,OAAA"}
1
+ {"version":3,"file":"index.d.mts","names":[],"sources":["../../src/transformers/index.ts"],"mappings":";;;;;AAkDA;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAAsB,eAAA,CACpB,IAAA,UACA,MAAA,EAAQ,aAAA,EACR,QAAA,WACA,OAAA,YACC,OAAA"}
@@ -8,7 +8,9 @@ import { attributeToStyle } from "./attributeToStyle.mjs";
8
8
  import { inlineCSS } from "./inlineCSS.mjs";
9
9
  import { removeAttributes } from "./removeAttributes.mjs";
10
10
  import { shorthandCSS } from "./shorthandCSS.mjs";
11
+ import { sixHex } from "./sixHex.mjs";
11
12
  import { addAttributes } from "./addAttributes.mjs";
13
+ import { filters } from "./filters/index.mjs";
12
14
  import { base } from "./base.mjs";
13
15
  import { entities } from "./entities.mjs";
14
16
  import { urlQuery } from "./urlQuery.mjs";
@@ -36,17 +38,19 @@ import { minify } from "./minify.mjs";
36
38
  * 4. CSS inliner
37
39
  * 5. Remove attributes
38
40
  * 6. Shorthand CSS
39
- * 7. Add attributes
40
- * 8. Base URL
41
- * 9. URL query
42
- * 10. Purge CSS (serializes/parses internally around email-comb)
43
- * 11. Entities
41
+ * 7. Six-digit HEX
42
+ * 8. Add attributes
43
+ * 9. Filters
44
+ * 10. Base URL
45
+ * 11. URL query
46
+ * 12. Purge CSS (serializes/parses internally around email-comb)
47
+ * 13. Entities
44
48
  * + Vue-generated comments stripped here (on serialized string)
45
- * 12. Replace strings
46
- * 13. Prettify
47
- * 14. Minify
49
+ * 14. Replace strings
50
+ * 15. Prettify
51
+ * 16. Minify
48
52
  */
49
- async function runTransformers(html, config, filePath) {
53
+ async function runTransformers(html, config, filePath, doctype) {
50
54
  let dom = parse(html);
51
55
  dom = await inlineLink(dom, filePath);
52
56
  dom = await tailwindcss(dom, config, filePath);
@@ -55,16 +59,20 @@ async function runTransformers(html, config, filePath) {
55
59
  dom = inlineCSS(dom, config.css);
56
60
  dom = removeAttributes(dom, config.html?.attributes);
57
61
  dom = shorthandCSS(dom, config.css);
62
+ dom = sixHex(dom, config.css);
58
63
  dom = addAttributes(dom, config.html?.attributes);
64
+ dom = filters(dom, config.filters);
59
65
  dom = base(dom, config.url);
60
66
  dom = urlQuery(dom, config.url);
61
67
  dom = purgeCSS(dom, config.css);
62
68
  dom = entities(dom, config.html?.decodeEntities);
63
- let result = serialize(dom);
64
- result = result.replaceAll("<!--[-->", "").replaceAll("<!--]-->", "");
69
+ const isXhtml = doctype ? /xhtml/i.test(doctype) : false;
70
+ let result = serialize(dom, { selfClosingTags: isXhtml });
71
+ result = result.replaceAll("<!--[-->", "").replaceAll("<!--]-->", "").replaceAll("<!--teleport start anchor-->", "").replaceAll("<!--teleport anchor-->", "").replaceAll("<!--teleport start-->", "").replaceAll("<!--teleport end-->", "");
65
72
  result = replaceStrings(result, config);
66
73
  result = await format(result, config);
67
74
  result = minify(result, config);
75
+ if (!isXhtml) result = result.replace(/ \/>/g, ">");
68
76
  return result;
69
77
  }
70
78
 
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","names":[],"sources":["../../src/transformers/index.ts"],"sourcesContent":["import { parse, serialize } from '../utils/ast/index.ts'\nimport { inlineLink } from './inlineLink.ts'\nimport { tailwindcss } from './tailwindcss.ts'\nimport { safeClassNames } from './safeClassNames.ts'\nimport { attributeToStyle } from './attributeToStyle.ts'\nimport { inlineCSS } from './inlineCSS.ts'\nimport { removeAttributes } from './removeAttributes.ts'\nimport { shorthandCSS } from './shorthandCSS.ts'\nimport { addAttributes } from './addAttributes.ts'\nimport { base } from './base.ts'\nimport { entities } from './entities.ts'\nimport { urlQuery } from './urlQuery.ts'\nimport { purgeCSS } from './purgeCSS.ts'\nimport { replaceStrings } from './replaceStrings.ts'\nimport { format } from './format.ts'\nimport { minify } from './minify.ts'\nimport type { MaizzleConfig } from '../types/config.ts'\n\n/**\n * Run all Maizzle transformers on the rendered HTML.\n *\n * The HTML is parsed into a DOM once at the start and passed through all\n * DOM-based transformers as a shared `ChildNode[]`. After all DOM transformers\n * complete, the DOM is serialized back to a string exactly once.\n *\n * String-only transformers (those that rely on external tools that require a\n * raw HTML string) then run on the serialized output.\n *\n * Transformers run in a specific order:\n * 0. Inline link stylesheets — replace `<link rel=\"stylesheet\">` with `<style>` tags\n * 1. Tailwind CSS — compile CSS, lower syntax, optimize (cleanup + merge media queries)\n * 2. Safe class names\n * 3. Attribute to style\n * 4. CSS inliner\n * 5. Remove attributes\n * 6. Shorthand CSS\n * 7. Add attributes\n * 8. Base URL\n * 9. URL query\n * 10. Purge CSS (serializes/parses internally around email-comb)\n * 11. Entities\n * + Vue-generated comments stripped here (on serialized string)\n * 12. Replace strings\n * 13. Prettify\n * 14. Minify\n */\nexport async function runTransformers(\n html: string,\n config: MaizzleConfig,\n filePath?: string,\n): Promise<string> {\n // Parse once — all DOM transformers share this array\n let dom = parse(html)\n\n // 0. Inline <link> stylesheets\n dom = await inlineLink(dom, filePath)\n\n // 1. Tailwind CSS — always runs first\n dom = await tailwindcss(dom, config, filePath)\n\n // 2. Safe class names\n dom = safeClassNames(dom, config.css)\n\n // 3. Attribute to style\n dom = attributeToStyle(dom, config.css)\n\n // 4. CSS inliner (serializes/parses internally around juice)\n dom = inlineCSS(dom, config.css)\n\n // 5. Remove attributes\n dom = removeAttributes(dom, config.html?.attributes)\n\n // 6. Shorthand CSS\n dom = shorthandCSS(dom, config.css)\n\n // 7. Add attributes\n dom = addAttributes(dom, config.html?.attributes)\n\n // 8. Base URL (serializes/parses internally for VML/MSO regex passes)\n dom = base(dom, config.url)\n\n // 9. URL query\n dom = urlQuery(dom, config.url)\n\n // 10. Purge CSS (serializes/parses internally around email-comb)\n dom = purgeCSS(dom, config.css)\n\n // 11. Entities\n dom = entities(dom, config.html?.decodeEntities)\n\n // Serialize once — remaining transformers operate on the HTML string\n let result = serialize(dom)\n\n // Remove Vue-generated comments after serializing\n result = result\n .replaceAll('<!--[-->', '')\n .replaceAll('<!--]-->', '')\n\n // 12. Replace strings\n result = replaceStrings(result, config)\n\n // 13. Format\n result = await format(result, config)\n\n // 14. Minify\n result = minify(result, config)\n\n return result\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA8CA,eAAsB,gBACpB,MACA,QACA,UACiB;CAEjB,IAAI,MAAM,MAAM,KAAK;AAGrB,OAAM,MAAM,WAAW,KAAK,SAAS;AAGrC,OAAM,MAAM,YAAY,KAAK,QAAQ,SAAS;AAG9C,OAAM,eAAe,KAAK,OAAO,IAAI;AAGrC,OAAM,iBAAiB,KAAK,OAAO,IAAI;AAGvC,OAAM,UAAU,KAAK,OAAO,IAAI;AAGhC,OAAM,iBAAiB,KAAK,OAAO,MAAM,WAAW;AAGpD,OAAM,aAAa,KAAK,OAAO,IAAI;AAGnC,OAAM,cAAc,KAAK,OAAO,MAAM,WAAW;AAGjD,OAAM,KAAK,KAAK,OAAO,IAAI;AAG3B,OAAM,SAAS,KAAK,OAAO,IAAI;AAG/B,OAAM,SAAS,KAAK,OAAO,IAAI;AAG/B,OAAM,SAAS,KAAK,OAAO,MAAM,eAAe;CAGhD,IAAI,SAAS,UAAU,IAAI;AAG3B,UAAS,OACN,WAAW,YAAY,GAAG,CAC1B,WAAW,YAAY,GAAG;AAG7B,UAAS,eAAe,QAAQ,OAAO;AAGvC,UAAS,MAAM,OAAO,QAAQ,OAAO;AAGrC,UAAS,OAAO,QAAQ,OAAO;AAE/B,QAAO"}
1
+ {"version":3,"file":"index.mjs","names":[],"sources":["../../src/transformers/index.ts"],"sourcesContent":["import { parse, serialize } from '../utils/ast/index.ts'\nimport { inlineLink } from './inlineLink.ts'\nimport { tailwindcss } from './tailwindcss.ts'\nimport { safeClassNames } from './safeClassNames.ts'\nimport { attributeToStyle } from './attributeToStyle.ts'\nimport { inlineCSS } from './inlineCSS.ts'\nimport { removeAttributes } from './removeAttributes.ts'\nimport { shorthandCSS } from './shorthandCSS.ts'\nimport { sixHex } from './sixHex.ts'\nimport { addAttributes } from './addAttributes.ts'\nimport { filters } from './filters/index.ts'\nimport { base } from './base.ts'\nimport { entities } from './entities.ts'\nimport { urlQuery } from './urlQuery.ts'\nimport { purgeCSS } from './purgeCSS.ts'\nimport { replaceStrings } from './replaceStrings.ts'\nimport { format } from './format.ts'\nimport { minify } from './minify.ts'\nimport type { MaizzleConfig } from '../types/config.ts'\n\n/**\n * Run all Maizzle transformers on the rendered HTML.\n *\n * The HTML is parsed into a DOM once at the start and passed through all\n * DOM-based transformers as a shared `ChildNode[]`. After all DOM transformers\n * complete, the DOM is serialized back to a string exactly once.\n *\n * String-only transformers (those that rely on external tools that require a\n * raw HTML string) then run on the serialized output.\n *\n * Transformers run in a specific order:\n * 0. Inline link stylesheets — replace `<link rel=\"stylesheet\">` with `<style>` tags\n * 1. Tailwind CSS — compile CSS, lower syntax, optimize (cleanup + merge media queries)\n * 2. Safe class names\n * 3. Attribute to style\n * 4. CSS inliner\n * 5. Remove attributes\n * 6. Shorthand CSS\n * 7. Six-digit HEX\n * 8. Add attributes\n * 9. Filters\n * 10. Base URL\n * 11. URL query\n * 12. Purge CSS (serializes/parses internally around email-comb)\n * 13. Entities\n * + Vue-generated comments stripped here (on serialized string)\n * 14. Replace strings\n * 15. Prettify\n * 16. Minify\n */\nexport async function runTransformers(\n html: string,\n config: MaizzleConfig,\n filePath?: string,\n doctype?: string,\n): Promise<string> {\n // Parse once — all DOM transformers share this array\n let dom = parse(html)\n\n // 0. Inline <link> stylesheets\n dom = await inlineLink(dom, filePath)\n\n // 1. Tailwind CSS — always runs first\n dom = await tailwindcss(dom, config, filePath)\n\n // 2. Safe class names\n dom = safeClassNames(dom, config.css)\n\n // 3. Attribute to style\n dom = attributeToStyle(dom, config.css)\n\n // 4. CSS inliner (serializes/parses internally around juice)\n dom = inlineCSS(dom, config.css)\n\n // 5. Remove attributes\n dom = removeAttributes(dom, config.html?.attributes)\n\n // 6. Shorthand CSS\n dom = shorthandCSS(dom, config.css)\n\n // 7. Six-digit HEX\n dom = sixHex(dom, config.css)\n\n // 8. Add attributes\n dom = addAttributes(dom, config.html?.attributes)\n\n // 9. Filters\n dom = filters(dom, config.filters)\n\n // 10. Base URL (serializes/parses internally for VML/MSO regex passes)\n dom = base(dom, config.url)\n\n // 11. URL query\n dom = urlQuery(dom, config.url)\n\n // 12. Purge CSS (serializes/parses internally around email-comb)\n dom = purgeCSS(dom, config.css)\n\n // 13. Entities\n dom = entities(dom, config.html?.decodeEntities)\n\n // Serialize once — remaining transformers operate on the HTML string\n const isXhtml = doctype ? /xhtml/i.test(doctype) : false\n let result = serialize(dom, { selfClosingTags: isXhtml })\n\n // Remove Vue-generated comments after serializing\n result = result\n .replaceAll('<!--[-->', '')\n .replaceAll('<!--]-->', '')\n .replaceAll('<!--teleport start anchor-->', '')\n .replaceAll('<!--teleport anchor-->', '')\n .replaceAll('<!--teleport start-->', '')\n .replaceAll('<!--teleport end-->', '')\n\n // 14. Replace strings\n result = replaceStrings(result, config)\n\n // 15. Format\n result = await format(result, config)\n\n // 16. Minify\n result = minify(result, config)\n\n // Strip self-closing slashes for HTML5 doctypes\n if (!isXhtml) {\n result = result.replace(/ \\/>/g, '>')\n }\n\n return result\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAkDA,eAAsB,gBACpB,MACA,QACA,UACA,SACiB;CAEjB,IAAI,MAAM,MAAM,KAAK;AAGrB,OAAM,MAAM,WAAW,KAAK,SAAS;AAGrC,OAAM,MAAM,YAAY,KAAK,QAAQ,SAAS;AAG9C,OAAM,eAAe,KAAK,OAAO,IAAI;AAGrC,OAAM,iBAAiB,KAAK,OAAO,IAAI;AAGvC,OAAM,UAAU,KAAK,OAAO,IAAI;AAGhC,OAAM,iBAAiB,KAAK,OAAO,MAAM,WAAW;AAGpD,OAAM,aAAa,KAAK,OAAO,IAAI;AAGnC,OAAM,OAAO,KAAK,OAAO,IAAI;AAG7B,OAAM,cAAc,KAAK,OAAO,MAAM,WAAW;AAGjD,OAAM,QAAQ,KAAK,OAAO,QAAQ;AAGlC,OAAM,KAAK,KAAK,OAAO,IAAI;AAG3B,OAAM,SAAS,KAAK,OAAO,IAAI;AAG/B,OAAM,SAAS,KAAK,OAAO,IAAI;AAG/B,OAAM,SAAS,KAAK,OAAO,MAAM,eAAe;CAGhD,MAAM,UAAU,UAAU,SAAS,KAAK,QAAQ,GAAG;CACnD,IAAI,SAAS,UAAU,KAAK,EAAE,iBAAiB,SAAS,CAAC;AAGzD,UAAS,OACN,WAAW,YAAY,GAAG,CAC1B,WAAW,YAAY,GAAG,CAC1B,WAAW,gCAAgC,GAAG,CAC9C,WAAW,0BAA0B,GAAG,CACxC,WAAW,yBAAyB,GAAG,CACvC,WAAW,uBAAuB,GAAG;AAGxC,UAAS,eAAe,QAAQ,OAAO;AAGvC,UAAS,MAAM,OAAO,QAAQ,OAAO;AAGrC,UAAS,OAAO,QAAQ,OAAO;AAG/B,KAAI,CAAC,QACH,UAAS,OAAO,QAAQ,SAAS,IAAI;AAGvC,QAAO"}
@@ -9,20 +9,7 @@ import { ChildNode } from "domhandler";
9
9
  * This is important for email client compatibility (especially Outlook on Windows).
10
10
  *
11
11
  * Enabled when `css.inline` is set to `true` or an object with options.
12
- *
13
- * Options:
14
- * - removeStyleTags: Remove style tags after inlining (default: false)
15
- * - removeInlinedSelectors: Remove classes after they've been inlined (default: true)
16
- * - preferUnitlessValues: Convert 0px, 0em, etc. to 0 (default: true)
17
- * - safelist: Selectors that should not be removed after inlining
18
- * - styleToAttribute: Map CSS properties to HTML attributes (e.g., background-color -> bgcolor)
19
- * - applyWidthAttributes: Add width attributes based on inline CSS (default: true)
20
- * - applyHeightAttributes: Add height attributes based on inline CSS (default: true)
21
- * - widthElements: Elements that can receive width attributes (default: ['img', 'video'])
22
- * - heightElements: Elements that can receive height attributes (default: ['img', 'video'])
23
- * - excludedProperties: CSS properties to exclude from inlining
24
- * - codeBlocks: Fenced code blocks to ignore (default: { EJS: { start: '<%', end: '%>' }, HBS: { start: '{{', end: '}}' } })
25
- * - customCSS: Additional CSS to inline
12
+ * All Juice options are supported and passed through directly.
26
13
  */
27
14
  declare function inlineCSS(dom: ChildNode[], config?: CssConfig): ChildNode[];
28
15
  //#endregion
@@ -1 +1 @@
1
- {"version":3,"file":"inlineCSS.d.mts","names":[],"sources":["../../src/transformers/inlineCSS.ts"],"mappings":";;;;;;AA2CA;;;;;;;;;;;;;;;;;;;;iBAAgB,SAAA,CAAU,GAAA,EAAK,SAAA,IAAa,MAAA,GAAQ,SAAA,GAAiB,SAAA"}
1
+ {"version":3,"file":"inlineCSS.d.mts","names":[],"sources":["../../src/transformers/inlineCSS.ts"],"mappings":";;;;;;AAeA;;;;;;;iBAAgB,SAAA,CAAU,GAAA,EAAK,SAAA,IAAa,MAAA,GAAQ,SAAA,GAAiB,SAAA"}
@@ -12,32 +12,17 @@ import juice from "juice";
12
12
  * This is important for email client compatibility (especially Outlook on Windows).
13
13
  *
14
14
  * Enabled when `css.inline` is set to `true` or an object with options.
15
- *
16
- * Options:
17
- * - removeStyleTags: Remove style tags after inlining (default: false)
18
- * - removeInlinedSelectors: Remove classes after they've been inlined (default: true)
19
- * - preferUnitlessValues: Convert 0px, 0em, etc. to 0 (default: true)
20
- * - safelist: Selectors that should not be removed after inlining
21
- * - styleToAttribute: Map CSS properties to HTML attributes (e.g., background-color -> bgcolor)
22
- * - applyWidthAttributes: Add width attributes based on inline CSS (default: true)
23
- * - applyHeightAttributes: Add height attributes based on inline CSS (default: true)
24
- * - widthElements: Elements that can receive width attributes (default: ['img', 'video'])
25
- * - heightElements: Elements that can receive height attributes (default: ['img', 'video'])
26
- * - excludedProperties: CSS properties to exclude from inlining
27
- * - codeBlocks: Fenced code blocks to ignore (default: { EJS: { start: '<%', end: '%>' }, HBS: { start: '{{', end: '}}' } })
28
- * - customCSS: Additional CSS to inline
15
+ * All Juice options are supported and passed through directly.
29
16
  */
30
17
  function inlineCSS(dom, config = {}) {
31
18
  const inline = config.inline;
32
19
  if (!inline) return dom;
33
- const options = typeof inline === "object" ? inline : {};
34
- const removeStyleTags = options.removeStyleTags ?? false;
35
- const customCSS = options.customCSS ?? "";
36
- juice.styleToAttribute = options.styleToAttribute ?? {};
37
- juice.excludedProperties = ["--tw-shadow", ...options.excludedProperties ?? []];
38
- juice.widthElements = (options.widthElements ?? ["img", "video"]).map((i) => i.toUpperCase());
39
- juice.heightElements = (options.heightElements ?? ["img", "video"]).map((i) => i.toUpperCase());
40
- if (options.codeBlocks && typeof options.codeBlocks === "object") Object.entries(options.codeBlocks).forEach(([key, value]) => {
20
+ const { preferUnitlessValues = true, safelist, customCSS = "", styleToAttribute, excludedProperties, widthElements, heightElements, codeBlocks, ...juicePassthrough } = typeof inline === "object" ? inline : {};
21
+ juice.styleToAttribute = styleToAttribute ?? {};
22
+ juice.excludedProperties = ["--tw-shadow", ...excludedProperties ?? []];
23
+ juice.widthElements = (widthElements ?? ["img", "video"]).map((i) => i.toUpperCase());
24
+ juice.heightElements = (heightElements ?? ["img", "video"]).map((i) => i.toUpperCase());
25
+ if (codeBlocks && typeof codeBlocks === "object") Object.entries(codeBlocks).forEach(([key, value]) => {
41
26
  if (value.start && value.end) juice.codeBlocks[key] = value;
42
27
  });
43
28
  walk(dom, (node) => {
@@ -45,31 +30,42 @@ function inlineCSS(dom, config = {}) {
45
30
  if (el.name === "style" && el.attribs) {
46
31
  if (el.attribs.embed && !("data-embed" in el.attribs)) el.attribs["data-embed"] = "";
47
32
  if (el.attribs["data-embed"] && !("embed" in el.attribs)) el.attribs.embed = "";
33
+ if ("data-embed" in el.attribs) el.attribs["data-maizzle-embed"] = "";
48
34
  }
49
35
  });
50
36
  const serialized = serialize(dom);
51
37
  let inlinedHtml;
52
38
  try {
53
- const juiceOptions = {
54
- removeStyleTags,
55
- removeInlinedSelectors: options.removeInlinedSelectors ?? true,
56
- preservedSelectors: options.safelist ?? [],
57
- applyWidthAttributes: options.applyWidthAttributes ?? true,
58
- applyHeightAttributes: options.applyHeightAttributes ?? true
59
- };
60
- if (customCSS) inlinedHtml = juice(serialized, {
61
- ...juiceOptions,
62
- extraCss: customCSS
39
+ inlinedHtml = juice(serialized, {
40
+ removeStyleTags: juicePassthrough.removeStyleTags ?? false,
41
+ removeInlinedSelectors: juicePassthrough.removeInlinedSelectors ?? true,
42
+ applyWidthAttributes: juicePassthrough.applyWidthAttributes ?? true,
43
+ applyHeightAttributes: juicePassthrough.applyHeightAttributes ?? true,
44
+ preservedSelectors: safelist ?? [],
45
+ ...customCSS ? { extraCss: customCSS } : {},
46
+ inlineDuplicateProperties: juicePassthrough.inlineDuplicateProperties ?? true,
47
+ ...juicePassthrough
63
48
  });
64
- else inlinedHtml = juice(serialized, juiceOptions);
65
49
  } catch {
66
50
  return dom;
67
51
  }
68
- const preferUnitlessValues = options.preferUnitlessValues ?? true;
69
52
  const result = parse(inlinedHtml);
70
- if (preferUnitlessValues) walk(result, (node) => {
53
+ walk(result, (node) => {
71
54
  const el = node;
72
- if (el.attribs?.style) el.attribs.style = el.attribs.style.replace(/\b0(px|rem|em|%|vh|vw|vmin|vmax|in|cm|mm|pt|pc|ex|ch)\b/g, "0");
55
+ if (el.attribs?.style) {
56
+ let style = el.attribs.style.replace(/:\s*/g, ": ").replace(/;\s*/g, "; ").trimEnd();
57
+ if (!style.endsWith(";")) style += ";";
58
+ if (preferUnitlessValues) style = style.replace(/\b0(px|rem|em|%|vh|vw|vmin|vmax|in|cm|mm|pt|pc|ex|ch)\b/g, "0");
59
+ el.attribs.style = style;
60
+ }
61
+ });
62
+ walk(result, (node) => {
63
+ const el = node;
64
+ if (el.name === "style" && el.attribs && "data-maizzle-embed" in el.attribs) {
65
+ el.attribs["data-embed"] = "";
66
+ el.attribs.embed = "";
67
+ delete el.attribs["data-maizzle-embed"];
68
+ }
73
69
  });
74
70
  return result;
75
71
  }
@@ -1 +1 @@
1
- {"version":3,"file":"inlineCSS.mjs","names":[],"sources":["../../src/transformers/inlineCSS.ts"],"sourcesContent":["import juice from 'juice'\nimport { walk, parse, serialize } from '../utils/ast/index.ts'\nimport type { ChildNode, Element } from 'domhandler'\nimport type { Options as JuiceOptions } from 'juice'\nimport type { CssConfig } from '../types/config.ts'\n\ninterface InlineCssOptions {\n removeStyleTags?: boolean\n removeInlinedSelectors?: boolean\n preferUnitlessValues?: boolean\n safelist?: string[]\n styleToAttribute?: Record<string, string>\n applyWidthAttributes?: boolean\n applyHeightAttributes?: boolean\n widthElements?: string[]\n heightElements?: string[]\n excludedProperties?: string[]\n codeBlocks?: Record<string, { start: string; end: string }>\n customCSS?: string\n}\n\n/**\n * Inline CSS transformer.\n *\n * Inlines CSS from `<style>` tags into inline style attributes on HTML elements.\n * This is important for email client compatibility (especially Outlook on Windows).\n *\n * Enabled when `css.inline` is set to `true` or an object with options.\n *\n * Options:\n * - removeStyleTags: Remove style tags after inlining (default: false)\n * - removeInlinedSelectors: Remove classes after they've been inlined (default: true)\n * - preferUnitlessValues: Convert 0px, 0em, etc. to 0 (default: true)\n * - safelist: Selectors that should not be removed after inlining\n * - styleToAttribute: Map CSS properties to HTML attributes (e.g., background-color -> bgcolor)\n * - applyWidthAttributes: Add width attributes based on inline CSS (default: true)\n * - applyHeightAttributes: Add height attributes based on inline CSS (default: true)\n * - widthElements: Elements that can receive width attributes (default: ['img', 'video'])\n * - heightElements: Elements that can receive height attributes (default: ['img', 'video'])\n * - excludedProperties: CSS properties to exclude from inlining\n * - codeBlocks: Fenced code blocks to ignore (default: { EJS: { start: '<%', end: '%>' }, HBS: { start: '{{', end: '}}' } })\n * - customCSS: Additional CSS to inline\n */\nexport function inlineCSS(dom: ChildNode[], config: CssConfig = {}): ChildNode[] {\n const inline = config.inline\n\n // Disabled when inline is falsy or not an object/truthy\n if (!inline) {\n return dom\n }\n\n // Build options from config\n const options: InlineCssOptions = typeof inline === 'object' ? inline : {}\n\n const removeStyleTags = options.removeStyleTags ?? false\n const customCSS = options.customCSS ?? ''\n\n // Configure Juice static properties\n juice.styleToAttribute = options.styleToAttribute ?? {}\n juice.excludedProperties = ['--tw-shadow', ...(options.excludedProperties ?? [])]\n juice.widthElements = (options.widthElements ?? ['img', 'video']).map(i => i.toUpperCase()) as unknown as HTMLElement[]\n juice.heightElements = (options.heightElements ?? ['img', 'video']).map(i => i.toUpperCase()) as unknown as HTMLElement[]\n\n // Add custom code blocks\n if (options.codeBlocks && typeof options.codeBlocks === 'object') {\n Object.entries(options.codeBlocks).forEach(([key, value]) => {\n if (value.start && value.end) {\n juice.codeBlocks[key] = value\n }\n })\n }\n\n // Handle style tags with embed attributes\n walk(dom, (node) => {\n const el = node as Element\n if (el.name === 'style' && el.attribs) {\n // Add data-embed to style tags with embed attribute\n if (el.attribs.embed && !('data-embed' in el.attribs)) {\n el.attribs['data-embed'] = ''\n }\n // Add embed to style tags with data-embed attribute\n if (el.attribs['data-embed'] && !('embed' in el.attribs)) {\n el.attribs.embed = ''\n }\n }\n })\n\n // Serialize for juice (juice requires a string)\n const serialized = serialize(dom)\n\n let inlinedHtml: string\n\n try {\n const juiceOptions: JuiceOptions = {\n removeStyleTags,\n removeInlinedSelectors: options.removeInlinedSelectors ?? true,\n preservedSelectors: options.safelist ?? [],\n applyWidthAttributes: options.applyWidthAttributes ?? true,\n applyHeightAttributes: options.applyHeightAttributes ?? true,\n }\n\n if (customCSS) {\n inlinedHtml = juice(serialized, { ...juiceOptions, extraCss: customCSS })\n } else {\n inlinedHtml = juice(serialized, juiceOptions)\n }\n } catch {\n // If Juice fails, return the dom unchanged\n return dom\n }\n\n // Post-process for preferUnitlessValues\n const preferUnitlessValues = options.preferUnitlessValues ?? true\n const result = parse(inlinedHtml)\n\n if (preferUnitlessValues) {\n walk(result, (node) => {\n const el = node as Element\n if (el.attribs?.style) {\n el.attribs.style = el.attribs.style.replace(\n /\\b0(px|rem|em|%|vh|vw|vmin|vmax|in|cm|mm|pt|pc|ex|ch)\\b/g,\n '0'\n )\n }\n })\n }\n\n return result\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA2CA,SAAgB,UAAU,KAAkB,SAAoB,EAAE,EAAe;CAC/E,MAAM,SAAS,OAAO;AAGtB,KAAI,CAAC,OACH,QAAO;CAIT,MAAM,UAA4B,OAAO,WAAW,WAAW,SAAS,EAAE;CAE1E,MAAM,kBAAkB,QAAQ,mBAAmB;CACnD,MAAM,YAAY,QAAQ,aAAa;AAGvC,OAAM,mBAAmB,QAAQ,oBAAoB,EAAE;AACvD,OAAM,qBAAqB,CAAC,eAAe,GAAI,QAAQ,sBAAsB,EAAE,CAAE;AACjF,OAAM,iBAAiB,QAAQ,iBAAiB,CAAC,OAAO,QAAQ,EAAE,KAAI,MAAK,EAAE,aAAa,CAAC;AAC3F,OAAM,kBAAkB,QAAQ,kBAAkB,CAAC,OAAO,QAAQ,EAAE,KAAI,MAAK,EAAE,aAAa,CAAC;AAG7F,KAAI,QAAQ,cAAc,OAAO,QAAQ,eAAe,SACtD,QAAO,QAAQ,QAAQ,WAAW,CAAC,SAAS,CAAC,KAAK,WAAW;AAC3D,MAAI,MAAM,SAAS,MAAM,IACvB,OAAM,WAAW,OAAO;GAE1B;AAIJ,MAAK,MAAM,SAAS;EAClB,MAAM,KAAK;AACX,MAAI,GAAG,SAAS,WAAW,GAAG,SAAS;AAErC,OAAI,GAAG,QAAQ,SAAS,EAAE,gBAAgB,GAAG,SAC3C,IAAG,QAAQ,gBAAgB;AAG7B,OAAI,GAAG,QAAQ,iBAAiB,EAAE,WAAW,GAAG,SAC9C,IAAG,QAAQ,QAAQ;;GAGvB;CAGF,MAAM,aAAa,UAAU,IAAI;CAEjC,IAAI;AAEJ,KAAI;EACF,MAAM,eAA6B;GACjC;GACA,wBAAwB,QAAQ,0BAA0B;GAC1D,oBAAoB,QAAQ,YAAY,EAAE;GAC1C,sBAAsB,QAAQ,wBAAwB;GACtD,uBAAuB,QAAQ,yBAAyB;GACzD;AAED,MAAI,UACF,eAAc,MAAM,YAAY;GAAE,GAAG;GAAc,UAAU;GAAW,CAAC;MAEzE,eAAc,MAAM,YAAY,aAAa;SAEzC;AAEN,SAAO;;CAIT,MAAM,uBAAuB,QAAQ,wBAAwB;CAC7D,MAAM,SAAS,MAAM,YAAY;AAEjC,KAAI,qBACF,MAAK,SAAS,SAAS;EACrB,MAAM,KAAK;AACX,MAAI,GAAG,SAAS,MACd,IAAG,QAAQ,QAAQ,GAAG,QAAQ,MAAM,QAClC,4DACA,IACD;GAEH;AAGJ,QAAO"}
1
+ {"version":3,"file":"inlineCSS.mjs","names":[],"sources":["../../src/transformers/inlineCSS.ts"],"sourcesContent":["import juice from 'juice'\nimport { walk, parse, serialize } from '../utils/ast/index.ts'\nimport type { ChildNode, Element } from 'domhandler'\nimport type { Options as JuiceOptions } from 'juice'\nimport type { CssConfig } from '../types/config.ts'\n\n/**\n * Inline CSS transformer.\n *\n * Inlines CSS from `<style>` tags into inline style attributes on HTML elements.\n * This is important for email client compatibility (especially Outlook on Windows).\n *\n * Enabled when `css.inline` is set to `true` or an object with options.\n * All Juice options are supported and passed through directly.\n */\nexport function inlineCSS(dom: ChildNode[], config: CssConfig = {}): ChildNode[] {\n const inline = config.inline\n\n // Disabled when inline is falsy or not an object/truthy\n if (!inline) {\n return dom\n }\n\n // Build options from config\n const options = typeof inline === 'object' ? inline : {}\n\n // Separate Maizzle-specific options from Juice options\n const {\n preferUnitlessValues = true,\n safelist,\n customCSS = '',\n styleToAttribute,\n excludedProperties,\n widthElements,\n heightElements,\n codeBlocks,\n ...juicePassthrough\n } = options\n\n // Configure Juice static properties\n juice.styleToAttribute = styleToAttribute ?? {}\n juice.excludedProperties = ['--tw-shadow', ...(excludedProperties ?? [])]\n juice.widthElements = (widthElements ?? ['img', 'video']).map(i => i.toUpperCase()) as unknown as HTMLElement[]\n juice.heightElements = (heightElements ?? ['img', 'video']).map(i => i.toUpperCase()) as unknown as HTMLElement[]\n\n // Add custom code blocks\n if (codeBlocks && typeof codeBlocks === 'object') {\n Object.entries(codeBlocks).forEach(([key, value]) => {\n if (value.start && value.end) {\n juice.codeBlocks[key] = value\n }\n })\n }\n\n // Handle style tags with embed attributes.\n // We add a marker attribute that persists through the pipeline,\n // then restore data-embed from it after Juice runs.\n walk(dom, (node) => {\n const el = node as Element\n if (el.name === 'style' && el.attribs) {\n // Sync data-embed embed\n if (el.attribs.embed && !('data-embed' in el.attribs)) {\n el.attribs['data-embed'] = ''\n }\n if (el.attribs['data-embed'] && !('embed' in el.attribs)) {\n el.attribs.embed = ''\n }\n\n // Add marker that persists through the pipeline\n if ('data-embed' in el.attribs) {\n el.attribs['data-maizzle-embed'] = ''\n }\n }\n })\n\n // Serialize for juice (juice requires a string)\n const serialized = serialize(dom)\n\n let inlinedHtml: string\n\n try {\n const juiceOptions: JuiceOptions = {\n removeStyleTags: juicePassthrough.removeStyleTags ?? false,\n removeInlinedSelectors: juicePassthrough.removeInlinedSelectors ?? true,\n applyWidthAttributes: juicePassthrough.applyWidthAttributes ?? true,\n applyHeightAttributes: juicePassthrough.applyHeightAttributes ?? true,\n preservedSelectors: safelist ?? [],\n ...customCSS ? { extraCss: customCSS } : {},\n inlineDuplicateProperties: juicePassthrough.inlineDuplicateProperties ?? true,\n ...juicePassthrough,\n }\n\n inlinedHtml = juice(serialized, juiceOptions)\n } catch {\n // If Juice fails, return the dom unchanged\n return dom\n }\n\n // Post-process for preferUnitlessValues\n const result = parse(inlinedHtml)\n\n walk(result, (node) => {\n const el = node as Element\n if (el.attribs?.style) {\n // Normalize style formatting: ensure spaces after : and ;\n let style = el.attribs.style\n .replace(/:\\s*/g, ': ')\n .replace(/;\\s*/g, '; ')\n .trimEnd()\n\n // Ensure trailing semicolon\n if (!style.endsWith(';')) {\n style += ';'\n }\n\n if (preferUnitlessValues) {\n style = style.replace(\n /\\b0(px|rem|em|%|vh|vw|vmin|vmax|in|cm|mm|pt|pc|ex|ch)\\b/g,\n '0'\n )\n }\n\n el.attribs.style = style\n }\n })\n\n // Restore data-embed from our marker, then remove the marker.\n // The purge step will handle final data-embed/embed removal.\n walk(result, (node) => {\n const el = node as Element\n if (el.name === 'style' && el.attribs && 'data-maizzle-embed' in el.attribs) {\n el.attribs['data-embed'] = ''\n el.attribs.embed = ''\n delete el.attribs['data-maizzle-embed']\n }\n })\n\n return result\n}\n"],"mappings":";;;;;;;;;;;;;;;;AAeA,SAAgB,UAAU,KAAkB,SAAoB,EAAE,EAAe;CAC/E,MAAM,SAAS,OAAO;AAGtB,KAAI,CAAC,OACH,QAAO;CAOT,MAAM,EACJ,uBAAuB,MACvB,UACA,YAAY,IACZ,kBACA,oBACA,eACA,gBACA,YACA,GAAG,qBAZW,OAAO,WAAW,WAAW,SAAS,EAAE;AAgBxD,OAAM,mBAAmB,oBAAoB,EAAE;AAC/C,OAAM,qBAAqB,CAAC,eAAe,GAAI,sBAAsB,EAAE,CAAE;AACzE,OAAM,iBAAiB,iBAAiB,CAAC,OAAO,QAAQ,EAAE,KAAI,MAAK,EAAE,aAAa,CAAC;AACnF,OAAM,kBAAkB,kBAAkB,CAAC,OAAO,QAAQ,EAAE,KAAI,MAAK,EAAE,aAAa,CAAC;AAGrF,KAAI,cAAc,OAAO,eAAe,SACtC,QAAO,QAAQ,WAAW,CAAC,SAAS,CAAC,KAAK,WAAW;AACnD,MAAI,MAAM,SAAS,MAAM,IACvB,OAAM,WAAW,OAAO;GAE1B;AAMJ,MAAK,MAAM,SAAS;EAClB,MAAM,KAAK;AACX,MAAI,GAAG,SAAS,WAAW,GAAG,SAAS;AAErC,OAAI,GAAG,QAAQ,SAAS,EAAE,gBAAgB,GAAG,SAC3C,IAAG,QAAQ,gBAAgB;AAE7B,OAAI,GAAG,QAAQ,iBAAiB,EAAE,WAAW,GAAG,SAC9C,IAAG,QAAQ,QAAQ;AAIrB,OAAI,gBAAgB,GAAG,QACrB,IAAG,QAAQ,wBAAwB;;GAGvC;CAGF,MAAM,aAAa,UAAU,IAAI;CAEjC,IAAI;AAEJ,KAAI;AAYF,gBAAc,MAAM,YAXe;GACjC,iBAAiB,iBAAiB,mBAAmB;GACrD,wBAAwB,iBAAiB,0BAA0B;GACnE,sBAAsB,iBAAiB,wBAAwB;GAC/D,uBAAuB,iBAAiB,yBAAyB;GACjE,oBAAoB,YAAY,EAAE;GAClC,GAAG,YAAY,EAAE,UAAU,WAAW,GAAG,EAAE;GAC3C,2BAA2B,iBAAiB,6BAA6B;GACzE,GAAG;GACJ,CAE4C;SACvC;AAEN,SAAO;;CAIT,MAAM,SAAS,MAAM,YAAY;AAEjC,MAAK,SAAS,SAAS;EACrB,MAAM,KAAK;AACX,MAAI,GAAG,SAAS,OAAO;GAErB,IAAI,QAAQ,GAAG,QAAQ,MACpB,QAAQ,SAAS,KAAK,CACtB,QAAQ,SAAS,KAAK,CACtB,SAAS;AAGZ,OAAI,CAAC,MAAM,SAAS,IAAI,CACtB,UAAS;AAGX,OAAI,qBACF,SAAQ,MAAM,QACZ,4DACA,IACD;AAGH,MAAG,QAAQ,QAAQ;;GAErB;AAIF,MAAK,SAAS,SAAS;EACrB,MAAM,KAAK;AACX,MAAI,GAAG,SAAS,WAAW,GAAG,WAAW,wBAAwB,GAAG,SAAS;AAC3E,MAAG,QAAQ,gBAAgB;AAC3B,MAAG,QAAQ,QAAQ;AACnB,UAAO,GAAG,QAAQ;;GAEpB;AAEF,QAAO"}
@@ -1 +1 @@
1
- {"version":3,"file":"purgeCSS.d.mts","names":[],"sources":["../../src/transformers/purgeCSS.ts"],"mappings":";;;;;;AA+CA;;;;;;;;;;;;;iBAAgB,QAAA,CAAS,GAAA,EAAK,SAAA,IAAa,MAAA,GAAQ,SAAA,GAAiB,SAAA"}
1
+ {"version":3,"file":"purgeCSS.d.mts","names":[],"sources":["../../src/transformers/purgeCSS.ts"],"mappings":";;;;;;AAkDA;;;;;;;;;;;;;iBAAgB,QAAA,CAAS,GAAA,EAAK,SAAA,IAAa,MAAA,GAAQ,SAAA,GAAiB,SAAA"}
@@ -1,7 +1,11 @@
1
1
  import { parse } from "../utils/ast/parser.mjs";
2
+ import { walk } from "../utils/ast/walker.mjs";
2
3
  import { serialize } from "../utils/ast/serializer.mjs";
3
4
  import "../utils/ast/index.mjs";
4
5
  import { defu } from "defu";
6
+ import postcss from "postcss";
7
+ import safeParser from "postcss-safe-parser";
8
+ import { selectAll } from "css-select";
5
9
  import { comb } from "email-comb";
6
10
 
7
11
  //#region src/transformers/purgeCSS.ts
@@ -57,8 +61,70 @@ function purgeCSS(dom, config = {}) {
57
61
  ...restUserOptions,
58
62
  whitelist: [...DEFAULT_SAFELIST, ...userSafelist]
59
63
  }, DEFAULT_OPTIONS);
64
+ const safelist = [...DEFAULT_SAFELIST, ...userSafelist];
65
+ dom = deepPurge(dom, safelist);
60
66
  const { result } = comb(serialize(dom), options);
61
- return parse(result);
67
+ let purgedDom = parse(result);
68
+ walk(purgedDom, (node) => {
69
+ const el = node;
70
+ if (el.name === "style" && el.attribs) {
71
+ delete el.attribs["data-embed"];
72
+ delete el.attribs.embed;
73
+ }
74
+ });
75
+ return purgedDom;
76
+ }
77
+ /**
78
+ * Deep purge: uses PostCSS to parse CSS in non-embedded style tags,
79
+ * then checks each selector against the DOM with css-select.
80
+ * Removes rules where no selector matches any element.
81
+ */
82
+ function isSafelisted(selector, safelist) {
83
+ return safelist.some((pattern) => {
84
+ if (pattern.startsWith("*") && pattern.endsWith("*")) return selector.includes(pattern.slice(1, -1));
85
+ if (pattern.endsWith("*")) return selector.startsWith(pattern.slice(0, -1));
86
+ if (pattern.startsWith("*")) return selector.endsWith(pattern.slice(1));
87
+ return selector === pattern;
88
+ });
89
+ }
90
+ function deepPurge(dom, safelist) {
91
+ walk(dom, (node) => {
92
+ const el = node;
93
+ if (el.name !== "style" || !el.attribs) return;
94
+ if ("data-embed" in el.attribs) return;
95
+ const textNode = el.children?.find((c) => c.type === "text");
96
+ if (!textNode?.data?.trim()) return;
97
+ const root = postcss.parse(textNode.data, { parser: safeParser });
98
+ root.walkRules((rule) => {
99
+ if (rule.parent?.type === "atrule") return;
100
+ const selectors = rule.selectors ?? [rule.selector];
101
+ const matched = selectors.filter((sel) => {
102
+ if (isSafelisted(sel, safelist)) return true;
103
+ if (/::[\w-]/.test(sel)) return true;
104
+ if (/(?<!:):(?!not\b|is\b|where\b|has\b)[\w-]/.test(sel.replace(/\\./g, ""))) return true;
105
+ try {
106
+ return selectAll(sel, dom).length > 0;
107
+ } catch {
108
+ return true;
109
+ }
110
+ });
111
+ if (matched.length === 0) rule.remove();
112
+ else if (matched.length < selectors.length) rule.selectors = matched;
113
+ });
114
+ root.walkAtRules((atRule) => {
115
+ if (atRule.nodes?.length === 0) atRule.remove();
116
+ });
117
+ const purgedCss = root.toString();
118
+ if (purgedCss.trim()) textNode.data = purgedCss;
119
+ else {
120
+ const parent = el.parent;
121
+ if (parent && "children" in parent) {
122
+ const idx = parent.children.indexOf(el);
123
+ if (idx !== -1) parent.children.splice(idx, 1);
124
+ }
125
+ }
126
+ });
127
+ return dom;
62
128
  }
63
129
 
64
130
  //#endregion