@maizzle/framework 6.0.0-rc.18 → 6.0.0-rc.19

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 (221) hide show
  1. package/dist/build.d.ts.map +1 -1
  2. package/dist/build.js +10 -6
  3. package/dist/build.js.map +1 -1
  4. package/dist/components/Button.vue +17 -39
  5. package/dist/components/Container.vue +6 -6
  6. package/dist/components/Hr.vue +20 -120
  7. package/dist/components/Html.vue +19 -1
  8. package/dist/components/NotPlaintext.vue +14 -0
  9. package/dist/components/{Vml.vue → OutlookBg.vue} +1 -1
  10. package/dist/components/Plaintext.vue +14 -0
  11. package/dist/components/QrCode.vue +157 -0
  12. package/dist/components/Spacer.vue +28 -27
  13. package/dist/components/utils.js +1 -1
  14. package/dist/components/utils.js.map +1 -1
  15. package/dist/composables/defineConfig.js +1 -2
  16. package/dist/composables/defineConfig.js.map +1 -1
  17. package/dist/composables/renderContext.js +1 -1
  18. package/dist/composables/useBaseUrl.js +3 -4
  19. package/dist/composables/useBaseUrl.js.map +1 -1
  20. package/dist/composables/useConfig.js +1 -2
  21. package/dist/composables/useConfig.js.map +1 -1
  22. package/dist/composables/useDoctype.js +1 -2
  23. package/dist/composables/useDoctype.js.map +1 -1
  24. package/dist/composables/useEvent.js +1 -2
  25. package/dist/composables/useEvent.js.map +1 -1
  26. package/dist/composables/useFont.js +1 -2
  27. package/dist/composables/useFont.js.map +1 -1
  28. package/dist/composables/useOutlookFallback.js +1 -2
  29. package/dist/composables/useOutlookFallback.js.map +1 -1
  30. package/dist/composables/usePlaintext.d.ts +2 -0
  31. package/dist/composables/usePlaintext.d.ts.map +1 -1
  32. package/dist/composables/usePlaintext.js +2 -2
  33. package/dist/composables/usePlaintext.js.map +1 -1
  34. package/dist/composables/usePreheader.js +1 -2
  35. package/dist/composables/usePreheader.js.map +1 -1
  36. package/dist/composables/useTransformers.d.ts +3 -3
  37. package/dist/composables/useTransformers.js +4 -5
  38. package/dist/composables/useTransformers.js.map +1 -1
  39. package/dist/composables/useUrlQuery.js +3 -4
  40. package/dist/composables/useUrlQuery.js.map +1 -1
  41. package/dist/config/defaults.js +1 -1
  42. package/dist/config/index.js +1 -2
  43. package/dist/config/index.js.map +1 -1
  44. package/dist/events/index.js +1 -1
  45. package/dist/events/index.js.map +1 -1
  46. package/dist/index.d.ts +9 -9
  47. package/dist/index.js +4 -5
  48. package/dist/plaintext.js +3 -4
  49. package/dist/plaintext.js.map +1 -1
  50. package/dist/plugin.js +1 -2
  51. package/dist/plugin.js.map +1 -1
  52. package/dist/plugins/postcss/mergeMediaQueries.js +1 -2
  53. package/dist/plugins/postcss/mergeMediaQueries.js.map +1 -1
  54. package/dist/plugins/postcss/pruneVars.js +1 -1
  55. package/dist/plugins/postcss/pruneVars.js.map +1 -1
  56. package/dist/plugins/postcss/quoteFontFamilies.js +1 -1
  57. package/dist/plugins/postcss/quoteFontFamilies.js.map +1 -1
  58. package/dist/plugins/postcss/removeDeclarations.js +1 -1
  59. package/dist/plugins/postcss/removeDeclarations.js.map +1 -1
  60. package/dist/plugins/postcss/resolveMaizzleImports.js +1 -2
  61. package/dist/plugins/postcss/resolveMaizzleImports.js.map +1 -1
  62. package/dist/plugins/postcss/resolveProps.js +1 -1
  63. package/dist/plugins/postcss/resolveProps.js.map +1 -1
  64. package/dist/plugins/postcss/tailwindCleanup.js +1 -1
  65. package/dist/plugins/postcss/tailwindCleanup.js.map +1 -1
  66. package/dist/prepare.js +1 -2
  67. package/dist/prepare.js.map +1 -1
  68. package/dist/render/active.d.ts +8 -0
  69. package/dist/render/active.d.ts.map +1 -0
  70. package/dist/render/active.js +12 -0
  71. package/dist/render/active.js.map +1 -0
  72. package/dist/render/createRenderer.d.ts.map +1 -1
  73. package/dist/render/createRenderer.js +6 -9
  74. package/dist/render/createRenderer.js.map +1 -1
  75. package/dist/render/index.d.ts.map +1 -1
  76. package/dist/render/index.js +13 -6
  77. package/dist/render/index.js.map +1 -1
  78. package/dist/render/injectFonts.js +1 -2
  79. package/dist/render/injectFonts.js.map +1 -1
  80. package/dist/render/plugins/codeBlockExtract.js +1 -1
  81. package/dist/render/plugins/codeBlockExtract.js.map +1 -1
  82. package/dist/render/plugins/markdownExtract.js +1 -2
  83. package/dist/render/plugins/markdownExtract.js.map +1 -1
  84. package/dist/render/plugins/rawExtract.js +1 -1
  85. package/dist/render/plugins/rawExtract.js.map +1 -1
  86. package/dist/render/plugins/rowSourceLocation.js +1 -1
  87. package/dist/render/plugins/rowSourceLocation.js.map +1 -1
  88. package/dist/serve.d.ts +2 -0
  89. package/dist/serve.d.ts.map +1 -1
  90. package/dist/serve.js +12 -7
  91. package/dist/serve.js.map +1 -1
  92. package/dist/server/compatibility.js +1 -2
  93. package/dist/server/compatibility.js.map +1 -1
  94. package/dist/server/email.js +1 -2
  95. package/dist/server/email.js.map +1 -1
  96. package/dist/server/linter.js +1 -2
  97. package/dist/server/linter.js.map +1 -1
  98. package/dist/server/sfc-utils.js +1 -2
  99. package/dist/server/sfc-utils.js.map +1 -1
  100. package/dist/tests/render/_helpers.d.ts +6 -0
  101. package/dist/tests/render/_helpers.d.ts.map +1 -0
  102. package/dist/tests/render/_helpers.js +16 -0
  103. package/dist/tests/render/_helpers.js.map +1 -0
  104. package/dist/transformers/addAttributes.js +3 -4
  105. package/dist/transformers/addAttributes.js.map +1 -1
  106. package/dist/transformers/attributeToStyle.d.ts +27 -14
  107. package/dist/transformers/attributeToStyle.d.ts.map +1 -1
  108. package/dist/transformers/attributeToStyle.js +34 -20
  109. package/dist/transformers/attributeToStyle.js.map +1 -1
  110. package/dist/transformers/base.d.ts +66 -3
  111. package/dist/transformers/base.d.ts.map +1 -1
  112. package/dist/transformers/base.js +50 -24
  113. package/dist/transformers/base.js.map +1 -1
  114. package/dist/transformers/columnWidth.js +1 -2
  115. package/dist/transformers/columnWidth.js.map +1 -1
  116. package/dist/transformers/entities.d.ts +31 -2
  117. package/dist/transformers/entities.d.ts.map +1 -1
  118. package/dist/transformers/entities.js +39 -7
  119. package/dist/transformers/entities.js.map +1 -1
  120. package/dist/transformers/filters/defaults.js +1 -1
  121. package/dist/transformers/filters/defaults.js.map +1 -1
  122. package/dist/transformers/filters/index.d.ts +31 -10
  123. package/dist/transformers/filters/index.d.ts.map +1 -1
  124. package/dist/transformers/filters/index.js +36 -14
  125. package/dist/transformers/filters/index.js.map +1 -1
  126. package/dist/transformers/format.d.ts +14 -7
  127. package/dist/transformers/format.d.ts.map +1 -1
  128. package/dist/transformers/format.js +15 -11
  129. package/dist/transformers/format.js.map +1 -1
  130. package/dist/transformers/index.js +49 -29
  131. package/dist/transformers/index.js.map +1 -1
  132. package/dist/transformers/inlineCss.d.ts +84 -0
  133. package/dist/transformers/inlineCss.d.ts.map +1 -0
  134. package/dist/transformers/{inlineCSS.js → inlineCss.js} +24 -14
  135. package/dist/transformers/inlineCss.js.map +1 -0
  136. package/dist/transformers/inlineLink.d.ts +26 -5
  137. package/dist/transformers/inlineLink.d.ts.map +1 -1
  138. package/dist/transformers/inlineLink.js +31 -7
  139. package/dist/transformers/inlineLink.js.map +1 -1
  140. package/dist/transformers/minify.d.ts +13 -9
  141. package/dist/transformers/minify.d.ts.map +1 -1
  142. package/dist/transformers/minify.js +14 -13
  143. package/dist/transformers/minify.js.map +1 -1
  144. package/dist/transformers/msoPlaceholders.js +1 -2
  145. package/dist/transformers/msoPlaceholders.js.map +1 -1
  146. package/dist/transformers/purgeCss.d.ts +43 -0
  147. package/dist/transformers/purgeCss.d.ts.map +1 -0
  148. package/dist/transformers/{purgeCSS.js → purgeCss.js} +32 -25
  149. package/dist/transformers/purgeCss.js.map +1 -0
  150. package/dist/transformers/removeAttributes.d.ts +43 -20
  151. package/dist/transformers/removeAttributes.d.ts.map +1 -1
  152. package/dist/transformers/removeAttributes.js +34 -27
  153. package/dist/transformers/removeAttributes.js.map +1 -1
  154. package/dist/transformers/replaceStrings.js +1 -1
  155. package/dist/transformers/replaceStrings.js.map +1 -1
  156. package/dist/transformers/safeClassNames.js +1 -2
  157. package/dist/transformers/safeClassNames.js.map +1 -1
  158. package/dist/transformers/shorthandCss.d.ts +47 -0
  159. package/dist/transformers/shorthandCss.d.ts.map +1 -0
  160. package/dist/transformers/shorthandCss.js +61 -0
  161. package/dist/transformers/shorthandCss.js.map +1 -0
  162. package/dist/transformers/sixHex.d.ts +16 -7
  163. package/dist/transformers/sixHex.d.ts.map +1 -1
  164. package/dist/transformers/sixHex.js +21 -9
  165. package/dist/transformers/sixHex.js.map +1 -1
  166. package/dist/transformers/tailwindComponent.js +1 -2
  167. package/dist/transformers/tailwindComponent.js.map +1 -1
  168. package/dist/transformers/tailwindcss.js +1 -2
  169. package/dist/transformers/tailwindcss.js.map +1 -1
  170. package/dist/transformers/urlQuery.d.ts +26 -14
  171. package/dist/transformers/urlQuery.d.ts.map +1 -1
  172. package/dist/transformers/urlQuery.js +32 -20
  173. package/dist/transformers/urlQuery.js.map +1 -1
  174. package/dist/types/config.d.ts +71 -19
  175. package/dist/types/config.d.ts.map +1 -1
  176. package/dist/types/config.js +1 -1
  177. package/dist/types/index.d.ts +2 -2
  178. package/dist/types/index.js +1 -1
  179. package/dist/utils/ast/index.js +1 -2
  180. package/dist/utils/ast/parser.js +1 -2
  181. package/dist/utils/ast/parser.js.map +1 -1
  182. package/dist/utils/ast/serializer.js +1 -2
  183. package/dist/utils/ast/serializer.js.map +1 -1
  184. package/dist/utils/ast/walker.js +1 -1
  185. package/dist/utils/ast/walker.js.map +1 -1
  186. package/dist/utils/compileTailwindCss.js +1 -2
  187. package/dist/utils/compileTailwindCss.js.map +1 -1
  188. package/dist/utils/decodeStyleEntities.js +1 -1
  189. package/dist/utils/decodeStyleEntities.js.map +1 -1
  190. package/dist/utils/detect.js +1 -2
  191. package/dist/utils/detect.js.map +1 -1
  192. package/dist/utils/output-markers.d.ts +29 -0
  193. package/dist/utils/output-markers.d.ts.map +1 -0
  194. package/dist/utils/output-markers.js +68 -0
  195. package/dist/utils/output-markers.js.map +1 -0
  196. package/dist/utils/url.js +1 -2
  197. package/dist/utils/url.js.map +1 -1
  198. package/node_modules/maizzle/README.md +24 -0
  199. package/node_modules/maizzle/dist/commands/make/component.mjs +1 -1
  200. package/node_modules/maizzle/dist/commands/make/config.mjs +1 -1
  201. package/node_modules/maizzle/dist/commands/make/layout.mjs +3 -3
  202. package/node_modules/maizzle/dist/commands/make/scaffold.mjs +1 -1
  203. package/node_modules/maizzle/dist/commands/make/stubs/Layout.vue +146 -0
  204. package/node_modules/maizzle/dist/commands/make/stubs/component.vue +2 -4
  205. package/node_modules/maizzle/dist/commands/make/stubs/config.ts +1 -5
  206. package/node_modules/maizzle/dist/commands/make/template.mjs +1 -1
  207. package/node_modules/maizzle/dist/commands/new.mjs +29 -24
  208. package/node_modules/maizzle/dist/index.mjs +28 -8
  209. package/node_modules/maizzle/package.json +1 -1
  210. package/package.json +2 -2
  211. package/dist/transformers/inlineCSS.d.ts +0 -17
  212. package/dist/transformers/inlineCSS.d.ts.map +0 -1
  213. package/dist/transformers/inlineCSS.js.map +0 -1
  214. package/dist/transformers/purgeCSS.d.ts +0 -23
  215. package/dist/transformers/purgeCSS.d.ts.map +0 -1
  216. package/dist/transformers/purgeCSS.js.map +0 -1
  217. package/dist/transformers/shorthandCSS.d.ts +0 -24
  218. package/dist/transformers/shorthandCSS.d.ts.map +0 -1
  219. package/dist/transformers/shorthandCSS.js +0 -48
  220. package/dist/transformers/shorthandCSS.js.map +0 -1
  221. package/node_modules/maizzle/dist/commands/make/stubs/layout.vue +0 -39
@@ -1,19 +1,31 @@
1
+ import { parse } from "../utils/ast/parser.js";
1
2
  import { walk } from "../utils/ast/walker.js";
3
+ import { serialize } from "../utils/ast/serializer.js";
2
4
  import "../utils/ast/index.js";
3
5
  import { conv } from "color-shorthand-hex-to-six-digit";
4
-
5
6
  //#region src/transformers/sixHex.ts
6
7
  const targets = new Set(["bgcolor", "color"]);
7
8
  /**
8
- * Six-digit HEX transformer.
9
- *
10
- * Converts 3-digit HEX color codes to 6-digit in `bgcolor` and `color`
9
+ * Convert 3-digit HEX color codes to 6-digit in `bgcolor` and `color`
11
10
  * attributes, for better email client compatibility.
12
11
  *
13
- * Enabled by default via `css.sixHex`.
12
+ * @param html HTML string to transform.
13
+ * @returns The transformed HTML string.
14
+ *
15
+ * @example
16
+ * import { sixHex } from '@maizzle/framework'
17
+ *
18
+ * const out = sixHex('<font color="#abc">x</font>')
14
19
  */
15
- function sixHex(dom, config = {}) {
16
- if (config.sixHex === false) return dom;
20
+ function sixHex(html) {
21
+ return serialize(sixHexDom(parse(html)));
22
+ }
23
+ /**
24
+ * DOM-form of {@link sixHex} used by the internal transformer pipeline.
25
+ * Takes a parsed DOM, returns a parsed DOM — avoids redundant
26
+ * serialize/parse round-trips when chained with other transformers.
27
+ */
28
+ function sixHexDom(dom) {
17
29
  walk(dom, (node) => {
18
30
  const el = node;
19
31
  if (!el.attribs) return;
@@ -24,7 +36,7 @@ function sixHex(dom, config = {}) {
24
36
  });
25
37
  return dom;
26
38
  }
27
-
28
39
  //#endregion
29
- export { sixHex };
40
+ export { sixHex, sixHexDom };
41
+
30
42
  //# sourceMappingURL=sixHex.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"sixHex.js","names":[],"sources":["../../src/transformers/sixHex.ts"],"sourcesContent":["import { conv } from 'color-shorthand-hex-to-six-digit'\nimport type { ChildNode, Element } from 'domhandler'\nimport { walk } from '../utils/ast/index.ts'\nimport type { CssConfig } from '../types/config.ts'\n\nconst targets = new Set(['bgcolor', 'color'])\n\n/**\n * Six-digit HEX transformer.\n *\n * Converts 3-digit HEX color codes to 6-digit in `bgcolor` and `color`\n * attributes, for better email client compatibility.\n *\n * Enabled by default via `css.sixHex`.\n */\nexport function sixHex(dom: ChildNode[], config: CssConfig = {}): ChildNode[] {\n if (config.sixHex === false) {\n return dom\n }\n\n walk(dom, (node) => {\n const el = node as Element\n\n if (!el.attribs) {\n return\n }\n\n for (const attr of targets) {\n const value = el.attribs[attr]\n\n if (value) {\n el.attribs[attr] = conv(value)\n }\n }\n })\n\n return dom\n}\n"],"mappings":";;;;;AAKA,MAAM,UAAU,IAAI,IAAI,CAAC,WAAW,QAAQ,CAAC;;;;;;;;;AAU7C,SAAgB,OAAO,KAAkB,SAAoB,EAAE,EAAe;AAC5E,KAAI,OAAO,WAAW,MACpB,QAAO;AAGT,MAAK,MAAM,SAAS;EAClB,MAAM,KAAK;AAEX,MAAI,CAAC,GAAG,QACN;AAGF,OAAK,MAAM,QAAQ,SAAS;GAC1B,MAAM,QAAQ,GAAG,QAAQ;AAEzB,OAAI,MACF,IAAG,QAAQ,QAAQ,KAAK,MAAM;;GAGlC;AAEF,QAAO"}
1
+ {"version":3,"file":"sixHex.js","names":[],"sources":["../../src/transformers/sixHex.ts"],"sourcesContent":["import { conv } from 'color-shorthand-hex-to-six-digit'\nimport type { ChildNode, Element } from 'domhandler'\nimport { parse, serialize, walk } from '../utils/ast/index.ts'\n\nconst targets = new Set(['bgcolor', 'color'])\n\n/**\n * Convert 3-digit HEX color codes to 6-digit in `bgcolor` and `color`\n * attributes, for better email client compatibility.\n *\n * @param html HTML string to transform.\n * @returns The transformed HTML string.\n *\n * @example\n * import { sixHex } from '@maizzle/framework'\n *\n * const out = sixHex('<font color=\"#abc\">x</font>')\n */\nexport function sixHex(html: string): string {\n return serialize(sixHexDom(parse(html)))\n}\n\n/**\n * DOM-form of {@link sixHex} used by the internal transformer pipeline.\n * Takes a parsed DOM, returns a parsed DOM — avoids redundant\n * serialize/parse round-trips when chained with other transformers.\n */\nexport function sixHexDom(dom: ChildNode[]): ChildNode[] {\n walk(dom, (node) => {\n const el = node as Element\n\n if (!el.attribs) {\n return\n }\n\n for (const attr of targets) {\n const value = el.attribs[attr]\n\n if (value) {\n el.attribs[attr] = conv(value)\n }\n }\n })\n\n return dom\n}\n"],"mappings":";;;;;;AAIA,MAAM,UAAU,IAAI,IAAI,CAAC,WAAW,QAAQ,CAAC;;;;;;;;;;;;;AAc7C,SAAgB,OAAO,MAAsB;CAC3C,OAAO,UAAU,UAAU,MAAM,KAAK,CAAC,CAAC;;;;;;;AAQ1C,SAAgB,UAAU,KAA+B;CACvD,KAAK,MAAM,SAAS;EAClB,MAAM,KAAK;EAEX,IAAI,CAAC,GAAG,SACN;EAGF,KAAK,MAAM,QAAQ,SAAS;GAC1B,MAAM,QAAQ,GAAG,QAAQ;GAEzB,IAAI,OACF,GAAG,QAAQ,QAAQ,KAAK,MAAM;;GAGlC;CAEF,OAAO"}
@@ -2,7 +2,6 @@ import { walk } from "../utils/ast/walker.js";
2
2
  import "../utils/ast/index.js";
3
3
  import { compileTailwindCss } from "../utils/compileTailwindCss.js";
4
4
  import { resolve } from "node:path";
5
-
6
5
  //#region src/transformers/tailwindComponent.ts
7
6
  const DEFAULT_SEED = "@import \"@maizzle/tailwindcss\";";
8
7
  const OPEN_RE = /^mz-tw:(\S+)$/;
@@ -87,7 +86,7 @@ function buildCssInput(configCss, classes) {
87
86
  if (!classes.size) return seed;
88
87
  return `${seed}\n@source inline("${[...classes].join(" ").replace(/"/g, "\\\"")}");`;
89
88
  }
90
-
91
89
  //#endregion
92
90
  export { tailwindComponent };
91
+
93
92
  //# sourceMappingURL=tailwindComponent.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"tailwindComponent.js","names":[],"sources":["../../src/transformers/tailwindComponent.ts"],"sourcesContent":["import { resolve } from 'node:path'\nimport type { ChildNode, Element, Comment } from 'domhandler'\nimport { walk } from '../utils/ast/index.ts'\nimport { compileTailwindCss } from '../utils/compileTailwindCss.ts'\nimport type { TailwindBlock } from '../composables/renderContext.ts'\nimport type { MaizzleConfig } from '../types/config.ts'\n\nconst DEFAULT_SEED = '@import \"@maizzle/tailwindcss\";'\n\ninterface BlockMeta {\n id: string\n configCss?: string\n nested: boolean\n classes: Set<string>\n}\n\nconst OPEN_RE = /^mz-tw:(\\S+)$/\nconst CLOSE_RE = /^\\/mz-tw:(\\S+)$/\n\n/**\n * Compile Tailwind CSS for each top-level <Tailwind> block in the render\n * context. Nested <Tailwind> instances are flattened: their classes flow\n * up to the outermost block, their `#config` slot (if any) is ignored.\n * One <style> per outermost block is appended to <head>; marker comments\n * are stripped after.\n */\nexport async function tailwindComponent(\n dom: ChildNode[],\n blocks: TailwindBlock[],\n config: MaizzleConfig,\n filePath?: string,\n): Promise<ChildNode[]> {\n if (!blocks.length) return dom\n\n const map = new Map<string, BlockMeta>()\n for (const b of blocks) {\n map.set(b.id, { id: b.id, configCss: b.css, nested: false, classes: new Set() })\n }\n\n const stack: string[] = []\n const markers: Comment[] = []\n\n walk(dom, (node) => {\n if (node.type === 'comment') {\n const data = (node as Comment).data\n const open = data.match(OPEN_RE)\n const close = data.match(CLOSE_RE)\n if (open) {\n const id = open[1]\n const meta = map.get(id)\n if (meta && stack.length > 0) meta.nested = true\n if (meta) stack.push(id)\n markers.push(node as Comment)\n } else if (close) {\n const id = close[1]\n if (stack[stack.length - 1] === id) stack.pop()\n markers.push(node as Comment)\n }\n return\n }\n\n const el = node as Element\n // Always assign to the OUTERMOST active marker (stack[0]) so nested\n // <Tailwind> blocks merge their classes into the parent's scope.\n if (el.attribs?.class && stack.length > 0) {\n map.get(stack[0])!.classes.add(el.attribs.class)\n }\n })\n\n const fromPath = filePath ?? resolve(process.cwd(), 'template.vue')\n\n let head: Element | undefined\n walk(dom, (n) => {\n if (!head && (n as Element).name === 'head') head = n as Element\n })\n\n if (!head) {\n throw new Error('`Tailwind` component requires `Head` component to be present in the template.')\n }\n\n // Compile + inject one <style raw> per outermost block. `raw` opts the\n // existing tailwindcss transformer out of recompiling already-compiled CSS.\n for (const meta of map.values()) {\n if (meta.nested) continue\n\n const cssInput = buildCssInput(meta.configCss, meta.classes)\n const css = (await compileTailwindCss(cssInput, config, `${fromPath}?tw=${meta.id}`)).trim()\n if (!css) continue\n\n const styleNode: Element = {\n type: 'tag',\n name: 'style',\n attribs: { raw: '' },\n children: [],\n parent: head,\n prev: null,\n next: null,\n } as any\n\n const textNode = {\n type: 'text',\n data: css,\n parent: styleNode,\n prev: null,\n next: null,\n } as any\n\n styleNode.children = [textNode]\n head.children.push(styleNode)\n }\n\n // Strip marker comments from their parents\n for (const c of markers) {\n const parent = c.parent as Element | null\n if (!parent?.children) continue\n const i = parent.children.indexOf(c)\n if (i >= 0) parent.children.splice(i, 1)\n }\n\n return dom\n}\n\nfunction buildCssInput(configCss: string | undefined, classes: Set<string>): string {\n const seed = configCss ?? DEFAULT_SEED\n\n if (!classes.size) return seed\n\n const inline = [...classes].join(' ').replace(/\"/g, '\\\\\"')\n return `${seed}\\n@source inline(\"${inline}\");`\n}\n"],"mappings":";;;;;;AAOA,MAAM,eAAe;AASrB,MAAM,UAAU;AAChB,MAAM,WAAW;;;;;;;;AASjB,eAAsB,kBACpB,KACA,QACA,QACA,UACsB;AACtB,KAAI,CAAC,OAAO,OAAQ,QAAO;CAE3B,MAAM,sBAAM,IAAI,KAAwB;AACxC,MAAK,MAAM,KAAK,OACd,KAAI,IAAI,EAAE,IAAI;EAAE,IAAI,EAAE;EAAI,WAAW,EAAE;EAAK,QAAQ;EAAO,yBAAS,IAAI,KAAK;EAAE,CAAC;CAGlF,MAAM,QAAkB,EAAE;CAC1B,MAAM,UAAqB,EAAE;AAE7B,MAAK,MAAM,SAAS;AAClB,MAAI,KAAK,SAAS,WAAW;GAC3B,MAAM,OAAQ,KAAiB;GAC/B,MAAM,OAAO,KAAK,MAAM,QAAQ;GAChC,MAAM,QAAQ,KAAK,MAAM,SAAS;AAClC,OAAI,MAAM;IACR,MAAM,KAAK,KAAK;IAChB,MAAM,OAAO,IAAI,IAAI,GAAG;AACxB,QAAI,QAAQ,MAAM,SAAS,EAAG,MAAK,SAAS;AAC5C,QAAI,KAAM,OAAM,KAAK,GAAG;AACxB,YAAQ,KAAK,KAAgB;cACpB,OAAO;IAChB,MAAM,KAAK,MAAM;AACjB,QAAI,MAAM,MAAM,SAAS,OAAO,GAAI,OAAM,KAAK;AAC/C,YAAQ,KAAK,KAAgB;;AAE/B;;EAGF,MAAM,KAAK;AAGX,MAAI,GAAG,SAAS,SAAS,MAAM,SAAS,EACtC,KAAI,IAAI,MAAM,GAAG,CAAE,QAAQ,IAAI,GAAG,QAAQ,MAAM;GAElD;CAEF,MAAM,WAAW,YAAY,QAAQ,QAAQ,KAAK,EAAE,eAAe;CAEnE,IAAI;AACJ,MAAK,MAAM,MAAM;AACf,MAAI,CAAC,QAAS,EAAc,SAAS,OAAQ,QAAO;GACpD;AAEF,KAAI,CAAC,KACH,OAAM,IAAI,MAAM,gFAAgF;AAKlG,MAAK,MAAM,QAAQ,IAAI,QAAQ,EAAE;AAC/B,MAAI,KAAK,OAAQ;EAGjB,MAAM,OAAO,MAAM,mBADF,cAAc,KAAK,WAAW,KAAK,QAAQ,EACZ,QAAQ,GAAG,SAAS,MAAM,KAAK,KAAK,EAAE,MAAM;AAC5F,MAAI,CAAC,IAAK;EAEV,MAAM,YAAqB;GACzB,MAAM;GACN,MAAM;GACN,SAAS,EAAE,KAAK,IAAI;GACpB,UAAU,EAAE;GACZ,QAAQ;GACR,MAAM;GACN,MAAM;GACP;AAUD,YAAU,WAAW,CARJ;GACf,MAAM;GACN,MAAM;GACN,QAAQ;GACR,MAAM;GACN,MAAM;GACP,CAE8B;AAC/B,OAAK,SAAS,KAAK,UAAU;;AAI/B,MAAK,MAAM,KAAK,SAAS;EACvB,MAAM,SAAS,EAAE;AACjB,MAAI,CAAC,QAAQ,SAAU;EACvB,MAAM,IAAI,OAAO,SAAS,QAAQ,EAAE;AACpC,MAAI,KAAK,EAAG,QAAO,SAAS,OAAO,GAAG,EAAE;;AAG1C,QAAO;;AAGT,SAAS,cAAc,WAA+B,SAA8B;CAClF,MAAM,OAAO,aAAa;AAE1B,KAAI,CAAC,QAAQ,KAAM,QAAO;AAG1B,QAAO,GAAG,KAAK,oBADA,CAAC,GAAG,QAAQ,CAAC,KAAK,IAAI,CAAC,QAAQ,MAAM,OAAM,CAChB"}
1
+ {"version":3,"file":"tailwindComponent.js","names":[],"sources":["../../src/transformers/tailwindComponent.ts"],"sourcesContent":["import { resolve } from 'node:path'\nimport type { ChildNode, Element, Comment } from 'domhandler'\nimport { walk } from '../utils/ast/index.ts'\nimport { compileTailwindCss } from '../utils/compileTailwindCss.ts'\nimport type { TailwindBlock } from '../composables/renderContext.ts'\nimport type { MaizzleConfig } from '../types/config.ts'\n\nconst DEFAULT_SEED = '@import \"@maizzle/tailwindcss\";'\n\ninterface BlockMeta {\n id: string\n configCss?: string\n nested: boolean\n classes: Set<string>\n}\n\nconst OPEN_RE = /^mz-tw:(\\S+)$/\nconst CLOSE_RE = /^\\/mz-tw:(\\S+)$/\n\n/**\n * Compile Tailwind CSS for each top-level <Tailwind> block in the render\n * context. Nested <Tailwind> instances are flattened: their classes flow\n * up to the outermost block, their `#config` slot (if any) is ignored.\n * One <style> per outermost block is appended to <head>; marker comments\n * are stripped after.\n */\nexport async function tailwindComponent(\n dom: ChildNode[],\n blocks: TailwindBlock[],\n config: MaizzleConfig,\n filePath?: string,\n): Promise<ChildNode[]> {\n if (!blocks.length) return dom\n\n const map = new Map<string, BlockMeta>()\n for (const b of blocks) {\n map.set(b.id, { id: b.id, configCss: b.css, nested: false, classes: new Set() })\n }\n\n const stack: string[] = []\n const markers: Comment[] = []\n\n walk(dom, (node) => {\n if (node.type === 'comment') {\n const data = (node as Comment).data\n const open = data.match(OPEN_RE)\n const close = data.match(CLOSE_RE)\n if (open) {\n const id = open[1]\n const meta = map.get(id)\n if (meta && stack.length > 0) meta.nested = true\n if (meta) stack.push(id)\n markers.push(node as Comment)\n } else if (close) {\n const id = close[1]\n if (stack[stack.length - 1] === id) stack.pop()\n markers.push(node as Comment)\n }\n return\n }\n\n const el = node as Element\n // Always assign to the OUTERMOST active marker (stack[0]) so nested\n // <Tailwind> blocks merge their classes into the parent's scope.\n if (el.attribs?.class && stack.length > 0) {\n map.get(stack[0])!.classes.add(el.attribs.class)\n }\n })\n\n const fromPath = filePath ?? resolve(process.cwd(), 'template.vue')\n\n let head: Element | undefined\n walk(dom, (n) => {\n if (!head && (n as Element).name === 'head') head = n as Element\n })\n\n if (!head) {\n throw new Error('`Tailwind` component requires `Head` component to be present in the template.')\n }\n\n // Compile + inject one <style raw> per outermost block. `raw` opts the\n // existing tailwindcss transformer out of recompiling already-compiled CSS.\n for (const meta of map.values()) {\n if (meta.nested) continue\n\n const cssInput = buildCssInput(meta.configCss, meta.classes)\n const css = (await compileTailwindCss(cssInput, config, `${fromPath}?tw=${meta.id}`)).trim()\n if (!css) continue\n\n const styleNode: Element = {\n type: 'tag',\n name: 'style',\n attribs: { raw: '' },\n children: [],\n parent: head,\n prev: null,\n next: null,\n } as any\n\n const textNode = {\n type: 'text',\n data: css,\n parent: styleNode,\n prev: null,\n next: null,\n } as any\n\n styleNode.children = [textNode]\n head.children.push(styleNode)\n }\n\n // Strip marker comments from their parents\n for (const c of markers) {\n const parent = c.parent as Element | null\n if (!parent?.children) continue\n const i = parent.children.indexOf(c)\n if (i >= 0) parent.children.splice(i, 1)\n }\n\n return dom\n}\n\nfunction buildCssInput(configCss: string | undefined, classes: Set<string>): string {\n const seed = configCss ?? DEFAULT_SEED\n\n if (!classes.size) return seed\n\n const inline = [...classes].join(' ').replace(/\"/g, '\\\\\"')\n return `${seed}\\n@source inline(\"${inline}\");`\n}\n"],"mappings":";;;;;AAOA,MAAM,eAAe;AASrB,MAAM,UAAU;AAChB,MAAM,WAAW;;;;;;;;AASjB,eAAsB,kBACpB,KACA,QACA,QACA,UACsB;CACtB,IAAI,CAAC,OAAO,QAAQ,OAAO;CAE3B,MAAM,sBAAM,IAAI,KAAwB;CACxC,KAAK,MAAM,KAAK,QACd,IAAI,IAAI,EAAE,IAAI;EAAE,IAAI,EAAE;EAAI,WAAW,EAAE;EAAK,QAAQ;EAAO,yBAAS,IAAI,KAAK;EAAE,CAAC;CAGlF,MAAM,QAAkB,EAAE;CAC1B,MAAM,UAAqB,EAAE;CAE7B,KAAK,MAAM,SAAS;EAClB,IAAI,KAAK,SAAS,WAAW;GAC3B,MAAM,OAAQ,KAAiB;GAC/B,MAAM,OAAO,KAAK,MAAM,QAAQ;GAChC,MAAM,QAAQ,KAAK,MAAM,SAAS;GAClC,IAAI,MAAM;IACR,MAAM,KAAK,KAAK;IAChB,MAAM,OAAO,IAAI,IAAI,GAAG;IACxB,IAAI,QAAQ,MAAM,SAAS,GAAG,KAAK,SAAS;IAC5C,IAAI,MAAM,MAAM,KAAK,GAAG;IACxB,QAAQ,KAAK,KAAgB;UACxB,IAAI,OAAO;IAChB,MAAM,KAAK,MAAM;IACjB,IAAI,MAAM,MAAM,SAAS,OAAO,IAAI,MAAM,KAAK;IAC/C,QAAQ,KAAK,KAAgB;;GAE/B;;EAGF,MAAM,KAAK;EAGX,IAAI,GAAG,SAAS,SAAS,MAAM,SAAS,GACtC,IAAI,IAAI,MAAM,GAAG,CAAE,QAAQ,IAAI,GAAG,QAAQ,MAAM;GAElD;CAEF,MAAM,WAAW,YAAY,QAAQ,QAAQ,KAAK,EAAE,eAAe;CAEnE,IAAI;CACJ,KAAK,MAAM,MAAM;EACf,IAAI,CAAC,QAAS,EAAc,SAAS,QAAQ,OAAO;GACpD;CAEF,IAAI,CAAC,MACH,MAAM,IAAI,MAAM,gFAAgF;CAKlG,KAAK,MAAM,QAAQ,IAAI,QAAQ,EAAE;EAC/B,IAAI,KAAK,QAAQ;EAGjB,MAAM,OAAO,MAAM,mBADF,cAAc,KAAK,WAAW,KAAK,QACN,EAAE,QAAQ,GAAG,SAAS,MAAM,KAAK,KAAK,EAAE,MAAM;EAC5F,IAAI,CAAC,KAAK;EAEV,MAAM,YAAqB;GACzB,MAAM;GACN,MAAM;GACN,SAAS,EAAE,KAAK,IAAI;GACpB,UAAU,EAAE;GACZ,QAAQ;GACR,MAAM;GACN,MAAM;GACP;EAUD,UAAU,WAAW,CAAC;GAPpB,MAAM;GACN,MAAM;GACN,QAAQ;GACR,MAAM;GACN,MAAM;GAGsB,CAAC;EAC/B,KAAK,SAAS,KAAK,UAAU;;CAI/B,KAAK,MAAM,KAAK,SAAS;EACvB,MAAM,SAAS,EAAE;EACjB,IAAI,CAAC,QAAQ,UAAU;EACvB,MAAM,IAAI,OAAO,SAAS,QAAQ,EAAE;EACpC,IAAI,KAAK,GAAG,OAAO,SAAS,OAAO,GAAG,EAAE;;CAG1C,OAAO;;AAGT,SAAS,cAAc,WAA+B,SAA8B;CAClF,MAAM,OAAO,aAAa;CAE1B,IAAI,CAAC,QAAQ,MAAM,OAAO;CAG1B,OAAO,GAAG,KAAK,oBADA,CAAC,GAAG,QAAQ,CAAC,KAAK,IAAI,CAAC,QAAQ,MAAM,OACX,CAAC"}
@@ -3,7 +3,6 @@ import "../utils/ast/index.js";
3
3
  import { compileTailwindCss } from "../utils/compileTailwindCss.js";
4
4
  import { decodeStyleEntities } from "../utils/decodeStyleEntities.js";
5
5
  import { dirname, relative, resolve } from "node:path";
6
-
7
6
  //#region src/transformers/tailwindcss.ts
8
7
  /**
9
8
  * Check if CSS content uses Tailwind features that require source scanning.
@@ -92,7 +91,7 @@ async function tailwindcss(dom, config, filePath) {
92
91
  }
93
92
  return dom;
94
93
  }
95
-
96
94
  //#endregion
97
95
  export { tailwindcss };
96
+
98
97
  //# sourceMappingURL=tailwindcss.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"tailwindcss.js","names":[],"sources":["../../src/transformers/tailwindcss.ts"],"sourcesContent":["import { resolve, dirname, relative } from 'node:path'\nimport type { ChildNode, Element } from 'domhandler'\nimport { walk } from '../utils/ast/index.ts'\nimport { decodeStyleEntities } from '../utils/decodeStyleEntities.ts'\nimport { compileTailwindCss } from '../utils/compileTailwindCss.ts'\nimport type { MaizzleConfig } from '../types/config.ts'\n\n/**\n * Check if CSS content uses Tailwind features that require source scanning.\n *\n * Only CSS that imports Tailwind (or @maizzle/tailwindcss) needs @source\n * directives. Plain CSS without Tailwind imports doesn't need scanning\n * and would pass through @source directives unconsumed.\n */\nfunction usesTailwind(css: string): boolean {\n return /((@import|@reference)\\s+[\"'](tailwindcss|@maizzle\\/tailwindcss)|@tailwind\\s)/.test(css)\n}\n\n/**\n * Build @source directives for Tailwind CSS scanning.\n *\n * Configures two types of sources:\n * 1. Exclusions for output dir and user-configured paths\n * 2. Inline source with all class attribute values from the rendered DOM,\n * capturing classes from all components (built-in + user), dynamic\n * expressions, and the template itself — Tailwind's scanner handles\n * the actual class extraction from these raw values\n */\nfunction buildSourceDirectives(dom: ChildNode[], config: MaizzleConfig, fromDir: string): string {\n const directives: string[] = []\n\n // Exclude output dir and user-configured paths\n const excludePaths = [\n resolve(config.output?.path ?? 'dist'),\n ...(config.css?.exclude ?? []).map(p => resolve(p)),\n ]\n\n for (const p of excludePaths) {\n directives.push(`@source not \"${relative(fromDir, resolve(p))}\";`)\n }\n\n // Inline source: collect all class attribute values from the rendered DOM.\n // After Vue SSR, the DOM contains every class from every component\n // (built-in framework components, user components, dynamic bindings).\n // We pass these raw values to Tailwind's scanner via @source inline().\n const classes: string[] = []\n walk(dom, (n) => {\n const cls = (n as Element).attribs?.class\n if (cls) classes.push(cls)\n })\n\n if (classes.length) {\n directives.push(`@source inline(\"${classes.join(' ')}\");`)\n }\n\n return directives.join('\\n')\n}\n\n/**\n * Tailwind CSS transformer.\n *\n * Compiles CSS inside <style> tags in the DOM using\n * @tailwindcss/postcss, then lowers modern CSS syntax with lightningcss.\n *\n * Configures Tailwind sources to scan:\n * - Rendered class attributes (via `@source inline`) for all classes from all components\n * - User project files (via Tailwind's auto-detection from base/from path)\n *\n * User `@source` and `@source not directives` in style tags are preserved.\n * Source directives are only added to style tags that import Tailwind.\n *\n * Runs as the first transformer in the pipeline so that subsequent\n * transformers (inliner, purge, etc.) work with fully compiled CSS.\n */\nexport async function tailwindcss(dom: ChildNode[], config: MaizzleConfig, filePath?: string): Promise<ChildNode[]> {\n const styleTags: { node: Element; cssContent: string }[] = []\n\n walk(dom, (node) => {\n if ((node as Element).name !== 'style') return\n\n const el = node as Element\n const attrs = el.attribs || {}\n\n // `raw` opts out of compilation entirely (marker is consumed here).\n // `embed`/`data-embed` only signal \"preserve tag after inlining\" — they\n // still need to go through compile so Tailwind/@apply resolves.\n if ('raw' in attrs) {\n delete el.attribs.raw\n return\n }\n\n // Get text content from children and decode HTML entities\n const rawContent = el.children\n .filter(child => child.type === 'text')\n .map(child => (child as any).data)\n .join('')\n\n if (!rawContent.trim()) return\n\n styleTags.push({ node: el, cssContent: decodeStyleEntities(rawContent) })\n })\n\n if (!styleTags.length) return dom\n\n const fromPath = filePath ?? resolve(process.cwd(), 'template.vue')\n const fromDir = dirname(fromPath)\n\n // Only compute source directives if at least one style tag uses Tailwind\n const hasTailwindStyles = styleTags.some(({ cssContent }) => usesTailwind(cssContent))\n const sourceDirectives = hasTailwindStyles\n ? buildSourceDirectives(dom, config, fromDir)\n : ''\n\n for (let i = 0; i < styleTags.length; i++) {\n const { node, cssContent } = styleTags[i]\n\n // Only add source directives to style tags that import Tailwind —\n // plain CSS doesn't need them and @tailwindcss/postcss would leave\n // the directives unconsumed in the output\n const fullCss = usesTailwind(cssContent)\n ? `${cssContent}\\n${sourceDirectives}`\n : cssContent\n\n try {\n const optimized = await compileTailwindCss(fullCss, config, `${fromPath}?style=${i}`)\n\n // Replace the style tag's children with the compiled CSS\n node.children = [{\n type: 'text',\n data: optimized,\n parent: node,\n } as any]\n } catch {\n // If CSS processing fails, still replace with decoded content\n // so HTML entities don't break the CSS\n node.children = [{\n type: 'text',\n data: cssContent,\n parent: node,\n } as any]\n }\n }\n\n return dom\n}\n"],"mappings":";;;;;;;;;;;;;;AAcA,SAAS,aAAa,KAAsB;AAC1C,QAAO,+EAA+E,KAAK,IAAI;;;;;;;;;;;;AAajG,SAAS,sBAAsB,KAAkB,QAAuB,SAAyB;CAC/F,MAAM,aAAuB,EAAE;CAG/B,MAAM,eAAe,CACnB,QAAQ,OAAO,QAAQ,QAAQ,OAAO,EACtC,IAAI,OAAO,KAAK,WAAW,EAAE,EAAE,KAAI,MAAK,QAAQ,EAAE,CAAC,CACpD;AAED,MAAK,MAAM,KAAK,aACd,YAAW,KAAK,gBAAgB,SAAS,SAAS,QAAQ,EAAE,CAAC,CAAC,IAAI;CAOpE,MAAM,UAAoB,EAAE;AAC5B,MAAK,MAAM,MAAM;EACf,MAAM,MAAO,EAAc,SAAS;AACpC,MAAI,IAAK,SAAQ,KAAK,IAAI;GAC1B;AAEF,KAAI,QAAQ,OACV,YAAW,KAAK,mBAAmB,QAAQ,KAAK,IAAI,CAAC,KAAK;AAG5D,QAAO,WAAW,KAAK,KAAK;;;;;;;;;;;;;;;;;;AAmB9B,eAAsB,YAAY,KAAkB,QAAuB,UAAyC;CAClH,MAAM,YAAqD,EAAE;AAE7D,MAAK,MAAM,SAAS;AAClB,MAAK,KAAiB,SAAS,QAAS;EAExC,MAAM,KAAK;AAMX,MAAI,UALU,GAAG,WAAW,EAAE,GAKV;AAClB,UAAO,GAAG,QAAQ;AAClB;;EAIF,MAAM,aAAa,GAAG,SACnB,QAAO,UAAS,MAAM,SAAS,OAAO,CACtC,KAAI,UAAU,MAAc,KAAK,CACjC,KAAK,GAAG;AAEX,MAAI,CAAC,WAAW,MAAM,CAAE;AAExB,YAAU,KAAK;GAAE,MAAM;GAAI,YAAY,oBAAoB,WAAW;GAAE,CAAC;GACzE;AAEF,KAAI,CAAC,UAAU,OAAQ,QAAO;CAE9B,MAAM,WAAW,YAAY,QAAQ,QAAQ,KAAK,EAAE,eAAe;CACnE,MAAM,UAAU,QAAQ,SAAS;CAIjC,MAAM,mBADoB,UAAU,MAAM,EAAE,iBAAiB,aAAa,WAAW,CAAC,GAElF,sBAAsB,KAAK,QAAQ,QAAQ,GAC3C;AAEJ,MAAK,IAAI,IAAI,GAAG,IAAI,UAAU,QAAQ,KAAK;EACzC,MAAM,EAAE,MAAM,eAAe,UAAU;EAKvC,MAAM,UAAU,aAAa,WAAW,GACpC,GAAG,WAAW,IAAI,qBAClB;AAEJ,MAAI;AAIF,QAAK,WAAW,CAAC;IACf,MAAM;IACN,MALgB,MAAM,mBAAmB,SAAS,QAAQ,GAAG,SAAS,SAAS,IAAI;IAMnF,QAAQ;IACT,CAAQ;UACH;AAGN,QAAK,WAAW,CAAC;IACf,MAAM;IACN,MAAM;IACN,QAAQ;IACT,CAAQ;;;AAIb,QAAO"}
1
+ {"version":3,"file":"tailwindcss.js","names":[],"sources":["../../src/transformers/tailwindcss.ts"],"sourcesContent":["import { resolve, dirname, relative } from 'node:path'\nimport type { ChildNode, Element } from 'domhandler'\nimport { walk } from '../utils/ast/index.ts'\nimport { decodeStyleEntities } from '../utils/decodeStyleEntities.ts'\nimport { compileTailwindCss } from '../utils/compileTailwindCss.ts'\nimport type { MaizzleConfig } from '../types/config.ts'\n\n/**\n * Check if CSS content uses Tailwind features that require source scanning.\n *\n * Only CSS that imports Tailwind (or @maizzle/tailwindcss) needs @source\n * directives. Plain CSS without Tailwind imports doesn't need scanning\n * and would pass through @source directives unconsumed.\n */\nfunction usesTailwind(css: string): boolean {\n return /((@import|@reference)\\s+[\"'](tailwindcss|@maizzle\\/tailwindcss)|@tailwind\\s)/.test(css)\n}\n\n/**\n * Build @source directives for Tailwind CSS scanning.\n *\n * Configures two types of sources:\n * 1. Exclusions for output dir and user-configured paths\n * 2. Inline source with all class attribute values from the rendered DOM,\n * capturing classes from all components (built-in + user), dynamic\n * expressions, and the template itself — Tailwind's scanner handles\n * the actual class extraction from these raw values\n */\nfunction buildSourceDirectives(dom: ChildNode[], config: MaizzleConfig, fromDir: string): string {\n const directives: string[] = []\n\n // Exclude output dir and user-configured paths\n const excludePaths = [\n resolve(config.output?.path ?? 'dist'),\n ...(config.css?.exclude ?? []).map(p => resolve(p)),\n ]\n\n for (const p of excludePaths) {\n directives.push(`@source not \"${relative(fromDir, resolve(p))}\";`)\n }\n\n // Inline source: collect all class attribute values from the rendered DOM.\n // After Vue SSR, the DOM contains every class from every component\n // (built-in framework components, user components, dynamic bindings).\n // We pass these raw values to Tailwind's scanner via @source inline().\n const classes: string[] = []\n walk(dom, (n) => {\n const cls = (n as Element).attribs?.class\n if (cls) classes.push(cls)\n })\n\n if (classes.length) {\n directives.push(`@source inline(\"${classes.join(' ')}\");`)\n }\n\n return directives.join('\\n')\n}\n\n/**\n * Tailwind CSS transformer.\n *\n * Compiles CSS inside <style> tags in the DOM using\n * @tailwindcss/postcss, then lowers modern CSS syntax with lightningcss.\n *\n * Configures Tailwind sources to scan:\n * - Rendered class attributes (via `@source inline`) for all classes from all components\n * - User project files (via Tailwind's auto-detection from base/from path)\n *\n * User `@source` and `@source not directives` in style tags are preserved.\n * Source directives are only added to style tags that import Tailwind.\n *\n * Runs as the first transformer in the pipeline so that subsequent\n * transformers (inliner, purge, etc.) work with fully compiled CSS.\n */\nexport async function tailwindcss(dom: ChildNode[], config: MaizzleConfig, filePath?: string): Promise<ChildNode[]> {\n const styleTags: { node: Element; cssContent: string }[] = []\n\n walk(dom, (node) => {\n if ((node as Element).name !== 'style') return\n\n const el = node as Element\n const attrs = el.attribs || {}\n\n // `raw` opts out of compilation entirely (marker is consumed here).\n // `embed`/`data-embed` only signal \"preserve tag after inlining\" — they\n // still need to go through compile so Tailwind/@apply resolves.\n if ('raw' in attrs) {\n delete el.attribs.raw\n return\n }\n\n // Get text content from children and decode HTML entities\n const rawContent = el.children\n .filter(child => child.type === 'text')\n .map(child => (child as any).data)\n .join('')\n\n if (!rawContent.trim()) return\n\n styleTags.push({ node: el, cssContent: decodeStyleEntities(rawContent) })\n })\n\n if (!styleTags.length) return dom\n\n const fromPath = filePath ?? resolve(process.cwd(), 'template.vue')\n const fromDir = dirname(fromPath)\n\n // Only compute source directives if at least one style tag uses Tailwind\n const hasTailwindStyles = styleTags.some(({ cssContent }) => usesTailwind(cssContent))\n const sourceDirectives = hasTailwindStyles\n ? buildSourceDirectives(dom, config, fromDir)\n : ''\n\n for (let i = 0; i < styleTags.length; i++) {\n const { node, cssContent } = styleTags[i]\n\n // Only add source directives to style tags that import Tailwind —\n // plain CSS doesn't need them and @tailwindcss/postcss would leave\n // the directives unconsumed in the output\n const fullCss = usesTailwind(cssContent)\n ? `${cssContent}\\n${sourceDirectives}`\n : cssContent\n\n try {\n const optimized = await compileTailwindCss(fullCss, config, `${fromPath}?style=${i}`)\n\n // Replace the style tag's children with the compiled CSS\n node.children = [{\n type: 'text',\n data: optimized,\n parent: node,\n } as any]\n } catch {\n // If CSS processing fails, still replace with decoded content\n // so HTML entities don't break the CSS\n node.children = [{\n type: 'text',\n data: cssContent,\n parent: node,\n } as any]\n }\n }\n\n return dom\n}\n"],"mappings":";;;;;;;;;;;;;AAcA,SAAS,aAAa,KAAsB;CAC1C,OAAO,+EAA+E,KAAK,IAAI;;;;;;;;;;;;AAajG,SAAS,sBAAsB,KAAkB,QAAuB,SAAyB;CAC/F,MAAM,aAAuB,EAAE;CAG/B,MAAM,eAAe,CACnB,QAAQ,OAAO,QAAQ,QAAQ,OAAO,EACtC,IAAI,OAAO,KAAK,WAAW,EAAE,EAAE,KAAI,MAAK,QAAQ,EAAE,CAAC,CACpD;CAED,KAAK,MAAM,KAAK,cACd,WAAW,KAAK,gBAAgB,SAAS,SAAS,QAAQ,EAAE,CAAC,CAAC,IAAI;CAOpE,MAAM,UAAoB,EAAE;CAC5B,KAAK,MAAM,MAAM;EACf,MAAM,MAAO,EAAc,SAAS;EACpC,IAAI,KAAK,QAAQ,KAAK,IAAI;GAC1B;CAEF,IAAI,QAAQ,QACV,WAAW,KAAK,mBAAmB,QAAQ,KAAK,IAAI,CAAC,KAAK;CAG5D,OAAO,WAAW,KAAK,KAAK;;;;;;;;;;;;;;;;;;AAmB9B,eAAsB,YAAY,KAAkB,QAAuB,UAAyC;CAClH,MAAM,YAAqD,EAAE;CAE7D,KAAK,MAAM,SAAS;EAClB,IAAK,KAAiB,SAAS,SAAS;EAExC,MAAM,KAAK;EAMX,IAAI,UALU,GAAG,WAAW,EAAE,GAKV;GAClB,OAAO,GAAG,QAAQ;GAClB;;EAIF,MAAM,aAAa,GAAG,SACnB,QAAO,UAAS,MAAM,SAAS,OAAO,CACtC,KAAI,UAAU,MAAc,KAAK,CACjC,KAAK,GAAG;EAEX,IAAI,CAAC,WAAW,MAAM,EAAE;EAExB,UAAU,KAAK;GAAE,MAAM;GAAI,YAAY,oBAAoB,WAAW;GAAE,CAAC;GACzE;CAEF,IAAI,CAAC,UAAU,QAAQ,OAAO;CAE9B,MAAM,WAAW,YAAY,QAAQ,QAAQ,KAAK,EAAE,eAAe;CACnE,MAAM,UAAU,QAAQ,SAAS;CAIjC,MAAM,mBADoB,UAAU,MAAM,EAAE,iBAAiB,aAAa,WAAW,CAC3C,GACtC,sBAAsB,KAAK,QAAQ,QAAQ,GAC3C;CAEJ,KAAK,IAAI,IAAI,GAAG,IAAI,UAAU,QAAQ,KAAK;EACzC,MAAM,EAAE,MAAM,eAAe,UAAU;EAKvC,MAAM,UAAU,aAAa,WAAW,GACpC,GAAG,WAAW,IAAI,qBAClB;EAEJ,IAAI;GAIF,KAAK,WAAW,CAAC;IACf,MAAM;IACN,MAAM,MALgB,mBAAmB,SAAS,QAAQ,GAAG,SAAS,SAAS,IAAI;IAMnF,QAAQ;IACT,CAAQ;UACH;GAGN,KAAK,WAAW,CAAC;IACf,MAAM;IACN,MAAM;IACN,QAAQ;IACT,CAAQ;;;CAIb,OAAO"}
@@ -1,24 +1,36 @@
1
- import { UrlConfig } from "../types/config.js";
1
+ import { UrlQueryOptions } from "../types/config.js";
2
2
  import { ChildNode } from "domhandler";
3
3
 
4
4
  //#region src/transformers/urlQuery.d.ts
5
5
  /**
6
- * URL query transformer.
6
+ * Append query parameters to URLs found in matching attributes/elements.
7
7
  *
8
- * Appends query parameters to URLs found in specified attributes of
9
- * specified HTML tags.
8
+ * @param html HTML string to transform.
9
+ * @param params Query parameters to append (e.g. `{ utm_source: 'newsletter' }`).
10
+ * @param options Behaviour overrides — `tags` (CSS selectors, default `['a']`),
11
+ * `attributes` (default `['src', 'href', 'poster', 'srcset', 'background']`),
12
+ * `strict` (default `true`, only rewrites absolute URLs),
13
+ * `qs` (forwarded to `query-string`, default `{ encode: false }`).
14
+ * @returns The transformed HTML string.
10
15
  *
11
- * Reads config from the `config.url` object in `MaizzleConfig` (pass
12
- * `config.url` directly when calling as a standalone transformer).
13
- * The `_options` key inside `query` controls behaviour:
14
- * - `tags` — CSS selectors for elements to process. Default: `['a']`
15
- * - `attributes` — attribute names to process. Default: `['src', 'href', 'poster', 'srcset', 'background']`
16
- * - `strict` — only append to absolute URLs. Default: `true`
17
- * - `qs` — options forwarded to query-string. Default: `{ encode: false }`
16
+ * @example
17
+ * import { urlQuery } from '@maizzle/framework'
18
18
  *
19
- * All non-`_options` keys inside `query` are treated as URL parameters to append.
19
+ * const out = urlQuery(
20
+ * '<a href="https://example.com">x</a>',
21
+ * { utm_source: 'newsletter' },
22
+ * )
23
+ *
24
+ * // Restrict to specific tags / attributes:
25
+ * urlQuery(html, { ref: 'email' }, { tags: ['a', 'img'], attributes: ['href', 'src'] })
26
+ */
27
+ declare function urlQuery(html: string, params?: Record<string, unknown>, options?: UrlQueryOptions): string;
28
+ /**
29
+ * DOM-form of {@link urlQuery} used by the internal transformer pipeline.
30
+ * Takes a parsed DOM, returns a parsed DOM — avoids redundant
31
+ * serialize/parse round-trips when chained with other transformers.
20
32
  */
21
- declare function urlQuery(dom: ChildNode[], config?: UrlConfig): ChildNode[];
33
+ declare function urlQueryDom(dom: ChildNode[], params?: Record<string, unknown>, options?: UrlQueryOptions): ChildNode[];
22
34
  //#endregion
23
- export { urlQuery };
35
+ export { urlQuery, urlQueryDom };
24
36
  //# sourceMappingURL=urlQuery.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"urlQuery.d.ts","names":[],"sources":["../../src/transformers/urlQuery.ts"],"mappings":";;;;;;AA0CA;;;;;;;;;;;;;;iBAAgB,QAAA,CAAS,GAAA,EAAK,SAAA,IAAa,MAAA,GAAQ,SAAA,GAAiB,SAAA"}
1
+ {"version":3,"file":"urlQuery.d.ts","names":[],"sources":["../../src/transformers/urlQuery.ts"],"mappings":";;;;;;AAiDA;;;;;;;;;;;AAaA;;;;;;;;;iBAbgB,QAAA,CACd,IAAA,UACA,MAAA,GAAQ,MAAA,mBACR,OAAA,GAAS,eAAA;;;;;;iBAUK,WAAA,CACd,GAAA,EAAK,SAAA,IACL,MAAA,GAAQ,MAAA,mBACR,OAAA,GAAS,eAAA,GACR,SAAA"}
@@ -1,7 +1,9 @@
1
+ import { parse } from "../utils/ast/parser.js";
2
+ import { serialize } from "../utils/ast/serializer.js";
3
+ import "../utils/ast/index.js";
1
4
  import { isAbsoluteUrl } from "../utils/url.js";
2
5
  import queryString from "query-string";
3
6
  import { selectAll } from "css-select";
4
-
5
7
  //#region src/transformers/urlQuery.ts
6
8
  const DEFAULT_ATTRIBUTES = [
7
9
  "src",
@@ -22,27 +24,37 @@ function appendParams(url, params, qsOptions, strict) {
22
24
  }, qsOptions);
23
25
  }
24
26
  /**
25
- * URL query transformer.
27
+ * Append query parameters to URLs found in matching attributes/elements.
28
+ *
29
+ * @param html HTML string to transform.
30
+ * @param params Query parameters to append (e.g. `{ utm_source: 'newsletter' }`).
31
+ * @param options Behaviour overrides — `tags` (CSS selectors, default `['a']`),
32
+ * `attributes` (default `['src', 'href', 'poster', 'srcset', 'background']`),
33
+ * `strict` (default `true`, only rewrites absolute URLs),
34
+ * `qs` (forwarded to `query-string`, default `{ encode: false }`).
35
+ * @returns The transformed HTML string.
26
36
  *
27
- * Appends query parameters to URLs found in specified attributes of
28
- * specified HTML tags.
37
+ * @example
38
+ * import { urlQuery } from '@maizzle/framework'
29
39
  *
30
- * Reads config from the `config.url` object in `MaizzleConfig` (pass
31
- * `config.url` directly when calling as a standalone transformer).
32
- * The `_options` key inside `query` controls behaviour:
33
- * - `tags` — CSS selectors for elements to process. Default: `['a']`
34
- * - `attributes` — attribute names to process. Default: `['src', 'href', 'poster', 'srcset', 'background']`
35
- * - `strict` — only append to absolute URLs. Default: `true`
36
- * - `qs` — options forwarded to query-string. Default: `{ encode: false }`
40
+ * const out = urlQuery(
41
+ * '<a href="https://example.com">x</a>',
42
+ * { utm_source: 'newsletter' },
43
+ * )
37
44
  *
38
- * All non-`_options` keys inside `query` are treated as URL parameters to append.
45
+ * // Restrict to specific tags / attributes:
46
+ * urlQuery(html, { ref: 'email' }, { tags: ['a', 'img'], attributes: ['href', 'src'] })
39
47
  */
40
- function urlQuery(dom, config = {}) {
41
- const queryConfig = config.query;
42
- if (!queryConfig || Object.keys(queryConfig).length === 0) return dom;
43
- const { _options, ...params } = queryConfig;
44
- const options = _options ?? {};
45
- if (Object.keys(params).length === 0) return dom;
48
+ function urlQuery(html, params = {}, options = {}) {
49
+ return serialize(urlQueryDom(parse(html), params, options));
50
+ }
51
+ /**
52
+ * DOM-form of {@link urlQuery} used by the internal transformer pipeline.
53
+ * Takes a parsed DOM, returns a parsed DOM — avoids redundant
54
+ * serialize/parse round-trips when chained with other transformers.
55
+ */
56
+ function urlQueryDom(dom, params = {}, options = {}) {
57
+ if (!params || Object.keys(params).length === 0) return dom;
46
58
  const tags = options.tags ?? DEFAULT_TAGS;
47
59
  const attributes = options.attributes ?? DEFAULT_ATTRIBUTES;
48
60
  const strict = options.strict ?? true;
@@ -59,7 +71,7 @@ function urlQuery(dom, config = {}) {
59
71
  }
60
72
  return dom;
61
73
  }
62
-
63
74
  //#endregion
64
- export { urlQuery };
75
+ export { urlQuery, urlQueryDom };
76
+
65
77
  //# sourceMappingURL=urlQuery.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"urlQuery.js","names":[],"sources":["../../src/transformers/urlQuery.ts"],"sourcesContent":["import queryString from 'query-string'\nimport { selectAll } from 'css-select'\nimport type { ChildNode, Element } from 'domhandler'\nimport { isAbsoluteUrl } from '../utils/url.ts'\nimport type { UrlConfig, UrlQueryOptions } from '../types/config.ts'\n\nconst DEFAULT_ATTRIBUTES = ['src', 'href', 'poster', 'srcset', 'background']\nconst DEFAULT_TAGS = ['a']\n\n/**\n * Append query parameters to a URL string using query-string.\n */\nfunction appendParams(\n url: string,\n params: Record<string, unknown>,\n qsOptions: queryString.StringifyOptions,\n strict: boolean,\n): string {\n if (strict && !isAbsoluteUrl(url)) return url\n\n return queryString.stringifyUrl(\n { url, query: params as queryString.StringifiableRecord },\n qsOptions,\n )\n}\n\n/**\n * URL query transformer.\n *\n * Appends query parameters to URLs found in specified attributes of\n * specified HTML tags.\n *\n * Reads config from the `config.url` object in `MaizzleConfig` (pass\n * `config.url` directly when calling as a standalone transformer).\n * The `_options` key inside `query` controls behaviour:\n * - `tags` CSS selectors for elements to process. Default: `['a']`\n * - `attributes` attribute names to process. Default: `['src', 'href', 'poster', 'srcset', 'background']`\n * - `strict` only append to absolute URLs. Default: `true`\n * - `qs` options forwarded to query-string. Default: `{ encode: false }`\n *\n * All non-`_options` keys inside `query` are treated as URL parameters to append.\n */\nexport function urlQuery(dom: ChildNode[], config: UrlConfig = {}): ChildNode[] {\n const queryConfig = config.query\n\n if (!queryConfig || Object.keys(queryConfig).length === 0) return dom\n\n const { _options, ...params } = queryConfig as Record<string, unknown>\n const options = (_options ?? {}) as UrlQueryOptions\n\n if (Object.keys(params).length === 0) return dom\n\n const tags = options.tags ?? DEFAULT_TAGS\n const attributes = options.attributes ?? DEFAULT_ATTRIBUTES\n const strict = options.strict ?? true\n const qsOptions: queryString.StringifyOptions = { encode: false, ...((options.qs ?? {}) as queryString.StringifyOptions) }\n\n // Use css-select to find all elements matching any of the tag selectors\n const selector = tags.join(', ')\n const elements = selectAll(selector, dom) as Element[]\n\n for (const el of elements) {\n for (const attr of attributes) {\n const value = el.attribs[attr]\n if (!value) continue\n\n const updated = appendParams(value, params, qsOptions, strict)\n if (updated !== value) {\n el.attribs[attr] = updated\n }\n }\n }\n\n return dom\n}\n"],"mappings":";;;;;AAMA,MAAM,qBAAqB;CAAC;CAAO;CAAQ;CAAU;CAAU;CAAa;AAC5E,MAAM,eAAe,CAAC,IAAI;;;;AAK1B,SAAS,aACP,KACA,QACA,WACA,QACQ;AACR,KAAI,UAAU,CAAC,cAAc,IAAI,CAAE,QAAO;AAE1C,QAAO,YAAY,aACjB;EAAE;EAAK,OAAO;EAA2C,EACzD,UACD;;;;;;;;;;;;;;;;;;AAmBH,SAAgB,SAAS,KAAkB,SAAoB,EAAE,EAAe;CAC9E,MAAM,cAAc,OAAO;AAE3B,KAAI,CAAC,eAAe,OAAO,KAAK,YAAY,CAAC,WAAW,EAAG,QAAO;CAElE,MAAM,EAAE,UAAU,GAAG,WAAW;CAChC,MAAM,UAAW,YAAY,EAAE;AAE/B,KAAI,OAAO,KAAK,OAAO,CAAC,WAAW,EAAG,QAAO;CAE7C,MAAM,OAAO,QAAQ,QAAQ;CAC7B,MAAM,aAAa,QAAQ,cAAc;CACzC,MAAM,SAAS,QAAQ,UAAU;CACjC,MAAM,YAA0C;EAAE,QAAQ;EAAO,GAAK,QAAQ,MAAM,EAAE;EAAoC;CAI1H,MAAM,WAAW,UADA,KAAK,KAAK,KAAK,EACK,IAAI;AAEzC,MAAK,MAAM,MAAM,SACf,MAAK,MAAM,QAAQ,YAAY;EAC7B,MAAM,QAAQ,GAAG,QAAQ;AACzB,MAAI,CAAC,MAAO;EAEZ,MAAM,UAAU,aAAa,OAAO,QAAQ,WAAW,OAAO;AAC9D,MAAI,YAAY,MACd,IAAG,QAAQ,QAAQ;;AAKzB,QAAO"}
1
+ {"version":3,"file":"urlQuery.js","names":[],"sources":["../../src/transformers/urlQuery.ts"],"sourcesContent":["import queryString from 'query-string'\nimport { selectAll } from 'css-select'\nimport type { ChildNode, Element } from 'domhandler'\nimport { parse, serialize } from '../utils/ast/index.ts'\nimport { isAbsoluteUrl } from '../utils/url.ts'\nimport type { UrlQueryOptions } from '../types/config.ts'\n\nconst DEFAULT_ATTRIBUTES = ['src', 'href', 'poster', 'srcset', 'background']\nconst DEFAULT_TAGS = ['a']\n\n/**\n * Append query parameters to a URL string using query-string.\n */\nfunction appendParams(\n url: string,\n params: Record<string, unknown>,\n qsOptions: queryString.StringifyOptions,\n strict: boolean,\n): string {\n if (strict && !isAbsoluteUrl(url)) return url\n\n return queryString.stringifyUrl(\n { url, query: params as queryString.StringifiableRecord },\n qsOptions,\n )\n}\n\n/**\n * Append query parameters to URLs found in matching attributes/elements.\n *\n * @param html HTML string to transform.\n * @param params Query parameters to append (e.g. `{ utm_source: 'newsletter' }`).\n * @param options Behaviour overrides `tags` (CSS selectors, default `['a']`),\n * `attributes` (default `['src', 'href', 'poster', 'srcset', 'background']`),\n * `strict` (default `true`, only rewrites absolute URLs),\n * `qs` (forwarded to `query-string`, default `{ encode: false }`).\n * @returns The transformed HTML string.\n *\n * @example\n * import { urlQuery } from '@maizzle/framework'\n *\n * const out = urlQuery(\n * '<a href=\"https://example.com\">x</a>',\n * { utm_source: 'newsletter' },\n * )\n *\n * // Restrict to specific tags / attributes:\n * urlQuery(html, { ref: 'email' }, { tags: ['a', 'img'], attributes: ['href', 'src'] })\n */\nexport function urlQuery(\n html: string,\n params: Record<string, unknown> = {},\n options: UrlQueryOptions = {},\n): string {\n return serialize(urlQueryDom(parse(html), params, options))\n}\n\n/**\n * DOM-form of {@link urlQuery} used by the internal transformer pipeline.\n * Takes a parsed DOM, returns a parsed DOM — avoids redundant\n * serialize/parse round-trips when chained with other transformers.\n */\nexport function urlQueryDom(\n dom: ChildNode[],\n params: Record<string, unknown> = {},\n options: UrlQueryOptions = {},\n): ChildNode[] {\n if (!params || Object.keys(params).length === 0) return dom\n\n const tags = options.tags ?? DEFAULT_TAGS\n const attributes = options.attributes ?? DEFAULT_ATTRIBUTES\n const strict = options.strict ?? true\n const qsOptions: queryString.StringifyOptions = { encode: false, ...((options.qs ?? {}) as queryString.StringifyOptions) }\n\n // Use css-select to find all elements matching any of the tag selectors\n const selector = tags.join(', ')\n const elements = selectAll(selector, dom) as Element[]\n\n for (const el of elements) {\n for (const attr of attributes) {\n const value = el.attribs[attr]\n if (!value) continue\n\n const updated = appendParams(value, params, qsOptions, strict)\n if (updated !== value) {\n el.attribs[attr] = updated\n }\n }\n }\n\n return dom\n}\n"],"mappings":";;;;;;;AAOA,MAAM,qBAAqB;CAAC;CAAO;CAAQ;CAAU;CAAU;CAAa;AAC5E,MAAM,eAAe,CAAC,IAAI;;;;AAK1B,SAAS,aACP,KACA,QACA,WACA,QACQ;CACR,IAAI,UAAU,CAAC,cAAc,IAAI,EAAE,OAAO;CAE1C,OAAO,YAAY,aACjB;EAAE;EAAK,OAAO;EAA2C,EACzD,UACD;;;;;;;;;;;;;;;;;;;;;;;;AAyBH,SAAgB,SACd,MACA,SAAkC,EAAE,EACpC,UAA2B,EAAE,EACrB;CACR,OAAO,UAAU,YAAY,MAAM,KAAK,EAAE,QAAQ,QAAQ,CAAC;;;;;;;AAQ7D,SAAgB,YACd,KACA,SAAkC,EAAE,EACpC,UAA2B,EAAE,EAChB;CACb,IAAI,CAAC,UAAU,OAAO,KAAK,OAAO,CAAC,WAAW,GAAG,OAAO;CAExD,MAAM,OAAO,QAAQ,QAAQ;CAC7B,MAAM,aAAa,QAAQ,cAAc;CACzC,MAAM,SAAS,QAAQ,UAAU;CACjC,MAAM,YAA0C;EAAE,QAAQ;EAAO,GAAK,QAAQ,MAAM,EAAE;EAAoC;CAI1H,MAAM,WAAW,UADA,KAAK,KAAK,KACQ,EAAE,IAAI;CAEzC,KAAK,MAAM,MAAM,UACf,KAAK,MAAM,QAAQ,YAAY;EAC7B,MAAM,QAAQ,GAAG,QAAQ;EACzB,IAAI,CAAC,OAAO;EAEZ,MAAM,UAAU,aAAa,OAAO,QAAQ,WAAW,OAAO;EAC9D,IAAI,YAAY,OACd,GAAG,QAAQ,QAAQ;;CAKzB,OAAO"}
@@ -1,9 +1,11 @@
1
1
  import { RemoveValue } from "../plugins/postcss/removeDeclarations.js";
2
2
  import { Directive, Plugin } from "vue";
3
3
  import { Options } from "juice";
4
- import * as oxfmt from "oxfmt";
4
+ import * as _$oxfmt from "oxfmt";
5
+ import * as _$html_crush0 from "html-crush";
5
6
  import { InlineConfig } from "vite";
6
- import * as shiki from "shiki";
7
+ import * as _$string_strip_html0 from "string-strip-html";
8
+ import * as _$shiki from "shiki";
7
9
  import { Options as Options$1 } from "unplugin-vue-markdown/types";
8
10
 
9
11
  //#region src/types/config.d.ts
@@ -186,9 +188,9 @@ interface CssConfig {
186
188
  sort?: 'mobile-first' | 'desktop-first' | ((a: string, b: string) => number);
187
189
  };
188
190
  /**
189
- * Convert unitless CSS values to their unitless equivalents.
191
+ * Strip units from zero values in inlined styles.
190
192
  *
191
- * For example, `line-height: 24px` with a `16px` font becomes `line-height: 1.5`.
193
+ * For example, `padding: 0px 16px` becomes `padding: 0 16px`.
192
194
  *
193
195
  * @default true
194
196
  */
@@ -229,7 +231,11 @@ interface CssConfig {
229
231
  */
230
232
  removeDeclarations?: Record<string, RemoveValue>;
231
233
  /**
232
- * File paths to exclude from CSS processing.
234
+ * Glob patterns or paths excluded from Tailwind's `@source` scanner.
235
+ *
236
+ * Tailwind won't generate utilities for classes used in these files.
237
+ * Useful for ignoring AMP variants or any templates whose classes
238
+ * shouldn't end up in the output CSS.
233
239
  *
234
240
  * @example
235
241
  * css: {
@@ -258,12 +264,23 @@ interface AttributesConfig {
258
264
  */
259
265
  add?: false | Record<string, false | Record<string, false | string | boolean | number>>;
260
266
  /**
261
- * Remove attributes from HTML elements by name or name-value pair.
267
+ * Remove attributes from HTML elements.
268
+ *
269
+ * Empty `style` and `class` attributes are always stripped, regardless
270
+ * of config. Entries added here are appended to those defaults.
271
+ *
272
+ * - String — remove when the attribute's value is empty.
273
+ * - `{ name, value: 'literal' }` — remove when the value matches exactly.
274
+ * - `{ name, value: /regex/ }` — remove when the value matches the regex.
262
275
  *
263
276
  * @example
264
277
  * html: {
265
278
  * attributes: {
266
- * remove: ['data-test', { name: 'class', value: /^js-/ }],
279
+ * remove: [
280
+ * 'data-foo',
281
+ * { name: 'role', value: 'none' },
282
+ * { name: 'class', value: /^js-/ },
283
+ * ],
267
284
  * }
268
285
  * }
269
286
  */
@@ -335,13 +352,16 @@ interface HtmlConfig {
335
352
  *
336
353
  * Set to `true` to enable with defaults, or pass options.
337
354
  */
338
- format?: boolean | oxfmt.FormatOptions;
355
+ format?: boolean | _$oxfmt.FormatOptions;
339
356
  /**
340
357
  * Minify the HTML output.
341
358
  *
342
- * Set to `true` to enable with defaults, or pass options.
359
+ * Set to `true` to enable with defaults, or pass `html-crush`
360
+ * options to customize.
361
+ *
362
+ * @see https://codsen.com/os/html-crush
343
363
  */
344
- minify?: boolean | Record<string, unknown>;
364
+ minify?: boolean | Partial<_$html_crush0.Opts>;
345
365
  }
346
366
  type FilterFunction = (str: string, value: string) => string;
347
367
  type FiltersConfig = false | Record<string, FilterFunction>;
@@ -351,7 +371,7 @@ interface MarkdownConfig extends Options$1 {
351
371
  *
352
372
  * @default 'github-light'
353
373
  */
354
- shikiTheme?: shiki.BundledTheme;
374
+ shikiTheme?: _$shiki.BundledTheme;
355
375
  }
356
376
  interface VueConfig {
357
377
  /** Vue plugins to register on the app instance before rendering. */
@@ -366,7 +386,7 @@ interface VueConfig {
366
386
  *
367
387
  * - `false` skips the listed transformer.
368
388
  * - `true` force-enables it for this run (only meaningful for boolean-driven
369
- * transformers: inlineCSS, purgeCSS, prettify, minify, shorthandCSS,
389
+ * transformers: inlineCss, purgeCss, prettify, minify, shorthandCss,
370
390
  * sixHex, safeClassNames, entities). Layers on the matching
371
391
  * `css.*` / `html.*` config slice.
372
392
  * - missing keys keep their default behavior.
@@ -382,20 +402,45 @@ interface VueConfig {
382
402
  interface TransformerToggles {
383
403
  safeClassNames?: boolean;
384
404
  attributeToStyle?: boolean;
385
- inlineCSS?: boolean;
405
+ inlineCss?: boolean;
386
406
  removeAttributes?: boolean;
387
- shorthandCSS?: boolean;
407
+ shorthandCss?: boolean;
388
408
  sixHex?: boolean;
389
409
  addAttributes?: boolean;
390
410
  filters?: boolean;
391
411
  baseURL?: boolean;
392
412
  urlQuery?: boolean;
393
- purgeCSS?: boolean;
413
+ purgeCss?: boolean;
394
414
  entities?: boolean;
395
415
  replaceStrings?: boolean;
396
416
  prettify?: boolean;
397
417
  minify?: boolean;
398
418
  }
419
+ /**
420
+ * Plaintext generation options.
421
+ *
422
+ * Control where plaintext files are written, what extension they use,
423
+ * and the options forwarded to `string-strip-html`.
424
+ */
425
+ interface PlaintextConfig {
426
+ /**
427
+ * Output directory for plaintext files. When omitted, files are written
428
+ * next to their HTML counterpart in `build.output.path`.
429
+ */
430
+ destination?: string;
431
+ /**
432
+ * File extension for plaintext files (without the leading dot).
433
+ *
434
+ * @default 'txt'
435
+ */
436
+ extension?: string;
437
+ /**
438
+ * Options forwarded to `string-strip-html`.
439
+ *
440
+ * @see https://codsen.com/os/string-strip-html
441
+ */
442
+ options?: Partial<_$string_strip_html0.Opts>;
443
+ }
399
444
  interface MaizzleConfig {
400
445
  /**
401
446
  * Root directory for the Maizzle email project.
@@ -536,11 +581,18 @@ interface MaizzleConfig {
536
581
  /**
537
582
  * Generate a plaintext version of the email.
538
583
  *
539
- * Set to `true` to enable, or pass a string path or options object.
584
+ * Set to `true` to enable with defaults, or pass an object to configure
585
+ * destination directory, file extension, and `string-strip-html` options.
540
586
  *
541
587
  * @default false
588
+ * @example
589
+ * plaintext: {
590
+ * destination: 'build_production/plaintext',
591
+ * extension: 'txt',
592
+ * options: { ignoreTags: ['br'] },
593
+ * }
542
594
  */
543
- plaintext?: boolean | string | Record<string, unknown>;
595
+ plaintext?: boolean | PlaintextConfig;
544
596
  /** PostCSS processing options. */
545
597
  postcss?: PostcssConfig;
546
598
  /**
@@ -552,7 +604,7 @@ interface MaizzleConfig {
552
604
  *
553
605
  * @default true
554
606
  * @example
555
- * useTransformers: { inlineCSS: false, minify: false }
607
+ * useTransformers: { inlineCss: false, minify: false }
556
608
  */
557
609
  useTransformers?: boolean | TransformerToggles;
558
610
  /**
@@ -636,5 +688,5 @@ interface MaizzleConfig {
636
688
  [key: string]: any;
637
689
  }
638
690
  //#endregion
639
- export { AttributesConfig, CaniemailClient, ChecksConfig, CssConfig, EntitiesConfig, FilterFunction, FiltersConfig, HtmlConfig, MaizzleConfig, MarkdownConfig, PostcssConfig, TransformerToggles, UrlConfig, UrlQuery, UrlQueryOptions, VueConfig };
691
+ export { AttributesConfig, CaniemailClient, ChecksConfig, CssConfig, EntitiesConfig, FilterFunction, FiltersConfig, HtmlConfig, MaizzleConfig, MarkdownConfig, PlaintextConfig, PostcssConfig, TransformerToggles, UrlConfig, UrlQuery, UrlQueryOptions, VueConfig };
640
692
  //# sourceMappingURL=config.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"config.d.ts","names":[],"sources":["../../src/types/config.ts"],"mappings":"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"}
1
+ {"version":3,"file":"config.d.ts","names":[],"sources":["../../src/types/config.ts"],"mappings":"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"}
@@ -1 +1 @@
1
- export { };
1
+ export {};
@@ -1,2 +1,2 @@
1
- import { AttributesConfig, CaniemailClient, ChecksConfig, CssConfig, EntitiesConfig, FilterFunction, FiltersConfig, HtmlConfig, MaizzleConfig, MarkdownConfig, PostcssConfig, TransformerToggles, UrlConfig, UrlQuery, UrlQueryOptions } from "./config.js";
2
- export { type AttributesConfig, type CaniemailClient, type ChecksConfig, type CssConfig, type EntitiesConfig, type FilterFunction, type FiltersConfig, type HtmlConfig, type MaizzleConfig, type MarkdownConfig, type PostcssConfig, type TransformerToggles, type UrlConfig, type UrlQuery, type UrlQueryOptions };
1
+ import { AttributesConfig, CaniemailClient, ChecksConfig, CssConfig, EntitiesConfig, FilterFunction, FiltersConfig, HtmlConfig, MaizzleConfig, MarkdownConfig, PlaintextConfig, PostcssConfig, TransformerToggles, UrlConfig, UrlQuery, UrlQueryOptions } from "./config.js";
2
+ export { type AttributesConfig, type CaniemailClient, type ChecksConfig, type CssConfig, type EntitiesConfig, type FilterFunction, type FiltersConfig, type HtmlConfig, type MaizzleConfig, type MarkdownConfig, type PlaintextConfig, type PostcssConfig, type TransformerToggles, type UrlConfig, type UrlQuery, type UrlQueryOptions };
@@ -1 +1 @@
1
- export { };
1
+ export {};
@@ -1,5 +1,4 @@
1
1
  import { parse } from "./parser.js";
2
2
  import { walk } from "./walker.js";
3
3
  import { serialize } from "./serializer.js";
4
-
5
- export { parse, serialize, walk };
4
+ export { parse, serialize, walk };
@@ -1,6 +1,5 @@
1
1
  import { Parser } from "htmlparser2";
2
2
  import { DomHandler } from "domhandler";
3
-
4
3
  //#region src/utils/ast/parser.ts
5
4
  function parse(html, options = {}) {
6
5
  const handler = new DomHandler();
@@ -9,7 +8,7 @@ function parse(html, options = {}) {
9
8
  parser.end();
10
9
  return handler.dom;
11
10
  }
12
-
13
11
  //#endregion
14
12
  export { parse };
13
+
15
14
  //# sourceMappingURL=parser.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"parser.js","names":[],"sources":["../../../src/utils/ast/parser.ts"],"sourcesContent":["import { Parser } from 'htmlparser2'\nimport { DomHandler } from 'domhandler'\nimport type { ChildNode, DomHandlerOptions } from 'domhandler'\n\nexport function parse(html: string, options: DomHandlerOptions = {}): ChildNode[] {\n const handler = new DomHandler()\n const parser = new Parser(handler, options)\n parser.write(html)\n parser.end()\n return handler.dom\n}\n"],"mappings":";;;;AAIA,SAAgB,MAAM,MAAc,UAA6B,EAAE,EAAe;CAChF,MAAM,UAAU,IAAI,YAAY;CAChC,MAAM,SAAS,IAAI,OAAO,SAAS,QAAQ;AAC3C,QAAO,MAAM,KAAK;AAClB,QAAO,KAAK;AACZ,QAAO,QAAQ"}
1
+ {"version":3,"file":"parser.js","names":[],"sources":["../../../src/utils/ast/parser.ts"],"sourcesContent":["import { Parser } from 'htmlparser2'\nimport { DomHandler } from 'domhandler'\nimport type { ChildNode, DomHandlerOptions } from 'domhandler'\n\nexport function parse(html: string, options: DomHandlerOptions = {}): ChildNode[] {\n const handler = new DomHandler()\n const parser = new Parser(handler, options)\n parser.write(html)\n parser.end()\n return handler.dom\n}\n"],"mappings":";;;AAIA,SAAgB,MAAM,MAAc,UAA6B,EAAE,EAAe;CAChF,MAAM,UAAU,IAAI,YAAY;CAChC,MAAM,SAAS,IAAI,OAAO,SAAS,QAAQ;CAC3C,OAAO,MAAM,KAAK;CAClB,OAAO,KAAK;CACZ,OAAO,QAAQ"}
@@ -1,6 +1,5 @@
1
1
  import { walk } from "./walker.js";
2
2
  import render from "dom-serializer";
3
-
4
3
  //#region src/utils/ast/serializer.ts
5
4
  /**
6
5
  * Re-encode < and > as entities in text nodes inside <code> elements.
@@ -31,7 +30,7 @@ function serialize(dom, options) {
31
30
  ...options
32
31
  });
33
32
  }
34
-
35
33
  //#endregion
36
34
  export { serialize };
35
+
37
36
  //# sourceMappingURL=serializer.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"serializer.js","names":[],"sources":["../../../src/utils/ast/serializer.ts"],"sourcesContent":["import render from 'dom-serializer'\nimport type { ChildNode } from 'domhandler'\nimport type { DomSerializerOptions } from 'dom-serializer'\nimport { walk } from './walker.ts'\n\n/**\n * Re-encode < and > as entities in text nodes inside <code> elements.\n *\n * The DOM parser decodes entities like &#x3C; into raw < in text nodes.\n * With encodeEntities: false the serializer outputs them as-is, which\n * creates broken HTML (e.g. </a> inside a code block closes the real tag).\n *\n * We selectively fix this for <code> contents only, so the rest of the\n * document (where encodeEntities: false is needed) is unaffected.\n */\nfunction encodeCodeTextNodes(dom: ChildNode[]): void {\n walk(dom, (node) => {\n const el = node as import('domhandler').Element\n if (el.name !== 'code') return\n\n walk(el.children ?? [], (child) => {\n if (child.type === 'text') {\n const text = child as import('domhandler').Text\n text.data = text.data.replace(/</g, '&lt;').replace(/>/g, '&gt;')\n }\n })\n })\n}\n\nexport function serialize(dom: ChildNode[], options?: DomSerializerOptions): string {\n encodeCodeTextNodes(dom)\n return render(dom, { encodeEntities: false, ...options })\n}\n"],"mappings":";;;;;;;;;;;;;;AAeA,SAAS,oBAAoB,KAAwB;AACnD,MAAK,MAAM,SAAS;EAClB,MAAM,KAAK;AACX,MAAI,GAAG,SAAS,OAAQ;AAExB,OAAK,GAAG,YAAY,EAAE,GAAG,UAAU;AACjC,OAAI,MAAM,SAAS,QAAQ;IACzB,MAAM,OAAO;AACb,SAAK,OAAO,KAAK,KAAK,QAAQ,MAAM,OAAO,CAAC,QAAQ,MAAM,OAAO;;IAEnE;GACF;;AAGJ,SAAgB,UAAU,KAAkB,SAAwC;AAClF,qBAAoB,IAAI;AACxB,QAAO,OAAO,KAAK;EAAE,gBAAgB;EAAO,GAAG;EAAS,CAAC"}
1
+ {"version":3,"file":"serializer.js","names":[],"sources":["../../../src/utils/ast/serializer.ts"],"sourcesContent":["import render from 'dom-serializer'\nimport type { ChildNode } from 'domhandler'\nimport type { DomSerializerOptions } from 'dom-serializer'\nimport { walk } from './walker.ts'\n\n/**\n * Re-encode < and > as entities in text nodes inside <code> elements.\n *\n * The DOM parser decodes entities like &#x3C; into raw < in text nodes.\n * With encodeEntities: false the serializer outputs them as-is, which\n * creates broken HTML (e.g. </a> inside a code block closes the real tag).\n *\n * We selectively fix this for <code> contents only, so the rest of the\n * document (where encodeEntities: false is needed) is unaffected.\n */\nfunction encodeCodeTextNodes(dom: ChildNode[]): void {\n walk(dom, (node) => {\n const el = node as import('domhandler').Element\n if (el.name !== 'code') return\n\n walk(el.children ?? [], (child) => {\n if (child.type === 'text') {\n const text = child as import('domhandler').Text\n text.data = text.data.replace(/</g, '&lt;').replace(/>/g, '&gt;')\n }\n })\n })\n}\n\nexport function serialize(dom: ChildNode[], options?: DomSerializerOptions): string {\n encodeCodeTextNodes(dom)\n return render(dom, { encodeEntities: false, ...options })\n}\n"],"mappings":";;;;;;;;;;;;;AAeA,SAAS,oBAAoB,KAAwB;CACnD,KAAK,MAAM,SAAS;EAClB,MAAM,KAAK;EACX,IAAI,GAAG,SAAS,QAAQ;EAExB,KAAK,GAAG,YAAY,EAAE,GAAG,UAAU;GACjC,IAAI,MAAM,SAAS,QAAQ;IACzB,MAAM,OAAO;IACb,KAAK,OAAO,KAAK,KAAK,QAAQ,MAAM,OAAO,CAAC,QAAQ,MAAM,OAAO;;IAEnE;GACF;;AAGJ,SAAgB,UAAU,KAAkB,SAAwC;CAClF,oBAAoB,IAAI;CACxB,OAAO,OAAO,KAAK;EAAE,gBAAgB;EAAO,GAAG;EAAS,CAAC"}
@@ -6,7 +6,7 @@ function walk(ast, callback) {
6
6
  }
7
7
  for (const node of ast) traverse(node);
8
8
  }
9
-
10
9
  //#endregion
11
10
  export { walk };
11
+
12
12
  //# sourceMappingURL=walker.js.map