@maizzle/framework 6.0.4 → 6.0.6

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 (72) hide show
  1. package/dist/composables/defineConfig.js +2 -1
  2. package/dist/composables/defineConfig.js.map +1 -1
  3. package/dist/plugins/postcss/quoteFontFamilies.js +1 -1
  4. package/dist/plugins/postcss/quoteFontFamilies.js.map +1 -1
  5. package/dist/render/createRenderer.js +15 -11
  6. package/dist/render/createRenderer.js.map +1 -1
  7. package/dist/render/parallel/buildWorker.js +2 -1
  8. package/dist/render/parallel/buildWorker.js.map +1 -1
  9. package/dist/serve.d.ts.map +1 -1
  10. package/dist/serve.js +2 -1
  11. package/dist/serve.js.map +1 -1
  12. package/dist/server/compatibility.js +5 -5
  13. package/dist/server/compatibility.js.map +1 -1
  14. package/dist/server/linter.js +2 -2
  15. package/dist/server/linter.js.map +1 -1
  16. package/dist/server/sfc-utils.js +1 -1
  17. package/dist/server/sfc-utils.js.map +1 -1
  18. package/dist/server/ui/.vite/deps/@lucide_vue.js +7313 -6416
  19. package/dist/server/ui/.vite/deps/@lucide_vue.js.map +1 -1
  20. package/dist/server/ui/.vite/deps/@vueuse_core.js +2 -4
  21. package/dist/server/ui/.vite/deps/@vueuse_core.js.map +1 -1
  22. package/dist/server/ui/.vite/deps/@vueuse_shared.js +1 -3
  23. package/dist/server/ui/.vite/deps/@vueuse_shared.js.map +1 -1
  24. package/dist/server/ui/.vite/deps/_metadata.json +17 -17
  25. package/dist/server/ui/.vite/deps/class-variance-authority.js +0 -2
  26. package/dist/server/ui/.vite/deps/class-variance-authority.js.map +1 -1
  27. package/dist/server/ui/.vite/deps/clsx.js +0 -2
  28. package/dist/server/ui/.vite/deps/culori.js +0 -2
  29. package/dist/server/ui/.vite/deps/culori.js.map +1 -1
  30. package/dist/server/ui/.vite/deps/reka-ui.js +63 -37
  31. package/dist/server/ui/.vite/deps/reka-ui.js.map +1 -1
  32. package/dist/server/ui/.vite/deps/tailwind-merge.js +1 -3
  33. package/dist/server/ui/.vite/deps/tailwind-merge.js.map +1 -1
  34. package/dist/server/ui/.vite/deps/vue-router.js +1 -3
  35. package/dist/server/ui/.vite/deps/vue-router.js.map +1 -1
  36. package/dist/server/ui/.vite/deps/vue.js +1 -1
  37. package/dist/server/ui/.vite/deps/{vue.runtime.esm-bundler-Dz9O_TVp.js → vue.runtime.esm-bundler-DjHXh3xg.js} +9 -6
  38. package/dist/server/ui/.vite/deps/{vue.runtime.esm-bundler-Dz9O_TVp.js.map → vue.runtime.esm-bundler-DjHXh3xg.js.map} +1 -1
  39. package/dist/transformers/addAttributes.js +1 -1
  40. package/dist/transformers/addAttributes.js.map +1 -1
  41. package/dist/transformers/entities.d.ts +21 -6
  42. package/dist/transformers/entities.d.ts.map +1 -1
  43. package/dist/transformers/entities.js +7 -7
  44. package/dist/transformers/entities.js.map +1 -1
  45. package/dist/transformers/index.d.ts +1 -0
  46. package/dist/transformers/index.d.ts.map +1 -1
  47. package/dist/transformers/index.js +10 -0
  48. package/dist/transformers/index.js.map +1 -1
  49. package/dist/transformers/sixHex.js +1 -1
  50. package/dist/transformers/sixHex.js.map +1 -1
  51. package/dist/types/config.d.ts +15 -0
  52. package/dist/types/config.d.ts.map +1 -1
  53. package/dist/utils/ast/serializer.js +1 -1
  54. package/dist/utils/ast/serializer.js.map +1 -1
  55. package/dist/utils/cssBox.js +1 -1
  56. package/dist/utils/cssBox.js.map +1 -1
  57. package/node_modules/maizzle/dist/commands/new.mjs +2 -2
  58. package/node_modules/maizzle/node_modules/commander/Readme.md +11 -15
  59. package/node_modules/maizzle/node_modules/commander/index.js +14 -17
  60. package/node_modules/maizzle/node_modules/commander/lib/argument.js +3 -6
  61. package/node_modules/maizzle/node_modules/commander/lib/command.js +46 -33
  62. package/node_modules/maizzle/node_modules/commander/lib/error.js +2 -5
  63. package/node_modules/maizzle/node_modules/commander/lib/help.js +4 -20
  64. package/node_modules/maizzle/node_modules/commander/lib/option.js +3 -6
  65. package/node_modules/maizzle/node_modules/commander/lib/suggestSimilar.js +2 -4
  66. package/node_modules/maizzle/node_modules/commander/package.json +10 -28
  67. package/node_modules/maizzle/node_modules/commander/typings/index.d.ts +3 -3
  68. package/node_modules/maizzle/package.json +2 -2
  69. package/package.json +2 -2
  70. package/node_modules/maizzle/node_modules/commander/esm.mjs +0 -16
  71. package/node_modules/maizzle/node_modules/commander/typings/esm.d.mts +0 -3
  72. /package/dist/server/ui/.vite/deps/{chunk-EAsCxrDo.js → rolldown-runtime-EAsCxrDo.js} +0 -0
@@ -68,7 +68,7 @@ function addAttributesDom(dom, config = {}) {
68
68
  if (attrName === "class" && el.attribs.class) {
69
69
  const existingClasses = el.attribs.class.split(/\s+/).filter(Boolean);
70
70
  const newClasses = String(attrValue).split(/\s+/).filter(Boolean);
71
- const mergedClasses = [...new Set([...existingClasses, ...newClasses])];
71
+ const mergedClasses = [.../* @__PURE__ */ new Set([...existingClasses, ...newClasses])];
72
72
  if (mergedClasses.join(" ") !== el.attribs.class) el.attribs.class = mergedClasses.join(" ");
73
73
  } else if (!(attrName in el.attribs)) el.attribs[attrName] = String(attrValue);
74
74
  }
@@ -1 +1 @@
1
- {"version":3,"file":"addAttributes.js","names":["merge"],"sources":["../../src/transformers/addAttributes.ts"],"sourcesContent":["import { defu as merge } from 'defu'\nimport type { ChildNode, Element } from 'domhandler'\nimport { parse, serialize, walk } from '../utils/ast/index.ts'\nimport type { AttributesConfig } from '../types/config.ts'\n\n/**\n * Default attributes to add to elements.\n */\nconst DEFAULT_ATTRIBUTES: Record<string, Record<string, string | boolean | number>> = {\n table: {\n cellpadding: 0,\n cellspacing: 0,\n role: 'none',\n },\n img: {\n alt: '',\n },\n}\n\n/**\n * Add attributes transformer.\n *\n * Automatically adds attributes to HTML elements based on CSS selectors.\n *\n * Default attributes (can be disabled by setting `attributes.add` to false):\n * - table: cellpadding=\"0\", cellspacing=\"0\", role=\"none\"\n * - img: alt=\"\"\n *\n * Supports tag, class, id, and attribute selectors.\n * Multiple selectors can be specified by comma-separating them.\n *\n * @param html HTML string to transform.\n * @param config Attributes config (see {@link AttributesConfig}).\n * @returns The transformed HTML string.\n *\n * @example\n * import { addAttributes } from '@maizzle/framework'\n *\n * const out = addAttributes('<div></div>', {\n * add: {\n * div: { role: 'article' },\n * '.test': { editable: true },\n * '#header': { 'data-id': 'main' },\n * 'div, p': { class: 'content' },\n * },\n * })\n */\nexport function addAttributes(html: string, config: AttributesConfig = {}): string {\n return serialize(addAttributesDom(parse(html), config))\n}\n\n/**\n * DOM-form of {@link addAttributes} 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 addAttributesDom(dom: ChildNode[], config: AttributesConfig = {}): ChildNode[] {\n const addConfig = config.add\n\n // Disabled when explicitly set to false\n if (addConfig === false) {\n return dom\n }\n\n // Deep merge user attributes on top of defaults using defu\n const userAttributes = typeof addConfig === 'object' ? addConfig : {}\n const attributesToAdd = merge(userAttributes, DEFAULT_ATTRIBUTES) as Record<string, false | Record<string, false | string | boolean | number>>\n\n // Process each selector pattern\n for (const [selectorPattern, attributes] of Object.entries(attributesToAdd)) {\n // User opted out of this selector entirely (e.g. `table: false`)\n if (attributes === false) continue\n // Split by comma for multiple selectors\n const selectors = selectorPattern.split(',').map(s => s.trim())\n\n walk(dom, (node) => {\n const el = node as Element\n if (!el.name) return\n\n // Check if element matches any selector in the pattern\n const matches = selectors.some(selector => elementMatches(el, selector))\n\n if (matches) {\n // Initialize attribs if needed\n if (!el.attribs) {\n el.attribs = {}\n }\n\n for (const [attrName, attrValue] of Object.entries(attributes)) {\n // User opted out of this specific attribute (e.g. `role: false`)\n if (attrValue === false) continue\n // Special handling for class - merge instead of replace\n if (attrName === 'class' && el.attribs.class) {\n const existingClasses = el.attribs.class.split(/\\s+/).filter(Boolean)\n const newClasses = String(attrValue).split(/\\s+/).filter(Boolean)\n const mergedClasses = [...new Set([...existingClasses, ...newClasses])]\n if (mergedClasses.join(' ') !== el.attribs.class) {\n el.attribs.class = mergedClasses.join(' ')\n }\n } else {\n // Only add attribute if not already present\n if (!(attrName in el.attribs)) {\n el.attribs[attrName] = String(attrValue)\n }\n }\n }\n }\n })\n }\n\n return dom\n}\n\n/**\n * Check if an element matches a CSS selector.\n * Supports: tag, .class, #id, [attribute], [attribute=value]\n */\nfunction elementMatches(el: Element, selector: string): boolean {\n // Remove whitespace\n selector = selector.trim()\n\n // Check for attribute selector [attr] or [attr=value]\n const attrMatch = selector.match(/^\\[([^\\]=]+)(?:=([^\\]]*))?\\]$/)\n if (attrMatch) {\n const [, attrName, attrValue] = attrMatch\n if (attrValue === undefined) {\n // Just checking if attribute exists\n return attrName in el.attribs\n } else {\n // Check if attribute has specific value\n return el.attribs?.[attrName] === attrValue\n }\n }\n\n // Check for class selector .class\n if (selector.startsWith('.')) {\n const className = selector.slice(1)\n const classes = el.attribs?.class?.split(/\\s+/) || []\n return classes.includes(className)\n }\n\n // Check for id selector #id\n if (selector.startsWith('#')) {\n const id = selector.slice(1)\n return el.attribs?.id === id\n }\n\n // Check for tag selector (possibly with attribute)\n // Split tag from attribute if present, e.g., \"div[role=alert]\"\n const tagAttrMatch = selector.match(/^([a-z][a-z0-9]*)\\[([^\\]]+)\\]$/i)\n if (tagAttrMatch) {\n const [, tagName, attrPart] = tagAttrMatch\n if (el.name !== tagName) return false\n\n // Parse attribute part: could be \"attr\" or \"attr=value\"\n const attrEqMatch = attrPart.match(/^([^=]+)(?:=(.*))?$/)\n if (attrEqMatch) {\n const [, attrName, attrValue] = attrEqMatch\n if (attrValue === undefined) {\n return attrName in el.attribs\n } else {\n return el.attribs?.[attrName] === attrValue\n }\n }\n return false\n }\n\n // Simple tag selector\n return el.name === selector\n}\n"],"mappings":";;;;;;;;;AAQA,MAAM,qBAAgF;CACpF,OAAO;EACL,aAAa;EACb,aAAa;EACb,MAAM;CACR;CACA,KAAK,EACH,KAAK,GACP;AACF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA8BA,SAAgB,cAAc,MAAc,SAA2B,CAAC,GAAW;CACjF,OAAO,UAAU,iBAAiB,MAAM,IAAI,GAAG,MAAM,CAAC;AACxD;;;;;;AAOA,SAAgB,iBAAiB,KAAkB,SAA2B,CAAC,GAAgB;CAC7F,MAAM,YAAY,OAAO;CAGzB,IAAI,cAAc,OAChB,OAAO;CAKT,MAAM,kBAAkBA,OADD,OAAO,cAAc,WAAW,YAAY,CAAC,GACtB,kBAAkB;CAGhE,KAAK,MAAM,CAAC,iBAAiB,eAAe,OAAO,QAAQ,eAAe,GAAG;EAE3E,IAAI,eAAe,OAAO;EAE1B,MAAM,YAAY,gBAAgB,MAAM,GAAG,CAAC,CAAC,KAAI,MAAK,EAAE,KAAK,CAAC;EAE9D,KAAK,MAAM,SAAS;GAClB,MAAM,KAAK;GACX,IAAI,CAAC,GAAG,MAAM;GAKd,IAFgB,UAAU,MAAK,aAAY,eAAe,IAAI,QAAQ,CAE5D,GAAG;IAEX,IAAI,CAAC,GAAG,SACN,GAAG,UAAU,CAAC;IAGhB,KAAK,MAAM,CAAC,UAAU,cAAc,OAAO,QAAQ,UAAU,GAAG;KAE9D,IAAI,cAAc,OAAO;KAEzB,IAAI,aAAa,WAAW,GAAG,QAAQ,OAAO;MAC5C,MAAM,kBAAkB,GAAG,QAAQ,MAAM,MAAM,KAAK,CAAC,CAAC,OAAO,OAAO;MACpE,MAAM,aAAa,OAAO,SAAS,CAAC,CAAC,MAAM,KAAK,CAAC,CAAC,OAAO,OAAO;MAChE,MAAM,gBAAgB,CAAC,GAAG,IAAI,IAAI,CAAC,GAAG,iBAAiB,GAAG,UAAU,CAAC,CAAC;MACtE,IAAI,cAAc,KAAK,GAAG,MAAM,GAAG,QAAQ,OACzC,GAAG,QAAQ,QAAQ,cAAc,KAAK,GAAG;KAE7C,OAEE,IAAI,EAAE,YAAY,GAAG,UACnB,GAAG,QAAQ,YAAY,OAAO,SAAS;IAG7C;GACF;EACF,CAAC;CACH;CAEA,OAAO;AACT;;;;;AAMA,SAAS,eAAe,IAAa,UAA2B;CAE9D,WAAW,SAAS,KAAK;CAGzB,MAAM,YAAY,SAAS,MAAM,+BAA+B;CAChE,IAAI,WAAW;EACb,MAAM,GAAG,UAAU,aAAa;EAChC,IAAI,cAAc,KAAA,GAEhB,OAAO,YAAY,GAAG;OAGtB,OAAO,GAAG,UAAU,cAAc;CAEtC;CAGA,IAAI,SAAS,WAAW,GAAG,GAAG;EAC5B,MAAM,YAAY,SAAS,MAAM,CAAC;EAElC,QADgB,GAAG,SAAS,OAAO,MAAM,KAAK,KAAK,CAAC,EAAA,CACrC,SAAS,SAAS;CACnC;CAGA,IAAI,SAAS,WAAW,GAAG,GAAG;EAC5B,MAAM,KAAK,SAAS,MAAM,CAAC;EAC3B,OAAO,GAAG,SAAS,OAAO;CAC5B;CAIA,MAAM,eAAe,SAAS,MAAM,iCAAiC;CACrE,IAAI,cAAc;EAChB,MAAM,GAAG,SAAS,YAAY;EAC9B,IAAI,GAAG,SAAS,SAAS,OAAO;EAGhC,MAAM,cAAc,SAAS,MAAM,qBAAqB;EACxD,IAAI,aAAa;GACf,MAAM,GAAG,UAAU,aAAa;GAChC,IAAI,cAAc,KAAA,GAChB,OAAO,YAAY,GAAG;QAEtB,OAAO,GAAG,UAAU,cAAc;EAEtC;EACA,OAAO;CACT;CAGA,OAAO,GAAG,SAAS;AACrB"}
1
+ {"version":3,"file":"addAttributes.js","names":["merge"],"sources":["../../src/transformers/addAttributes.ts"],"sourcesContent":["import { defu as merge } from 'defu'\nimport type { ChildNode, Element } from 'domhandler'\nimport { parse, serialize, walk } from '../utils/ast/index.ts'\nimport type { AttributesConfig } from '../types/config.ts'\n\n/**\n * Default attributes to add to elements.\n */\nconst DEFAULT_ATTRIBUTES: Record<string, Record<string, string | boolean | number>> = {\n table: {\n cellpadding: 0,\n cellspacing: 0,\n role: 'none',\n },\n img: {\n alt: '',\n },\n}\n\n/**\n * Add attributes transformer.\n *\n * Automatically adds attributes to HTML elements based on CSS selectors.\n *\n * Default attributes (can be disabled by setting `attributes.add` to false):\n * - table: cellpadding=\"0\", cellspacing=\"0\", role=\"none\"\n * - img: alt=\"\"\n *\n * Supports tag, class, id, and attribute selectors.\n * Multiple selectors can be specified by comma-separating them.\n *\n * @param html HTML string to transform.\n * @param config Attributes config (see {@link AttributesConfig}).\n * @returns The transformed HTML string.\n *\n * @example\n * import { addAttributes } from '@maizzle/framework'\n *\n * const out = addAttributes('<div></div>', {\n * add: {\n * div: { role: 'article' },\n * '.test': { editable: true },\n * '#header': { 'data-id': 'main' },\n * 'div, p': { class: 'content' },\n * },\n * })\n */\nexport function addAttributes(html: string, config: AttributesConfig = {}): string {\n return serialize(addAttributesDom(parse(html), config))\n}\n\n/**\n * DOM-form of {@link addAttributes} 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 addAttributesDom(dom: ChildNode[], config: AttributesConfig = {}): ChildNode[] {\n const addConfig = config.add\n\n // Disabled when explicitly set to false\n if (addConfig === false) {\n return dom\n }\n\n // Deep merge user attributes on top of defaults using defu\n const userAttributes = typeof addConfig === 'object' ? addConfig : {}\n const attributesToAdd = merge(userAttributes, DEFAULT_ATTRIBUTES) as Record<string, false | Record<string, false | string | boolean | number>>\n\n // Process each selector pattern\n for (const [selectorPattern, attributes] of Object.entries(attributesToAdd)) {\n // User opted out of this selector entirely (e.g. `table: false`)\n if (attributes === false) continue\n // Split by comma for multiple selectors\n const selectors = selectorPattern.split(',').map(s => s.trim())\n\n walk(dom, (node) => {\n const el = node as Element\n if (!el.name) return\n\n // Check if element matches any selector in the pattern\n const matches = selectors.some(selector => elementMatches(el, selector))\n\n if (matches) {\n // Initialize attribs if needed\n if (!el.attribs) {\n el.attribs = {}\n }\n\n for (const [attrName, attrValue] of Object.entries(attributes)) {\n // User opted out of this specific attribute (e.g. `role: false`)\n if (attrValue === false) continue\n // Special handling for class - merge instead of replace\n if (attrName === 'class' && el.attribs.class) {\n const existingClasses = el.attribs.class.split(/\\s+/).filter(Boolean)\n const newClasses = String(attrValue).split(/\\s+/).filter(Boolean)\n const mergedClasses = [...new Set([...existingClasses, ...newClasses])]\n if (mergedClasses.join(' ') !== el.attribs.class) {\n el.attribs.class = mergedClasses.join(' ')\n }\n } else {\n // Only add attribute if not already present\n if (!(attrName in el.attribs)) {\n el.attribs[attrName] = String(attrValue)\n }\n }\n }\n }\n })\n }\n\n return dom\n}\n\n/**\n * Check if an element matches a CSS selector.\n * Supports: tag, .class, #id, [attribute], [attribute=value]\n */\nfunction elementMatches(el: Element, selector: string): boolean {\n // Remove whitespace\n selector = selector.trim()\n\n // Check for attribute selector [attr] or [attr=value]\n const attrMatch = selector.match(/^\\[([^\\]=]+)(?:=([^\\]]*))?\\]$/)\n if (attrMatch) {\n const [, attrName, attrValue] = attrMatch\n if (attrValue === undefined) {\n // Just checking if attribute exists\n return attrName in el.attribs\n } else {\n // Check if attribute has specific value\n return el.attribs?.[attrName] === attrValue\n }\n }\n\n // Check for class selector .class\n if (selector.startsWith('.')) {\n const className = selector.slice(1)\n const classes = el.attribs?.class?.split(/\\s+/) || []\n return classes.includes(className)\n }\n\n // Check for id selector #id\n if (selector.startsWith('#')) {\n const id = selector.slice(1)\n return el.attribs?.id === id\n }\n\n // Check for tag selector (possibly with attribute)\n // Split tag from attribute if present, e.g., \"div[role=alert]\"\n const tagAttrMatch = selector.match(/^([a-z][a-z0-9]*)\\[([^\\]]+)\\]$/i)\n if (tagAttrMatch) {\n const [, tagName, attrPart] = tagAttrMatch\n if (el.name !== tagName) return false\n\n // Parse attribute part: could be \"attr\" or \"attr=value\"\n const attrEqMatch = attrPart.match(/^([^=]+)(?:=(.*))?$/)\n if (attrEqMatch) {\n const [, attrName, attrValue] = attrEqMatch\n if (attrValue === undefined) {\n return attrName in el.attribs\n } else {\n return el.attribs?.[attrName] === attrValue\n }\n }\n return false\n }\n\n // Simple tag selector\n return el.name === selector\n}\n"],"mappings":";;;;;;;;;AAQA,MAAM,qBAAgF;CACpF,OAAO;EACL,aAAa;EACb,aAAa;EACb,MAAM;CACR;CACA,KAAK,EACH,KAAK,GACP;AACF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA8BA,SAAgB,cAAc,MAAc,SAA2B,CAAC,GAAW;CACjF,OAAO,UAAU,iBAAiB,MAAM,IAAI,GAAG,MAAM,CAAC;AACxD;;;;;;AAOA,SAAgB,iBAAiB,KAAkB,SAA2B,CAAC,GAAgB;CAC7F,MAAM,YAAY,OAAO;CAGzB,IAAI,cAAc,OAChB,OAAO;CAKT,MAAM,kBAAkBA,OADD,OAAO,cAAc,WAAW,YAAY,CAAC,GACtB,kBAAkB;CAGhE,KAAK,MAAM,CAAC,iBAAiB,eAAe,OAAO,QAAQ,eAAe,GAAG;EAE3E,IAAI,eAAe,OAAO;EAE1B,MAAM,YAAY,gBAAgB,MAAM,GAAG,CAAC,CAAC,KAAI,MAAK,EAAE,KAAK,CAAC;EAE9D,KAAK,MAAM,SAAS;GAClB,MAAM,KAAK;GACX,IAAI,CAAC,GAAG,MAAM;GAKd,IAFgB,UAAU,MAAK,aAAY,eAAe,IAAI,QAAQ,CAE5D,GAAG;IAEX,IAAI,CAAC,GAAG,SACN,GAAG,UAAU,CAAC;IAGhB,KAAK,MAAM,CAAC,UAAU,cAAc,OAAO,QAAQ,UAAU,GAAG;KAE9D,IAAI,cAAc,OAAO;KAEzB,IAAI,aAAa,WAAW,GAAG,QAAQ,OAAO;MAC5C,MAAM,kBAAkB,GAAG,QAAQ,MAAM,MAAM,KAAK,CAAC,CAAC,OAAO,OAAO;MACpE,MAAM,aAAa,OAAO,SAAS,CAAC,CAAC,MAAM,KAAK,CAAC,CAAC,OAAO,OAAO;MAChE,MAAM,gBAAgB,CAAC,mBAAG,IAAI,IAAI,CAAC,GAAG,iBAAiB,GAAG,UAAU,CAAC,CAAC;MACtE,IAAI,cAAc,KAAK,GAAG,MAAM,GAAG,QAAQ,OACzC,GAAG,QAAQ,QAAQ,cAAc,KAAK,GAAG;KAE7C,OAEE,IAAI,EAAE,YAAY,GAAG,UACnB,GAAG,QAAQ,YAAY,OAAO,SAAS;IAG7C;GACF;EACF,CAAC;CACH;CAEA,OAAO;AACT;;;;;AAMA,SAAS,eAAe,IAAa,UAA2B;CAE9D,WAAW,SAAS,KAAK;CAGzB,MAAM,YAAY,SAAS,MAAM,+BAA+B;CAChE,IAAI,WAAW;EACb,MAAM,GAAG,UAAU,aAAa;EAChC,IAAI,cAAc,KAAA,GAEhB,OAAO,YAAY,GAAG;OAGtB,OAAO,GAAG,UAAU,cAAc;CAEtC;CAGA,IAAI,SAAS,WAAW,GAAG,GAAG;EAC5B,MAAM,YAAY,SAAS,MAAM,CAAC;EAElC,QADgB,GAAG,SAAS,OAAO,MAAM,KAAK,KAAK,CAAC,EAAA,CACrC,SAAS,SAAS;CACnC;CAGA,IAAI,SAAS,WAAW,GAAG,GAAG;EAC5B,MAAM,KAAK,SAAS,MAAM,CAAC;EAC3B,OAAO,GAAG,SAAS,OAAO;CAC5B;CAIA,MAAM,eAAe,SAAS,MAAM,iCAAiC;CACrE,IAAI,cAAc;EAChB,MAAM,GAAG,SAAS,YAAY;EAC9B,IAAI,GAAG,SAAS,SAAS,OAAO;EAGhC,MAAM,cAAc,SAAS,MAAM,qBAAqB;EACxD,IAAI,aAAa;GACf,MAAM,GAAG,UAAU,aAAa;GAChC,IAAI,cAAc,KAAA,GAChB,OAAO,YAAY,GAAG;QAEtB,OAAO,GAAG,UAAU,cAAc;EAEtC;EACA,OAAO;CACT;CAGA,OAAO,GAAG,SAAS;AACrB"}
@@ -3,9 +3,24 @@ import { ChildNode } from "domhandler";
3
3
 
4
4
  //#region src/transformers/entities.d.ts
5
5
  /**
6
- * Replace literal Unicode characters in text nodes with their HTML entity
7
- * equivalents (zero-width joiners, non-breaking spaces, smart quotes,
8
- * dashes, etc.) for better email-client rendering.
6
+ * Node types {@link entitiesDom} encodes. Both default to `true`.
7
+ */
8
+ interface EntitiesScope {
9
+ /** Encode entities in text nodes */
10
+ text?: boolean;
11
+ /**
12
+ * Encode entities in comment nodes. MSO conditional comment content is
13
+ * rendered by Outlook, and comment data survives parse round-trips
14
+ * un-decoded — so encoding here protects whitespace-only conditionals
15
+ * (e.g. `<Outlook>&nbsp;</Outlook>` spacers) from being collapsed
16
+ * or removed by email-comb and html-crush downstream.
17
+ */
18
+ comments?: boolean;
19
+ }
20
+ /**
21
+ * Replace literal Unicode characters in text and comment nodes with their
22
+ * HTML entity equivalents (zero-width joiners, non-breaking spaces, smart
23
+ * quotes, dashes, etc.) for better email-client rendering.
9
24
  *
10
25
  * @param html HTML string to transform.
11
26
  * @param custom Extra entries merged on top of the built-in entity map, or
@@ -25,13 +40,13 @@ import { ChildNode } from "domhandler";
25
40
  * // Disable the transform
26
41
  * entities('hello world', false)
27
42
  */
28
- declare function entities(html: string, custom?: EntitiesConfig): string;
43
+ declare function entities(html: string, custom?: EntitiesConfig, scope?: EntitiesScope): string;
29
44
  /**
30
45
  * DOM-form of {@link entities} used by the internal transformer pipeline.
31
46
  * Takes a parsed DOM, returns a parsed DOM — avoids redundant
32
47
  * serialize/parse round-trips when chained with other transformers.
33
48
  */
34
- declare function entitiesDom(dom: ChildNode[], custom?: EntitiesConfig): ChildNode[];
49
+ declare function entitiesDom(dom: ChildNode[], custom?: EntitiesConfig, scope?: EntitiesScope): ChildNode[];
35
50
  //#endregion
36
- export { entities, entitiesDom };
51
+ export { EntitiesScope, entities, entitiesDom };
37
52
  //# sourceMappingURL=entities.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"entities.d.ts","names":[],"sources":["../../src/transformers/entities.ts"],"mappings":";;;;;;;AAsDA;;;;;;;;AAAoE;AASpE;;;;;;;;;;;iBATgB,QAAA,CAAS,IAAA,UAAc,MAAA,GAAQ,cAAqB;;;AASmB;;;iBAAvE,WAAA,CAAY,GAAA,EAAK,SAAA,IAAa,MAAA,GAAQ,cAAA,GAAwB,SAAA"}
1
+ {"version":3,"file":"entities.d.ts","names":[],"sources":["../../src/transformers/entities.ts"],"mappings":";;;;;;;UAkCiB,aAAA;EAAa;EAE5B,IAAA;EAAA;AAQQ;AA0BV;;;;;EA1BE,QAAQ;AAAA;;;;AA0BqF;AAS/F;;;;;;;;;;;;;;;;;AAAkH;;iBATlG,QAAA,CAAS,IAAA,UAAc,MAAA,GAAQ,cAAA,EAAuB,KAAA,GAAO,aAAkB;;;;;;iBAS/E,WAAA,CAAY,GAAA,EAAK,SAAA,IAAa,MAAA,GAAQ,cAAA,EAAuB,KAAA,GAAO,aAAA,GAAqB,SAAA"}
@@ -30,9 +30,9 @@ const DEFAULT_ENTITIES = {
30
30
  "›": "&rsaquo;"
31
31
  };
32
32
  /**
33
- * Replace literal Unicode characters in text nodes with their HTML entity
34
- * equivalents (zero-width joiners, non-breaking spaces, smart quotes,
35
- * dashes, etc.) for better email-client rendering.
33
+ * Replace literal Unicode characters in text and comment nodes with their
34
+ * HTML entity equivalents (zero-width joiners, non-breaking spaces, smart
35
+ * quotes, dashes, etc.) for better email-client rendering.
36
36
  *
37
37
  * @param html HTML string to transform.
38
38
  * @param custom Extra entries merged on top of the built-in entity map, or
@@ -52,19 +52,19 @@ const DEFAULT_ENTITIES = {
52
52
  * // Disable the transform
53
53
  * entities('hello world', false)
54
54
  */
55
- function entities(html, custom = true) {
56
- return serialize(entitiesDom(parse(html), custom));
55
+ function entities(html, custom = true, scope = {}) {
56
+ return serialize(entitiesDom(parse(html), custom, scope));
57
57
  }
58
58
  /**
59
59
  * DOM-form of {@link entities} used by the internal transformer pipeline.
60
60
  * Takes a parsed DOM, returns a parsed DOM — avoids redundant
61
61
  * serialize/parse round-trips when chained with other transformers.
62
62
  */
63
- function entitiesDom(dom, custom = true) {
63
+ function entitiesDom(dom, custom = true, scope = {}) {
64
64
  if (!custom) return dom;
65
65
  const map = typeof custom === "object" ? defu$1(custom, DEFAULT_ENTITIES) : DEFAULT_ENTITIES;
66
66
  walk(dom, (node) => {
67
- if (node.type === "text") for (const [char, entity] of Object.entries(map)) node.data = node.data.split(char).join(entity);
67
+ if (node.type === "text" && scope.text !== false || node.type === "comment" && scope.comments !== false) for (const [char, entity] of Object.entries(map)) node.data = node.data.split(char).join(entity);
68
68
  });
69
69
  return dom;
70
70
  }
@@ -1 +1 @@
1
- {"version":3,"file":"entities.js","names":["merge"],"sources":["../../src/transformers/entities.ts"],"sourcesContent":["import { defu as merge } from 'defu'\nimport type { ChildNode } from 'domhandler'\nimport { parse, serialize, walk } from '../utils/ast/index.ts'\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 '\\uFEFF': '&#65279;',\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\n/**\n * Replace literal Unicode characters in text nodes with their HTML entity\n * equivalents (zero-width joiners, non-breaking spaces, smart quotes,\n * dashes, etc.) for better email-client rendering.\n *\n * @param html HTML string to transform.\n * @param custom Extra entries merged on top of the built-in entity map, or\n * `false` to disable the transform. Defaults to `true`\n * (built-ins only).\n * @returns The transformed HTML string.\n *\n * @example\n * import { entities } from '@maizzle/framework'\n *\n * // Defaults only\n * entities('hello world') // → 'hello&nbsp;world'\n *\n * // Add a custom mapping\n * entities('© Maizzle', { '©': '&copy;' })\n *\n * // Disable the transform\n * entities('hello world', false)\n */\nexport function entities(html: string, custom: EntitiesConfig = true): string {\n return serialize(entitiesDom(parse(html), custom))\n}\n\n/**\n * DOM-form of {@link entities} 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 entitiesDom(dom: ChildNode[], custom: EntitiesConfig = true): ChildNode[] {\n if (!custom) return dom\n\n const map = typeof custom === 'object'\n ? merge(custom 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,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;AACZ;;;;;;;;;;;;;;;;;;;;;;;;AAyBA,SAAgB,SAAS,MAAc,SAAyB,MAAc;CAC5E,OAAO,UAAU,YAAY,MAAM,IAAI,GAAG,MAAM,CAAC;AACnD;;;;;;AAOA,SAAgB,YAAY,KAAkB,SAAyB,MAAmB;CACxF,IAAI,CAAC,QAAQ,OAAO;CAEpB,MAAM,MAAM,OAAO,WAAW,WAC1BA,OAAM,QAAkC,gBAAgB,IACxD;CAEJ,KAAK,MAAM,SAAS;EAClB,IAAI,KAAK,SAAS,QAChB,KAAK,MAAM,CAAC,MAAM,WAAW,OAAO,QAAQ,GAAG,GAC7C,KAAK,OAAO,KAAK,KAAK,MAAM,IAAI,CAAC,CAAC,KAAK,MAAM;CAGnD,CAAC;CAED,OAAO;AACT"}
1
+ {"version":3,"file":"entities.js","names":["merge"],"sources":["../../src/transformers/entities.ts"],"sourcesContent":["import { defu as merge } from 'defu'\nimport type { ChildNode } from 'domhandler'\nimport { parse, serialize, walk } from '../utils/ast/index.ts'\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 '\\uFEFF': '&#65279;',\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\n/**\n * Node types {@link entitiesDom} encodes. Both default to `true`.\n */\nexport interface EntitiesScope {\n /** Encode entities in text nodes */\n text?: boolean\n /**\n * Encode entities in comment nodes. MSO conditional comment content is\n * rendered by Outlook, and comment data survives parse round-trips\n * un-decoded — so encoding here protects whitespace-only conditionals\n * (e.g. `<Outlook>&nbsp;</Outlook>` spacers) from being collapsed\n * or removed by email-comb and html-crush downstream.\n */\n comments?: boolean\n}\n\n/**\n * Replace literal Unicode characters in text and comment nodes with their\n * HTML entity equivalents (zero-width joiners, non-breaking spaces, smart\n * quotes, dashes, etc.) for better email-client rendering.\n *\n * @param html HTML string to transform.\n * @param custom Extra entries merged on top of the built-in entity map, or\n * `false` to disable the transform. Defaults to `true`\n * (built-ins only).\n * @returns The transformed HTML string.\n *\n * @example\n * import { entities } from '@maizzle/framework'\n *\n * // Defaults only\n * entities('hello world') // → 'hello&nbsp;world'\n *\n * // Add a custom mapping\n * entities('© Maizzle', { '©': '&copy;' })\n *\n * // Disable the transform\n * entities('hello world', false)\n */\nexport function entities(html: string, custom: EntitiesConfig = true, scope: EntitiesScope = {}): string {\n return serialize(entitiesDom(parse(html), custom, scope))\n}\n\n/**\n * DOM-form of {@link entities} 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 entitiesDom(dom: ChildNode[], custom: EntitiesConfig = true, scope: EntitiesScope = {}): ChildNode[] {\n if (!custom) return dom\n\n const map = typeof custom === 'object'\n ? merge(custom as Record<string, string>, DEFAULT_ENTITIES)\n : DEFAULT_ENTITIES\n\n walk(dom, (node) => {\n if (\n (node.type === 'text' && scope.text !== false)\n || (node.type === 'comment' && scope.comments !== false)\n ) {\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,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;AACZ;;;;;;;;;;;;;;;;;;;;;;;;AAyCA,SAAgB,SAAS,MAAc,SAAyB,MAAM,QAAuB,CAAC,GAAW;CACvG,OAAO,UAAU,YAAY,MAAM,IAAI,GAAG,QAAQ,KAAK,CAAC;AAC1D;;;;;;AAOA,SAAgB,YAAY,KAAkB,SAAyB,MAAM,QAAuB,CAAC,GAAgB;CACnH,IAAI,CAAC,QAAQ,OAAO;CAEpB,MAAM,MAAM,OAAO,WAAW,WAC1BA,OAAM,QAAkC,gBAAgB,IACxD;CAEJ,KAAK,MAAM,SAAS;EAClB,IACG,KAAK,SAAS,UAAU,MAAM,SAAS,SACpC,KAAK,SAAS,aAAa,MAAM,aAAa,OAElD,KAAK,MAAM,CAAC,MAAM,WAAW,OAAO,QAAQ,GAAG,GAC7C,KAAK,OAAO,KAAK,KAAK,MAAM,IAAI,CAAC,CAAC,KAAK,MAAM;CAGnD,CAAC;CAED,OAAO;AACT"}
@@ -25,6 +25,7 @@ import { TailwindBlock } from "../composables/renderContext.js";
25
25
  * 9. Filters
26
26
  * 10. Base URL
27
27
  * 11. URL query
28
+ * 11.5 Entities in comment nodes (before purge — protects MSO conditionals)
28
29
  * 12. Purge CSS (serializes/parses internally around email-comb)
29
30
  * 13. Entities
30
31
  * + Vue-generated comments stripped here (on serialized string)
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","names":[],"sources":["../../src/transformers/index.ts"],"mappings":";;;;;;AAwDA;;;;;;;;;;;;;;;;;AAMU;;;;;;;;;;;iBANY,eAAA,CACpB,IAAA,UACA,MAAA,EAAQ,aAAA,EACR,QAAA,WACA,OAAA,WACA,cAAA,GAAiB,aAAA,KAChB,OAAA"}
1
+ {"version":3,"file":"index.d.ts","names":[],"sources":["../../src/transformers/index.ts"],"mappings":";;;;;;AAyDA;;;;;;;;;;;;;;;;;AAMU;;;;;;;;;;;;iBANY,eAAA,CACpB,IAAA,UACA,MAAA,EAAQ,aAAA,EACR,QAAA,WACA,OAAA,WACA,cAAA,GAAiB,aAAA,KAChB,OAAA"}
@@ -47,6 +47,7 @@ import { minify } from "./minify.js";
47
47
  * 9. Filters
48
48
  * 10. Base URL
49
49
  * 11. URL query
50
+ * 11.5 Entities in comment nodes (before purge — protects MSO conditionals)
50
51
  * 12. Purge CSS (serializes/parses internally around email-comb)
51
52
  * 13. Entities
52
53
  * + Vue-generated comments stripped here (on serialized string)
@@ -122,6 +123,15 @@ async function runTransformers(html, config, filePath, doctype, tailwindBlocks)
122
123
  const { _options: queryOptions, ...queryParams } = effective.url.query;
123
124
  dom = urlQueryDom(dom, queryParams, queryOptions ?? {});
124
125
  }
126
+ /**
127
+ * 11.5. Encode entities in comment nodes before purge/minify. Raw
128
+ * invisible chars (e.g. U+00A0 from Vue decoding &nbsp; at compile
129
+ * time) inside MSO conditionals make email-comb remove the whole
130
+ * "whitespace-only" conditional and html-crush collapse the chars.
131
+ * Text nodes are skipped here — purge's internal parse round-trip
132
+ * would decode them again — comment data survives un-decoded.
133
+ */
134
+ if (enabled("entities")) dom = entitiesDom(dom, effective.html?.decodeEntities, { text: false });
125
135
  if (enabled("purgeCss") && effective.css?.purge) {
126
136
  const purgeOptions = typeof effective.css.purge === "object" ? effective.css.purge : {};
127
137
  dom = purgeCssDom(dom, purgeOptions);
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":[],"sources":["../../src/transformers/index.ts"],"sourcesContent":["import { parse, serialize } from '../utils/ast/index.ts'\nimport { inlineLinkDom } from './inlineLink.ts'\nimport { tailwindComponent } from './tailwindComponent.ts'\nimport { tailwindcss } from './tailwindcss.ts'\nimport { safeSelectorsDom } from './safeSelectors.ts'\nimport { attributeToStyleDom } from './attributeToStyle.ts'\nimport { inlineCssDom } from './inlineCss.ts'\nimport { msoPlaceholders } from './msoPlaceholders.ts'\nimport { columnWidth } from './columnWidth.ts'\nimport { imgWidthDom } from './imgWidth.ts'\nimport { removeAttributesDom } from './removeAttributes.ts'\nimport { shorthandCssDom } from './shorthandCss.ts'\nimport { sixHexDom } from './sixHex.ts'\nimport { addAttributesDom } from './addAttributes.ts'\nimport { filtersDom } from './filters/index.ts'\nimport { baseDom } from './base.ts'\nimport { entitiesDom } from './entities.ts'\nimport { urlQueryDom } from './urlQuery.ts'\nimport { purgeCssDom } from './purgeCss.ts'\nimport { replaceStrings } from './replaceStrings.ts'\nimport { format } from './format.ts'\nimport { minifyCodeInline } from './minifyCodeInline.ts'\nimport { minify } from './minify.ts'\nimport type { MaizzleConfig } from '../types/config.ts'\nimport type { TailwindBlock } from '../composables/renderContext.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 tailwindBlocks?: TailwindBlock[],\n): Promise<string> {\n /**\n * Per-transformer skip map — only honored when useTransformers is an object.\n * Whole-pipeline opt-out (`useTransformers === false`) is handled upstream\n * in build.ts / render so we never reach this function in that case.\n *\n * A toggle set to `true` *force-enables* its transformer for this run\n * by layering on the matching config slice (e.g. `prettify: true`\n * sets `html.format = true`). This only applies to transformers\n * whose enable flag is a plain boolean — data-driven ones\n * (filters, baseURL, urlQuery, etc.) need actual config\n * values, so a bare `true` for those is a no-op.\n */\n const toggles = typeof config.useTransformers === 'object' ? config.useTransformers : null\n const enabled = (key: keyof NonNullable<typeof toggles>) => toggles?.[key] !== false\n\n let effective = config\n if (toggles) {\n const cssOver: Record<string, unknown> = {}\n const htmlOver: Record<string, unknown> = {}\n if (toggles.inlineCss === true) cssOver.inline = true\n if (toggles.purgeCss === true) cssOver.purge = true\n if (toggles.safeSelectors === true) cssOver.safe = true\n if (toggles.shorthandCss === true) cssOver.shorthand = true\n if (toggles.sixHex === true) cssOver.sixHex = true\n if (toggles.prettify === true) htmlOver.format = true\n if (toggles.minify === true) htmlOver.minify = true\n if (toggles.entities === true) htmlOver.decodeEntities = true\n\n if (Object.keys(cssOver).length || Object.keys(htmlOver).length) {\n effective = {\n ...config,\n css: { ...config.css, ...cssOver },\n html: { ...config.html, ...htmlOver },\n }\n }\n }\n\n // Parse once — all DOM transformers share this array\n let dom = parse(html)\n\n // 0. Inline <link> stylesheets\n dom = await inlineLinkDom(dom, filePath)\n\n // 0.5. <Tailwind> component — compile per-block scoped CSS, inject into <head>\n if (tailwindBlocks?.length) {\n dom = await tailwindComponent(dom, tailwindBlocks, effective, filePath)\n }\n\n // 1. Tailwind CSS — always runs first\n dom = await tailwindcss(dom, effective, filePath)\n\n // 2. Safe class names\n if (enabled('safeSelectors')) dom = safeSelectorsDom(dom, effective.css)\n\n // 3. Attribute to style\n if (enabled('attributeToStyle') && typeof effective.css?.inline === 'object' && effective.css.inline.attributeToStyle) {\n dom = attributeToStyleDom(dom, effective.css.inline.attributeToStyle)\n }\n\n // 4. CSS inliner (serializes/parses internally around juice)\n if (enabled('inlineCss') && effective.css?.inline) {\n const inlineOptions = typeof effective.css.inline === 'object' ? effective.css.inline : {}\n dom = inlineCssDom(dom, inlineOptions)\n }\n\n // 4.5. Resolve MSO placeholders (table width + td style) from inlined CSS\n dom = msoPlaceholders(dom)\n\n // 4.6. Resolve Column min-width placeholders from nearest sized ancestor\n dom = columnWidth(dom)\n\n // 4.7. Backfill width on <Img> images that inherit their parent's width\n dom = imgWidthDom(dom)\n\n // 5. Remove attributes\n if (enabled('removeAttributes')) {\n const removeRules = effective.html?.attributes?.remove\n dom = removeAttributesDom(dom, Array.isArray(removeRules) ? removeRules : [])\n }\n\n // 6. Shorthand CSS\n if (enabled('shorthandCss') && effective.css?.shorthand) {\n const shorthandOptions = typeof effective.css.shorthand === 'object' ? effective.css.shorthand : {}\n dom = shorthandCssDom(dom, shorthandOptions)\n }\n\n // 7. Six-digit HEX\n if (enabled('sixHex') && effective.css?.sixHex !== false) dom = sixHexDom(dom)\n\n // 8. Add attributes\n if (enabled('addAttributes')) dom = addAttributesDom(dom, effective.html?.attributes)\n\n // 9. Filters\n if (enabled('filters')) dom = filtersDom(dom, effective.filters)\n\n // 10. Base URL (serializes/parses internally for VML/MSO regex passes)\n if (enabled('baseURL') && effective.url?.base) dom = baseDom(dom, effective.url.base)\n\n // 11. URL query\n if (enabled('urlQuery') && effective.url?.query && Object.keys(effective.url.query).length > 0) {\n const { _options: queryOptions, ...queryParams } = effective.url.query as Record<string, unknown>\n dom = urlQueryDom(dom, queryParams, (queryOptions ?? {}) as import('../types/config.ts').UrlQueryOptions)\n }\n\n // 12. Remove unused CSS (serializes/parses internally around email-comb)\n if (enabled('purgeCss') && effective.css?.purge) {\n const purgeOptions = typeof effective.css.purge === 'object' ? effective.css.purge : {}\n dom = purgeCssDom(dom, purgeOptions)\n }\n\n // 13. Entities\n if (enabled('entities')) dom = entitiesDom(dom, effective.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 // 14. Replace strings\n if (enabled('replaceStrings')) result = replaceStrings(result, effective)\n\n // 15. Format — skipped when `minify` is enabled\n const minifyWillRun = enabled('minify') && !!effective.html?.minify\n if (enabled('prettify') && !minifyWillRun && effective.html?.format) {\n const formatOptions = typeof effective.html.format === 'object' ? effective.html.format : {}\n result = await format(result, formatOptions)\n }\n\n // 16. Minify\n if (enabled('minify') && effective.html?.minify) {\n const minifyOptions = typeof effective.html.minify === 'object' ? effective.html.minify : {}\n result = minify(result, minifyOptions)\n }\n\n /**\n * Strip self-closing slashes for HTML5 doctypes, but preserve content\n * inside MSO conditional comments (XML-ish, case/syntax sensitive).\n * MUST run BEFORE minifyCodeInline: at this point, CodeInline's\n * shiki output is still marker-encoded (§MZLT§/§MZGT§), so any\n * ` />` in the highlighted source code (e.g. a Vue self-close\n * tag) hasn't materialized yet and can't be mistakenly\n * stripped from inside a `<code>` element.\n */\n if (!isXhtml) {\n result = result.replace(\n /<!--\\[if [^\\]]*\\]>[\\s\\S]*?<!\\[endif\\]-->|( \\/>)/g,\n (match, selfClose) => selfClose ? '>' : match,\n )\n }\n\n /**\n * 16.5. Strip whitespace inside `data-minify-inline` markers (CodeInline's\n * Shiki output, etc.). Runs after format/minify so it cleans up the\n * pretty-printer's indentation between sibling tags.\n */\n result = minifyCodeInline(result)\n\n return result\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAwDA,eAAsB,gBACpB,MACA,QACA,UACA,SACA,gBACiB;;;;;;;;;;;;;CAajB,MAAM,UAAU,OAAO,OAAO,oBAAoB,WAAW,OAAO,kBAAkB;CACtF,MAAM,WAAW,QAA2C,UAAU,SAAS;CAE/E,IAAI,YAAY;CAChB,IAAI,SAAS;EACX,MAAM,UAAmC,CAAC;EAC1C,MAAM,WAAoC,CAAC;EAC3C,IAAI,QAAQ,cAAc,MAAM,QAAQ,SAAS;EACjD,IAAI,QAAQ,aAAa,MAAM,QAAQ,QAAQ;EAC/C,IAAI,QAAQ,kBAAkB,MAAM,QAAQ,OAAO;EACnD,IAAI,QAAQ,iBAAiB,MAAM,QAAQ,YAAY;EACvD,IAAI,QAAQ,WAAW,MAAM,QAAQ,SAAS;EAC9C,IAAI,QAAQ,aAAa,MAAM,SAAS,SAAS;EACjD,IAAI,QAAQ,WAAW,MAAM,SAAS,SAAS;EAC/C,IAAI,QAAQ,aAAa,MAAM,SAAS,iBAAiB;EAEzD,IAAI,OAAO,KAAK,OAAO,CAAC,CAAC,UAAU,OAAO,KAAK,QAAQ,CAAC,CAAC,QACvD,YAAY;GACV,GAAG;GACH,KAAK;IAAE,GAAG,OAAO;IAAK,GAAG;GAAQ;GACjC,MAAM;IAAE,GAAG,OAAO;IAAM,GAAG;GAAS;EACtC;CAEJ;CAGA,IAAI,MAAM,MAAM,IAAI;CAGpB,MAAM,MAAM,cAAc,KAAK,QAAQ;CAGvC,IAAI,gBAAgB,QAClB,MAAM,MAAM,kBAAkB,KAAK,gBAAgB,WAAW,QAAQ;CAIxE,MAAM,MAAM,YAAY,KAAK,WAAW,QAAQ;CAGhD,IAAI,QAAQ,eAAe,GAAG,MAAM,iBAAiB,KAAK,UAAU,GAAG;CAGvE,IAAI,QAAQ,kBAAkB,KAAK,OAAO,UAAU,KAAK,WAAW,YAAY,UAAU,IAAI,OAAO,kBACnG,MAAM,oBAAoB,KAAK,UAAU,IAAI,OAAO,gBAAgB;CAItE,IAAI,QAAQ,WAAW,KAAK,UAAU,KAAK,QAAQ;EACjD,MAAM,gBAAgB,OAAO,UAAU,IAAI,WAAW,WAAW,UAAU,IAAI,SAAS,CAAC;EACzF,MAAM,aAAa,KAAK,aAAa;CACvC;CAGA,MAAM,gBAAgB,GAAG;CAGzB,MAAM,YAAY,GAAG;CAGrB,MAAM,YAAY,GAAG;CAGrB,IAAI,QAAQ,kBAAkB,GAAG;EAC/B,MAAM,cAAc,UAAU,MAAM,YAAY;EAChD,MAAM,oBAAoB,KAAK,MAAM,QAAQ,WAAW,IAAI,cAAc,CAAC,CAAC;CAC9E;CAGA,IAAI,QAAQ,cAAc,KAAK,UAAU,KAAK,WAAW;EACvD,MAAM,mBAAmB,OAAO,UAAU,IAAI,cAAc,WAAW,UAAU,IAAI,YAAY,CAAC;EAClG,MAAM,gBAAgB,KAAK,gBAAgB;CAC7C;CAGA,IAAI,QAAQ,QAAQ,KAAK,UAAU,KAAK,WAAW,OAAO,MAAM,UAAU,GAAG;CAG7E,IAAI,QAAQ,eAAe,GAAG,MAAM,iBAAiB,KAAK,UAAU,MAAM,UAAU;CAGpF,IAAI,QAAQ,SAAS,GAAG,MAAM,WAAW,KAAK,UAAU,OAAO;CAG/D,IAAI,QAAQ,SAAS,KAAK,UAAU,KAAK,MAAM,MAAM,QAAQ,KAAK,UAAU,IAAI,IAAI;CAGpF,IAAI,QAAQ,UAAU,KAAK,UAAU,KAAK,SAAS,OAAO,KAAK,UAAU,IAAI,KAAK,CAAC,CAAC,SAAS,GAAG;EAC9F,MAAM,EAAE,UAAU,cAAc,GAAG,gBAAgB,UAAU,IAAI;EACjE,MAAM,YAAY,KAAK,aAAc,gBAAgB,CAAC,CAAkD;CAC1G;CAGA,IAAI,QAAQ,UAAU,KAAK,UAAU,KAAK,OAAO;EAC/C,MAAM,eAAe,OAAO,UAAU,IAAI,UAAU,WAAW,UAAU,IAAI,QAAQ,CAAC;EACtF,MAAM,YAAY,KAAK,YAAY;CACrC;CAGA,IAAI,QAAQ,UAAU,GAAG,MAAM,YAAY,KAAK,UAAU,MAAM,cAAc;CAG9E,MAAM,UAAU,UAAU,SAAS,KAAK,OAAO,IAAI;CACnD,IAAI,SAAS,UAAU,KAAK,EAAE,iBAAiB,QAAQ,CAAC;CAGxD,IAAI,QAAQ,gBAAgB,GAAG,SAAS,eAAe,QAAQ,SAAS;CAGxE,MAAM,gBAAgB,QAAQ,QAAQ,KAAK,CAAC,CAAC,UAAU,MAAM;CAC7D,IAAI,QAAQ,UAAU,KAAK,CAAC,iBAAiB,UAAU,MAAM,QAAQ;EACnE,MAAM,gBAAgB,OAAO,UAAU,KAAK,WAAW,WAAW,UAAU,KAAK,SAAS,CAAC;EAC3F,SAAS,MAAM,OAAO,QAAQ,aAAa;CAC7C;CAGA,IAAI,QAAQ,QAAQ,KAAK,UAAU,MAAM,QAAQ;EAC/C,MAAM,gBAAgB,OAAO,UAAU,KAAK,WAAW,WAAW,UAAU,KAAK,SAAS,CAAC;EAC3F,SAAS,OAAO,QAAQ,aAAa;CACvC;;;;;;;;;;CAWA,IAAI,CAAC,SACH,SAAS,OAAO,QACd,qDACC,OAAO,cAAc,YAAY,MAAM,KAC1C;;;;;;CAQF,SAAS,iBAAiB,MAAM;CAEhC,OAAO;AACT"}
1
+ {"version":3,"file":"index.js","names":[],"sources":["../../src/transformers/index.ts"],"sourcesContent":["import { parse, serialize } from '../utils/ast/index.ts'\nimport { inlineLinkDom } from './inlineLink.ts'\nimport { tailwindComponent } from './tailwindComponent.ts'\nimport { tailwindcss } from './tailwindcss.ts'\nimport { safeSelectorsDom } from './safeSelectors.ts'\nimport { attributeToStyleDom } from './attributeToStyle.ts'\nimport { inlineCssDom } from './inlineCss.ts'\nimport { msoPlaceholders } from './msoPlaceholders.ts'\nimport { columnWidth } from './columnWidth.ts'\nimport { imgWidthDom } from './imgWidth.ts'\nimport { removeAttributesDom } from './removeAttributes.ts'\nimport { shorthandCssDom } from './shorthandCss.ts'\nimport { sixHexDom } from './sixHex.ts'\nimport { addAttributesDom } from './addAttributes.ts'\nimport { filtersDom } from './filters/index.ts'\nimport { baseDom } from './base.ts'\nimport { entitiesDom } from './entities.ts'\nimport { urlQueryDom } from './urlQuery.ts'\nimport { purgeCssDom } from './purgeCss.ts'\nimport { replaceStrings } from './replaceStrings.ts'\nimport { format } from './format.ts'\nimport { minifyCodeInline } from './minifyCodeInline.ts'\nimport { minify } from './minify.ts'\nimport type { MaizzleConfig } from '../types/config.ts'\nimport type { TailwindBlock } from '../composables/renderContext.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 * 11.5 Entities in comment nodes (before purge — protects MSO conditionals)\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 tailwindBlocks?: TailwindBlock[],\n): Promise<string> {\n /**\n * Per-transformer skip map — only honored when useTransformers is an object.\n * Whole-pipeline opt-out (`useTransformers === false`) is handled upstream\n * in build.ts / render so we never reach this function in that case.\n *\n * A toggle set to `true` *force-enables* its transformer for this run\n * by layering on the matching config slice (e.g. `prettify: true`\n * sets `html.format = true`). This only applies to transformers\n * whose enable flag is a plain boolean — data-driven ones\n * (filters, baseURL, urlQuery, etc.) need actual config\n * values, so a bare `true` for those is a no-op.\n */\n const toggles = typeof config.useTransformers === 'object' ? config.useTransformers : null\n const enabled = (key: keyof NonNullable<typeof toggles>) => toggles?.[key] !== false\n\n let effective = config\n if (toggles) {\n const cssOver: Record<string, unknown> = {}\n const htmlOver: Record<string, unknown> = {}\n if (toggles.inlineCss === true) cssOver.inline = true\n if (toggles.purgeCss === true) cssOver.purge = true\n if (toggles.safeSelectors === true) cssOver.safe = true\n if (toggles.shorthandCss === true) cssOver.shorthand = true\n if (toggles.sixHex === true) cssOver.sixHex = true\n if (toggles.prettify === true) htmlOver.format = true\n if (toggles.minify === true) htmlOver.minify = true\n if (toggles.entities === true) htmlOver.decodeEntities = true\n\n if (Object.keys(cssOver).length || Object.keys(htmlOver).length) {\n effective = {\n ...config,\n css: { ...config.css, ...cssOver },\n html: { ...config.html, ...htmlOver },\n }\n }\n }\n\n // Parse once — all DOM transformers share this array\n let dom = parse(html)\n\n // 0. Inline <link> stylesheets\n dom = await inlineLinkDom(dom, filePath)\n\n // 0.5. <Tailwind> component — compile per-block scoped CSS, inject into <head>\n if (tailwindBlocks?.length) {\n dom = await tailwindComponent(dom, tailwindBlocks, effective, filePath)\n }\n\n // 1. Tailwind CSS — always runs first\n dom = await tailwindcss(dom, effective, filePath)\n\n // 2. Safe class names\n if (enabled('safeSelectors')) dom = safeSelectorsDom(dom, effective.css)\n\n // 3. Attribute to style\n if (enabled('attributeToStyle') && typeof effective.css?.inline === 'object' && effective.css.inline.attributeToStyle) {\n dom = attributeToStyleDom(dom, effective.css.inline.attributeToStyle)\n }\n\n // 4. CSS inliner (serializes/parses internally around juice)\n if (enabled('inlineCss') && effective.css?.inline) {\n const inlineOptions = typeof effective.css.inline === 'object' ? effective.css.inline : {}\n dom = inlineCssDom(dom, inlineOptions)\n }\n\n // 4.5. Resolve MSO placeholders (table width + td style) from inlined CSS\n dom = msoPlaceholders(dom)\n\n // 4.6. Resolve Column min-width placeholders from nearest sized ancestor\n dom = columnWidth(dom)\n\n // 4.7. Backfill width on <Img> images that inherit their parent's width\n dom = imgWidthDom(dom)\n\n // 5. Remove attributes\n if (enabled('removeAttributes')) {\n const removeRules = effective.html?.attributes?.remove\n dom = removeAttributesDom(dom, Array.isArray(removeRules) ? removeRules : [])\n }\n\n // 6. Shorthand CSS\n if (enabled('shorthandCss') && effective.css?.shorthand) {\n const shorthandOptions = typeof effective.css.shorthand === 'object' ? effective.css.shorthand : {}\n dom = shorthandCssDom(dom, shorthandOptions)\n }\n\n // 7. Six-digit HEX\n if (enabled('sixHex') && effective.css?.sixHex !== false) dom = sixHexDom(dom)\n\n // 8. Add attributes\n if (enabled('addAttributes')) dom = addAttributesDom(dom, effective.html?.attributes)\n\n // 9. Filters\n if (enabled('filters')) dom = filtersDom(dom, effective.filters)\n\n // 10. Base URL (serializes/parses internally for VML/MSO regex passes)\n if (enabled('baseURL') && effective.url?.base) dom = baseDom(dom, effective.url.base)\n\n // 11. URL query\n if (enabled('urlQuery') && effective.url?.query && Object.keys(effective.url.query).length > 0) {\n const { _options: queryOptions, ...queryParams } = effective.url.query as Record<string, unknown>\n dom = urlQueryDom(dom, queryParams, (queryOptions ?? {}) as import('../types/config.ts').UrlQueryOptions)\n }\n\n /**\n * 11.5. Encode entities in comment nodes before purge/minify. Raw\n * invisible chars (e.g. U+00A0 from Vue decoding &nbsp; at compile\n * time) inside MSO conditionals make email-comb remove the whole\n * \"whitespace-only\" conditional and html-crush collapse the chars.\n * Text nodes are skipped here — purge's internal parse round-trip\n * would decode them again — comment data survives un-decoded.\n */\n if (enabled('entities')) dom = entitiesDom(dom, effective.html?.decodeEntities, { text: false })\n\n // 12. Remove unused CSS (serializes/parses internally around email-comb)\n if (enabled('purgeCss') && effective.css?.purge) {\n const purgeOptions = typeof effective.css.purge === 'object' ? effective.css.purge : {}\n dom = purgeCssDom(dom, purgeOptions)\n }\n\n // 13. Entities\n if (enabled('entities')) dom = entitiesDom(dom, effective.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 // 14. Replace strings\n if (enabled('replaceStrings')) result = replaceStrings(result, effective)\n\n // 15. Format — skipped when `minify` is enabled\n const minifyWillRun = enabled('minify') && !!effective.html?.minify\n if (enabled('prettify') && !minifyWillRun && effective.html?.format) {\n const formatOptions = typeof effective.html.format === 'object' ? effective.html.format : {}\n result = await format(result, formatOptions)\n }\n\n // 16. Minify\n if (enabled('minify') && effective.html?.minify) {\n const minifyOptions = typeof effective.html.minify === 'object' ? effective.html.minify : {}\n result = minify(result, minifyOptions)\n }\n\n /**\n * Strip self-closing slashes for HTML5 doctypes, but preserve content\n * inside MSO conditional comments (XML-ish, case/syntax sensitive).\n * MUST run BEFORE minifyCodeInline: at this point, CodeInline's\n * shiki output is still marker-encoded (§MZLT§/§MZGT§), so any\n * ` />` in the highlighted source code (e.g. a Vue self-close\n * tag) hasn't materialized yet and can't be mistakenly\n * stripped from inside a `<code>` element.\n */\n if (!isXhtml) {\n result = result.replace(\n /<!--\\[if [^\\]]*\\]>[\\s\\S]*?<!\\[endif\\]-->|( \\/>)/g,\n (match, selfClose) => selfClose ? '>' : match,\n )\n }\n\n /**\n * 16.5. Strip whitespace inside `data-minify-inline` markers (CodeInline's\n * Shiki output, etc.). Runs after format/minify so it cleans up the\n * pretty-printer's indentation between sibling tags.\n */\n result = minifyCodeInline(result)\n\n return result\n}\n"],"mappings":"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"}
@@ -4,7 +4,7 @@ import { serialize } from "../utils/ast/serializer.js";
4
4
  import "../utils/ast/index.js";
5
5
  import { conv } from "color-shorthand-hex-to-six-digit";
6
6
  //#region src/transformers/sixHex.ts
7
- const targets = new Set(["bgcolor", "color"]);
7
+ const targets = /* @__PURE__ */ new Set(["bgcolor", "color"]);
8
8
  /**
9
9
  * Convert 3-digit HEX color codes to 6-digit in `bgcolor` and `color`
10
10
  * attributes, for better email client compatibility.
@@ -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 { 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,OAAO,CAAC;;;;;;;;;;;;;AAc5C,SAAgB,OAAO,MAAsB;CAC3C,OAAO,UAAU,UAAU,MAAM,IAAI,CAAC,CAAC;AACzC;;;;;;AAOA,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,KAAK;EAEjC;CACF,CAAC;CAED,OAAO;AACT"}
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,0BAAU,IAAI,IAAI,CAAC,WAAW,OAAO,CAAC;;;;;;;;;;;;;AAc5C,SAAgB,OAAO,MAAsB;CAC3C,OAAO,UAAU,UAAU,MAAM,IAAI,CAAC,CAAC;AACzC;;;;;;AAOA,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,KAAK;EAEjC;CACF,CAAC;CAED,OAAO;AACT"}
@@ -586,6 +586,21 @@ interface MaizzleConfig {
586
586
  * @default 3000
587
587
  */
588
588
  port?: number;
589
+ /**
590
+ * Expose the dev server on the network.
591
+ *
592
+ * Set to `true` to listen on all interfaces (prints a network URL +
593
+ * QR code), or pass a string to bind a specific address. The
594
+ * `--host` CLI flag takes precedence over this.
595
+ *
596
+ * @default false
597
+ *
598
+ * @example
599
+ * server: {
600
+ * host: true,
601
+ * }
602
+ */
603
+ host?: boolean | string;
589
604
  /**
590
605
  * Additional file paths to watch for changes.
591
606
  *
@@ -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,6 +1,6 @@
1
1
  import render from "dom-serializer";
2
2
  //#region src/utils/ast/serializer.ts
3
- const RAW_TEXT_ELEMENTS = new Set(["script", "style"]);
3
+ const RAW_TEXT_ELEMENTS = /* @__PURE__ */ new Set(["script", "style"]);
4
4
  /**
5
5
  * Re-encode `<` and `>` in text nodes before serialization.
6
6
  *
@@ -1 +1 @@
1
- {"version":3,"file":"serializer.js","names":[],"sources":["../../../src/utils/ast/serializer.ts"],"sourcesContent":["import render from 'dom-serializer'\nimport type { ChildNode, Element, Text } from 'domhandler'\nimport type { DomSerializerOptions } from 'dom-serializer'\n\nconst RAW_TEXT_ELEMENTS = new Set(['script', 'style'])\n\n/**\n * Re-encode `<` and `>` in text nodes before serialization.\n *\n * The parser decodes entities like `&lt;` into raw `<` in text nodes. With\n * `encodeEntities: false` (needed so other transformers can emit entity\n * strings such as `&nbsp;` verbatim), the serializer would write those raw\n * `<` characters as-is, turning escaped text (e.g. a Vue `{{ html }}`\n * interpolation containing `<p>...</p>`) into real DOM downstream.\n *\n * `&` is intentionally not re-encoded: the `entities` transformer writes\n * literal entity strings (`&nbsp;`, `&mdash;`) directly into text-node data\n * and relies on the serializer leaving them alone.\n *\n * Skip `<script>` / `<style>` — their children are raw-text containers, and\n * CSS/JS legitimately contains `<` and `>`.\n */\nfunction encodeTextNodes(dom: ChildNode[], inRawText = false): void {\n for (const node of dom) {\n if (node.type === 'text') {\n if (!inRawText) {\n const text = node as Text\n text.data = text.data\n .replace(/</g, '&lt;')\n .replace(/>/g, '&gt;')\n }\n continue\n }\n\n if ('children' in node && (node as Element).children?.length) {\n const el = node as Element\n const nextRaw = inRawText || RAW_TEXT_ELEMENTS.has(el.name)\n encodeTextNodes(el.children as ChildNode[], nextRaw)\n }\n }\n}\n\nexport function serialize(dom: ChildNode[], options?: DomSerializerOptions): string {\n encodeTextNodes(dom)\n return render(dom, { encodeEntities: false, ...options })\n}\n"],"mappings":";;AAIA,MAAM,oBAAoB,IAAI,IAAI,CAAC,UAAU,OAAO,CAAC;;;;;;;;;;;;;;;;;AAkBrD,SAAS,gBAAgB,KAAkB,YAAY,OAAa;CAClE,KAAK,MAAM,QAAQ,KAAK;EACtB,IAAI,KAAK,SAAS,QAAQ;GACxB,IAAI,CAAC,WAAW;IACd,MAAM,OAAO;IACb,KAAK,OAAO,KAAK,KACd,QAAQ,MAAM,MAAM,CAAC,CACrB,QAAQ,MAAM,MAAM;GACzB;GACA;EACF;EAEA,IAAI,cAAc,QAAS,KAAiB,UAAU,QAAQ;GAC5D,MAAM,KAAK;GACX,MAAM,UAAU,aAAa,kBAAkB,IAAI,GAAG,IAAI;GAC1D,gBAAgB,GAAG,UAAyB,OAAO;EACrD;CACF;AACF;AAEA,SAAgB,UAAU,KAAkB,SAAwC;CAClF,gBAAgB,GAAG;CACnB,OAAO,OAAO,KAAK;EAAE,gBAAgB;EAAO,GAAG;CAAQ,CAAC;AAC1D"}
1
+ {"version":3,"file":"serializer.js","names":[],"sources":["../../../src/utils/ast/serializer.ts"],"sourcesContent":["import render from 'dom-serializer'\nimport type { ChildNode, Element, Text } from 'domhandler'\nimport type { DomSerializerOptions } from 'dom-serializer'\n\nconst RAW_TEXT_ELEMENTS = new Set(['script', 'style'])\n\n/**\n * Re-encode `<` and `>` in text nodes before serialization.\n *\n * The parser decodes entities like `&lt;` into raw `<` in text nodes. With\n * `encodeEntities: false` (needed so other transformers can emit entity\n * strings such as `&nbsp;` verbatim), the serializer would write those raw\n * `<` characters as-is, turning escaped text (e.g. a Vue `{{ html }}`\n * interpolation containing `<p>...</p>`) into real DOM downstream.\n *\n * `&` is intentionally not re-encoded: the `entities` transformer writes\n * literal entity strings (`&nbsp;`, `&mdash;`) directly into text-node data\n * and relies on the serializer leaving them alone.\n *\n * Skip `<script>` / `<style>` — their children are raw-text containers, and\n * CSS/JS legitimately contains `<` and `>`.\n */\nfunction encodeTextNodes(dom: ChildNode[], inRawText = false): void {\n for (const node of dom) {\n if (node.type === 'text') {\n if (!inRawText) {\n const text = node as Text\n text.data = text.data\n .replace(/</g, '&lt;')\n .replace(/>/g, '&gt;')\n }\n continue\n }\n\n if ('children' in node && (node as Element).children?.length) {\n const el = node as Element\n const nextRaw = inRawText || RAW_TEXT_ELEMENTS.has(el.name)\n encodeTextNodes(el.children as ChildNode[], nextRaw)\n }\n }\n}\n\nexport function serialize(dom: ChildNode[], options?: DomSerializerOptions): string {\n encodeTextNodes(dom)\n return render(dom, { encodeEntities: false, ...options })\n}\n"],"mappings":";;AAIA,MAAM,oCAAoB,IAAI,IAAI,CAAC,UAAU,OAAO,CAAC;;;;;;;;;;;;;;;;;AAkBrD,SAAS,gBAAgB,KAAkB,YAAY,OAAa;CAClE,KAAK,MAAM,QAAQ,KAAK;EACtB,IAAI,KAAK,SAAS,QAAQ;GACxB,IAAI,CAAC,WAAW;IACd,MAAM,OAAO;IACb,KAAK,OAAO,KAAK,KACd,QAAQ,MAAM,MAAM,CAAC,CACrB,QAAQ,MAAM,MAAM;GACzB;GACA;EACF;EAEA,IAAI,cAAc,QAAS,KAAiB,UAAU,QAAQ;GAC5D,MAAM,KAAK;GACX,MAAM,UAAU,aAAa,kBAAkB,IAAI,GAAG,IAAI;GAC1D,gBAAgB,GAAG,UAAyB,OAAO;EACrD;CACF;AACF;AAEA,SAAgB,UAAU,KAAkB,SAAwC;CAClF,gBAAgB,GAAG;CACnB,OAAO,OAAO,KAAK;EAAE,gBAAgB;EAAO,GAAG;CAAQ,CAAC;AAC1D"}
@@ -1,5 +1,5 @@
1
1
  //#region src/utils/cssBox.ts
2
- const NO_BORDER_STYLES = new Set(["none", "hidden"]);
2
+ const NO_BORDER_STYLES = /* @__PURE__ */ new Set(["none", "hidden"]);
3
3
  /**
4
4
  * Parse a length token into px. Handles `Npx`, `Nrem`, `Nem`, `Npt`, and
5
5
  * unitless N (treated as px). Returns null for percentages, calc(),
@@ -1 +1 @@
1
- {"version":3,"file":"cssBox.js","names":[],"sources":["../../src/utils/cssBox.ts"],"sourcesContent":["import type { Root } from 'postcss'\n\nexport const NO_BORDER_STYLES = new Set(['none', 'hidden'])\n\n/**\n * Parse a length token into px. Handles `Npx`, `Nrem`, `Nem`, `Npt`, and\n * unitless N (treated as px). Returns null for percentages, calc(),\n * keywords, or anything that doesn't reduce to a concrete length.\n */\nexport function lengthToPx(value: string): number | null {\n const m = value.trim().match(/^([\\d.]+)(px|rem|em|pt)?$/i)\n if (!m) return null\n const n = parseFloat(m[1])\n const unit = (m[2] || 'px').toLowerCase()\n return n * (unit === 'rem' || unit === 'em' ? 16 : unit === 'pt' ? 1.333 : 1)\n}\n\n/**\n * Expand a 1-4 token CSS shorthand (T R B L) into a left/right pair:\n * 1: all sides\n * 2: TB RL\n * 3: T RL B\n * 4: T R B L\n */\nexport function shorthandSides(value: string): { left?: string; right?: string } {\n const parts = value.trim().split(/\\s+/)\n switch (parts.length) {\n case 1: return { left: parts[0], right: parts[0] }\n case 2:\n case 3: return { left: parts[1], right: parts[1] }\n case 4: return { left: parts[3], right: parts[1] }\n default: return {}\n }\n}\n\n/**\n * Read horizontal padding (left + right) px from a parsed style root.\n * Percentages are skipped since they'd need a known container width.\n */\nexport function horizontalPaddingPx(root: Root): number {\n let left: number | null = null\n let right: number | null = null\n\n root.walkDecls((d) => {\n switch (d.prop) {\n case 'padding': {\n const { left: l, right: r } = shorthandSides(d.value)\n if (l) left = lengthToPx(l)\n if (r) right = lengthToPx(r)\n break\n }\n case 'padding-left':\n left = lengthToPx(d.value)\n break\n case 'padding-right':\n right = lengthToPx(d.value)\n break\n }\n })\n\n return (left ?? 0) + (right ?? 0)\n}\n\n/**\n * Extract a px length from a CSS border shorthand (e.g. `1px solid red` → 1).\n * Returns null when the value indicates no border (`none` or `hidden`).\n * Defaults to 3px (CSS `medium`) when a visible style is set but no\n * explicit width token is present in the shorthand value.\n */\nexport function shorthandBorderWidthPx(value: string): number | null {\n const tokens = value.trim().split(/\\s+/)\n if (tokens.some((t) => NO_BORDER_STYLES.has(t.toLowerCase()))) return null\n for (const t of tokens) {\n const px = lengthToPx(t)\n if (px != null) return px\n }\n return 3\n}\n\n/**\n * Read horizontal border widths (left + right) px from a parsed style root.\n * Per-side `border-style: none|hidden` overrides count as zero\n * contribution. Returns total px or 0 when nothing resolves.\n */\nexport function horizontalBorderPx(root: Root): number {\n let left: number | null = null\n let right: number | null = null\n let leftNone = false\n let rightNone = false\n\n root.walkDecls((d) => {\n switch (d.prop) {\n case 'border': {\n const w = shorthandBorderWidthPx(d.value)\n if (w == null) {\n leftNone = rightNone = true\n }\n else {\n left = right = w\n leftNone = rightNone = false\n }\n break\n }\n case 'border-width': {\n const { left: l, right: r } = shorthandSides(d.value)\n if (l) left = lengthToPx(l) ?? left\n if (r) right = lengthToPx(r) ?? right\n break\n }\n case 'border-style': {\n const { left: l, right: r } = shorthandSides(d.value)\n if (l && NO_BORDER_STYLES.has(l.toLowerCase())) leftNone = true\n if (r && NO_BORDER_STYLES.has(r.toLowerCase())) rightNone = true\n break\n }\n case 'border-left': {\n const w = shorthandBorderWidthPx(d.value)\n if (w == null) leftNone = true\n else { left = w; leftNone = false }\n break\n }\n case 'border-right': {\n const w = shorthandBorderWidthPx(d.value)\n if (w == null) rightNone = true\n else { right = w; rightNone = false }\n break\n }\n case 'border-left-width':\n left = lengthToPx(d.value) ?? left\n break\n case 'border-right-width':\n right = lengthToPx(d.value) ?? right\n break\n case 'border-left-style':\n if (NO_BORDER_STYLES.has(d.value.trim().toLowerCase())) leftNone = true\n break\n case 'border-right-style':\n if (NO_BORDER_STYLES.has(d.value.trim().toLowerCase())) rightNone = true\n break\n }\n })\n\n return (leftNone ? 0 : (left ?? 0)) + (rightNone ? 0 : (right ?? 0))\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"cssBox.js","names":[],"sources":["../../src/utils/cssBox.ts"],"sourcesContent":["import type { Root } from 'postcss'\n\nexport const NO_BORDER_STYLES = new Set(['none', 'hidden'])\n\n/**\n * Parse a length token into px. Handles `Npx`, `Nrem`, `Nem`, `Npt`, and\n * unitless N (treated as px). Returns null for percentages, calc(),\n * keywords, or anything that doesn't reduce to a concrete length.\n */\nexport function lengthToPx(value: string): number | null {\n const m = value.trim().match(/^([\\d.]+)(px|rem|em|pt)?$/i)\n if (!m) return null\n const n = parseFloat(m[1])\n const unit = (m[2] || 'px').toLowerCase()\n return n * (unit === 'rem' || unit === 'em' ? 16 : unit === 'pt' ? 1.333 : 1)\n}\n\n/**\n * Expand a 1-4 token CSS shorthand (T R B L) into a left/right pair:\n * 1: all sides\n * 2: TB RL\n * 3: T RL B\n * 4: T R B L\n */\nexport function shorthandSides(value: string): { left?: string; right?: string } {\n const parts = value.trim().split(/\\s+/)\n switch (parts.length) {\n case 1: return { left: parts[0], right: parts[0] }\n case 2:\n case 3: return { left: parts[1], right: parts[1] }\n case 4: return { left: parts[3], right: parts[1] }\n default: return {}\n }\n}\n\n/**\n * Read horizontal padding (left + right) px from a parsed style root.\n * Percentages are skipped since they'd need a known container width.\n */\nexport function horizontalPaddingPx(root: Root): number {\n let left: number | null = null\n let right: number | null = null\n\n root.walkDecls((d) => {\n switch (d.prop) {\n case 'padding': {\n const { left: l, right: r } = shorthandSides(d.value)\n if (l) left = lengthToPx(l)\n if (r) right = lengthToPx(r)\n break\n }\n case 'padding-left':\n left = lengthToPx(d.value)\n break\n case 'padding-right':\n right = lengthToPx(d.value)\n break\n }\n })\n\n return (left ?? 0) + (right ?? 0)\n}\n\n/**\n * Extract a px length from a CSS border shorthand (e.g. `1px solid red` → 1).\n * Returns null when the value indicates no border (`none` or `hidden`).\n * Defaults to 3px (CSS `medium`) when a visible style is set but no\n * explicit width token is present in the shorthand value.\n */\nexport function shorthandBorderWidthPx(value: string): number | null {\n const tokens = value.trim().split(/\\s+/)\n if (tokens.some((t) => NO_BORDER_STYLES.has(t.toLowerCase()))) return null\n for (const t of tokens) {\n const px = lengthToPx(t)\n if (px != null) return px\n }\n return 3\n}\n\n/**\n * Read horizontal border widths (left + right) px from a parsed style root.\n * Per-side `border-style: none|hidden` overrides count as zero\n * contribution. Returns total px or 0 when nothing resolves.\n */\nexport function horizontalBorderPx(root: Root): number {\n let left: number | null = null\n let right: number | null = null\n let leftNone = false\n let rightNone = false\n\n root.walkDecls((d) => {\n switch (d.prop) {\n case 'border': {\n const w = shorthandBorderWidthPx(d.value)\n if (w == null) {\n leftNone = rightNone = true\n }\n else {\n left = right = w\n leftNone = rightNone = false\n }\n break\n }\n case 'border-width': {\n const { left: l, right: r } = shorthandSides(d.value)\n if (l) left = lengthToPx(l) ?? left\n if (r) right = lengthToPx(r) ?? right\n break\n }\n case 'border-style': {\n const { left: l, right: r } = shorthandSides(d.value)\n if (l && NO_BORDER_STYLES.has(l.toLowerCase())) leftNone = true\n if (r && NO_BORDER_STYLES.has(r.toLowerCase())) rightNone = true\n break\n }\n case 'border-left': {\n const w = shorthandBorderWidthPx(d.value)\n if (w == null) leftNone = true\n else { left = w; leftNone = false }\n break\n }\n case 'border-right': {\n const w = shorthandBorderWidthPx(d.value)\n if (w == null) rightNone = true\n else { right = w; rightNone = false }\n break\n }\n case 'border-left-width':\n left = lengthToPx(d.value) ?? left\n break\n case 'border-right-width':\n right = lengthToPx(d.value) ?? right\n break\n case 'border-left-style':\n if (NO_BORDER_STYLES.has(d.value.trim().toLowerCase())) leftNone = true\n break\n case 'border-right-style':\n if (NO_BORDER_STYLES.has(d.value.trim().toLowerCase())) rightNone = true\n break\n }\n })\n\n return (leftNone ? 0 : (left ?? 0)) + (rightNone ? 0 : (right ?? 0))\n}\n"],"mappings":"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"}
@@ -122,9 +122,9 @@ async function newProject(starterArg, dirArg, options = {}) {
122
122
  starter: async () => {
123
123
  const starter = await p.select({
124
124
  message: "Select a Starter",
125
- initialValue: "maizzle/maizzle#next",
125
+ initialValue: "maizzle/maizzle#master",
126
126
  options: [{
127
- value: "maizzle/maizzle#next",
127
+ value: "maizzle/maizzle#master",
128
128
  label: "Default"
129
129
  }, {
130
130
  value: "custom",
@@ -76,7 +76,7 @@ The two most used option types are a boolean option, and an option which takes i
76
76
  Example file: [split.js](./examples/split.js)
77
77
 
78
78
  ```js
79
- const { program } = require('commander');
79
+ import { program } from 'commander';
80
80
 
81
81
  program
82
82
  .option('--first')
@@ -91,10 +91,10 @@ console.log(program.args[0].split(options.separator, limit));
91
91
  ```
92
92
 
93
93
  ```console
94
- $ node split.js -s / --fits a/b/c
94
+ $ node split.js -s - --fits a-b-c
95
95
  error: unknown option '--fits'
96
96
  (Did you mean --first?)
97
- $ node split.js -s / --first a/b/c
97
+ $ node split.js -s - --first a-b-c
98
98
  [ 'a' ]
99
99
  ```
100
100
 
@@ -103,7 +103,7 @@ Here is a more complete program using a subcommand and with descriptions for the
103
103
  Example file: [string-util.js](./examples/string-util.js)
104
104
 
105
105
  ```js
106
- const { Command } = require('commander');
106
+ import { Command } from 'commander';
107
107
  const program = new Command();
108
108
 
109
109
  program
@@ -138,7 +138,7 @@ Options:
138
138
  -s, --separator <char> separator character (default: ",")
139
139
  -h, --help display help for command
140
140
 
141
- $ node string-util.js split --separator=/ a/b/c
141
+ $ node string-util.js split --separator=- a-b-c
142
142
  [ 'a', 'b', 'c' ]
143
143
  ```
144
144
 
@@ -147,11 +147,10 @@ More samples can be found in the [examples](https://github.com/tj/commander.js/t
147
147
  ## Declaring _program_ variable
148
148
 
149
149
  Commander exports a global object which is convenient for quick programs.
150
- This is used in the examples in this README for brevity.
150
+ This is used in some examples in this README for brevity.
151
151
 
152
152
  ```js
153
- // CommonJS (.cjs)
154
- const { program } = require('commander');
153
+ import { program } from 'commander';
155
154
  ```
156
155
 
157
156
  For larger programs which may use commander in multiple ways, including unit testing, it is better to create a local `Command` object to use.
@@ -276,10 +275,7 @@ cheese: stilton
276
275
  ### Other option types, negatable boolean and boolean|value
277
276
 
278
277
  You can define a boolean option long name with a leading `no-` to set the option value to `false` when used.
279
- Defined alone, this also makes the option `true` by default.
280
-
281
- If you define `--foo` first, adding `--no-foo` does not change the default value from what it would
282
- otherwise be.
278
+ Defined alone without a matching positive option, this also makes the option `true` by default.
283
279
 
284
280
  Example file: [options-negatable.js](./examples/options-negatable.js)
285
281
 
@@ -558,7 +554,7 @@ Configuration options can be passed with the call to `.command()` and `.addComma
558
554
  remove the command from the generated help output. Specifying `isDefault: true` will run the subcommand if no other
559
555
  subcommand is specified. (Example file: [defaultCommand.js](./examples/defaultCommand.js).)
560
556
 
561
- You can add alternative names for a command with `.alias()`. (Example file: [alias.js](./examples/alias.js).)
557
+ You can add alternative names for a command with `.alias()`. (Example file: [alias.cjs](./examples/alias.cjs).)
562
558
 
563
559
  `.command()` automatically copies the inherited settings from the parent command to the newly created subcommand. This is only done during creation; any later setting changes to the parent are not inherited.
564
560
 
@@ -1060,7 +1056,7 @@ node -r ts-node/register pm.ts
1060
1056
  This factory function creates a new command. It is exported and may be used instead of using `new`, like:
1061
1057
 
1062
1058
  ```js
1063
- const { createCommand } = require('commander');
1059
+ import { createCommand } from 'commander';
1064
1060
  const program = createCommand();
1065
1061
  ```
1066
1062
 
@@ -1163,7 +1159,7 @@ There is more information available about:
1163
1159
 
1164
1160
  ## Support
1165
1161
 
1166
- The current version of Commander is fully supported on Long Term Support versions of Node.js, and requires at least v20.
1162
+ The current version of Commander is fully supported on Long Term Support versions of Node.js, and requires at least v22.12.0.
1167
1163
 
1168
1164
  Older major versions of Commander receive security updates for 12 months. For more see: [Release Policy](./docs/release-policy.md).
1169
1165
 
@@ -1,24 +1,21 @@
1
- const { Argument } = require('./lib/argument.js');
2
- const { Command } = require('./lib/command.js');
3
- const { CommanderError, InvalidArgumentError } = require('./lib/error.js');
4
- const { Help } = require('./lib/help.js');
5
- const { Option } = require('./lib/option.js');
1
+ import { Argument } from './lib/argument.js';
2
+ import { Command } from './lib/command.js';
3
+ import { CommanderError, InvalidArgumentError } from './lib/error.js';
4
+ import { Help } from './lib/help.js';
5
+ import { Option } from './lib/option.js';
6
6
 
7
- exports.program = new Command();
7
+ export const program = new Command();
8
8
 
9
- exports.createCommand = (name) => new Command(name);
10
- exports.createOption = (flags, description) => new Option(flags, description);
11
- exports.createArgument = (name, description) => new Argument(name, description);
9
+ export const createCommand = (name) => new Command(name);
10
+ export const createOption = (flags, description) =>
11
+ new Option(flags, description);
12
+ export const createArgument = (name, description) =>
13
+ new Argument(name, description);
12
14
 
13
15
  /**
14
16
  * Expose classes
15
17
  */
16
18
 
17
- exports.Command = Command;
18
- exports.Option = Option;
19
- exports.Argument = Argument;
20
- exports.Help = Help;
21
-
22
- exports.CommanderError = CommanderError;
23
- exports.InvalidArgumentError = InvalidArgumentError;
24
- exports.InvalidOptionArgumentError = InvalidArgumentError; // Deprecated
19
+ export { Command, Option, Argument, Help };
20
+ export { CommanderError, InvalidArgumentError };
21
+ export { InvalidArgumentError as InvalidOptionArgumentError }; // Deprecated
@@ -1,6 +1,6 @@
1
- const { InvalidArgumentError } = require('./error.js');
1
+ import { InvalidArgumentError } from './error.js';
2
2
 
3
- class Argument {
3
+ export class Argument {
4
4
  /**
5
5
  * Initialize a new command argument with the given name and description.
6
6
  * The default is that the argument is required, and you can explicitly
@@ -140,11 +140,8 @@ class Argument {
140
140
  * @private
141
141
  */
142
142
 
143
- function humanReadableArgName(arg) {
143
+ export function humanReadableArgName(arg) {
144
144
  const nameOutput = arg.name() + (arg.variadic === true ? '...' : '');
145
145
 
146
146
  return arg.required ? '<' + nameOutput + '>' : '[' + nameOutput + ']';
147
147
  }
148
-
149
- exports.Argument = Argument;
150
- exports.humanReadableArgName = humanReadableArgName;