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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (347) hide show
  1. package/bin/maizzle.mjs +1 -1
  2. package/dist/_virtual/_rolldown/runtime.mjs +32 -0
  3. package/dist/build.mjs +6 -3
  4. package/dist/build.mjs.map +1 -1
  5. package/dist/components/Body.vue +111 -0
  6. package/dist/components/Button.vue +68 -14
  7. package/dist/components/CodeBlock.vue +68 -0
  8. package/dist/components/CodeInline.vue +49 -0
  9. package/dist/components/Column.vue +78 -0
  10. package/dist/components/Container.vue +53 -0
  11. package/dist/components/Divider.vue +28 -0
  12. package/dist/components/Head.vue +30 -0
  13. package/dist/components/Heading.vue +28 -0
  14. package/dist/components/Html.vue +104 -0
  15. package/dist/components/Img.vue +70 -0
  16. package/dist/components/Layout.vue +93 -0
  17. package/dist/components/Link.vue +26 -0
  18. package/dist/components/Markdown.vue +89 -0
  19. package/dist/components/Outlook.vue +36 -0
  20. package/dist/components/Overlap.vue +84 -0
  21. package/dist/components/Preheader.vue +20 -0
  22. package/dist/components/Row.vue +91 -0
  23. package/dist/components/Section.vue +83 -0
  24. package/dist/components/Spacer.vue +50 -7
  25. package/dist/components/Text.vue +29 -0
  26. package/dist/components/Vml.vue +165 -13
  27. package/dist/composables/renderContext.d.mts +5 -0
  28. package/dist/composables/renderContext.d.mts.map +1 -1
  29. package/dist/composables/renderContext.mjs.map +1 -1
  30. package/dist/composables/usePreheader.d.mts +24 -0
  31. package/dist/composables/usePreheader.d.mts.map +1 -0
  32. package/dist/composables/usePreheader.mjs +29 -0
  33. package/dist/composables/usePreheader.mjs.map +1 -0
  34. package/dist/config/defaults.mjs +1 -3
  35. package/dist/config/defaults.mjs.map +1 -1
  36. package/dist/config/index.mjs +7 -0
  37. package/dist/config/index.mjs.map +1 -1
  38. package/dist/index.d.mts +4 -2
  39. package/dist/index.mjs +3 -1
  40. package/dist/node_modules/picomatch/index.mjs +13 -0
  41. package/dist/node_modules/picomatch/index.mjs.map +1 -0
  42. package/dist/node_modules/picomatch/lib/constants.mjs +174 -0
  43. package/dist/node_modules/picomatch/lib/constants.mjs.map +1 -0
  44. package/dist/node_modules/picomatch/lib/parse.mjs +1067 -0
  45. package/dist/node_modules/picomatch/lib/parse.mjs.map +1 -0
  46. package/dist/node_modules/picomatch/lib/picomatch.mjs +304 -0
  47. package/dist/node_modules/picomatch/lib/picomatch.mjs.map +1 -0
  48. package/dist/node_modules/picomatch/lib/scan.mjs +296 -0
  49. package/dist/node_modules/picomatch/lib/scan.mjs.map +1 -0
  50. package/dist/node_modules/picomatch/lib/utils.mjs +53 -0
  51. package/dist/node_modules/picomatch/lib/utils.mjs.map +1 -0
  52. package/dist/plugin.d.mts.map +1 -1
  53. package/dist/plugin.mjs +24 -7
  54. package/dist/plugin.mjs.map +1 -1
  55. package/dist/plugins/postcss/resolveProps.d.mts +8 -0
  56. package/dist/plugins/postcss/resolveProps.d.mts.map +1 -0
  57. package/dist/plugins/postcss/resolveProps.mjs +144 -0
  58. package/dist/plugins/postcss/resolveProps.mjs.map +1 -0
  59. package/dist/plugins/postcss/tailwindCleanup.d.mts.map +1 -1
  60. package/dist/plugins/postcss/tailwindCleanup.mjs +46 -13
  61. package/dist/plugins/postcss/tailwindCleanup.mjs.map +1 -1
  62. package/dist/render/createRenderer.d.mts +8 -3
  63. package/dist/render/createRenderer.d.mts.map +1 -1
  64. package/dist/render/createRenderer.mjs +146 -10
  65. package/dist/render/createRenderer.mjs.map +1 -1
  66. package/dist/render/index.mjs +6 -3
  67. package/dist/render/index.mjs.map +1 -1
  68. package/dist/serve.d.mts.map +1 -1
  69. package/dist/serve.mjs +157 -63
  70. package/dist/serve.mjs.map +1 -1
  71. package/dist/server/compatibility.d.mts +1 -2
  72. package/dist/server/compatibility.d.mts.map +1 -1
  73. package/dist/server/compatibility.mjs +30 -16
  74. package/dist/server/compatibility.mjs.map +1 -1
  75. package/dist/server/email.d.mts +17 -0
  76. package/dist/server/email.d.mts.map +1 -0
  77. package/dist/server/email.mjs +41 -0
  78. package/dist/server/email.mjs.map +1 -0
  79. package/dist/server/linter.d.mts +1 -2
  80. package/dist/server/linter.d.mts.map +1 -1
  81. package/dist/server/linter.mjs +60 -71
  82. package/dist/server/linter.mjs.map +1 -1
  83. package/dist/server/ui/App.vue +206 -70
  84. package/dist/server/ui/components/ui/checkbox/Checkbox.vue +35 -0
  85. package/dist/server/ui/components/ui/checkbox/index.ts +1 -0
  86. package/dist/server/ui/components/ui/command/CommandDialog.vue +1 -1
  87. package/dist/server/ui/components/ui/command/CommandInput.vue +19 -1
  88. package/dist/server/ui/components/ui/command/CommandItem.vue +1 -1
  89. package/dist/server/ui/components/ui/command/CommandList.vue +1 -1
  90. package/dist/server/ui/components/ui/command/CommandShortcut.vue +1 -1
  91. package/dist/server/ui/components/ui/dialog/DialogOverlay.vue +9 -1
  92. package/dist/server/ui/components/ui/dropdown-menu/DropdownMenuItem.vue +1 -1
  93. package/dist/server/ui/components/ui/scroll-area/ScrollBar.vue +1 -1
  94. package/dist/server/ui/components/ui/sheet/SheetContent.vue +1 -1
  95. package/dist/server/ui/components/ui/sheet/SheetOverlay.vue +9 -1
  96. package/dist/server/ui/components/ui/sidebar/Sidebar.vue +8 -1
  97. package/dist/server/ui/components/ui/sidebar/SidebarProvider.vue +1 -1
  98. package/dist/server/ui/components/ui/sidebar/SidebarTrigger.vue +5 -4
  99. package/dist/server/ui/components/ui/tags-input/TagsInput.vue +26 -0
  100. package/dist/server/ui/components/ui/tags-input/TagsInputInput.vue +17 -0
  101. package/dist/server/ui/components/ui/tags-input/TagsInputItem.vue +19 -0
  102. package/dist/server/ui/components/ui/tags-input/TagsInputItemDelete.vue +22 -0
  103. package/dist/server/ui/components/ui/tags-input/TagsInputItemText.vue +17 -0
  104. package/dist/server/ui/components/ui/tags-input/index.ts +5 -0
  105. package/dist/server/ui/components/ui/toggle/index.ts +3 -3
  106. package/dist/server/ui/components/ui/toggle-group/ToggleGroup.vue +1 -1
  107. package/dist/server/ui/components/ui/toggle-group/ToggleGroupItem.vue +2 -2
  108. package/dist/server/ui/main.css +20 -20
  109. package/dist/server/ui/pages/Home.vue +12 -5
  110. package/dist/server/ui/pages/Preview.vue +506 -216
  111. package/dist/transformers/entities.d.mts.map +1 -1
  112. package/dist/transformers/entities.mjs +3 -0
  113. package/dist/transformers/entities.mjs.map +1 -1
  114. package/dist/transformers/filters/defaults.d.mts +6 -0
  115. package/dist/transformers/filters/defaults.d.mts.map +1 -0
  116. package/dist/transformers/filters/defaults.mjs +78 -0
  117. package/dist/transformers/filters/defaults.mjs.map +1 -0
  118. package/dist/transformers/filters/index.d.mts +22 -0
  119. package/dist/transformers/filters/index.d.mts.map +1 -0
  120. package/dist/transformers/filters/index.mjs +67 -0
  121. package/dist/transformers/filters/index.mjs.map +1 -0
  122. package/dist/transformers/index.d.mts +11 -9
  123. package/dist/transformers/index.d.mts.map +1 -1
  124. package/dist/transformers/index.mjs +19 -11
  125. package/dist/transformers/index.mjs.map +1 -1
  126. package/dist/transformers/inlineCSS.d.mts +1 -14
  127. package/dist/transformers/inlineCSS.d.mts.map +1 -1
  128. package/dist/transformers/inlineCSS.mjs +32 -36
  129. package/dist/transformers/inlineCSS.mjs.map +1 -1
  130. package/dist/transformers/purgeCSS.d.mts.map +1 -1
  131. package/dist/transformers/purgeCSS.mjs +67 -1
  132. package/dist/transformers/purgeCSS.mjs.map +1 -1
  133. package/dist/transformers/sixHex.d.mts +16 -0
  134. package/dist/transformers/sixHex.d.mts.map +1 -0
  135. package/dist/transformers/sixHex.mjs +30 -0
  136. package/dist/transformers/sixHex.mjs.map +1 -0
  137. package/dist/transformers/tailwindcss.d.mts +6 -2
  138. package/dist/transformers/tailwindcss.d.mts.map +1 -1
  139. package/dist/transformers/tailwindcss.mjs +54 -30
  140. package/dist/transformers/tailwindcss.mjs.map +1 -1
  141. package/dist/types/config.d.mts +436 -23
  142. package/dist/types/config.d.mts.map +1 -1
  143. package/dist/types/index.d.mts +2 -2
  144. package/dist/utils/ast/serializer.d.mts +3 -2
  145. package/dist/utils/ast/serializer.d.mts.map +1 -1
  146. package/dist/utils/ast/serializer.mjs +24 -0
  147. package/dist/utils/ast/serializer.mjs.map +1 -1
  148. package/dist/utils/detect.d.mts +5 -0
  149. package/dist/utils/detect.d.mts.map +1 -0
  150. package/dist/utils/detect.mjs +11 -0
  151. package/dist/utils/detect.mjs.map +1 -0
  152. package/node_modules/@clack/core/CHANGELOG.md +87 -4
  153. package/node_modules/@clack/core/README.md +1 -1
  154. package/node_modules/@clack/core/dist/index.d.mts +186 -48
  155. package/node_modules/@clack/core/dist/index.mjs +10 -14
  156. package/node_modules/@clack/core/dist/index.mjs.map +1 -1
  157. package/node_modules/@clack/core/package.json +7 -9
  158. package/node_modules/@clack/prompts/CHANGELOG.md +171 -7
  159. package/node_modules/@clack/prompts/README.md +66 -3
  160. package/node_modules/@clack/prompts/dist/index.d.mts +302 -76
  161. package/node_modules/@clack/prompts/dist/index.mjs +134 -84
  162. package/node_modules/@clack/prompts/dist/index.mjs.map +1 -1
  163. package/node_modules/@clack/prompts/package.json +14 -10
  164. package/node_modules/citty/LICENSE +0 -15
  165. package/node_modules/citty/README.md +166 -69
  166. package/node_modules/citty/dist/index.d.mts +88 -56
  167. package/node_modules/citty/dist/index.mjs +399 -437
  168. package/node_modules/citty/package.json +28 -35
  169. package/node_modules/giget/README.md +59 -11
  170. package/node_modules/giget/dist/THIRD-PARTY-LICENSES.md +205 -0
  171. package/node_modules/giget/dist/_chunks/giget.mjs +508 -0
  172. package/node_modules/giget/dist/_chunks/libs/citty.mjs +269 -0
  173. package/node_modules/giget/dist/_chunks/libs/nypm.d.mts +1 -0
  174. package/node_modules/giget/dist/_chunks/libs/nypm.mjs +669 -0
  175. package/node_modules/giget/dist/_chunks/libs/tar.mjs +2931 -0
  176. package/node_modules/giget/dist/_chunks/rolldown-runtime.mjs +14 -0
  177. package/node_modules/giget/dist/cli.d.mts +1 -0
  178. package/node_modules/giget/dist/cli.mjs +89 -111
  179. package/node_modules/giget/dist/index.d.mts +46 -35
  180. package/node_modules/giget/dist/index.mjs +2 -22
  181. package/node_modules/giget/package.json +32 -45
  182. package/node_modules/maizzle/README.md +140 -0
  183. package/node_modules/maizzle/bin/maizzle.mjs +5 -0
  184. package/node_modules/maizzle/dist/commands/new.d.mts +7 -0
  185. package/node_modules/maizzle/dist/commands/new.mjs +253 -0
  186. package/node_modules/{@maizzle/cli → maizzle}/dist/index.d.mts +1 -1
  187. package/node_modules/maizzle/dist/index.mjs +44 -0
  188. package/node_modules/{commander → maizzle/node_modules/commander}/Readme.md +94 -67
  189. package/node_modules/{commander → maizzle/node_modules/commander}/lib/argument.js +5 -4
  190. package/node_modules/{commander → maizzle/node_modules/commander}/lib/command.js +154 -39
  191. package/node_modules/{commander → maizzle/node_modules/commander}/lib/help.js +77 -39
  192. package/node_modules/{commander → maizzle/node_modules/commander}/lib/option.js +16 -3
  193. package/node_modules/{commander → maizzle/node_modules/commander}/package-support.json +4 -1
  194. package/node_modules/{commander → maizzle/node_modules/commander}/package.json +8 -8
  195. package/node_modules/{commander → maizzle/node_modules/commander}/typings/index.d.ts +71 -3
  196. package/node_modules/{@maizzle/cli → maizzle}/package.json +14 -12
  197. package/node_modules/tinyexec/README.md +49 -3
  198. package/node_modules/tinyexec/dist/main.d.mts +25 -14
  199. package/node_modules/tinyexec/dist/main.mjs +148 -100
  200. package/node_modules/tinyexec/package.json +9 -8
  201. package/package.json +17 -13
  202. package/dist/server/ui/components/ui/resizable/ResizableHandle.vue +0 -30
  203. package/dist/server/ui/components/ui/resizable/ResizablePanel.vue +0 -21
  204. package/dist/server/ui/components/ui/resizable/ResizablePanelGroup.vue +0 -25
  205. package/dist/server/ui/components/ui/resizable/index.ts +0 -3
  206. package/node_modules/@clack/core/dist/index.cjs +0 -15
  207. package/node_modules/@clack/core/dist/index.cjs.map +0 -1
  208. package/node_modules/@clack/core/dist/index.d.cts +0 -211
  209. package/node_modules/@clack/core/dist/index.d.ts +0 -211
  210. package/node_modules/@clack/prompts/dist/index.cjs +0 -87
  211. package/node_modules/@clack/prompts/dist/index.cjs.map +0 -1
  212. package/node_modules/@clack/prompts/dist/index.d.cts +0 -165
  213. package/node_modules/@clack/prompts/dist/index.d.ts +0 -165
  214. package/node_modules/@maizzle/cli/README.md +0 -58
  215. package/node_modules/@maizzle/cli/dist/index.mjs +0 -42
  216. package/node_modules/citty/dist/index.cjs +0 -475
  217. package/node_modules/citty/dist/index.d.cts +0 -80
  218. package/node_modules/citty/dist/index.d.ts +0 -80
  219. package/node_modules/consola/LICENSE +0 -47
  220. package/node_modules/consola/README.md +0 -352
  221. package/node_modules/consola/basic.d.ts +0 -1
  222. package/node_modules/consola/browser.d.ts +0 -1
  223. package/node_modules/consola/core.d.ts +0 -1
  224. package/node_modules/consola/dist/basic.cjs +0 -32
  225. package/node_modules/consola/dist/basic.d.cts +0 -23
  226. package/node_modules/consola/dist/basic.d.mts +0 -21
  227. package/node_modules/consola/dist/basic.d.ts +0 -23
  228. package/node_modules/consola/dist/basic.mjs +0 -24
  229. package/node_modules/consola/dist/browser.cjs +0 -84
  230. package/node_modules/consola/dist/browser.d.cts +0 -23
  231. package/node_modules/consola/dist/browser.d.mts +0 -21
  232. package/node_modules/consola/dist/browser.d.ts +0 -23
  233. package/node_modules/consola/dist/browser.mjs +0 -76
  234. package/node_modules/consola/dist/chunks/prompt.cjs +0 -288
  235. package/node_modules/consola/dist/chunks/prompt.mjs +0 -280
  236. package/node_modules/consola/dist/core.cjs +0 -517
  237. package/node_modules/consola/dist/core.d.cts +0 -459
  238. package/node_modules/consola/dist/core.d.mts +0 -459
  239. package/node_modules/consola/dist/core.d.ts +0 -459
  240. package/node_modules/consola/dist/core.mjs +0 -512
  241. package/node_modules/consola/dist/index.cjs +0 -663
  242. package/node_modules/consola/dist/index.d.cts +0 -24
  243. package/node_modules/consola/dist/index.d.mts +0 -22
  244. package/node_modules/consola/dist/index.d.ts +0 -24
  245. package/node_modules/consola/dist/index.mjs +0 -651
  246. package/node_modules/consola/dist/shared/consola.DCGIlDNP.cjs +0 -75
  247. package/node_modules/consola/dist/shared/consola.DRwqZj3T.mjs +0 -72
  248. package/node_modules/consola/dist/shared/consola.DXBYu-KD.mjs +0 -288
  249. package/node_modules/consola/dist/shared/consola.DwRq1yyg.cjs +0 -312
  250. package/node_modules/consola/dist/utils.cjs +0 -64
  251. package/node_modules/consola/dist/utils.d.cts +0 -286
  252. package/node_modules/consola/dist/utils.d.mts +0 -286
  253. package/node_modules/consola/dist/utils.d.ts +0 -286
  254. package/node_modules/consola/dist/utils.mjs +0 -54
  255. package/node_modules/consola/lib/index.cjs +0 -10
  256. package/node_modules/consola/package.json +0 -136
  257. package/node_modules/consola/utils.d.ts +0 -1
  258. package/node_modules/create-maizzle/README.md +0 -86
  259. package/node_modules/create-maizzle/bin/create-maizzle.mjs +0 -4
  260. package/node_modules/create-maizzle/node_modules/@clack/core/CHANGELOG.md +0 -340
  261. package/node_modules/create-maizzle/node_modules/@clack/core/LICENSE +0 -9
  262. package/node_modules/create-maizzle/node_modules/@clack/core/README.md +0 -22
  263. package/node_modules/create-maizzle/node_modules/@clack/core/dist/index.d.mts +0 -349
  264. package/node_modules/create-maizzle/node_modules/@clack/core/dist/index.mjs +0 -11
  265. package/node_modules/create-maizzle/node_modules/@clack/core/dist/index.mjs.map +0 -1
  266. package/node_modules/create-maizzle/node_modules/@clack/core/package.json +0 -60
  267. package/node_modules/create-maizzle/node_modules/@clack/prompts/CHANGELOG.md +0 -576
  268. package/node_modules/create-maizzle/node_modules/@clack/prompts/LICENSE +0 -9
  269. package/node_modules/create-maizzle/node_modules/@clack/prompts/README.md +0 -270
  270. package/node_modules/create-maizzle/node_modules/@clack/prompts/dist/index.d.mts +0 -391
  271. package/node_modules/create-maizzle/node_modules/@clack/prompts/dist/index.mjs +0 -137
  272. package/node_modules/create-maizzle/node_modules/@clack/prompts/dist/index.mjs.map +0 -1
  273. package/node_modules/create-maizzle/node_modules/@clack/prompts/package.json +0 -65
  274. package/node_modules/create-maizzle/package.json +0 -47
  275. package/node_modules/create-maizzle/src/index.js +0 -242
  276. package/node_modules/defu/LICENSE +0 -21
  277. package/node_modules/defu/README.md +0 -171
  278. package/node_modules/defu/dist/defu.cjs +0 -77
  279. package/node_modules/defu/dist/defu.d.cts +0 -31
  280. package/node_modules/defu/dist/defu.d.mts +0 -29
  281. package/node_modules/defu/dist/defu.d.ts +0 -31
  282. package/node_modules/defu/dist/defu.mjs +0 -69
  283. package/node_modules/defu/lib/defu.cjs +0 -10
  284. package/node_modules/defu/lib/defu.d.cts +0 -12
  285. package/node_modules/defu/package.json +0 -48
  286. package/node_modules/giget/dist/shared/giget.OCaTp9b-.mjs +0 -468
  287. package/node_modules/node-fetch-native/LICENSE +0 -114
  288. package/node_modules/node-fetch-native/README.md +0 -225
  289. package/node_modules/node-fetch-native/dist/chunks/multipart-parser.cjs +0 -2
  290. package/node_modules/node-fetch-native/dist/chunks/multipart-parser.mjs +0 -2
  291. package/node_modules/node-fetch-native/dist/index.cjs +0 -1
  292. package/node_modules/node-fetch-native/dist/index.mjs +0 -1
  293. package/node_modules/node-fetch-native/dist/native.cjs +0 -1
  294. package/node_modules/node-fetch-native/dist/native.mjs +0 -1
  295. package/node_modules/node-fetch-native/dist/node.cjs +0 -19
  296. package/node_modules/node-fetch-native/dist/node.mjs +0 -19
  297. package/node_modules/node-fetch-native/dist/polyfill.cjs +0 -1
  298. package/node_modules/node-fetch-native/dist/polyfill.mjs +0 -1
  299. package/node_modules/node-fetch-native/dist/proxy-stub.cjs +0 -1
  300. package/node_modules/node-fetch-native/dist/proxy-stub.mjs +0 -1
  301. package/node_modules/node-fetch-native/dist/proxy.cjs +0 -58
  302. package/node_modules/node-fetch-native/dist/shared/node-fetch-native.DfbY2q-x.mjs +0 -1
  303. package/node_modules/node-fetch-native/dist/shared/node-fetch-native.DhEqb06g.cjs +0 -1
  304. package/node_modules/node-fetch-native/index.d.ts +0 -1
  305. package/node_modules/node-fetch-native/lib/empty.cjs +0 -0
  306. package/node_modules/node-fetch-native/lib/empty.mjs +0 -0
  307. package/node_modules/node-fetch-native/lib/index.cjs +0 -11
  308. package/node_modules/node-fetch-native/lib/index.d.cts +0 -10
  309. package/node_modules/node-fetch-native/lib/index.d.mts +0 -10
  310. package/node_modules/node-fetch-native/lib/index.d.ts +0 -10
  311. package/node_modules/node-fetch-native/lib/native.cjs +0 -11
  312. package/node_modules/node-fetch-native/lib/polyfill.d.cts +0 -1
  313. package/node_modules/node-fetch-native/lib/polyfill.d.mts +0 -1
  314. package/node_modules/node-fetch-native/lib/polyfill.d.ts +0 -1
  315. package/node_modules/node-fetch-native/lib/proxy.d.ts +0 -32
  316. package/node_modules/node-fetch-native/node.d.ts +0 -1
  317. package/node_modules/node-fetch-native/package.json +0 -138
  318. package/node_modules/node-fetch-native/polyfill.d.ts +0 -1
  319. package/node_modules/node-fetch-native/proxy.d.ts +0 -1
  320. package/node_modules/nypm/node_modules/citty/LICENSE +0 -21
  321. package/node_modules/nypm/node_modules/citty/README.md +0 -231
  322. package/node_modules/nypm/node_modules/citty/dist/index.d.mts +0 -112
  323. package/node_modules/nypm/node_modules/citty/dist/index.mjs +0 -425
  324. package/node_modules/nypm/node_modules/citty/package.json +0 -42
  325. /package/node_modules/{nypm/node_modules/citty → citty}/dist/THIRD-PARTY-LICENSES.md +0 -0
  326. /package/node_modules/{nypm/node_modules/citty → citty}/dist/_chunks/libs/scule.mjs +0 -0
  327. /package/node_modules/{@maizzle/cli → maizzle}/LICENSE +0 -0
  328. /package/node_modules/{@maizzle/cli → maizzle}/dist/commands/make/component.d.mts +0 -0
  329. /package/node_modules/{@maizzle/cli → maizzle}/dist/commands/make/component.mjs +0 -0
  330. /package/node_modules/{@maizzle/cli → maizzle}/dist/commands/make/config.d.mts +0 -0
  331. /package/node_modules/{@maizzle/cli → maizzle}/dist/commands/make/config.mjs +0 -0
  332. /package/node_modules/{@maizzle/cli → maizzle}/dist/commands/make/layout.d.mts +0 -0
  333. /package/node_modules/{@maizzle/cli → maizzle}/dist/commands/make/layout.mjs +0 -0
  334. /package/node_modules/{@maizzle/cli → maizzle}/dist/commands/make/scaffold.d.mts +0 -0
  335. /package/node_modules/{@maizzle/cli → maizzle}/dist/commands/make/scaffold.mjs +0 -0
  336. /package/node_modules/{@maizzle/cli → maizzle}/dist/commands/make/stubs/component.vue +0 -0
  337. /package/node_modules/{@maizzle/cli → maizzle}/dist/commands/make/stubs/config.ts +0 -0
  338. /package/node_modules/{@maizzle/cli → maizzle}/dist/commands/make/stubs/layout.vue +0 -0
  339. /package/node_modules/{@maizzle/cli → maizzle}/dist/commands/make/stubs/template.vue +0 -0
  340. /package/node_modules/{@maizzle/cli → maizzle}/dist/commands/make/template.d.mts +0 -0
  341. /package/node_modules/{@maizzle/cli → maizzle}/dist/commands/make/template.mjs +0 -0
  342. /package/node_modules/{commander → maizzle/node_modules/commander}/LICENSE +0 -0
  343. /package/node_modules/{commander → maizzle/node_modules/commander}/esm.mjs +0 -0
  344. /package/node_modules/{commander → maizzle/node_modules/commander}/index.js +0 -0
  345. /package/node_modules/{commander → maizzle/node_modules/commander}/lib/error.js +0 -0
  346. /package/node_modules/{commander → maizzle/node_modules/commander}/lib/suggestSimilar.js +0 -0
  347. /package/node_modules/{commander → maizzle/node_modules/commander}/typings/esm.d.mts +0 -0
@@ -0,0 +1,41 @@
1
+ import nodemailer from "nodemailer";
2
+
3
+ //#region src/server/email.ts
4
+ async function sendEmail(payload, config, templateConfig) {
5
+ const emailConfig = templateConfig.server?.email ?? config.server?.email;
6
+ let transport;
7
+ let isEthereal = false;
8
+ if (emailConfig?.transport) transport = nodemailer.createTransport(emailConfig.transport);
9
+ else {
10
+ const testAccount = await nodemailer.createTestAccount();
11
+ transport = nodemailer.createTransport({
12
+ host: "smtp.ethereal.email",
13
+ port: 587,
14
+ secure: false,
15
+ auth: {
16
+ user: testAccount.user,
17
+ pass: testAccount.pass
18
+ }
19
+ });
20
+ isEthereal = true;
21
+ }
22
+ const from = emailConfig?.from ?? "Maizzle <maizzle@ethereal.email>";
23
+ const info = await transport.sendMail({
24
+ from,
25
+ to: payload.to.join(", "),
26
+ subject: payload.subject || "Test email",
27
+ html: payload.html,
28
+ text: payload.text || void 0
29
+ });
30
+ const previewUrl = isEthereal ? nodemailer.getTestMessageUrl(info) || void 0 : void 0;
31
+ const recipient = payload.to.length === 1 ? payload.to[0] : `${payload.to.length} recipients`;
32
+ return {
33
+ success: true,
34
+ message: isEthereal ? "Sent via Ethereal" : `Sent to ${recipient}`,
35
+ previewUrl: typeof previewUrl === "string" ? previewUrl : void 0
36
+ };
37
+ }
38
+
39
+ //#endregion
40
+ export { sendEmail };
41
+ //# sourceMappingURL=email.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"email.mjs","names":[],"sources":["../../src/server/email.ts"],"sourcesContent":["import nodemailer from 'nodemailer'\nimport type { MaizzleConfig } from '../types/index.ts'\n\nexport interface SendEmailPayload {\n to: string[]\n subject: string\n html: string\n text?: string\n}\n\ninterface SendEmailResponse {\n success: boolean\n message: string\n previewUrl?: string\n}\n\nexport async function sendEmail(\n payload: SendEmailPayload,\n config: MaizzleConfig,\n templateConfig: MaizzleConfig,\n): Promise<SendEmailResponse> {\n // Template-level config takes priority over global config\n const emailConfig = templateConfig.server?.email ?? config.server?.email\n\n let transport: nodemailer.Transporter\n let isEthereal = false\n\n if (emailConfig?.transport) {\n transport = nodemailer.createTransport(emailConfig.transport as any)\n } else {\n // Fallback to Ethereal\n const testAccount = await nodemailer.createTestAccount()\n transport = nodemailer.createTransport({\n host: 'smtp.ethereal.email',\n port: 587,\n secure: false,\n auth: {\n user: testAccount.user,\n pass: testAccount.pass,\n },\n })\n isEthereal = true\n }\n\n const from = emailConfig?.from ?? 'Maizzle <maizzle@ethereal.email>'\n\n const info = await transport.sendMail({\n from,\n to: payload.to.join(', '),\n subject: payload.subject || 'Test email',\n html: payload.html,\n text: payload.text || undefined,\n })\n\n const previewUrl = isEthereal ? nodemailer.getTestMessageUrl(info) || undefined : undefined\n\n const recipient = payload.to.length === 1\n ? payload.to[0]\n : `${payload.to.length} recipients`\n\n return {\n success: true,\n message: isEthereal\n ? 'Sent via Ethereal'\n : `Sent to ${recipient}`,\n previewUrl: typeof previewUrl === 'string' ? previewUrl : undefined,\n }\n}\n"],"mappings":";;;AAgBA,eAAsB,UACpB,SACA,QACA,gBAC4B;CAE5B,MAAM,cAAc,eAAe,QAAQ,SAAS,OAAO,QAAQ;CAEnE,IAAI;CACJ,IAAI,aAAa;AAEjB,KAAI,aAAa,UACf,aAAY,WAAW,gBAAgB,YAAY,UAAiB;MAC/D;EAEL,MAAM,cAAc,MAAM,WAAW,mBAAmB;AACxD,cAAY,WAAW,gBAAgB;GACrC,MAAM;GACN,MAAM;GACN,QAAQ;GACR,MAAM;IACJ,MAAM,YAAY;IAClB,MAAM,YAAY;IACnB;GACF,CAAC;AACF,eAAa;;CAGf,MAAM,OAAO,aAAa,QAAQ;CAElC,MAAM,OAAO,MAAM,UAAU,SAAS;EACpC;EACA,IAAI,QAAQ,GAAG,KAAK,KAAK;EACzB,SAAS,QAAQ,WAAW;EAC5B,MAAM,QAAQ;EACd,MAAM,QAAQ,QAAQ;EACvB,CAAC;CAEF,MAAM,aAAa,aAAa,WAAW,kBAAkB,KAAK,IAAI,SAAY;CAElF,MAAM,YAAY,QAAQ,GAAG,WAAW,IACpC,QAAQ,GAAG,KACX,GAAG,QAAQ,GAAG,OAAO;AAEzB,QAAO;EACL,SAAS;EACT,SAAS,aACL,sBACA,WAAW;EACf,YAAY,OAAO,eAAe,WAAW,aAAa;EAC3D"}
@@ -1,6 +1,5 @@
1
- import { MaizzleConfig } from "../types/config.mjs";
2
1
  //#region src/server/linter.d.ts
3
- declare function serveLint(url: string, config: MaizzleConfig, res: any): Promise<void>;
2
+ declare function serveLint(url: string, res: any): void;
4
3
  //#endregion
5
4
  export { serveLint };
6
5
  //# sourceMappingURL=linter.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"linter.d.mts","names":[],"sources":["../../src/server/linter.ts"],"mappings":";;iBAYsB,SAAA,CAAU,GAAA,UAAa,MAAA,EAAQ,aAAA,EAAe,GAAA,QAAQ,OAAA"}
1
+ {"version":3,"file":"linter.d.mts","names":[],"sources":["../../src/server/linter.ts"],"mappings":";iBAUgB,SAAA,CAAU,GAAA,UAAa,GAAA"}
@@ -1,18 +1,11 @@
1
1
  import { readFileSync } from "node:fs";
2
2
  import { resolve } from "node:path";
3
- import { glob } from "tinyglobby";
4
3
 
5
4
  //#region src/server/linter.ts
6
- async function serveLint(url, config, res) {
7
- const templateSlug = url.replace("/__maizzle/lint/", "").replace(/\?.*$/, "");
8
- const match = (await glob(config.content ?? ["emails/**/*.vue"])).find((t) => t.replace(/\.(vue|md)$/, "") === templateSlug);
9
- if (!match) {
10
- res.statusCode = 404;
11
- res.end(JSON.stringify({ error: "Template not found" }));
12
- return;
13
- }
5
+ function serveLint(url, res) {
6
+ const filePath = url.replace("/__maizzle/lint/", "").replace(/\?.*$/, "");
14
7
  try {
15
- const source = readFileSync(resolve(match), "utf-8");
8
+ const source = readFileSync(resolve(filePath), "utf-8");
16
9
  const templateMatch = source.match(/<template\b[^>]*>([\s\S]*)<\/template>/);
17
10
  const issues = lintHtml(templateMatch ? templateMatch[1] : source, templateMatch ? source.slice(0, source.indexOf(templateMatch[0]) + templateMatch[0].indexOf(templateMatch[1])).split("\n").length - 1 : 0);
18
11
  res.setHeader("Content-Type", "application/json");
@@ -22,98 +15,90 @@ async function serveLint(url, config, res) {
22
15
  res.end(JSON.stringify({ error: error.message }));
23
16
  }
24
17
  }
18
+ function lineAt(html, offset, lineOffset) {
19
+ return html.slice(0, offset).split("\n").length + lineOffset;
20
+ }
25
21
  function lintHtml(html, lineOffset = 0) {
26
22
  const issues = [];
27
- const lines = html.split("\n");
28
- for (let i = 0; i < lines.length; i++) {
29
- const line = lines[i];
30
- const lineNum = i + 1 + lineOffset;
31
- const imgMatches = [...line.matchAll(/<img\b[^>]*?>/gi)];
32
- for (const match of imgMatches) {
33
- const tag = match[0];
23
+ for (const m of Array.from(html.matchAll(/<([a-zA-Z][a-zA-Z0-9]*)\b([\s\S]*?)>/g))) {
24
+ const tag = m[0];
25
+ const tagName = m[1].toLowerCase();
26
+ const line = lineAt(html, m.index, lineOffset);
27
+ if (tagName === "img") {
34
28
  if (!/\balt\s*=/i.test(tag)) issues.push({
35
29
  type: "warning",
36
30
  title: "Missing alt text",
37
31
  message: "Image is missing the alt attribute",
38
- line: lineNum
32
+ line
39
33
  });
40
- }
41
- for (const match of imgMatches) {
42
- const srcMatch = match[0].match(/\bsrc\s*=\s*["']([^"']*)["']/i);
34
+ const srcMatch = tag.match(/\bsrc\s*=\s*["']([^"']*)["']/i);
43
35
  if (!srcMatch) issues.push({
44
36
  type: "error",
45
37
  title: "Missing image src",
46
38
  message: "Image tag has no src attribute",
47
- line: lineNum
39
+ line
48
40
  });
49
41
  else if (!srcMatch[1].trim()) issues.push({
50
42
  type: "error",
51
43
  title: "Empty image src",
52
44
  message: "Image src attribute is empty",
53
- line: lineNum
45
+ line
54
46
  });
55
47
  else if (srcMatch[1].trim().startsWith("http:")) issues.push({
56
48
  type: "warning",
57
49
  title: "Insecure image src",
58
50
  message: "Image loads over HTTP instead of HTTPS",
59
- line: lineNum
51
+ line
60
52
  });
61
53
  }
62
- const linkMatches = [...line.matchAll(/<a\b[^>]*?>/gi)];
63
- for (const match of linkMatches) {
64
- const hrefMatch = match[0].match(/\bhref\s*=\s*["']([^"']*)["']/i);
65
- if (!hrefMatch) issues.push({
66
- type: "error",
67
- title: "Missing link href",
68
- message: "Anchor tag has no href attribute",
69
- line: lineNum
54
+ const hrefMatch = tag.match(/\bhref\s*=\s*["']([^"']*)["']/i);
55
+ if (hrefMatch) {
56
+ const href = hrefMatch[1].trim();
57
+ if (!href) issues.push({
58
+ type: "warning",
59
+ title: "Empty link href",
60
+ message: "Link href attribute is empty",
61
+ line
62
+ });
63
+ else if (href === "#" || href === "/") issues.push({
64
+ type: "warning",
65
+ title: "Placeholder link",
66
+ message: `Link href is "${href}"`,
67
+ line
68
+ });
69
+ else if (href.startsWith("http:")) issues.push({
70
+ type: "warning",
71
+ title: "Insecure link",
72
+ message: "Link uses HTTP instead of HTTPS",
73
+ line
74
+ });
75
+ else if (href.startsWith("http") && !/^https?:\/\/.+\..+/i.test(href)) issues.push({
76
+ type: "warning",
77
+ title: "Invalid link",
78
+ message: `Link href "${href}" looks malformed`,
79
+ line
70
80
  });
71
- else {
72
- const href = hrefMatch[1].trim();
73
- if (!href) issues.push({
74
- type: "warning",
75
- title: "Empty link href",
76
- message: "Link href attribute is empty",
77
- line: lineNum
78
- });
79
- else if (href === "#" || href === "/") issues.push({
80
- type: "warning",
81
- title: "Placeholder link",
82
- message: `Link href is "${href}"`,
83
- line: lineNum
84
- });
85
- else if (href.startsWith("http:")) issues.push({
86
- type: "warning",
87
- title: "Insecure link",
88
- message: "Link uses HTTP instead of HTTPS",
89
- line: lineNum
90
- });
91
- else if (href.startsWith("http") && !/^https?:\/\/.+\..+/i.test(href)) issues.push({
92
- type: "warning",
93
- title: "Invalid link",
94
- message: `Link href "${href}" looks malformed`,
95
- line: lineNum
96
- });
97
- }
98
81
  }
99
- const resourceMatches = [...line.matchAll(/<(?:link|script|source)\b[^>]*?>/gi)];
100
- for (const match of resourceMatches) {
101
- const attrMatch = match[0].match(/\b(?:href|src)\s*=\s*["']([^"']*)["']/i);
82
+ if ([
83
+ "link",
84
+ "script",
85
+ "source"
86
+ ].includes(tagName)) {
87
+ const attrMatch = tag.match(/\b(?:href|src)\s*=\s*["']([^"']*)["']/i);
102
88
  if (attrMatch && attrMatch[1].trim().startsWith("http:")) issues.push({
103
89
  type: "warning",
104
90
  title: "Insecure resource",
105
91
  message: "Resource loads over HTTP instead of HTTPS",
106
- line: lineNum
92
+ line
107
93
  });
108
94
  }
109
- const urlMatches = [...line.matchAll(/url\s*\(\s*["']?(http:[^"')]+)["']?\s*\)/gi)];
110
- for (const _match of urlMatches) issues.push({
111
- type: "warning",
112
- title: "Insecure CSS url()",
113
- message: "CSS url() loads over HTTP instead of HTTPS",
114
- line: lineNum
115
- });
116
95
  }
96
+ for (const m of Array.from(html.matchAll(/url\s*\(\s*["']?(http:[^"')]+)["']?\s*\)/gi))) issues.push({
97
+ type: "warning",
98
+ title: "Insecure CSS url()",
99
+ message: "CSS url() loads over HTTP instead of HTTPS",
100
+ line: lineAt(html, m.index, lineOffset)
101
+ });
117
102
  const voidElements = new Set([
118
103
  "area",
119
104
  "base",
@@ -174,7 +159,11 @@ function lintHtml(html, lineOffset = 0) {
174
159
  if (!trackedTags.has(tagName) || voidElements.has(tagName)) continue;
175
160
  if (fullMatch.endsWith("/>")) continue;
176
161
  if (fullMatch.startsWith("</")) {
177
- const lastOpen = stack.findLastIndex((s) => s.tag === tagName);
162
+ let lastOpen = -1;
163
+ for (let j = stack.length - 1; j >= 0; j--) if (stack[j].tag === tagName) {
164
+ lastOpen = j;
165
+ break;
166
+ }
178
167
  if (lastOpen !== -1) stack.splice(lastOpen, 1);
179
168
  } else stack.push({
180
169
  tag: tagName,
@@ -1 +1 @@
1
- {"version":3,"file":"linter.mjs","names":[],"sources":["../../src/server/linter.ts"],"sourcesContent":["import { readFileSync } from 'node:fs'\nimport { resolve } from 'node:path'\nimport { glob } from 'tinyglobby'\nimport type { MaizzleConfig } from '../types/index.ts'\n\ninterface LintIssue {\n type: 'error' | 'warning'\n title: string\n message: string\n line?: number\n}\n\nexport async function serveLint(url: string, config: MaizzleConfig, res: any) {\n const templateSlug = url.replace('/__maizzle/lint/', '').replace(/\\?.*$/, '')\n\n const contentPatterns = config.content ?? ['emails/**/*.vue']\n const templates = await glob(contentPatterns)\n const match = templates.find(t => t.replace(/\\.(vue|md)$/, '') === templateSlug)\n\n if (!match) {\n res.statusCode = 404\n res.end(JSON.stringify({ error: 'Template not found' }))\n return\n }\n\n try {\n const source = readFileSync(resolve(match), 'utf-8')\n\n // Extract only the <template> block for linting\n const templateMatch = source.match(/<template\\b[^>]*>([\\s\\S]*)<\\/template>/)\n const html = templateMatch ? templateMatch[1] : source\n\n // Calculate the offset of the <template> content within the source file\n const templateOffset = templateMatch\n ? source.slice(0, source.indexOf(templateMatch[0]) + templateMatch[0].indexOf(templateMatch[1])).split('\\n').length - 1\n : 0\n\n const issues = lintHtml(html, templateOffset)\n\n res.setHeader('Content-Type', 'application/json')\n res.end(JSON.stringify(issues))\n } catch (error: any) {\n res.statusCode = 500\n res.end(JSON.stringify({ error: error.message }))\n }\n}\n\nfunction lintHtml(html: string, lineOffset = 0): LintIssue[] {\n const issues: LintIssue[] = []\n const lines = html.split('\\n')\n\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i]\n const lineNum = i + 1 + lineOffset\n\n // Images missing alt text\n const imgMatches = [...line.matchAll(/<img\\b[^>]*?>/gi)]\n for (const match of imgMatches) {\n const tag = match[0]\n if (!/\\balt\\s*=/i.test(tag)) {\n issues.push({\n type: 'warning',\n title: 'Missing alt text',\n message: 'Image is missing the alt attribute',\n line: lineNum,\n })\n }\n }\n\n // Images with empty or missing src\n for (const match of imgMatches) {\n const tag = match[0]\n const srcMatch = tag.match(/\\bsrc\\s*=\\s*[\"']([^\"']*)[\"']/i)\n if (!srcMatch) {\n issues.push({\n type: 'error',\n title: 'Missing image src',\n message: 'Image tag has no src attribute',\n line: lineNum,\n })\n } else if (!srcMatch[1].trim()) {\n issues.push({\n type: 'error',\n title: 'Empty image src',\n message: 'Image src attribute is empty',\n line: lineNum,\n })\n } else if (srcMatch[1].trim().startsWith('http:')) {\n issues.push({\n type: 'warning',\n title: 'Insecure image src',\n message: 'Image loads over HTTP instead of HTTPS',\n line: lineNum,\n })\n }\n }\n\n // Links: missing href, empty href, placeholder href\n const linkMatches = [...line.matchAll(/<a\\b[^>]*?>/gi)]\n for (const match of linkMatches) {\n const tag = match[0]\n const hrefMatch = tag.match(/\\bhref\\s*=\\s*[\"']([^\"']*)[\"']/i)\n\n if (!hrefMatch) {\n issues.push({\n type: 'error',\n title: 'Missing link href',\n message: 'Anchor tag has no href attribute',\n line: lineNum,\n })\n } else {\n const href = hrefMatch[1].trim()\n if (!href) {\n issues.push({\n type: 'warning',\n title: 'Empty link href',\n message: 'Link href attribute is empty',\n line: lineNum,\n })\n } else if (href === '#' || href === '/') {\n issues.push({\n type: 'warning',\n title: 'Placeholder link',\n message: `Link href is \"${href}\"`,\n line: lineNum,\n })\n } else if (href.startsWith('http:')) {\n issues.push({\n type: 'warning',\n title: 'Insecure link',\n message: 'Link uses HTTP instead of HTTPS',\n line: lineNum,\n })\n } else if (href.startsWith('http') && !/^https?:\\/\\/.+\\..+/i.test(href)) {\n issues.push({\n type: 'warning',\n title: 'Invalid link',\n message: `Link href \"${href}\" looks malformed`,\n line: lineNum,\n })\n }\n }\n }\n\n // Insecure resources (<link href>, <script src>, <source src>)\n const resourceMatches = [...line.matchAll(/<(?:link|script|source)\\b[^>]*?>/gi)]\n for (const match of resourceMatches) {\n const tag = match[0]\n const attrMatch = tag.match(/\\b(?:href|src)\\s*=\\s*[\"']([^\"']*)[\"']/i)\n if (attrMatch && attrMatch[1].trim().startsWith('http:')) {\n issues.push({\n type: 'warning',\n title: 'Insecure resource',\n message: 'Resource loads over HTTP instead of HTTPS',\n line: lineNum,\n })\n }\n }\n\n // Insecure CSS url() references\n const urlMatches = [...line.matchAll(/url\\s*\\(\\s*[\"']?(http:[^\"')]+)[\"']?\\s*\\)/gi)]\n for (const _match of urlMatches) {\n issues.push({\n type: 'warning',\n title: 'Insecure CSS url()',\n message: 'CSS url() loads over HTTP instead of HTTPS',\n line: lineNum,\n })\n }\n }\n\n // Check for unclosed tags (block-level and common inline elements)\n const voidElements = new Set([\n 'area', 'base', 'br', 'col', 'embed', 'hr', 'img', 'input',\n 'link', 'meta', 'param', 'source', 'track', 'wbr',\n ])\n\n const trackedTags = new Set([\n 'a', 'b', 'body', 'div', 'em', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6',\n 'head', 'html', 'i', 'li', 'ol', 'p', 'span', 'strong', 'style',\n 'table', 'tbody', 'td', 'tfoot', 'th', 'thead', 'title', 'tr', 'u', 'ul',\n ])\n\n const stack: Array<{ tag: string, line: number }> = []\n\n // Strip comments and content inside <style>/<script> to avoid false matches\n const stripped = html\n .replace(/<!--[\\s\\S]*?-->/g, (m) => '\\n'.repeat((m.match(/\\n/g) || []).length))\n .replace(/<(style|script)\\b[^>]*>[\\s\\S]*?<\\/\\1>/gi, (m) => '\\n'.repeat((m.match(/\\n/g) || []).length))\n\n const strippedLines = stripped.split('\\n')\n\n for (let i = 0; i < strippedLines.length; i++) {\n const line = strippedLines[i]\n const tagRegex = /<\\/?([a-zA-Z][a-zA-Z0-9]*)\\b[^>]*\\/?>/g\n let m\n\n while ((m = tagRegex.exec(line)) !== null) {\n const fullMatch = m[0]\n const tagName = m[1].toLowerCase()\n\n if (!trackedTags.has(tagName) || voidElements.has(tagName)) continue\n if (fullMatch.endsWith('/>')) continue\n\n if (fullMatch.startsWith('</')) {\n // Closing tag\n const lastOpen = stack.findLastIndex(s => s.tag === tagName)\n if (lastOpen !== -1) {\n stack.splice(lastOpen, 1)\n }\n } else {\n // Opening tag\n stack.push({ tag: tagName, line: i + 1 + lineOffset })\n }\n }\n }\n\n for (const unclosed of stack) {\n issues.push({\n type: 'error',\n title: 'Unclosed tag',\n message: `<${unclosed.tag}> tag is not closed`,\n line: unclosed.line,\n })\n }\n\n // Sort: errors first, then warnings, then by line\n issues.sort((a, b) => {\n if (a.type !== b.type) return a.type === 'error' ? -1 : 1\n return (a.line ?? 0) - (b.line ?? 0)\n })\n\n return issues\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"linter.mjs","names":[],"sources":["../../src/server/linter.ts"],"sourcesContent":["import { readFileSync } from 'node:fs'\nimport { resolve } from 'node:path'\n\ninterface LintIssue {\n type: 'error' | 'warning'\n title: string\n message: string\n line?: number\n}\n\nexport function serveLint(url: string, res: any) {\n const filePath = url.replace('/__maizzle/lint/', '').replace(/\\?.*$/, '')\n\n try {\n const source = readFileSync(resolve(filePath), 'utf-8')\n\n // Extract only the <template> block for linting\n const templateMatch = source.match(/<template\\b[^>]*>([\\s\\S]*)<\\/template>/)\n const html = templateMatch ? templateMatch[1] : source\n\n // Calculate the offset of the <template> content within the source file\n const templateOffset = templateMatch\n ? source.slice(0, source.indexOf(templateMatch[0]) + templateMatch[0].indexOf(templateMatch[1])).split('\\n').length - 1\n : 0\n\n const issues = lintHtml(html, templateOffset)\n\n res.setHeader('Content-Type', 'application/json')\n res.end(JSON.stringify(issues))\n } catch (error: any) {\n res.statusCode = 500\n res.end(JSON.stringify({ error: error.message }))\n }\n}\n\nfunction lineAt(html: string, offset: number, lineOffset: number): number {\n return html.slice(0, offset).split('\\n').length + lineOffset\n}\n\nfunction lintHtml(html: string, lineOffset = 0): LintIssue[] {\n const issues: LintIssue[] = []\n\n // Match all tags (multiline) — [^>] doesn't cross > so use [\\s\\S] with lazy quantifier\n const tagRe = /<([a-zA-Z][a-zA-Z0-9]*)\\b([\\s\\S]*?)>/g\n\n for (const m of Array.from(html.matchAll(tagRe))) {\n const tag = m[0]\n const tagName = m[1].toLowerCase()\n const line = lineAt(html, m.index!, lineOffset)\n\n // Images\n if (tagName === 'img') {\n if (!/\\balt\\s*=/i.test(tag)) {\n issues.push({ type: 'warning', title: 'Missing alt text', message: 'Image is missing the alt attribute', line })\n }\n\n const srcMatch = tag.match(/\\bsrc\\s*=\\s*[\"']([^\"']*)[\"']/i)\n if (!srcMatch) {\n issues.push({ type: 'error', title: 'Missing image src', message: 'Image tag has no src attribute', line })\n } else if (!srcMatch[1].trim()) {\n issues.push({ type: 'error', title: 'Empty image src', message: 'Image src attribute is empty', line })\n } else if (srcMatch[1].trim().startsWith('http:')) {\n issues.push({ type: 'warning', title: 'Insecure image src', message: 'Image loads over HTTP instead of HTTPS', line })\n }\n }\n\n // Any tag with href (catches <a>, <Button>, etc.)\n const hrefMatch = tag.match(/\\bhref\\s*=\\s*[\"']([^\"']*)[\"']/i)\n if (hrefMatch) {\n const href = hrefMatch[1].trim()\n if (!href) {\n issues.push({ type: 'warning', title: 'Empty link href', message: 'Link href attribute is empty', line })\n } else if (href === '#' || href === '/') {\n issues.push({ type: 'warning', title: 'Placeholder link', message: `Link href is \"${href}\"`, line })\n } else if (href.startsWith('http:')) {\n issues.push({ type: 'warning', title: 'Insecure link', message: 'Link uses HTTP instead of HTTPS', line })\n } else if (href.startsWith('http') && !/^https?:\\/\\/.+\\..+/i.test(href)) {\n issues.push({ type: 'warning', title: 'Invalid link', message: `Link href \"${href}\" looks malformed`, line })\n }\n }\n\n // Insecure resources (<link>, <script>, <source>)\n if (['link', 'script', 'source'].includes(tagName)) {\n const attrMatch = tag.match(/\\b(?:href|src)\\s*=\\s*[\"']([^\"']*)[\"']/i)\n if (attrMatch && attrMatch[1].trim().startsWith('http:')) {\n issues.push({ type: 'warning', title: 'Insecure resource', message: 'Resource loads over HTTP instead of HTTPS', line })\n }\n }\n }\n\n // Insecure CSS url() references\n for (const m of Array.from(html.matchAll(/url\\s*\\(\\s*[\"']?(http:[^\"')]+)[\"']?\\s*\\)/gi))) {\n issues.push({ type: 'warning', title: 'Insecure CSS url()', message: 'CSS url() loads over HTTP instead of HTTPS', line: lineAt(html, m.index!, lineOffset) })\n }\n\n // Check for unclosed tags (block-level and common inline elements)\n const voidElements = new Set([\n 'area', 'base', 'br', 'col', 'embed', 'hr', 'img', 'input',\n 'link', 'meta', 'param', 'source', 'track', 'wbr',\n ])\n\n const trackedTags = new Set([\n 'a', 'b', 'body', 'div', 'em', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6',\n 'head', 'html', 'i', 'li', 'ol', 'p', 'span', 'strong', 'style',\n 'table', 'tbody', 'td', 'tfoot', 'th', 'thead', 'title', 'tr', 'u', 'ul',\n ])\n\n const stack: Array<{ tag: string, line: number }> = []\n\n // Strip comments and content inside <style>/<script> to avoid false matches\n const stripped = html\n .replace(/<!--[\\s\\S]*?-->/g, (m) => '\\n'.repeat((m.match(/\\n/g) || []).length))\n .replace(/<(style|script)\\b[^>]*>[\\s\\S]*?<\\/\\1>/gi, (m) => '\\n'.repeat((m.match(/\\n/g) || []).length))\n\n const strippedLines = stripped.split('\\n')\n\n for (let i = 0; i < strippedLines.length; i++) {\n const line = strippedLines[i]\n const tagRegex = /<\\/?([a-zA-Z][a-zA-Z0-9]*)\\b[^>]*\\/?>/g\n let m\n\n while ((m = tagRegex.exec(line)) !== null) {\n const fullMatch = m[0]\n const tagName = m[1].toLowerCase()\n\n if (!trackedTags.has(tagName) || voidElements.has(tagName)) continue\n if (fullMatch.endsWith('/>')) continue\n\n if (fullMatch.startsWith('</')) {\n // Closing tag\n let lastOpen = -1\n for (let j = stack.length - 1; j >= 0; j--) {\n if (stack[j].tag === tagName) { lastOpen = j; break }\n }\n if (lastOpen !== -1) {\n stack.splice(lastOpen, 1)\n }\n } else {\n // Opening tag\n stack.push({ tag: tagName, line: i + 1 + lineOffset })\n }\n }\n }\n\n for (const unclosed of stack) {\n issues.push({\n type: 'error',\n title: 'Unclosed tag',\n message: `<${unclosed.tag}> tag is not closed`,\n line: unclosed.line,\n })\n }\n\n // Sort: errors first, then warnings, then by line\n issues.sort((a, b) => {\n if (a.type !== b.type) return a.type === 'error' ? -1 : 1\n return (a.line ?? 0) - (b.line ?? 0)\n })\n\n return issues\n}\n"],"mappings":";;;;AAUA,SAAgB,UAAU,KAAa,KAAU;CAC/C,MAAM,WAAW,IAAI,QAAQ,oBAAoB,GAAG,CAAC,QAAQ,SAAS,GAAG;AAEzE,KAAI;EACF,MAAM,SAAS,aAAa,QAAQ,SAAS,EAAE,QAAQ;EAGvD,MAAM,gBAAgB,OAAO,MAAM,yCAAyC;EAQ5E,MAAM,SAAS,SAPF,gBAAgB,cAAc,KAAK,QAGzB,gBACnB,OAAO,MAAM,GAAG,OAAO,QAAQ,cAAc,GAAG,GAAG,cAAc,GAAG,QAAQ,cAAc,GAAG,CAAC,CAAC,MAAM,KAAK,CAAC,SAAS,IACpH,EAEyC;AAE7C,MAAI,UAAU,gBAAgB,mBAAmB;AACjD,MAAI,IAAI,KAAK,UAAU,OAAO,CAAC;UACxB,OAAY;AACnB,MAAI,aAAa;AACjB,MAAI,IAAI,KAAK,UAAU,EAAE,OAAO,MAAM,SAAS,CAAC,CAAC;;;AAIrD,SAAS,OAAO,MAAc,QAAgB,YAA4B;AACxE,QAAO,KAAK,MAAM,GAAG,OAAO,CAAC,MAAM,KAAK,CAAC,SAAS;;AAGpD,SAAS,SAAS,MAAc,aAAa,GAAgB;CAC3D,MAAM,SAAsB,EAAE;AAK9B,MAAK,MAAM,KAAK,MAAM,KAAK,KAAK,SAFlB,wCAEiC,CAAC,EAAE;EAChD,MAAM,MAAM,EAAE;EACd,MAAM,UAAU,EAAE,GAAG,aAAa;EAClC,MAAM,OAAO,OAAO,MAAM,EAAE,OAAQ,WAAW;AAG/C,MAAI,YAAY,OAAO;AACrB,OAAI,CAAC,aAAa,KAAK,IAAI,CACzB,QAAO,KAAK;IAAE,MAAM;IAAW,OAAO;IAAoB,SAAS;IAAsC;IAAM,CAAC;GAGlH,MAAM,WAAW,IAAI,MAAM,gCAAgC;AAC3D,OAAI,CAAC,SACH,QAAO,KAAK;IAAE,MAAM;IAAS,OAAO;IAAqB,SAAS;IAAkC;IAAM,CAAC;YAClG,CAAC,SAAS,GAAG,MAAM,CAC5B,QAAO,KAAK;IAAE,MAAM;IAAS,OAAO;IAAmB,SAAS;IAAgC;IAAM,CAAC;YAC9F,SAAS,GAAG,MAAM,CAAC,WAAW,QAAQ,CAC/C,QAAO,KAAK;IAAE,MAAM;IAAW,OAAO;IAAsB,SAAS;IAA0C;IAAM,CAAC;;EAK1H,MAAM,YAAY,IAAI,MAAM,iCAAiC;AAC7D,MAAI,WAAW;GACb,MAAM,OAAO,UAAU,GAAG,MAAM;AAChC,OAAI,CAAC,KACH,QAAO,KAAK;IAAE,MAAM;IAAW,OAAO;IAAmB,SAAS;IAAgC;IAAM,CAAC;YAChG,SAAS,OAAO,SAAS,IAClC,QAAO,KAAK;IAAE,MAAM;IAAW,OAAO;IAAoB,SAAS,iBAAiB,KAAK;IAAI;IAAM,CAAC;YAC3F,KAAK,WAAW,QAAQ,CACjC,QAAO,KAAK;IAAE,MAAM;IAAW,OAAO;IAAiB,SAAS;IAAmC;IAAM,CAAC;YACjG,KAAK,WAAW,OAAO,IAAI,CAAC,sBAAsB,KAAK,KAAK,CACrE,QAAO,KAAK;IAAE,MAAM;IAAW,OAAO;IAAgB,SAAS,cAAc,KAAK;IAAoB;IAAM,CAAC;;AAKjH,MAAI;GAAC;GAAQ;GAAU;GAAS,CAAC,SAAS,QAAQ,EAAE;GAClD,MAAM,YAAY,IAAI,MAAM,yCAAyC;AACrE,OAAI,aAAa,UAAU,GAAG,MAAM,CAAC,WAAW,QAAQ,CACtD,QAAO,KAAK;IAAE,MAAM;IAAW,OAAO;IAAqB,SAAS;IAA6C;IAAM,CAAC;;;AAM9H,MAAK,MAAM,KAAK,MAAM,KAAK,KAAK,SAAS,6CAA6C,CAAC,CACrF,QAAO,KAAK;EAAE,MAAM;EAAW,OAAO;EAAsB,SAAS;EAA8C,MAAM,OAAO,MAAM,EAAE,OAAQ,WAAW;EAAE,CAAC;CAIhK,MAAM,eAAe,IAAI,IAAI;EAC3B;EAAQ;EAAQ;EAAM;EAAO;EAAS;EAAM;EAAO;EACnD;EAAQ;EAAQ;EAAS;EAAU;EAAS;EAC7C,CAAC;CAEF,MAAM,cAAc,IAAI,IAAI;EAC1B;EAAK;EAAK;EAAQ;EAAO;EAAM;EAAM;EAAM;EAAM;EAAM;EAAM;EAC7D;EAAQ;EAAQ;EAAK;EAAM;EAAM;EAAK;EAAQ;EAAU;EACxD;EAAS;EAAS;EAAM;EAAS;EAAM;EAAS;EAAS;EAAM;EAAK;EACrE,CAAC;CAEF,MAAM,QAA8C,EAAE;CAOtD,MAAM,gBAJW,KACd,QAAQ,qBAAqB,MAAM,KAAK,QAAQ,EAAE,MAAM,MAAM,IAAI,EAAE,EAAE,OAAO,CAAC,CAC9E,QAAQ,4CAA4C,MAAM,KAAK,QAAQ,EAAE,MAAM,MAAM,IAAI,EAAE,EAAE,OAAO,CAAC,CAEzE,MAAM,KAAK;AAE1C,MAAK,IAAI,IAAI,GAAG,IAAI,cAAc,QAAQ,KAAK;EAC7C,MAAM,OAAO,cAAc;EAC3B,MAAM,WAAW;EACjB,IAAI;AAEJ,UAAQ,IAAI,SAAS,KAAK,KAAK,MAAM,MAAM;GACzC,MAAM,YAAY,EAAE;GACpB,MAAM,UAAU,EAAE,GAAG,aAAa;AAElC,OAAI,CAAC,YAAY,IAAI,QAAQ,IAAI,aAAa,IAAI,QAAQ,CAAE;AAC5D,OAAI,UAAU,SAAS,KAAK,CAAE;AAE9B,OAAI,UAAU,WAAW,KAAK,EAAE;IAE9B,IAAI,WAAW;AACf,SAAK,IAAI,IAAI,MAAM,SAAS,GAAG,KAAK,GAAG,IACrC,KAAI,MAAM,GAAG,QAAQ,SAAS;AAAE,gBAAW;AAAG;;AAEhD,QAAI,aAAa,GACf,OAAM,OAAO,UAAU,EAAE;SAI3B,OAAM,KAAK;IAAE,KAAK;IAAS,MAAM,IAAI,IAAI;IAAY,CAAC;;;AAK5D,MAAK,MAAM,YAAY,MACrB,QAAO,KAAK;EACV,MAAM;EACN,OAAO;EACP,SAAS,IAAI,SAAS,IAAI;EAC1B,MAAM,SAAS;EAChB,CAAC;AAIJ,QAAO,MAAM,GAAG,MAAM;AACpB,MAAI,EAAE,SAAS,EAAE,KAAM,QAAO,EAAE,SAAS,UAAU,KAAK;AACxD,UAAQ,EAAE,QAAQ,MAAM,EAAE,QAAQ;GAClC;AAEF,QAAO"}