@maizzle/framework 6.1.0 → 6.1.2

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 (63) hide show
  1. package/dist/build.js +2 -1
  2. package/dist/build.js.map +1 -1
  3. package/dist/config/index.js.map +1 -1
  4. package/dist/plugins/postcss/mergeMediaQueries.js +2 -1
  5. package/dist/plugins/postcss/mergeMediaQueries.js.map +1 -1
  6. package/dist/plugins/postcss/resolveMaizzleImports.js.map +1 -1
  7. package/dist/render/buildTemplate.js +4 -2
  8. package/dist/render/buildTemplate.js.map +1 -1
  9. package/dist/render/createRenderer.d.ts +7 -0
  10. package/dist/render/createRenderer.d.ts.map +1 -1
  11. package/dist/render/createRenderer.js +46 -3
  12. package/dist/render/createRenderer.js.map +1 -1
  13. package/dist/serve.js +19 -10
  14. package/dist/serve.js.map +1 -1
  15. package/dist/server/compatibility.js +2 -1
  16. package/dist/server/compatibility.js.map +1 -1
  17. package/dist/server/linter.js +2 -1
  18. package/dist/server/linter.js.map +1 -1
  19. package/dist/server/sfc-utils.js.map +1 -1
  20. package/dist/server/ui/.vite/deps/@lucide_vue.js +6845 -6285
  21. package/dist/server/ui/.vite/deps/@lucide_vue.js.map +1 -1
  22. package/dist/server/ui/.vite/deps/@vueuse_core.js +2 -6
  23. package/dist/server/ui/.vite/deps/@vueuse_core.js.map +1 -1
  24. package/dist/server/ui/.vite/deps/@vueuse_shared.js +1 -1
  25. package/dist/server/ui/.vite/deps/@vueuse_shared.js.map +1 -1
  26. package/dist/server/ui/.vite/deps/_metadata.json +15 -15
  27. package/dist/server/ui/.vite/deps/culori.js +8 -6
  28. package/dist/server/ui/.vite/deps/culori.js.map +1 -1
  29. package/dist/server/ui/.vite/deps/reka-ui.js +63 -73
  30. package/dist/server/ui/.vite/deps/reka-ui.js.map +1 -1
  31. package/dist/server/ui/.vite/deps/tailwind-merge.js.map +1 -1
  32. package/dist/server/ui/.vite/deps/vue-router.js +5 -13
  33. package/dist/server/ui/.vite/deps/vue-router.js.map +1 -1
  34. package/dist/server/ui/.vite/deps/vue.js +1 -1
  35. package/dist/server/ui/.vite/deps/{vue.runtime.esm-bundler-BHD3r-bP.js → vue.runtime.esm-bundler-S54atuNJ.js} +323 -259
  36. package/dist/server/ui/.vite/deps/{vue.runtime.esm-bundler-BHD3r-bP.js.map → vue.runtime.esm-bundler-S54atuNJ.js.map} +1 -1
  37. package/dist/transformers/format.js +2 -1
  38. package/dist/transformers/format.js.map +1 -1
  39. package/dist/transformers/index.d.ts +1 -1
  40. package/dist/transformers/index.d.ts.map +1 -1
  41. package/dist/transformers/index.js +4 -4
  42. package/dist/transformers/index.js.map +1 -1
  43. package/dist/transformers/inlineCss.js +3 -2
  44. package/dist/transformers/inlineCss.js.map +1 -1
  45. package/dist/transformers/inlineLink.js +2 -1
  46. package/dist/transformers/inlineLink.js.map +1 -1
  47. package/dist/transformers/minify.js +2 -1
  48. package/dist/transformers/minify.js.map +1 -1
  49. package/dist/transformers/tailwindComponent.d.ts +1 -1
  50. package/dist/transformers/tailwindComponent.d.ts.map +1 -1
  51. package/dist/transformers/tailwindComponent.js +26 -7
  52. package/dist/transformers/tailwindComponent.js.map +1 -1
  53. package/dist/transformers/tailwindcss.d.ts +10 -3
  54. package/dist/transformers/tailwindcss.d.ts.map +1 -1
  55. package/dist/transformers/tailwindcss.js +30 -14
  56. package/dist/transformers/tailwindcss.js.map +1 -1
  57. package/dist/transformers/urlQuery.js +2 -1
  58. package/dist/transformers/urlQuery.js.map +1 -1
  59. package/dist/types/config.d.ts +11 -0
  60. package/dist/types/config.d.ts.map +1 -1
  61. package/dist/utils/cssBox.js +2 -6
  62. package/dist/utils/cssBox.js.map +1 -1
  63. package/package.json +2 -2
package/dist/serve.js CHANGED
@@ -23,7 +23,8 @@ import { renderUnicodeCompact } from "uqr";
23
23
  import tailwindcss from "@tailwindcss/vite";
24
24
  import { createHighlighter } from "shiki";
25
25
  //#region src/serve.ts
26
- const devUIDir = resolve(dirname(fileURLToPath(import.meta.url)), "server/ui");
26
+ const __dirname = dirname(fileURLToPath(import.meta.url));
27
+ const devUIDir = resolve(__dirname, "server/ui");
27
28
  const require = createRequire(import.meta.url);
28
29
  const version = JSON.parse(readFileSync(resolve(dirname(fileURLToPath(import.meta.url)), "../package.json"), "utf-8")).version;
29
30
  const pkg = (name) => {
@@ -43,7 +44,8 @@ const pkg = (name) => {
43
44
  const pkgEsmEntry = (name) => {
44
45
  const dir = pkg(name);
45
46
  const pj = JSON.parse(readFileSync(resolve(dir, "package.json"), "utf-8"));
46
- return resolve(dir, pj.exports?.["."]?.import ?? pj.module ?? pj.main);
47
+ const entry = pj.exports?.["."]?.import ?? pj.module ?? pj.main;
48
+ return resolve(dir, entry);
47
49
  };
48
50
  /**
49
51
  * Start the Maizzle dev server.
@@ -320,7 +322,8 @@ async function serveDevUI(server, res, url, config) {
320
322
  res.end(transformed);
321
323
  }
322
324
  async function serveTemplateList(config, res) {
323
- const data = (await glob(config.content ?? ["emails/**/*.vue"])).map((t) => ({
325
+ const contentPatterns = config.content ?? ["emails/**/*.vue"];
326
+ const data = (await glob(contentPatterns)).map((t) => ({
324
327
  name: basename(t).replace(/\.(vue|md)$/, ""),
325
328
  path: t,
326
329
  href: "/" + t.replace(/\.(vue|md)$/, "")
@@ -376,7 +379,7 @@ function getRendered(absolutePath, config, renderer, events) {
376
379
  html: rendered.html
377
380
  });
378
381
  const doctype = rendered.doctype ?? templateConfig.doctype ?? "<!DOCTYPE html>";
379
- if (templateConfig.useTransformers !== false) html = await runTransformers(html, templateConfig, absolutePath, doctype, rendered.tailwindBlocks);
382
+ if (templateConfig.useTransformers !== false) html = await runTransformers(html, templateConfig, absolutePath, doctype, rendered.tailwindBlocks, rendered.sourceFiles);
380
383
  return {
381
384
  rawHtml: await events.fireAfterTransform({
382
385
  config: templateConfig,
@@ -401,7 +404,8 @@ function getRendered(absolutePath, config, renderer, events) {
401
404
  */
402
405
  async function serveRenderedTemplate(url, config, renderer, events, res) {
403
406
  const templateSlug = url.replace("/__maizzle/render/", "").replace(/\?.*$/, "");
404
- const match = (await glob(config.content ?? ["emails/**/*.vue"])).find((t) => t.replace(/\.(vue|md)$/, "") === templateSlug);
407
+ const contentPatterns = config.content ?? ["emails/**/*.vue"];
408
+ const match = (await glob(contentPatterns)).find((t) => t.replace(/\.(vue|md)$/, "") === templateSlug);
405
409
  if (!match) {
406
410
  res.statusCode = 404;
407
411
  res.end("Template not found");
@@ -429,7 +433,8 @@ async function getHighlighter() {
429
433
  }
430
434
  async function serveHighlightedSource(url, config, renderer, events, res) {
431
435
  const templateSlug = url.replace("/__maizzle/source/", "").replace(/\?.*$/, "");
432
- const match = (await glob(config.content ?? ["emails/**/*.vue"])).find((t) => t.replace(/\.(vue|md)$/, "") === templateSlug);
436
+ const contentPatterns = config.content ?? ["emails/**/*.vue"];
437
+ const match = (await glob(contentPatterns)).find((t) => t.replace(/\.(vue|md)$/, "") === templateSlug);
433
438
  if (!match) {
434
439
  res.statusCode = 404;
435
440
  res.end("Template not found");
@@ -455,7 +460,8 @@ async function serveHighlightedSource(url, config, renderer, events, res) {
455
460
  }
456
461
  async function serveVueSource(url, config, res) {
457
462
  const templateSlug = url.replace("/__maizzle/vue-source/", "").replace(/\?.*$/, "");
458
- const match = (await glob(config.content ?? ["emails/**/*.vue"])).find((t) => t.replace(/\.(vue|md)$/, "") === templateSlug);
463
+ const contentPatterns = config.content ?? ["emails/**/*.vue"];
464
+ const match = (await glob(contentPatterns)).find((t) => t.replace(/\.(vue|md)$/, "") === templateSlug);
459
465
  if (!match) {
460
466
  res.statusCode = 404;
461
467
  res.end("Template not found");
@@ -480,7 +486,8 @@ async function serveVueSource(url, config, res) {
480
486
  }
481
487
  async function servePlaintext(url, config, renderer, events, res) {
482
488
  const templateSlug = url.replace("/__maizzle/plaintext/", "").replace(/\?.*$/, "");
483
- const match = (await glob(config.content ?? ["emails/**/*.vue"])).find((t) => t.replace(/\.(vue|md)$/, "") === templateSlug);
489
+ const contentPatterns = config.content ?? ["emails/**/*.vue"];
490
+ const match = (await glob(contentPatterns)).find((t) => t.replace(/\.(vue|md)$/, "") === templateSlug);
484
491
  if (!match) {
485
492
  res.statusCode = 404;
486
493
  res.end("Template not found");
@@ -520,7 +527,8 @@ function humanFileSize(bytes, si = false, dp = 2) {
520
527
  }
521
528
  async function serveStats(url, config, renderer, events, res) {
522
529
  const templateSlug = url.replace("/__maizzle/stats/", "").replace(/\?.*$/, "");
523
- const match = (await glob(config.content ?? ["emails/**/*.vue"])).find((t) => t.replace(/\.(vue|md)$/, "") === templateSlug);
530
+ const contentPatterns = config.content ?? ["emails/**/*.vue"];
531
+ const match = (await glob(contentPatterns)).find((t) => t.replace(/\.(vue|md)$/, "") === templateSlug);
524
532
  if (!match) {
525
533
  res.statusCode = 404;
526
534
  res.end(JSON.stringify({ error: "Template not found" }));
@@ -549,7 +557,8 @@ async function serveStats(url, config, renderer, events, res) {
549
557
  }
550
558
  async function serveEmailEndpoint(url, req, res, config, renderer, events) {
551
559
  const templateSlug = url.replace("/__maizzle/email/", "").replace(/\?.*$/, "");
552
- const match = (await glob(config.content ?? ["emails/**/*.vue"])).find((t) => t.replace(/\.(vue|md)$/, "") === templateSlug);
560
+ const contentPatterns = config.content ?? ["emails/**/*.vue"];
561
+ const match = (await glob(contentPatterns)).find((t) => t.replace(/\.(vue|md)$/, "") === templateSlug);
553
562
  if (!match) {
554
563
  res.statusCode = 404;
555
564
  res.end(JSON.stringify({
package/dist/serve.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"serve.js","names":["parsePath"],"sources":["../src/serve.ts"],"sourcesContent":["import { readFileSync } from 'node:fs'\nimport { dirname, resolve, basename, parse as parsePath } from 'node:path'\nimport { fileURLToPath } from 'node:url'\nimport { createRequire } from 'node:module'\nimport { createServer, createLogger, type ViteDevServer } from 'vite'\nimport { renderUnicodeCompact } from 'uqr'\nimport vue from '@vitejs/plugin-vue'\nimport tailwindcss from '@tailwindcss/vite'\nimport { glob } from 'tinyglobby'\nimport { createHighlighter, type Highlighter } from 'shiki'\nimport { createPlaintext } from './plaintext.ts'\nimport { stripForHtml, stripForPlaintext } from './utils/output-markers.ts'\nimport { resolveConfig } from './config/index.ts'\nimport { runTransformers } from './transformers/index.ts'\nimport { EventManager } from './events/index.ts'\nimport { cloneConfig } from './utils/cloneConfig.ts'\nimport { createRenderer, type Renderer, type RenderedTemplate } from './render/createRenderer.ts'\nimport { _setCurrentTemplate } from './composables/useCurrentTemplate.ts'\nimport { setActiveRenderer } from './render/active.ts'\nimport { serveCompatibility } from './server/compatibility.ts'\nimport { serveLint } from './server/linter.ts'\nimport { sendEmail } from './server/email.ts'\nimport { normalizeComponentSources } from './utils/componentSources.ts'\nimport { createWatchedFileMatcher } from './utils/watchPaths.ts'\nimport type { MaizzleConfig } from './types/index.ts'\n\nconst __dirname = dirname(fileURLToPath(import.meta.url))\nconst devUIDir = resolve(__dirname, 'server/ui')\n\nconst require = createRequire(import.meta.url)\n\nconst version = JSON.parse(\n readFileSync(resolve(dirname(fileURLToPath(import.meta.url)), '../package.json'), 'utf-8'),\n).version\n\nconst pkg = (name: string) => {\n const resolved = require.resolve(name).replace(/\\\\/g, '/')\n const marker = `node_modules/${name}`\n const idx = resolved.lastIndexOf(marker)\n\n return resolved.slice(0, idx + marker.length)\n}\n\n/**\n * Resolve a package's ESM entry via its `exports` map. Aliasing to the\n * package directory bypasses `exports` (it only keys off the bare name),\n * so directory resolution can fall back to a UMD/CJS bundle — which Vite 8\n * flags `needsInterop` and then default-imports, breaking ESM-only deps\n * like culori (named exports, no default). Point the alias at the real\n * ESM entry instead.\n */\nconst pkgEsmEntry = (name: string) => {\n const dir = pkg(name)\n const pj = JSON.parse(readFileSync(resolve(dir, 'package.json'), 'utf-8'))\n const entry = pj.exports?.['.']?.import ?? pj.module ?? pj.main\n return resolve(dir, entry)\n}\n\nexport interface ServeOptions {\n config?: Partial<MaizzleConfig> | string\n /** Override the dev server port (takes precedence over config.server.port) */\n port?: number\n /** Expose the server on the network (e.g. --host) */\n host?: boolean | string\n /** When true, suppresses the startup banner/URL output. */\n silent?: boolean\n}\n\n/**\n * Start the Maizzle dev server.\n *\n * Creates two things:\n * 1. A Vite dev server for the dev UI (sidebar + preview, with Vue + Tailwind for the UI itself)\n * 2. A Renderer instance for SSR rendering email templates\n *\n * Template rendering goes through the Renderer, not the Vite dev server.\n */\nexport async function serve(options: ServeOptions = {}) {\n const start = performance.now()\n\n let config = await resolveConfig(options.config)\n const port = options.port ?? config.server?.port ?? 3000\n const host = options.host ?? config.server?.host\n\n // Create a renderer for SSR rendering email templates (with dts for dev)\n let renderer = await createRenderer({ dts: true, markdown: config.markdown, root: config.root, componentDirs: normalizeComponentSources(config.components?.source, process.cwd()), vite: config.vite, customElements: config.vue?.customElements })\n\n /**\n * Register so user-land render() calls reuse this renderer instead of\n * spinning up another Vite SSR server (which collides when the host\n * app is itself a Vite dev process — e.g. TanStack Start).\n */\n setActiveRenderer(renderer)\n\n const events = new EventManager()\n events.registerConfig(config)\n await events.fireBeforeCreate({ config })\n\n const server = await createServer({\n configFile: false,\n plugins: [\n // Vue and Tailwind are only for the dev UI SPA, not for email templates\n vue(),\n tailwindcss(),\n maizzleDevPlugin(config, renderer, events, options.config),\n ],\n resolve: {\n dedupe: ['vue'],\n alias: [\n { find: '@', replacement: devUIDir },\n { find: 'vue', replacement: resolve(pkg('vue'), 'dist/vue.runtime.esm-bundler.js') },\n // culori is ESM-only — alias to its ESM entry, not the package dir (see pkgEsmEntry)\n { find: 'culori', replacement: pkgEsmEntry('culori') },\n ...['vue-router', 'reka-ui', '@vueuse/core', '@vueuse/shared', '@lucide/vue', 'class-variance-authority', 'clsx', 'tailwind-merge']\n .map(name => ({ find: name, replacement: pkg(name) })),\n ],\n },\n cacheDir: resolve(devUIDir, '.vite'),\n optimizeDeps: {\n noDiscovery: true,\n include: [\n 'vue',\n 'vue-router',\n '@lucide/vue',\n '@vueuse/core',\n '@vueuse/shared',\n 'reka-ui',\n 'class-variance-authority',\n 'clsx',\n 'tailwind-merge',\n 'culori',\n ],\n },\n server: {\n // Cherry-pick Vite's `server` options (e.g. watch.ignored) from the\n // user's `vite` config; Maizzle's required keys below take precedence.\n ...config.vite?.server,\n port,\n host,\n fs: {\n ...config.vite?.server?.fs,\n allow: [process.cwd(), config.root ?? process.cwd(), devUIDir, ...['vue', 'vue-router', 'reka-ui', '@vueuse/core', '@vueuse/shared', '@lucide/vue', 'class-variance-authority', 'clsx', 'tailwind-merge', 'culori'].map(pkg), ...(config.vite?.server?.fs?.allow ?? [])],\n },\n },\n customLogger: customLogger(),\n })\n\n // Store renderer ref on server for cleanup\n const originalClose = server.close.bind(server)\n server.close = async () => {\n setActiveRenderer(null)\n await renderer.close()\n return originalClose()\n }\n\n await server.listen()\n\n const startupTime = Math.round(performance.now() - start)\n\n if (!options.silent) {\n printBanner(server, startupTime)\n }\n\n // Expose startup time so the plugin can print it later\n ; (server as any)._maizzleStartupTime = startupTime\n\n return server\n}\n\n/**\n * Internal Vite plugin that adds Maizzle middleware and file watching to the dev UI server.\n */\nfunction maizzleDevPlugin(\n config: MaizzleConfig,\n renderer: Renderer,\n events: EventManager,\n configInput: Partial<MaizzleConfig> | string | undefined,\n) {\n return {\n name: 'maizzle:dev',\n enforce: 'pre' as const,\n\n hotUpdate: {\n order: 'pre' as const,\n handler({ file }: { file: string }) {\n /**\n * Prevent Tailwind/Vue from triggering a full reload for email template\n * files. Maizzle handles these via custom HMR events in the\n * watcher below.\n */\n if (isTemplateFile(file)) {\n return []\n }\n },\n },\n\n configureServer(server: ViteDevServer) {\n // File watching\n const defaultWatchPaths = [\n 'maizzle.config.js',\n 'maizzle.config.ts',\n 'tailwind.config.js',\n 'tailwind.config.ts',\n 'locales/**',\n ]\n\n const userWatchPaths = config.server?.watch ?? []\n const watchPaths = [...defaultWatchPaths, ...userWatchPaths]\n // Match against cwd, not config.root: the watched paths (maizzle/tailwind\n // configs, locales) are project-root relative, and `watcher.add` below\n // resolves them against cwd too. Using config.root would break matching\n // when root points at a subdirectory (e.g. the Vite-plugin setup).\n const isWatchedFile = createWatchedFileMatcher(watchPaths, process.cwd())\n\n for (const watchPath of watchPaths) {\n server.watcher.add(watchPath)\n }\n\n /**\n * Serialize watcher work onto one chain. The change handler closes and\n * recreates the renderer across awaits; without serialization a second\n * event firing mid-reload closes a stale renderer and leaks the new one.\n * Errors are caught so one failed task doesn't break the chain.\n */\n let watcherChain: Promise<void> = Promise.resolve()\n const enqueue = (task: () => Promise<void>): Promise<void> => {\n watcherChain = watcherChain.then(task).catch((err) => {\n console.error('[maizzle] watcher task failed:', err)\n })\n return watcherChain\n }\n\n server.watcher.on('add', file => enqueue(async () => {\n if (isTemplateFile(file)) {\n await renderer.invalidateAll()\n bumpGeneration()\n server.ws.send({ type: 'custom', event: 'maizzle:templates-changed' })\n }\n }))\n\n server.watcher.on('unlink', file => enqueue(async () => {\n if (isTemplateFile(file)) {\n await renderer.invalidateAll()\n bumpGeneration()\n server.ws.send({ type: 'custom', event: 'maizzle:templates-changed' })\n }\n }))\n\n server.watcher.on('change', file => enqueue(async () => {\n if (isWatchedFile(file)) {\n config = await resolveConfig(configInput)\n\n // Re-register event handlers against the reloaded config (the config\n // object is replaced wholesale, so old handlers would be stale).\n events.clear()\n events.registerConfig(config)\n\n // Recreate the renderer so config changes (e.g. markdown.shikiTheme) take effect\n await renderer.close()\n renderer = await createRenderer({ dts: true, markdown: config.markdown, root: config.root, componentDirs: normalizeComponentSources(config.components?.source, process.cwd()), vite: config.vite, customElements: config.vue?.customElements })\n\n // Re-register the new renderer so user-land render() calls don't keep\n // reusing the closed one (see setActiveRenderer above).\n setActiveRenderer(renderer)\n\n /**\n * Push UI-relevant config bits so the dev UI reacts to live edits\n * without a page reload. Uses the same shape as the initial\n * inject.\n */\n server.ws.send({ type: 'custom', event: 'maizzle:config-updated', data: buildUiConfig(config) })\n }\n\n /**\n * Invalidate all renderer modules so component and config changes\n * are picked up on the next render (Tailwind recompiles with\n * fresh content).\n */\n await renderer.invalidateAll()\n bumpGeneration()\n\n if (\n isTemplateFile(file)\n || isWatchedFile(file)\n ) {\n server.ws.send({ type: 'custom', event: 'maizzle:template-updated', data: { file } })\n }\n }))\n\n // API middleware (before Vite's middleware)\n server.middlewares.use(async (req: any, res: any, next: any) => {\n const url = req.url || '/'\n\n if (url === '/__maizzle/templates') {\n return serveTemplateList(config, res)\n }\n\n if (url.startsWith('/__maizzle/render/')) {\n return await serveRenderedTemplate(url, config, renderer, events, res)\n }\n\n if (url.startsWith('/__maizzle/source/')) {\n return await serveHighlightedSource(url, config, renderer, events, res)\n }\n\n if (url.startsWith('/__maizzle/compatibility/')) {\n return await serveCompatibility(url, res, config, normalizeComponentSources(config.components?.source, process.cwd()))\n }\n\n if (url.startsWith('/__maizzle/lint/')) {\n return await serveLint(url, res, config, normalizeComponentSources(config.components?.source, process.cwd()))\n }\n\n if (url.startsWith('/__maizzle/vue-source/')) {\n return await serveVueSource(url, config, res)\n }\n\n if (url.startsWith('/__maizzle/plaintext/')) {\n return await servePlaintext(url, config, renderer, events, res)\n }\n\n if (url.startsWith('/__maizzle/stats/')) {\n return await serveStats(url, config, renderer, events, res)\n }\n\n if (url.startsWith('/__maizzle/email/') && req.method === 'POST') {\n return await serveEmailEndpoint(url, req, res, config, renderer, events)\n }\n\n if (url === '/__maizzle/email-config') {\n return serveEmailConfig(config, res)\n }\n\n next()\n })\n\n // Dev UI fallback (after Vite's middleware)\n return () => {\n server.middlewares.use(async (req: any, res: any, next: any) => {\n if (isNavigationRequest(req)) {\n return await serveDevUI(server, res, req.url || '/', config)\n }\n\n next()\n })\n }\n },\n }\n}\n\nfunction isTemplateFile(file: string): boolean {\n return (file.endsWith('.vue') || file.endsWith('.md')) && !file.includes('server/ui')\n}\n\nfunction isNavigationRequest(req: any): boolean {\n const accept = req.headers?.accept || ''\n return req.method === 'GET' && accept.includes('text/html')\n}\n\n/**\n * Shape exposed to the dev UI both at initial HTML load (as\n * `window.__MAIZZLE_CONFIG__`) and on the `maizzle:config-updated` HMR event.\n * Add UI-visible config bits here; consumers on both ends pick up automatically.\n */\nfunction buildUiConfig(config: MaizzleConfig) {\n return {\n checks: config.server?.checks ?? true,\n }\n}\n\nasync function serveDevUI(server: ViteDevServer, res: any, url: string, config: MaizzleConfig) {\n let indexHtml = readFileSync(resolve(devUIDir, 'index.html'), 'utf-8')\n\n indexHtml = indexHtml.replace('./main.ts', `/@fs/${resolve(devUIDir, 'main.ts')}`)\n indexHtml = indexHtml.replace('./favicon.svg', `/@fs/${resolve(devUIDir, 'favicon.svg')}`)\n\n const configScript = `<script>window.__MAIZZLE_CONFIG__ = ${JSON.stringify(buildUiConfig(config))};</script>`\n indexHtml = indexHtml.replace('</head>', `${configScript}</head>`)\n\n const transformed = await server.transformIndexHtml(url, indexHtml)\n\n res.setHeader('Content-Type', 'text/html')\n res.end(transformed)\n}\n\nasync function serveTemplateList(config: MaizzleConfig, res: any) {\n const contentPatterns = config.content ?? ['emails/**/*.vue']\n const templates = await glob(contentPatterns)\n\n const data = templates.map(t => ({\n name: basename(t).replace(/\\.(vue|md)$/, ''),\n path: t,\n href: '/' + t.replace(/\\.(vue|md)$/, ''),\n }))\n\n res.setHeader('Content-Type', 'application/json')\n res.end(JSON.stringify(data))\n}\n\ninterface DedupedRender {\n /** Transformer output — before doctype prepend / stripForHtml / stripForPlaintext. */\n rawHtml: string\n doctype: string\n templateConfig: MaizzleConfig\n rendered: RenderedTemplate\n}\n\n/**\n * Render-result memo for the dev server. A single template save makes the\n * browser fire several endpoint requests in parallel (render, source, stats,\n * plaintext, email) that each need the same SSR render + transformer output.\n * Keying the in-flight Promise by `${generation}:${path}` collapses those into\n * one render and dedupes concurrent requests. The watcher bumps the generation\n * (and clears the cache) on every file/config change, so results never go\n * stale. Each endpoint applies its own tail step (doctype prepend, strip,\n * highlight, …) on top of `rawHtml`, keeping output byte-identical.\n */\nlet renderGeneration = 0\nconst renderCache = new Map<string, Promise<DedupedRender>>()\n\nfunction bumpGeneration() {\n renderGeneration++\n renderCache.clear()\n}\n\nfunction getRendered(absolutePath: string, config: MaizzleConfig, renderer: Renderer, events: EventManager): Promise<DedupedRender> {\n const key = `${renderGeneration}:${absolutePath}`\n let promise = renderCache.get(key)\n if (!promise) {\n promise = (async () => {\n _setCurrentTemplate(parsePath(absolutePath))\n try {\n /**\n * Mirror the build's per-template event pipeline (see buildTemplate)\n * so dev preview fires the same beforeRender / afterRender /\n * afterTransform hooks and matches production output. Clone config so\n * beforeRender mutations stay scoped to this render.\n */\n const renderConfig = cloneConfig(config)\n const template = { source: readFileSync(absolutePath, 'utf-8'), path: parsePath(absolutePath) }\n const originalSource = template.source\n\n await events.fireBeforeRender({ config: renderConfig, template })\n\n const rendered = await renderer.render(\n absolutePath,\n renderConfig,\n template.source !== originalSource ? { source: template.source } : undefined,\n )\n\n for (const { name, handler } of rendered.sfcEventHandlers) {\n events.on(name, handler)\n }\n\n const templateConfig = rendered.templateConfig\n let html = await events.fireAfterRender({ config: templateConfig, template, html: rendered.html })\n const doctype = rendered.doctype ?? templateConfig.doctype ?? '<!DOCTYPE html>'\n\n if (templateConfig.useTransformers !== false) {\n html = await runTransformers(html, templateConfig, absolutePath, doctype, rendered.tailwindBlocks)\n }\n\n const rawHtml = await events.fireAfterTransform({ config: templateConfig, template, html })\n\n return { rawHtml, doctype, templateConfig, rendered }\n } finally {\n _setCurrentTemplate(undefined)\n events.clearSfcHandlers()\n }\n })()\n renderCache.set(key, promise)\n }\n return promise\n}\n\n/**\n * SSR render a .vue template using the Renderer (not the dev UI server).\n */\nasync function serveRenderedTemplate(url: string, config: MaizzleConfig, renderer: Renderer, events: EventManager, res: any) {\n const templateSlug = url.replace('/__maizzle/render/', '').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('Template not found')\n return\n }\n\n const absolutePath = resolve(match)\n\n try {\n const { rawHtml, doctype } = await getRendered(absolutePath, config, renderer, events)\n let html = rawHtml\n if (doctype) html = `${doctype}\\n${html}`\n\n res.setHeader('Content-Type', 'text/html')\n res.end(stripForHtml(html))\n } catch (error: any) {\n res.statusCode = 500\n res.end(`<pre>${error.stack || error.message}</pre>`)\n }\n}\n\nlet highlighter: Highlighter | null = null\n\nasync function getHighlighter() {\n if (!highlighter) {\n highlighter = await createHighlighter({\n themes: ['laserwave'],\n langs: ['html', 'vue'],\n })\n }\n return highlighter\n}\n\nasync function serveHighlightedSource(url: string, config: MaizzleConfig, renderer: Renderer, events: EventManager, res: any) {\n const templateSlug = url.replace('/__maizzle/source/', '').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('Template not found')\n return\n }\n\n const absolutePath = resolve(match)\n\n try {\n const { rawHtml, doctype } = await getRendered(absolutePath, config, renderer, events)\n const html = stripForHtml(doctype ? `${doctype}\\n${rawHtml}` : rawHtml)\n\n const hl = await getHighlighter()\n const highlighted = hl.codeToHtml(html, {\n lang: 'html',\n theme: 'laserwave',\n transformers: [{\n line(node, line) {\n node.properties['data-line'] = line\n },\n }],\n })\n\n res.setHeader('Content-Type', 'text/html')\n res.end(highlighted)\n } catch (error: any) {\n res.statusCode = 500\n res.end(`<pre>${error.stack || error.message}</pre>`)\n }\n}\n\nasync function serveVueSource(url: string, config: MaizzleConfig, res: any) {\n const templateSlug = url.replace('/__maizzle/vue-source/', '').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('Template not found')\n return\n }\n\n try {\n const source = readFileSync(resolve(match), 'utf-8')\n const lang = match.endsWith('.md') ? 'html' : 'vue'\n\n const hl = await getHighlighter()\n const highlighted = hl.codeToHtml(source, {\n lang,\n theme: 'laserwave',\n transformers: [{\n line(node, line) {\n node.properties['data-line'] = line\n },\n }],\n })\n\n res.setHeader('Content-Type', 'text/html')\n res.end(highlighted)\n } catch (error: any) {\n res.statusCode = 500\n res.end(`<pre>${error.stack || error.message}</pre>`)\n }\n}\n\nasync function servePlaintext(url: string, config: MaizzleConfig, renderer: Renderer, events: EventManager, res: any) {\n const templateSlug = url.replace('/__maizzle/plaintext/', '').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('Template not found')\n return\n }\n\n const absolutePath = resolve(match)\n\n try {\n const { rawHtml } = await getRendered(absolutePath, config, renderer, events)\n const plaintext = createPlaintext(stripForPlaintext(rawHtml))\n\n res.setHeader('Content-Type', 'text/plain')\n res.end(plaintext)\n } catch (error: any) {\n res.statusCode = 500\n res.end(error.message)\n }\n}\n\nfunction humanFileSize(bytes: number, si = false, dp = 2) {\n const threshold = si ? 1000 : 1024\n\n if (Math.abs(bytes) < threshold) {\n return bytes + ' B'\n }\n\n const units = ['KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB']\n let u = -1\n const r = 10 ** dp\n\n do {\n bytes /= threshold\n ++u\n } while (Math.round(Math.abs(bytes) * r) / r >= threshold && u < units.length - 1)\n\n return bytes.toFixed(dp) + ' ' + units[u]\n}\n\nasync function serveStats(url: string, config: MaizzleConfig, renderer: Renderer, events: EventManager, res: any) {\n const templateSlug = url.replace('/__maizzle/stats/', '').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 const absolutePath = resolve(match)\n\n try {\n const { rawHtml } = await getRendered(absolutePath, config, renderer, events)\n const html = stripForHtml(rawHtml)\n\n const sizeBytes = new TextEncoder().encode(html).length\n\n // Count images: <img> tags and CSS background images\n const imgTags = (html.match(/<img\\b[^>]*>/gi) || []).length\n const bgImages = (html.match(/url\\s*\\([^)]+\\)/gi) || []).length\n const totalImages = imgTags + bgImages\n\n // Count links\n const links = (html.match(/<a\\b[^>]*href\\s*=/gi) || []).length\n\n res.setHeader('Content-Type', 'application/json')\n res.end(JSON.stringify({\n size: {\n bytes: sizeBytes,\n formatted: humanFileSize(sizeBytes),\n },\n images: totalImages,\n links,\n }))\n } catch (error: any) {\n res.statusCode = 500\n res.end(JSON.stringify({ error: error.message }))\n }\n}\n\nasync function serveEmailEndpoint(url: string, req: any, res: any, config: MaizzleConfig, renderer: Renderer, events: EventManager) {\n const templateSlug = url.replace('/__maizzle/email/', '').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({ success: false, message: 'Template not found' }))\n return\n }\n\n let body = ''\n for await (const chunk of req) body += chunk\n\n let payload: { to: string[]; subject: string }\n\n try {\n payload = JSON.parse(body)\n } catch {\n res.statusCode = 400\n res.end(JSON.stringify({ success: false, message: 'Invalid JSON' }))\n return\n }\n\n if (!payload.to?.length) {\n res.statusCode = 400\n res.end(JSON.stringify({ success: false, message: 'Missing recipients' }))\n return\n }\n\n const absolutePath = resolve(match)\n\n try {\n const { rawHtml, doctype, templateConfig } = await getRendered(absolutePath, config, renderer, events)\n let html = doctype ? `${doctype}\\n${rawHtml}` : rawHtml\n\n const text = createPlaintext(stripForPlaintext(html))\n html = stripForHtml(html)\n\n const result = await sendEmail(\n { to: payload.to, subject: payload.subject, html, text },\n config,\n templateConfig,\n )\n\n res.setHeader('Content-Type', 'application/json')\n res.end(JSON.stringify(result))\n } catch (error: any) {\n res.statusCode = 500\n res.end(JSON.stringify({ success: false, message: error.message }))\n }\n}\n\nfunction serveEmailConfig(config: MaizzleConfig, res: any) {\n const emailConfig = config.server?.email\n res.setHeader('Content-Type', 'application/json')\n res.end(JSON.stringify({\n to: emailConfig?.to ? (Array.isArray(emailConfig.to) ? emailConfig.to : [emailConfig.to]) : [],\n from: emailConfig?.from ?? '',\n subject: emailConfig?.subject ?? '',\n hasTransport: !!emailConfig?.transport,\n }))\n}\n\nexport function printBanner(server: ViteDevServer, startupTime?: number) {\n const info = server.config.logger.info\n const time = startupTime ?? (server as any)._maizzleStartupTime\n\n const networkUrl = server.resolvedUrls?.network[0]\n if (networkUrl) {\n const qr = renderUnicodeCompact(networkUrl, { border: 1 })\n info('')\n info(qr.split('\\n').map(line => ` ${line}`).join('\\n'))\n }\n\n info('')\n info(` \\x1b[32m\\x1b[1mMAIZZLE\\x1b[0m\\x1b[32m v${version}\\x1b[0m \\x1b[2mready in\\x1b[0m \\x1b[1m${time}\\x1b[0m ms`)\n info('')\n server.printUrls()\n info('')\n}\n\nfunction customLogger() {\n const logger = createLogger('info')\n const warn = logger.warn\n\n logger.warn = (message, options) => {\n if (typeof message === 'string' && message.includes('<tr> cannot be child of <table>')) {\n return\n }\n\n warn(message, options)\n }\n\n return logger\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"serve.js","names":["parsePath"],"sources":["../src/serve.ts"],"sourcesContent":["import { readFileSync } from 'node:fs'\nimport { dirname, resolve, basename, parse as parsePath } from 'node:path'\nimport { fileURLToPath } from 'node:url'\nimport { createRequire } from 'node:module'\nimport { createServer, createLogger, type ViteDevServer } from 'vite'\nimport { renderUnicodeCompact } from 'uqr'\nimport vue from '@vitejs/plugin-vue'\nimport tailwindcss from '@tailwindcss/vite'\nimport { glob } from 'tinyglobby'\nimport { createHighlighter, type Highlighter } from 'shiki'\nimport { createPlaintext } from './plaintext.ts'\nimport { stripForHtml, stripForPlaintext } from './utils/output-markers.ts'\nimport { resolveConfig } from './config/index.ts'\nimport { runTransformers } from './transformers/index.ts'\nimport { EventManager } from './events/index.ts'\nimport { cloneConfig } from './utils/cloneConfig.ts'\nimport { createRenderer, type Renderer, type RenderedTemplate } from './render/createRenderer.ts'\nimport { _setCurrentTemplate } from './composables/useCurrentTemplate.ts'\nimport { setActiveRenderer } from './render/active.ts'\nimport { serveCompatibility } from './server/compatibility.ts'\nimport { serveLint } from './server/linter.ts'\nimport { sendEmail } from './server/email.ts'\nimport { normalizeComponentSources } from './utils/componentSources.ts'\nimport { createWatchedFileMatcher } from './utils/watchPaths.ts'\nimport type { MaizzleConfig } from './types/index.ts'\n\nconst __dirname = dirname(fileURLToPath(import.meta.url))\nconst devUIDir = resolve(__dirname, 'server/ui')\n\nconst require = createRequire(import.meta.url)\n\nconst version = JSON.parse(\n readFileSync(resolve(dirname(fileURLToPath(import.meta.url)), '../package.json'), 'utf-8'),\n).version\n\nconst pkg = (name: string) => {\n const resolved = require.resolve(name).replace(/\\\\/g, '/')\n const marker = `node_modules/${name}`\n const idx = resolved.lastIndexOf(marker)\n\n return resolved.slice(0, idx + marker.length)\n}\n\n/**\n * Resolve a package's ESM entry via its `exports` map. Aliasing to the\n * package directory bypasses `exports` (it only keys off the bare name),\n * so directory resolution can fall back to a UMD/CJS bundle — which Vite 8\n * flags `needsInterop` and then default-imports, breaking ESM-only deps\n * like culori (named exports, no default). Point the alias at the real\n * ESM entry instead.\n */\nconst pkgEsmEntry = (name: string) => {\n const dir = pkg(name)\n const pj = JSON.parse(readFileSync(resolve(dir, 'package.json'), 'utf-8'))\n const entry = pj.exports?.['.']?.import ?? pj.module ?? pj.main\n return resolve(dir, entry)\n}\n\nexport interface ServeOptions {\n config?: Partial<MaizzleConfig> | string\n /** Override the dev server port (takes precedence over config.server.port) */\n port?: number\n /** Expose the server on the network (e.g. --host) */\n host?: boolean | string\n /** When true, suppresses the startup banner/URL output. */\n silent?: boolean\n}\n\n/**\n * Start the Maizzle dev server.\n *\n * Creates two things:\n * 1. A Vite dev server for the dev UI (sidebar + preview, with Vue + Tailwind for the UI itself)\n * 2. A Renderer instance for SSR rendering email templates\n *\n * Template rendering goes through the Renderer, not the Vite dev server.\n */\nexport async function serve(options: ServeOptions = {}) {\n const start = performance.now()\n\n let config = await resolveConfig(options.config)\n const port = options.port ?? config.server?.port ?? 3000\n const host = options.host ?? config.server?.host\n\n // Create a renderer for SSR rendering email templates (with dts for dev)\n let renderer = await createRenderer({ dts: true, markdown: config.markdown, root: config.root, componentDirs: normalizeComponentSources(config.components?.source, process.cwd()), vite: config.vite, customElements: config.vue?.customElements })\n\n /**\n * Register so user-land render() calls reuse this renderer instead of\n * spinning up another Vite SSR server (which collides when the host\n * app is itself a Vite dev process — e.g. TanStack Start).\n */\n setActiveRenderer(renderer)\n\n const events = new EventManager()\n events.registerConfig(config)\n await events.fireBeforeCreate({ config })\n\n const server = await createServer({\n configFile: false,\n plugins: [\n // Vue and Tailwind are only for the dev UI SPA, not for email templates\n vue(),\n tailwindcss(),\n maizzleDevPlugin(config, renderer, events, options.config),\n ],\n resolve: {\n dedupe: ['vue'],\n alias: [\n { find: '@', replacement: devUIDir },\n { find: 'vue', replacement: resolve(pkg('vue'), 'dist/vue.runtime.esm-bundler.js') },\n // culori is ESM-only — alias to its ESM entry, not the package dir (see pkgEsmEntry)\n { find: 'culori', replacement: pkgEsmEntry('culori') },\n ...['vue-router', 'reka-ui', '@vueuse/core', '@vueuse/shared', '@lucide/vue', 'class-variance-authority', 'clsx', 'tailwind-merge']\n .map(name => ({ find: name, replacement: pkg(name) })),\n ],\n },\n cacheDir: resolve(devUIDir, '.vite'),\n optimizeDeps: {\n noDiscovery: true,\n include: [\n 'vue',\n 'vue-router',\n '@lucide/vue',\n '@vueuse/core',\n '@vueuse/shared',\n 'reka-ui',\n 'class-variance-authority',\n 'clsx',\n 'tailwind-merge',\n 'culori',\n ],\n },\n server: {\n // Cherry-pick Vite's `server` options (e.g. watch.ignored) from the\n // user's `vite` config; Maizzle's required keys below take precedence.\n ...config.vite?.server,\n port,\n host,\n fs: {\n ...config.vite?.server?.fs,\n allow: [process.cwd(), config.root ?? process.cwd(), devUIDir, ...['vue', 'vue-router', 'reka-ui', '@vueuse/core', '@vueuse/shared', '@lucide/vue', 'class-variance-authority', 'clsx', 'tailwind-merge', 'culori'].map(pkg), ...(config.vite?.server?.fs?.allow ?? [])],\n },\n },\n customLogger: customLogger(),\n })\n\n // Store renderer ref on server for cleanup\n const originalClose = server.close.bind(server)\n server.close = async () => {\n setActiveRenderer(null)\n await renderer.close()\n return originalClose()\n }\n\n await server.listen()\n\n const startupTime = Math.round(performance.now() - start)\n\n if (!options.silent) {\n printBanner(server, startupTime)\n }\n\n // Expose startup time so the plugin can print it later\n ; (server as any)._maizzleStartupTime = startupTime\n\n return server\n}\n\n/**\n * Internal Vite plugin that adds Maizzle middleware and file watching to the dev UI server.\n */\nfunction maizzleDevPlugin(\n config: MaizzleConfig,\n renderer: Renderer,\n events: EventManager,\n configInput: Partial<MaizzleConfig> | string | undefined,\n) {\n return {\n name: 'maizzle:dev',\n enforce: 'pre' as const,\n\n hotUpdate: {\n order: 'pre' as const,\n handler({ file }: { file: string }) {\n /**\n * Prevent Tailwind/Vue from triggering a full reload for email template\n * files. Maizzle handles these via custom HMR events in the\n * watcher below.\n */\n if (isTemplateFile(file)) {\n return []\n }\n },\n },\n\n configureServer(server: ViteDevServer) {\n // File watching\n const defaultWatchPaths = [\n 'maizzle.config.js',\n 'maizzle.config.ts',\n 'tailwind.config.js',\n 'tailwind.config.ts',\n 'locales/**',\n ]\n\n const userWatchPaths = config.server?.watch ?? []\n const watchPaths = [...defaultWatchPaths, ...userWatchPaths]\n // Match against cwd, not config.root: the watched paths (maizzle/tailwind\n // configs, locales) are project-root relative, and `watcher.add` below\n // resolves them against cwd too. Using config.root would break matching\n // when root points at a subdirectory (e.g. the Vite-plugin setup).\n const isWatchedFile = createWatchedFileMatcher(watchPaths, process.cwd())\n\n for (const watchPath of watchPaths) {\n server.watcher.add(watchPath)\n }\n\n /**\n * Serialize watcher work onto one chain. The change handler closes and\n * recreates the renderer across awaits; without serialization a second\n * event firing mid-reload closes a stale renderer and leaks the new one.\n * Errors are caught so one failed task doesn't break the chain.\n */\n let watcherChain: Promise<void> = Promise.resolve()\n const enqueue = (task: () => Promise<void>): Promise<void> => {\n watcherChain = watcherChain.then(task).catch((err) => {\n console.error('[maizzle] watcher task failed:', err)\n })\n return watcherChain\n }\n\n server.watcher.on('add', file => enqueue(async () => {\n if (isTemplateFile(file)) {\n await renderer.invalidateAll()\n bumpGeneration()\n server.ws.send({ type: 'custom', event: 'maizzle:templates-changed' })\n }\n }))\n\n server.watcher.on('unlink', file => enqueue(async () => {\n if (isTemplateFile(file)) {\n await renderer.invalidateAll()\n bumpGeneration()\n server.ws.send({ type: 'custom', event: 'maizzle:templates-changed' })\n }\n }))\n\n server.watcher.on('change', file => enqueue(async () => {\n if (isWatchedFile(file)) {\n config = await resolveConfig(configInput)\n\n // Re-register event handlers against the reloaded config (the config\n // object is replaced wholesale, so old handlers would be stale).\n events.clear()\n events.registerConfig(config)\n\n // Recreate the renderer so config changes (e.g. markdown.shikiTheme) take effect\n await renderer.close()\n renderer = await createRenderer({ dts: true, markdown: config.markdown, root: config.root, componentDirs: normalizeComponentSources(config.components?.source, process.cwd()), vite: config.vite, customElements: config.vue?.customElements })\n\n // Re-register the new renderer so user-land render() calls don't keep\n // reusing the closed one (see setActiveRenderer above).\n setActiveRenderer(renderer)\n\n /**\n * Push UI-relevant config bits so the dev UI reacts to live edits\n * without a page reload. Uses the same shape as the initial\n * inject.\n */\n server.ws.send({ type: 'custom', event: 'maizzle:config-updated', data: buildUiConfig(config) })\n }\n\n /**\n * Invalidate all renderer modules so component and config changes\n * are picked up on the next render (Tailwind recompiles with\n * fresh content).\n */\n await renderer.invalidateAll()\n bumpGeneration()\n\n if (\n isTemplateFile(file)\n || isWatchedFile(file)\n ) {\n server.ws.send({ type: 'custom', event: 'maizzle:template-updated', data: { file } })\n }\n }))\n\n // API middleware (before Vite's middleware)\n server.middlewares.use(async (req: any, res: any, next: any) => {\n const url = req.url || '/'\n\n if (url === '/__maizzle/templates') {\n return serveTemplateList(config, res)\n }\n\n if (url.startsWith('/__maizzle/render/')) {\n return await serveRenderedTemplate(url, config, renderer, events, res)\n }\n\n if (url.startsWith('/__maizzle/source/')) {\n return await serveHighlightedSource(url, config, renderer, events, res)\n }\n\n if (url.startsWith('/__maizzle/compatibility/')) {\n return await serveCompatibility(url, res, config, normalizeComponentSources(config.components?.source, process.cwd()))\n }\n\n if (url.startsWith('/__maizzle/lint/')) {\n return await serveLint(url, res, config, normalizeComponentSources(config.components?.source, process.cwd()))\n }\n\n if (url.startsWith('/__maizzle/vue-source/')) {\n return await serveVueSource(url, config, res)\n }\n\n if (url.startsWith('/__maizzle/plaintext/')) {\n return await servePlaintext(url, config, renderer, events, res)\n }\n\n if (url.startsWith('/__maizzle/stats/')) {\n return await serveStats(url, config, renderer, events, res)\n }\n\n if (url.startsWith('/__maizzle/email/') && req.method === 'POST') {\n return await serveEmailEndpoint(url, req, res, config, renderer, events)\n }\n\n if (url === '/__maizzle/email-config') {\n return serveEmailConfig(config, res)\n }\n\n next()\n })\n\n // Dev UI fallback (after Vite's middleware)\n return () => {\n server.middlewares.use(async (req: any, res: any, next: any) => {\n if (isNavigationRequest(req)) {\n return await serveDevUI(server, res, req.url || '/', config)\n }\n\n next()\n })\n }\n },\n }\n}\n\nfunction isTemplateFile(file: string): boolean {\n return (file.endsWith('.vue') || file.endsWith('.md')) && !file.includes('server/ui')\n}\n\nfunction isNavigationRequest(req: any): boolean {\n const accept = req.headers?.accept || ''\n return req.method === 'GET' && accept.includes('text/html')\n}\n\n/**\n * Shape exposed to the dev UI both at initial HTML load (as\n * `window.__MAIZZLE_CONFIG__`) and on the `maizzle:config-updated` HMR event.\n * Add UI-visible config bits here; consumers on both ends pick up automatically.\n */\nfunction buildUiConfig(config: MaizzleConfig) {\n return {\n checks: config.server?.checks ?? true,\n }\n}\n\nasync function serveDevUI(server: ViteDevServer, res: any, url: string, config: MaizzleConfig) {\n let indexHtml = readFileSync(resolve(devUIDir, 'index.html'), 'utf-8')\n\n indexHtml = indexHtml.replace('./main.ts', `/@fs/${resolve(devUIDir, 'main.ts')}`)\n indexHtml = indexHtml.replace('./favicon.svg', `/@fs/${resolve(devUIDir, 'favicon.svg')}`)\n\n const configScript = `<script>window.__MAIZZLE_CONFIG__ = ${JSON.stringify(buildUiConfig(config))};</script>`\n indexHtml = indexHtml.replace('</head>', `${configScript}</head>`)\n\n const transformed = await server.transformIndexHtml(url, indexHtml)\n\n res.setHeader('Content-Type', 'text/html')\n res.end(transformed)\n}\n\nasync function serveTemplateList(config: MaizzleConfig, res: any) {\n const contentPatterns = config.content ?? ['emails/**/*.vue']\n const templates = await glob(contentPatterns)\n\n const data = templates.map(t => ({\n name: basename(t).replace(/\\.(vue|md)$/, ''),\n path: t,\n href: '/' + t.replace(/\\.(vue|md)$/, ''),\n }))\n\n res.setHeader('Content-Type', 'application/json')\n res.end(JSON.stringify(data))\n}\n\ninterface DedupedRender {\n /** Transformer output — before doctype prepend / stripForHtml / stripForPlaintext. */\n rawHtml: string\n doctype: string\n templateConfig: MaizzleConfig\n rendered: RenderedTemplate\n}\n\n/**\n * Render-result memo for the dev server. A single template save makes the\n * browser fire several endpoint requests in parallel (render, source, stats,\n * plaintext, email) that each need the same SSR render + transformer output.\n * Keying the in-flight Promise by `${generation}:${path}` collapses those into\n * one render and dedupes concurrent requests. The watcher bumps the generation\n * (and clears the cache) on every file/config change, so results never go\n * stale. Each endpoint applies its own tail step (doctype prepend, strip,\n * highlight, …) on top of `rawHtml`, keeping output byte-identical.\n */\nlet renderGeneration = 0\nconst renderCache = new Map<string, Promise<DedupedRender>>()\n\nfunction bumpGeneration() {\n renderGeneration++\n renderCache.clear()\n}\n\nfunction getRendered(absolutePath: string, config: MaizzleConfig, renderer: Renderer, events: EventManager): Promise<DedupedRender> {\n const key = `${renderGeneration}:${absolutePath}`\n let promise = renderCache.get(key)\n if (!promise) {\n promise = (async () => {\n _setCurrentTemplate(parsePath(absolutePath))\n try {\n /**\n * Mirror the build's per-template event pipeline (see buildTemplate)\n * so dev preview fires the same beforeRender / afterRender /\n * afterTransform hooks and matches production output. Clone config so\n * beforeRender mutations stay scoped to this render.\n */\n const renderConfig = cloneConfig(config)\n const template = { source: readFileSync(absolutePath, 'utf-8'), path: parsePath(absolutePath) }\n const originalSource = template.source\n\n await events.fireBeforeRender({ config: renderConfig, template })\n\n const rendered = await renderer.render(\n absolutePath,\n renderConfig,\n template.source !== originalSource ? { source: template.source } : undefined,\n )\n\n for (const { name, handler } of rendered.sfcEventHandlers) {\n events.on(name, handler)\n }\n\n const templateConfig = rendered.templateConfig\n let html = await events.fireAfterRender({ config: templateConfig, template, html: rendered.html })\n const doctype = rendered.doctype ?? templateConfig.doctype ?? '<!DOCTYPE html>'\n\n if (templateConfig.useTransformers !== false) {\n html = await runTransformers(html, templateConfig, absolutePath, doctype, rendered.tailwindBlocks, rendered.sourceFiles)\n }\n\n const rawHtml = await events.fireAfterTransform({ config: templateConfig, template, html })\n\n return { rawHtml, doctype, templateConfig, rendered }\n } finally {\n _setCurrentTemplate(undefined)\n events.clearSfcHandlers()\n }\n })()\n renderCache.set(key, promise)\n }\n return promise\n}\n\n/**\n * SSR render a .vue template using the Renderer (not the dev UI server).\n */\nasync function serveRenderedTemplate(url: string, config: MaizzleConfig, renderer: Renderer, events: EventManager, res: any) {\n const templateSlug = url.replace('/__maizzle/render/', '').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('Template not found')\n return\n }\n\n const absolutePath = resolve(match)\n\n try {\n const { rawHtml, doctype } = await getRendered(absolutePath, config, renderer, events)\n let html = rawHtml\n if (doctype) html = `${doctype}\\n${html}`\n\n res.setHeader('Content-Type', 'text/html')\n res.end(stripForHtml(html))\n } catch (error: any) {\n res.statusCode = 500\n res.end(`<pre>${error.stack || error.message}</pre>`)\n }\n}\n\nlet highlighter: Highlighter | null = null\n\nasync function getHighlighter() {\n if (!highlighter) {\n highlighter = await createHighlighter({\n themes: ['laserwave'],\n langs: ['html', 'vue'],\n })\n }\n return highlighter\n}\n\nasync function serveHighlightedSource(url: string, config: MaizzleConfig, renderer: Renderer, events: EventManager, res: any) {\n const templateSlug = url.replace('/__maizzle/source/', '').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('Template not found')\n return\n }\n\n const absolutePath = resolve(match)\n\n try {\n const { rawHtml, doctype } = await getRendered(absolutePath, config, renderer, events)\n const html = stripForHtml(doctype ? `${doctype}\\n${rawHtml}` : rawHtml)\n\n const hl = await getHighlighter()\n const highlighted = hl.codeToHtml(html, {\n lang: 'html',\n theme: 'laserwave',\n transformers: [{\n line(node, line) {\n node.properties['data-line'] = line\n },\n }],\n })\n\n res.setHeader('Content-Type', 'text/html')\n res.end(highlighted)\n } catch (error: any) {\n res.statusCode = 500\n res.end(`<pre>${error.stack || error.message}</pre>`)\n }\n}\n\nasync function serveVueSource(url: string, config: MaizzleConfig, res: any) {\n const templateSlug = url.replace('/__maizzle/vue-source/', '').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('Template not found')\n return\n }\n\n try {\n const source = readFileSync(resolve(match), 'utf-8')\n const lang = match.endsWith('.md') ? 'html' : 'vue'\n\n const hl = await getHighlighter()\n const highlighted = hl.codeToHtml(source, {\n lang,\n theme: 'laserwave',\n transformers: [{\n line(node, line) {\n node.properties['data-line'] = line\n },\n }],\n })\n\n res.setHeader('Content-Type', 'text/html')\n res.end(highlighted)\n } catch (error: any) {\n res.statusCode = 500\n res.end(`<pre>${error.stack || error.message}</pre>`)\n }\n}\n\nasync function servePlaintext(url: string, config: MaizzleConfig, renderer: Renderer, events: EventManager, res: any) {\n const templateSlug = url.replace('/__maizzle/plaintext/', '').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('Template not found')\n return\n }\n\n const absolutePath = resolve(match)\n\n try {\n const { rawHtml } = await getRendered(absolutePath, config, renderer, events)\n const plaintext = createPlaintext(stripForPlaintext(rawHtml))\n\n res.setHeader('Content-Type', 'text/plain')\n res.end(plaintext)\n } catch (error: any) {\n res.statusCode = 500\n res.end(error.message)\n }\n}\n\nfunction humanFileSize(bytes: number, si = false, dp = 2) {\n const threshold = si ? 1000 : 1024\n\n if (Math.abs(bytes) < threshold) {\n return bytes + ' B'\n }\n\n const units = ['KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB']\n let u = -1\n const r = 10 ** dp\n\n do {\n bytes /= threshold\n ++u\n } while (Math.round(Math.abs(bytes) * r) / r >= threshold && u < units.length - 1)\n\n return bytes.toFixed(dp) + ' ' + units[u]\n}\n\nasync function serveStats(url: string, config: MaizzleConfig, renderer: Renderer, events: EventManager, res: any) {\n const templateSlug = url.replace('/__maizzle/stats/', '').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 const absolutePath = resolve(match)\n\n try {\n const { rawHtml } = await getRendered(absolutePath, config, renderer, events)\n const html = stripForHtml(rawHtml)\n\n const sizeBytes = new TextEncoder().encode(html).length\n\n // Count images: <img> tags and CSS background images\n const imgTags = (html.match(/<img\\b[^>]*>/gi) || []).length\n const bgImages = (html.match(/url\\s*\\([^)]+\\)/gi) || []).length\n const totalImages = imgTags + bgImages\n\n // Count links\n const links = (html.match(/<a\\b[^>]*href\\s*=/gi) || []).length\n\n res.setHeader('Content-Type', 'application/json')\n res.end(JSON.stringify({\n size: {\n bytes: sizeBytes,\n formatted: humanFileSize(sizeBytes),\n },\n images: totalImages,\n links,\n }))\n } catch (error: any) {\n res.statusCode = 500\n res.end(JSON.stringify({ error: error.message }))\n }\n}\n\nasync function serveEmailEndpoint(url: string, req: any, res: any, config: MaizzleConfig, renderer: Renderer, events: EventManager) {\n const templateSlug = url.replace('/__maizzle/email/', '').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({ success: false, message: 'Template not found' }))\n return\n }\n\n let body = ''\n for await (const chunk of req) body += chunk\n\n let payload: { to: string[]; subject: string }\n\n try {\n payload = JSON.parse(body)\n } catch {\n res.statusCode = 400\n res.end(JSON.stringify({ success: false, message: 'Invalid JSON' }))\n return\n }\n\n if (!payload.to?.length) {\n res.statusCode = 400\n res.end(JSON.stringify({ success: false, message: 'Missing recipients' }))\n return\n }\n\n const absolutePath = resolve(match)\n\n try {\n const { rawHtml, doctype, templateConfig } = await getRendered(absolutePath, config, renderer, events)\n let html = doctype ? `${doctype}\\n${rawHtml}` : rawHtml\n\n const text = createPlaintext(stripForPlaintext(html))\n html = stripForHtml(html)\n\n const result = await sendEmail(\n { to: payload.to, subject: payload.subject, html, text },\n config,\n templateConfig,\n )\n\n res.setHeader('Content-Type', 'application/json')\n res.end(JSON.stringify(result))\n } catch (error: any) {\n res.statusCode = 500\n res.end(JSON.stringify({ success: false, message: error.message }))\n }\n}\n\nfunction serveEmailConfig(config: MaizzleConfig, res: any) {\n const emailConfig = config.server?.email\n res.setHeader('Content-Type', 'application/json')\n res.end(JSON.stringify({\n to: emailConfig?.to ? (Array.isArray(emailConfig.to) ? emailConfig.to : [emailConfig.to]) : [],\n from: emailConfig?.from ?? '',\n subject: emailConfig?.subject ?? '',\n hasTransport: !!emailConfig?.transport,\n }))\n}\n\nexport function printBanner(server: ViteDevServer, startupTime?: number) {\n const info = server.config.logger.info\n const time = startupTime ?? (server as any)._maizzleStartupTime\n\n const networkUrl = server.resolvedUrls?.network[0]\n if (networkUrl) {\n const qr = renderUnicodeCompact(networkUrl, { border: 1 })\n info('')\n info(qr.split('\\n').map(line => ` ${line}`).join('\\n'))\n }\n\n info('')\n info(` \\x1b[32m\\x1b[1mMAIZZLE\\x1b[0m\\x1b[32m v${version}\\x1b[0m \\x1b[2mready in\\x1b[0m \\x1b[1m${time}\\x1b[0m ms`)\n info('')\n server.printUrls()\n info('')\n}\n\nfunction customLogger() {\n const logger = createLogger('info')\n const warn = logger.warn\n\n logger.warn = (message, options) => {\n if (typeof message === 'string' && message.includes('<tr> cannot be child of <table>')) {\n return\n }\n\n warn(message, options)\n }\n\n return logger\n}\n"],"mappings":"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"}
@@ -767,7 +767,8 @@ function labelFor(idx, level) {
767
767
  async function scan(rootFile, config, componentDirs, allowedClients) {
768
768
  const idx = await initCompatibility();
769
769
  if (!idx) return [];
770
- const componentMap = await buildComponentMap(config.root ?? process.cwd(), componentDirs);
770
+ const root = config.root ?? process.cwd();
771
+ const componentMap = await buildComponentMap(root, componentDirs);
771
772
  const streams = [];
772
773
  collectStreams(rootFile, componentMap, /* @__PURE__ */ new Set(), streams);
773
774
  const issues = [];
@@ -1 +1 @@
1
- {"version":3,"file":"compatibility.js","names":["compileWithPipeline"],"sources":["../../src/server/compatibility.ts"],"sourcesContent":["import { readFileSync } from 'node:fs'\nimport { resolve } from 'node:path'\nimport postcss, { type Declaration, type AtRule, type Rule } from 'postcss'\nimport safeParser from 'postcss-safe-parser'\nimport valueParser from 'postcss-value-parser'\nimport { Parser } from 'htmlparser2'\nimport { DomHandler, type ChildNode, type Element } from 'domhandler'\nimport { parseSfcBlocks, findComponentTags, buildComponentMap, isFrameworkComponent, type SfcBlock } from './sfc-utils.ts'\nimport { scanLint } from './linter.ts'\nimport { tailwindcss as compileWithPipeline } from '../transformers/tailwindcss.ts'\nimport type { MaizzleConfig } from '../types/index.ts'\nimport type { NormalizedComponentSource } from '../utils/componentSources.ts'\n\nconst API_URL = 'https://www.caniemail.com/api/data.json'\nconst DEFAULT_CLIENTS = new Set(['gmail', 'apple-mail', 'outlook', 'yahoo'])\n\ntype SupportLevel = 'unsupported' | 'mitigated' | 'unknown'\n\ninterface Feature {\n slug: string\n title: string\n url: string\n category: string\n stats: any\n}\n\ninterface Issue {\n kind: 'compat' | 'lint'\n slug?: string\n title: string\n url?: string\n category: string\n line?: number\n file: string\n // compat-only\n supportLevel?: SupportLevel\n supportLabel?: string\n affectedClients?: string[]\n // lint-only\n severity?: 'error' | 'warning'\n message?: string\n}\n\ninterface Indexes {\n nicenames: { supported: string, mitigated: string, unsupported: string, unknown: string, mixed: string }\n familyNicenames: Record<string, string>\n cssProp: Map<string, Feature[]>\n cssPropValue: Map<string, Array<{ value: string, feature: Feature }>>\n cssAtRule: Map<string, Feature[]>\n cssMediaFeature: Map<string, Feature[]>\n cssPseudoClass: Map<string, Feature[]>\n cssPseudoElement: Map<string, Feature[]>\n cssFunction: Map<string, Feature[]>\n cssUnit: Map<string, Feature[]>\n cssImportant?: Feature\n cssVariables?: Feature\n cssNesting?: Feature\n cssComments?: Feature\n cssModernColor?: Feature\n htmlTag: Map<string, Feature[]>\n htmlAttr: Map<string, Feature[]>\n htmlInputType: Map<string, Feature[]>\n htmlButtonType: Map<string, Feature[]>\n htmlDoctype?: Feature\n htmlComments?: Feature\n htmlAnchorLinks?: Feature\n htmlMailtoLinks?: Feature\n htmlMetaColorScheme?: Feature\n htmlSemantics?: Feature\n htmlStyleInBody?: Feature\n imageExt: Map<string, Feature[]>\n /** All features by slug — unfiltered, used for URL lookups (e.g. by lint). */\n bySlug: Map<string, { title: string, url: string }>\n}\n\nlet indexes: Indexes | null = null\nlet initPromise: Promise<Indexes | null> | null = null\n\nfunction mpush<K, V>(m: Map<K, V[]>, k: K, v: V) {\n const arr = m.get(k)\n if (arr) arr.push(v)\n else m.set(k, [v])\n}\n\nfunction emptyIndexes(nicenames: any, familyNicenames: Record<string, string>): Indexes {\n return {\n nicenames,\n familyNicenames,\n cssProp: new Map(), cssPropValue: new Map(), cssAtRule: new Map(),\n cssMediaFeature: new Map(), cssPseudoClass: new Map(), cssPseudoElement: new Map(),\n cssFunction: new Map(), cssUnit: new Map(),\n htmlTag: new Map(), htmlAttr: new Map(), htmlInputType: new Map(), htmlButtonType: new Map(),\n imageExt: new Map(),\n bySlug: new Map(),\n }\n}\n\nfunction hasAnyNonY(stats: any): boolean {\n if (!stats) return false\n for (const family in stats) {\n for (const plat in stats[family]) {\n for (const ver in stats[family][plat]) {\n const v = stripNotes(String(stats[family][plat][ver]).trim())\n if (v && v !== 'y') return true\n }\n }\n }\n return false\n}\n\n/** Strip `#N` note markers — `\"y #1\"` → `\"y\"`. Notes document edge cases but\n * don't change support semantics, so treat `y #1` as fully supported. */\nfunction stripNotes(v: string): string {\n return v.split(/\\s+/).filter(t => t && !t.startsWith('#')).join(' ')\n}\n\nfunction computeSupport(stats: any, familyNicenames: Record<string, string>, allowedClients: Set<string> | 'all'): { level: SupportLevel, affected: string[] } | null {\n let nY = 0, nN = 0, nU = 0, nPartial = 0, total = 0\n const affectedFamilies = new Set<string>()\n for (const family in stats) {\n if (allowedClients !== 'all' && !allowedClients.has(family)) continue\n let familyHasNonY = false\n for (const plat in stats[family]) {\n /**\n * Only score the latest version per (family, platform) — legacy\n * versions (Outlook 2007, etc.) otherwise flag modern-widely\n * supported features as partial forever.\n */\n const versions = Object.keys(stats[family][plat]).sort()\n const latest = versions[versions.length - 1]\n if (!latest) continue\n total++\n const v = stripNotes(String(stats[family][plat][latest]).trim())\n if (v === 'y') nY++\n else if (v === 'n') { nN++; familyHasNonY = true }\n else if (v === 'u') { nU++; familyHasNonY = true }\n else { nPartial++; familyHasNonY = true }\n }\n if (familyHasNonY) affectedFamilies.add(family)\n }\n if (!total) return null\n if (nY === total) return null\n const affected = [...affectedFamilies].map(f => familyNicenames[f] ?? f).sort()\n if (nN === total) return { level: 'unsupported', affected }\n if (nU === total) return { level: 'unknown', affected }\n return { level: 'mitigated', affected }\n}\n\n/**\n * Slugs we never report. Fundamental HTML (every email uses these) plus\n * CSS noise that's not actionable (comments, !important usage).\n */\nconst IGNORED_SLUGS = new Set([\n // Required/unavoidable tags\n 'html-doctype', 'html-comments',\n 'html-html', 'html-head', 'html-body', 'html-title',\n 'html-meta', 'html-meta-color-scheme',\n 'html-style', 'html-link',\n 'html-div', 'html-span', 'html-br', 'html-p', 'html-a', 'html-img',\n 'html-table', 'html-tr', 'html-td', 'html-th',\n 'html-thead', 'html-tbody', 'html-tfoot',\n 'html-h1-h6', 'html-lists',\n 'html-strong', 'html-em', 'html-b', 'html-i', 'html-u',\n 'html-semantics',\n // Ubiquitous attributes — always present, caveats aren't actionable.\n 'html-role', 'html-hidden', 'html-width', 'html-height',\n // CSS noise\n 'css-comments', 'css-important',\n /**\n * CSS fundamentals — universally used with known minor caveats; flagging\n * them as \"partial\" is noise rather than signal.\n */\n 'css-margin', 'css-padding', 'css-border',\n 'css-font-size', 'css-font-weight', 'css-font', 'css-font-family',\n 'css-line-height', 'css-letter-spacing', 'css-text-align',\n 'css-text-decoration', 'css-text-transform', 'css-color',\n 'css-background', 'css-background-color',\n 'css-width', 'css-height',\n 'css-display',\n])\n\nfunction classify(f: Feature, idx: Indexes) {\n const slug = f.slug\n /**\n * Retain html-style feature for the body-only detector even though it's\n * blacklisted from the normal html-tag detection path. Title is\n * suffixed so the flag reads as a body-placement warning, not a\n * blanket `<style>`.\n */\n if (slug === 'html-style') {\n idx.htmlStyleInBody = { ...f, title: `${f.title} in <body>` }\n return\n }\n if (IGNORED_SLUGS.has(slug)) return\n\n if (f.category === 'css') return classifyCss(f, slug, idx)\n if (f.category === 'html') return classifyHtml(f, slug, idx)\n if (f.category === 'image') {\n const ext = slug.slice('image-'.length)\n if (ext === 'base64') return\n mpush(idx.imageExt, ext, f)\n }\n // 'others' (amp, bimi) intentionally skipped\n}\n\nfunction classifyCss(f: Feature, slug: string, idx: Indexes) {\n // Specials first\n switch (slug) {\n case 'css-important': idx.cssImportant = f; return\n case 'css-variables': idx.cssVariables = f; return\n case 'css-nesting': idx.cssNesting = f; return\n case 'css-comments': idx.cssComments = f; return\n case 'css-modern-color': idx.cssModernColor = f; return\n case 'css-display-flex': mpushPropValue(idx, 'display', 'flex', f); return\n case 'css-display-grid': mpushPropValue(idx, 'display', 'grid', f); return\n case 'css-display-none': mpushPropValue(idx, 'display', 'none', f); return\n case 'css-rgb': mpush(idx.cssFunction, 'rgb', f); return\n case 'css-rgba': mpush(idx.cssFunction, 'rgba', f); return\n case 'css-linear-gradient': mpush(idx.cssFunction, 'linear-gradient', f); return\n case 'css-radial-gradient': mpush(idx.cssFunction, 'radial-gradient', f); return\n case 'css-conic-gradient': mpush(idx.cssFunction, 'conic-gradient', f); return\n }\n\n if (slug.startsWith('css-at-media-') && slug !== 'css-at-media') {\n mpush(idx.cssMediaFeature, slug.slice('css-at-media-'.length), f)\n return\n }\n if (slug.startsWith('css-at-')) {\n mpush(idx.cssAtRule, slug.slice('css-at-'.length), f)\n return\n }\n if (slug.startsWith('css-pseudo-class-')) {\n mpush(idx.cssPseudoClass, slug.slice('css-pseudo-class-'.length), f)\n return\n }\n if (slug.startsWith('css-pseudo-element-')) {\n mpush(idx.cssPseudoElement, slug.slice('css-pseudo-element-'.length), f)\n return\n }\n if (slug.startsWith('css-unit-')) {\n const u = slug.slice('css-unit-'.length)\n if (u === 'calc') { mpush(idx.cssFunction, 'calc', f); return }\n if (u === 'initial') return // keyword detection is noisy; skip\n const unit = u === 'percent' ? '%' : u\n mpush(idx.cssUnit, unit, f)\n return\n }\n if (slug.startsWith('css-function-')) {\n mpush(idx.cssFunction, slug.slice('css-function-'.length), f)\n return\n }\n // css-selector-* — skip (too broad to detect meaningfully)\n if (slug.startsWith('css-selector-')) return\n\n // Fallback: treat as property name\n mpush(idx.cssProp, slug.slice('css-'.length), f)\n}\n\nfunction mpushPropValue(idx: Indexes, prop: string, value: string, f: Feature) {\n const arr = idx.cssPropValue.get(prop)\n if (arr) arr.push({ value, feature: f })\n else idx.cssPropValue.set(prop, [{ value, feature: f }])\n}\n\nconst HTML_ATTR_SLUGS = new Set([\n 'align', 'background', 'cellpadding', 'cellspacing', 'height', 'width',\n 'valign', 'target', 'srcset', 'lang', 'dir', 'role', 'required', 'hidden',\n])\n\nfunction classifyHtml(f: Feature, slug: string, idx: Indexes) {\n // Specials\n switch (slug) {\n case 'html-doctype': idx.htmlDoctype = f; return\n case 'html-comments': idx.htmlComments = f; return\n case 'html-anchor-links': idx.htmlAnchorLinks = f; return\n case 'html-mailto-links': idx.htmlMailtoLinks = f; return\n case 'html-meta-color-scheme': idx.htmlMetaColorScheme = f; return\n case 'html-semantics': idx.htmlSemantics = f; return\n case 'html-loading-attribute': mpush(idx.htmlAttr, 'loading', f); return\n case 'html-image-maps':\n mpush(idx.htmlTag, 'map', f); mpush(idx.htmlTag, 'area', f); mpush(idx.htmlAttr, 'usemap', f); return\n case 'html-lists':\n for (const t of ['ul', 'ol', 'li', 'dl', 'dt', 'dd']) mpush(idx.htmlTag, t, f)\n return\n case 'html-h1-h6':\n for (const t of ['h1', 'h2', 'h3', 'h4', 'h5', 'h6']) mpush(idx.htmlTag, t, f)\n return\n }\n\n if (slug.startsWith('html-input-')) {\n mpush(idx.htmlInputType, slug.slice('html-input-'.length), f)\n return\n }\n if (slug.startsWith('html-button-')) {\n mpush(idx.htmlButtonType, slug.slice('html-button-'.length), f)\n return\n }\n if (slug.startsWith('html-aria-')) {\n mpush(idx.htmlAttr, slug.slice('html-'.length), f)\n return\n }\n const name = slug.slice('html-'.length)\n if (HTML_ATTR_SLUGS.has(name)) {\n mpush(idx.htmlAttr, name, f)\n return\n }\n mpush(idx.htmlTag, name, f)\n}\n\nexport async function initCompatibility(): Promise<Indexes | null> {\n if (indexes) return indexes\n if (initPromise) return initPromise\n initPromise = (async () => {\n try {\n const res = await fetch(API_URL)\n if (!res.ok) return null\n const data = await res.json()\n const idx = emptyIndexes(data.nicenames?.support ?? {}, data.nicenames?.family ?? {})\n for (const item of data.data ?? []) {\n /**\n * Record every slug's title/url so lint can look up caniemail\n * pages for issues that map to a known feature, even ignored.\n */\n if (item.slug && item.url) idx.bySlug.set(item.slug, { title: item.title, url: item.url })\n /**\n * Index the feature if any cell anywhere in the matrix is non-y.\n * Per-request aggregation (with the active client filter)\n * decides whether to actually surface the issue.\n */\n if (!hasAnyNonY(item.stats)) continue\n const f: Feature = {\n slug: item.slug,\n title: item.title,\n url: item.url,\n category: item.category,\n stats: item.stats,\n }\n classify(f, idx)\n }\n indexes = idx\n return idx\n } catch {\n return null\n }\n })()\n return initPromise\n}\n\n/**\n * Note: fetch of the caniemail dataset is lazy — it fires on the first\n * check request, not at module load, so `server.checks: false` pays\n * no network cost.\n */\n\ninterface FileStreams {\n path: string\n source: string\n template: SfcBlock | null\n styles: SfcBlock[]\n classes: Set<string>\n}\n\nfunction collectStreams(\n filePath: string,\n componentMap: Map<string, string>,\n visited: Set<string>,\n out: FileStreams[],\n) {\n if (visited.has(filePath)) return\n visited.add(filePath)\n\n let source: string\n try {\n source = readFileSync(filePath, 'utf-8')\n } catch { return }\n\n const { template, styles } = parseSfcBlocks(source)\n const classes = new Set<string>()\n if (template) extractClasses(template.content, classes)\n\n out.push({ path: filePath, source, template, styles, classes })\n\n if (template) {\n for (const tag of findComponentTags(template.content)) {\n const cp = componentMap.get(tag.toLowerCase())\n if (cp) collectStreams(cp, componentMap, visited, out)\n }\n }\n}\n\nfunction extractClasses(html: string, out: Set<string>) {\n const parser = new Parser({\n onopentag(_tag, attrs) {\n const c = attrs.class\n if (!c) return\n for (const t of c.split(/\\s+/)) if (t) out.add(t)\n },\n }, { decodeEntities: true })\n parser.write(html)\n parser.end()\n}\n\nfunction parseWithIndices(html: string): ChildNode[] {\n const handler = new DomHandler(undefined, { withStartIndices: true })\n const parser = new Parser(handler)\n parser.write(html)\n parser.end()\n return handler.dom\n}\n\nfunction findStyleNodes(nodes: ChildNode[], out: Element[] = []): Element[] {\n for (const n of nodes) {\n const el = n as Element\n if (el.name === 'style') out.push(el)\n if (el.children?.length) findStyleNodes(el.children as ChildNode[], out)\n }\n return out\n}\n\n/**\n * Parse each file's template, collect every `<style>` node with its source\n * line (via htmlparser2 start indices), then pass the combined DOM through\n * the framework's real Tailwind pipeline. The pipeline resolves imports\n * (@maizzle/tailwindcss), compiles utilities from class attrs, lowers modern\n * CSS via lightningcss, and resolves static calc() — so what we walk matches\n * what ships.\n */\nasync function compileViaPipeline(\n streams: FileStreams[],\n config: MaizzleConfig,\n rootFile: string,\n): Promise<Array<{ file: string, css: string, line: number }>> {\n const all: ChildNode[] = []\n const tracked: Array<{ node: Element, file: string, line: number }> = []\n\n for (const s of streams) {\n if (!s.template) continue\n const templateStart = s.source.indexOf(s.template.content)\n const nodes = parseWithIndices(s.template.content)\n for (const styleNode of findStyleNodes(nodes)) {\n const startIdx = (styleNode as any).startIndex ?? 0\n const line = offsetToLine(s.source, templateStart + startIdx)\n tracked.push({ node: styleNode, file: s.path, line })\n }\n for (const n of nodes) all.push(n)\n }\n\n if (!tracked.length) return []\n\n try {\n await compileWithPipeline(all, config, rootFile)\n } catch { return [] }\n\n return tracked\n .map(t => {\n const txt = t.node.children?.find(c => (c as any).type === 'text') as any\n return txt?.data ? { file: t.file, css: txt.data as string, line: t.line } : null\n })\n .filter((x): x is { file: string, css: string, line: number } => x !== null)\n}\n\n/**\n * Walk CSS AST with detectors. Calls onHit per feature hit.\n * `selector` is the containing rule's selector (undefined if no rule ancestor).\n */\nfunction walkCss(\n css: string,\n idx: Indexes,\n onHit: (feature: Feature, node: { line?: number, selector?: string }) => void,\n) {\n let root: postcss.Root\n try { root = safeParser(css) } catch { return }\n\n const containingSelector = (n: postcss.Node | undefined): string | undefined => {\n let p = n?.parent\n while (p && p.type !== 'root') {\n if (p.type === 'rule') return (p as Rule).selector\n p = p.parent\n }\n return undefined\n }\n\n if (idx.cssComments) {\n root.walkComments((c) => { onHit(idx.cssComments!, { line: c.source?.start?.line, selector: containingSelector(c) }) })\n }\n\n root.walkAtRules((atRule: AtRule) => {\n const line = atRule.source?.start?.line\n let sel = containingSelector(atRule)\n if (atRule.name === 'media' && !sel) {\n const innerSelectors: string[] = []\n atRule.walkRules((r) => { innerSelectors.push(r.selector) })\n if (innerSelectors.length) sel = innerSelectors.join(', ')\n }\n\n if (atRule.name === 'media') {\n /**\n * Pick the most specific media-feature match (prefers-color-scheme,\n * hover, orientation, …). If one matches, skip the generic\n * `css-at-media` to avoid duplicate rows on the same line.\n */\n const specific: Feature[] = []\n if (idx.cssMediaFeature.size) {\n for (const [feat, fs2] of idx.cssMediaFeature) {\n if (atRule.params.includes(`(${feat}`) || atRule.params.includes(feat)) {\n specific.push(...fs2)\n }\n }\n }\n if (specific.length) {\n for (const f of specific) onHit(f, { line, selector: sel })\n } else {\n const fs = idx.cssAtRule.get('media')\n if (fs) for (const f of fs) onHit(f, { line, selector: sel })\n }\n } else {\n const fs = idx.cssAtRule.get(atRule.name)\n if (fs) for (const f of fs) onHit(f, { line, selector: sel })\n }\n })\n\n root.walkRules((rule: Rule) => {\n const line = rule.source?.start?.line\n const sel = rule.selector\n if (idx.cssPseudoClass.size) {\n for (const [name, fs] of idx.cssPseudoClass) {\n const re = new RegExp(`(^|[^:]):${escapeRe(name)}(\\\\b|\\\\()`)\n if (re.test(sel)) for (const f of fs) onHit(f, { line, selector: sel })\n }\n }\n if (idx.cssPseudoElement.size) {\n for (const [name, fs] of idx.cssPseudoElement) {\n const re = new RegExp(`::${escapeRe(name)}\\\\b`)\n if (re.test(sel)) for (const f of fs) onHit(f, { line, selector: sel })\n }\n }\n })\n\n root.walkDecls((decl: Declaration) => {\n const line = decl.source?.start?.line\n const sel = containingSelector(decl)\n const prop = decl.prop\n\n if (idx.cssImportant && decl.important) onHit(idx.cssImportant, { line, selector: sel })\n if (idx.cssVariables && prop.startsWith('--')) onHit(idx.cssVariables, { line, selector: sel })\n\n const fs = idx.cssProp.get(prop)\n if (fs) for (const f of fs) onHit(f, { line, selector: sel })\n\n const pvs = idx.cssPropValue.get(prop)\n if (pvs) {\n const v = decl.value.trim().toLowerCase()\n for (const pv of pvs) if (v === pv.value) onHit(pv.feature, { line, selector: sel })\n }\n\n if (idx.cssFunction.size || idx.cssUnit.size || idx.cssVariables || idx.cssModernColor) {\n try {\n valueParser(decl.value).walk((n) => {\n if (n.type === 'function') {\n const fname = n.value.toLowerCase()\n const fs2 = idx.cssFunction.get(fname)\n if (fs2) for (const f of fs2) onHit(f, { line, selector: sel })\n if (idx.cssVariables && fname === 'var') onHit(idx.cssVariables, { line, selector: sel })\n if (idx.cssModernColor && MODERN_COLOR_FNS.has(fname)) onHit(idx.cssModernColor, { line, selector: sel })\n } else if (n.type === 'word') {\n const m = /^-?\\d*\\.?\\d+([a-z%]+)$/i.exec(n.value)\n if (m) {\n const unit = m[1].toLowerCase()\n const fs2 = idx.cssUnit.get(unit)\n if (fs2) for (const f of fs2) onHit(f, { line, selector: sel })\n }\n }\n })\n } catch {}\n }\n })\n}\n\nconst MODERN_COLOR_FNS = new Set(['oklch', 'oklab', 'lch', 'lab', 'color', 'color-mix', 'hwb'])\n\nfunction escapeRe(s: string): string {\n return s.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&')\n}\n\nfunction offsetToLine(source: string, offset: number): number {\n let line = 1\n for (let i = 0; i < offset && i < source.length; i++) {\n if (source.charCodeAt(i) === 10) line++\n }\n return line\n}\n\nfunction walkTemplate(\n html: string,\n idx: Indexes,\n fileLineOffset: number,\n source: string,\n templateStartOffset: number,\n onHit: (feature: Feature, line: number) => void,\n) {\n const semanticTags = new Set(['article', 'aside', 'details', 'figcaption', 'figure',\n 'footer', 'header', 'main', 'mark', 'nav', 'section', 'time', 'summary'])\n\n /**\n * Stack of tags that opened a body-scope: a literal <body> or a\n * <Teleport to=\"body...\"> whose rendered contents land inside body.\n */\n const bodyScopeStack: string[] = []\n const parser = new Parser({\n onopentag(tag, attrs) {\n const startIdx = (parser as any).startIndex as number\n const line = offsetToLine(source, templateStartOffset + startIdx)\n\n const tagFs = idx.htmlTag.get(tag)\n if (tagFs) for (const f of tagFs) onHit(f, line)\n\n if (idx.htmlSemantics && semanticTags.has(tag)) onHit(idx.htmlSemantics, line)\n\n if (tag === 'style' && bodyScopeStack.length > 0 && idx.htmlStyleInBody) {\n onHit(idx.htmlStyleInBody, line)\n }\n if (tag === 'body') bodyScopeStack.push(tag)\n else if (tag === 'teleport' && /body/i.test(attrs.to ?? '')) bodyScopeStack.push(tag)\n\n for (const attr in attrs) {\n const attrFs = idx.htmlAttr.get(attr)\n if (attrFs) for (const f of attrFs) onHit(f, line)\n }\n\n if (tag === 'input' && attrs.type) {\n const fs = idx.htmlInputType.get(attrs.type.toLowerCase())\n if (fs) for (const f of fs) onHit(f, line)\n }\n if (tag === 'button' && attrs.type) {\n const fs = idx.htmlButtonType.get(attrs.type.toLowerCase())\n if (fs) for (const f of fs) onHit(f, line)\n }\n if (tag === 'a' && attrs.href) {\n const h = attrs.href.trim()\n if (idx.htmlMailtoLinks && /^mailto:/i.test(h)) onHit(idx.htmlMailtoLinks, line)\n else if (idx.htmlAnchorLinks && h.startsWith('#')) onHit(idx.htmlAnchorLinks, line)\n }\n if (tag === 'meta' && idx.htmlMetaColorScheme\n && attrs.name?.toLowerCase() === 'color-scheme') onHit(idx.htmlMetaColorScheme, line)\n\n // Image formats via src / srcset\n if (idx.imageExt.size && (attrs.src || attrs.srcset)) {\n const urls: string[] = []\n if (attrs.src) urls.push(attrs.src)\n if (attrs.srcset) for (const part of attrs.srcset.split(',')) urls.push(part.trim().split(/\\s+/)[0])\n for (const url of urls) {\n const m = /\\.([a-z0-9]+)(?:\\?|#|$)/i.exec(url)\n if (!m) continue\n const fs = idx.imageExt.get(m[1].toLowerCase())\n if (fs) for (const f of fs) onHit(f, line)\n }\n }\n\n // inline style attribute → scan as CSS decl list\n if (attrs.style) scanInlineStyle(attrs.style, idx, line, onHit)\n },\n onclosetag(tag) {\n const top = bodyScopeStack[bodyScopeStack.length - 1]\n if (top === tag) bodyScopeStack.pop()\n },\n onprocessinginstruction(name) {\n if (idx.htmlDoctype && name.toLowerCase() === '!doctype') {\n const startIdx = (parser as any).startIndex as number\n onHit(idx.htmlDoctype, offsetToLine(source, templateStartOffset + startIdx))\n }\n },\n oncomment() {\n if (idx.htmlComments) {\n const startIdx = (parser as any).startIndex as number\n onHit(idx.htmlComments, offsetToLine(source, templateStartOffset + startIdx))\n }\n },\n }, { decodeEntities: false, lowerCaseTags: true, lowerCaseAttributeNames: true })\n\n parser.write(html)\n parser.end()\n}\n\nfunction scanInlineStyle(\n style: string,\n idx: Indexes,\n line: number,\n onHit: (feature: Feature, line: number) => void,\n) {\n // Wrap in a rule so safeParser produces a Root with declarations\n const wrapped = `*{${style}}`\n try {\n const root = safeParser(wrapped)\n root.walkDecls((decl) => {\n if (idx.cssImportant && decl.important) onHit(idx.cssImportant, line)\n const fs = idx.cssProp.get(decl.prop)\n if (fs) for (const f of fs) onHit(f, line)\n if (idx.cssVariables && decl.prop.startsWith('--')) onHit(idx.cssVariables, line)\n const pvs = idx.cssPropValue.get(decl.prop)\n if (pvs) {\n const v = decl.value.trim().toLowerCase()\n for (const pv of pvs) if (v === pv.value) onHit(pv.feature, line)\n }\n if (idx.cssFunction.size || idx.cssUnit.size || idx.cssVariables || idx.cssModernColor) {\n try {\n valueParser(decl.value).walk((n) => {\n if (n.type === 'function') {\n const fname = n.value.toLowerCase()\n const fs2 = idx.cssFunction.get(fname)\n if (fs2) for (const f of fs2) onHit(f, line)\n if (idx.cssVariables && fname === 'var') onHit(idx.cssVariables, line)\n if (idx.cssModernColor && MODERN_COLOR_FNS.has(fname)) onHit(idx.cssModernColor, line)\n } else if (n.type === 'word') {\n const m = /^-?\\d*\\.?\\d+([a-z%]+)$/i.exec(n.value)\n if (m) {\n const fs2 = idx.cssUnit.get(m[1].toLowerCase())\n if (fs2) for (const f of fs2) onHit(f, line)\n }\n }\n })\n } catch {}\n }\n })\n } catch {}\n}\n\nfunction labelFor(idx: Indexes, level: SupportLevel): string {\n const n = idx.nicenames\n if (level === 'unsupported') return n.unsupported ?? 'Not supported'\n if (level === 'mitigated') return n.mitigated ?? 'Partially supported'\n return n.unknown ?? 'Support unknown'\n}\n\nasync function scan(\n rootFile: string,\n config: MaizzleConfig,\n componentDirs: NormalizedComponentSource[],\n allowedClients: Set<string> | 'all',\n): Promise<Issue[]> {\n const idx = await initCompatibility()\n if (!idx) return []\n\n const root = config.root ?? process.cwd()\n const componentMap = await buildComponentMap(root, componentDirs)\n const streams: FileStreams[] = []\n collectStreams(rootFile, componentMap, new Set(), streams)\n\n const issues: Issue[] = []\n const seen = new Set<string>()\n const resolvedCache = new Map<string, { level: SupportLevel, affected: string[] } | null>()\n const resolveSupport = (f: Feature) => {\n let cached = resolvedCache.get(f.slug)\n if (cached === undefined) {\n cached = computeSupport(f.stats, idx.familyNicenames, allowedClients)\n resolvedCache.set(f.slug, cached)\n }\n return cached\n }\n const add = (f: Feature, file: string, line?: number) => {\n const key = `${f.slug}|${file}|${line ?? 0}`\n if (seen.has(key)) return\n const support = resolveSupport(f)\n if (!support) return\n seen.add(key)\n issues.push({\n kind: 'compat',\n slug: f.slug, title: f.title, url: f.url, category: f.category,\n supportLevel: support.level, supportLabel: labelFor(idx, support.level),\n affectedClients: support.affected,\n line, file,\n })\n }\n\n /**\n * Stream A: compiled CSS from real pipeline — reflects shipped output\n * (Tailwind utilities resolved, @maizzle/tailwindcss imported, calc\n * resolved, modern CSS lowered). Filter hits whose containing\n * selector doesn't reference a user class — drops Tailwind\n * preflight noise. For hits without a class selector\n * (e.g. @media, user-written rules), attribute to the\n * file that owned the style block.\n */\n const compiledBlocks = await compileViaPipeline(streams, config, rootFile)\n for (const block of compiledBlocks) {\n walkCss(block.css, idx, (feature, node) => {\n const locations = classLocations(node.selector, streams)\n if (!locations.length) {\n add(feature, block.file, block.line)\n return\n }\n /**\n * @media features collapse to a single source line: the first use\n * of whatever class/variant triggered the wrapper. Other\n * features show up for every occurrence.\n */\n if (feature.slug.startsWith('css-at-media')) {\n add(feature, locations[0].file, locations[0].line)\n } else {\n for (const { file, line } of locations) add(feature, file, line)\n }\n })\n }\n\n // Stream C: source template per file\n for (const s of streams) {\n if (!s.template) continue\n walkTemplate(s.template.content, idx, s.template.offset, s.source,\n s.source.indexOf(s.template.content),\n (feature, line) => add(feature, s.path, line))\n }\n\n return issues\n}\n\n/**\n * Return every (file, line) where any class from the selector appears in a\n * template. Scans every stream so a shared utility class used in multiple\n * components surfaces once per occurrence.\n */\nfunction classLocations(\n selector: string | undefined,\n streams: FileStreams[],\n): Array<{ file: string, line: number }> {\n if (!selector) return []\n const classNames = extractSelectorClasses(selector)\n if (!classNames.length) return []\n const out: Array<{ file: string, line: number }> = []\n const seen = new Set<string>()\n for (const cn of classNames) {\n for (const s of streams) {\n if (!s.classes.has(cn) || !s.template) continue\n const tpl = s.template.content\n const tplStart = s.source.indexOf(tpl)\n let pos = 0\n while (true) {\n const i = tpl.indexOf(cn, pos)\n if (i < 0) break\n pos = i + cn.length\n // Whole-word boundary: adjacent char must be whitespace or quote\n const before = i > 0 ? tpl[i - 1] : ' '\n const after = i + cn.length < tpl.length ? tpl[i + cn.length] : ' '\n if (!isClassBoundary(before) || !isClassBoundary(after)) continue\n const line = offsetToLine(s.source, tplStart + i)\n const key = `${s.path}|${line}`\n if (seen.has(key)) continue\n seen.add(key)\n out.push({ file: s.path, line })\n }\n }\n }\n return out\n}\n\nfunction isClassBoundary(c: string): boolean {\n return c === ' ' || c === '\\t' || c === '\\n' || c === '\\r' || c === '\"' || c === \"'\"\n}\n\nfunction extractSelectorClasses(selector: string): string[] {\n const out: string[] = []\n const re = /\\.((?:\\\\.|[\\w-])+)/g\n let m\n while ((m = re.exec(selector)) !== null) {\n out.push(m[1].replace(/\\\\(.)/g, '$1'))\n }\n return out\n}\n\nconst CATEGORY_ORDER = ['css', 'html', 'image', 'others']\nconst LEVEL_ORDER: Record<string, number> = { error: 0, unsupported: 1, warning: 2, mitigated: 3, unknown: 4 }\n\nfunction orderKey(i: Issue): number {\n if (i.kind === 'lint') return LEVEL_ORDER[i.severity!] ?? 99\n return LEVEL_ORDER[i.supportLevel!] ?? 99\n}\n\nfunction resolveChecksConfig(config: MaizzleConfig) {\n const raw = (config as any).server?.checks\n if (raw === false) return null\n const clients: Set<string> | 'all' = raw?.clients === 'all'\n ? 'all'\n : Array.isArray(raw?.clients) && raw.clients.length\n ? new Set(raw.clients as string[])\n : DEFAULT_CLIENTS\n const level: 'error' | 'warning' | 'lint' | null = raw?.level ?? null\n return { clients, level }\n}\n\nfunction passesLevelFilter(issue: Issue, level: 'error' | 'warning' | 'lint' | null): boolean {\n if (!level) return true\n if (level === 'lint') return issue.kind === 'lint'\n if (issue.kind === 'lint') {\n return level === 'error' ? issue.severity === 'error' : issue.severity === 'warning'\n }\n // compat\n return level === 'error'\n ? issue.supportLevel === 'unsupported'\n : issue.supportLevel === 'mitigated' || issue.supportLevel === 'unknown'\n}\n\nexport async function serveCompatibility(\n url: string,\n res: any,\n config: MaizzleConfig,\n componentDirs: NormalizedComponentSource[],\n) {\n const filePath = url.replace('/__maizzle/compatibility/', '').replace(/\\?.*$/, '')\n const checksCfg = resolveChecksConfig(config)\n try {\n res.setHeader('Content-Type', 'application/json')\n if (!checksCfg) {\n /**\n * Defensive: UI hides the tab using window.__MAIZZLE_CONFIG__ so\n * it shouldn't reach this endpoint when disabled, but if\n * something else does, return an empty list.\n */\n res.end(JSON.stringify([]))\n return\n }\n const absolutePath = resolve(filePath)\n const [compatIssues, lintIssues] = await Promise.all([\n scan(absolutePath, config, componentDirs, checksCfg.clients),\n scanLint(absolutePath, config, componentDirs),\n ])\n\n const idx = await initCompatibility()\n const lintAsIssues: Issue[] = lintIssues.map((li) => {\n const info = li.slug ? idx?.bySlug.get(li.slug) : undefined\n return {\n kind: 'lint',\n slug: li.slug,\n title: li.title,\n url: info?.url,\n category: li.category,\n severity: li.type,\n message: li.message,\n line: li.line,\n file: li.file,\n }\n })\n\n let issues: Issue[] = [...compatIssues, ...lintAsIssues]\n issues = issues.filter((i) => !isFrameworkComponent(i.file))\n if (checksCfg.level) issues = issues.filter((i) => passesLevelFilter(i, checksCfg.level))\n issues.sort((a, b) => {\n const c = CATEGORY_ORDER.indexOf(a.category) - CATEGORY_ORDER.indexOf(b.category)\n if (c) return c\n const l = orderKey(a) - orderKey(b)\n if (l) return l\n return (a.slug ?? a.title).localeCompare(b.slug ?? b.title)\n })\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"],"mappings":"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"}
1
+ {"version":3,"file":"compatibility.js","names":["compileWithPipeline"],"sources":["../../src/server/compatibility.ts"],"sourcesContent":["import { readFileSync } from 'node:fs'\nimport { resolve } from 'node:path'\nimport postcss, { type Declaration, type AtRule, type Rule } from 'postcss'\nimport safeParser from 'postcss-safe-parser'\nimport valueParser from 'postcss-value-parser'\nimport { Parser } from 'htmlparser2'\nimport { DomHandler, type ChildNode, type Element } from 'domhandler'\nimport { parseSfcBlocks, findComponentTags, buildComponentMap, isFrameworkComponent, type SfcBlock } from './sfc-utils.ts'\nimport { scanLint } from './linter.ts'\nimport { tailwindcss as compileWithPipeline } from '../transformers/tailwindcss.ts'\nimport type { MaizzleConfig } from '../types/index.ts'\nimport type { NormalizedComponentSource } from '../utils/componentSources.ts'\n\nconst API_URL = 'https://www.caniemail.com/api/data.json'\nconst DEFAULT_CLIENTS = new Set(['gmail', 'apple-mail', 'outlook', 'yahoo'])\n\ntype SupportLevel = 'unsupported' | 'mitigated' | 'unknown'\n\ninterface Feature {\n slug: string\n title: string\n url: string\n category: string\n stats: any\n}\n\ninterface Issue {\n kind: 'compat' | 'lint'\n slug?: string\n title: string\n url?: string\n category: string\n line?: number\n file: string\n // compat-only\n supportLevel?: SupportLevel\n supportLabel?: string\n affectedClients?: string[]\n // lint-only\n severity?: 'error' | 'warning'\n message?: string\n}\n\ninterface Indexes {\n nicenames: { supported: string, mitigated: string, unsupported: string, unknown: string, mixed: string }\n familyNicenames: Record<string, string>\n cssProp: Map<string, Feature[]>\n cssPropValue: Map<string, Array<{ value: string, feature: Feature }>>\n cssAtRule: Map<string, Feature[]>\n cssMediaFeature: Map<string, Feature[]>\n cssPseudoClass: Map<string, Feature[]>\n cssPseudoElement: Map<string, Feature[]>\n cssFunction: Map<string, Feature[]>\n cssUnit: Map<string, Feature[]>\n cssImportant?: Feature\n cssVariables?: Feature\n cssNesting?: Feature\n cssComments?: Feature\n cssModernColor?: Feature\n htmlTag: Map<string, Feature[]>\n htmlAttr: Map<string, Feature[]>\n htmlInputType: Map<string, Feature[]>\n htmlButtonType: Map<string, Feature[]>\n htmlDoctype?: Feature\n htmlComments?: Feature\n htmlAnchorLinks?: Feature\n htmlMailtoLinks?: Feature\n htmlMetaColorScheme?: Feature\n htmlSemantics?: Feature\n htmlStyleInBody?: Feature\n imageExt: Map<string, Feature[]>\n /** All features by slug — unfiltered, used for URL lookups (e.g. by lint). */\n bySlug: Map<string, { title: string, url: string }>\n}\n\nlet indexes: Indexes | null = null\nlet initPromise: Promise<Indexes | null> | null = null\n\nfunction mpush<K, V>(m: Map<K, V[]>, k: K, v: V) {\n const arr = m.get(k)\n if (arr) arr.push(v)\n else m.set(k, [v])\n}\n\nfunction emptyIndexes(nicenames: any, familyNicenames: Record<string, string>): Indexes {\n return {\n nicenames,\n familyNicenames,\n cssProp: new Map(), cssPropValue: new Map(), cssAtRule: new Map(),\n cssMediaFeature: new Map(), cssPseudoClass: new Map(), cssPseudoElement: new Map(),\n cssFunction: new Map(), cssUnit: new Map(),\n htmlTag: new Map(), htmlAttr: new Map(), htmlInputType: new Map(), htmlButtonType: new Map(),\n imageExt: new Map(),\n bySlug: new Map(),\n }\n}\n\nfunction hasAnyNonY(stats: any): boolean {\n if (!stats) return false\n for (const family in stats) {\n for (const plat in stats[family]) {\n for (const ver in stats[family][plat]) {\n const v = stripNotes(String(stats[family][plat][ver]).trim())\n if (v && v !== 'y') return true\n }\n }\n }\n return false\n}\n\n/** Strip `#N` note markers — `\"y #1\"` → `\"y\"`. Notes document edge cases but\n * don't change support semantics, so treat `y #1` as fully supported. */\nfunction stripNotes(v: string): string {\n return v.split(/\\s+/).filter(t => t && !t.startsWith('#')).join(' ')\n}\n\nfunction computeSupport(stats: any, familyNicenames: Record<string, string>, allowedClients: Set<string> | 'all'): { level: SupportLevel, affected: string[] } | null {\n let nY = 0, nN = 0, nU = 0, nPartial = 0, total = 0\n const affectedFamilies = new Set<string>()\n for (const family in stats) {\n if (allowedClients !== 'all' && !allowedClients.has(family)) continue\n let familyHasNonY = false\n for (const plat in stats[family]) {\n /**\n * Only score the latest version per (family, platform) — legacy\n * versions (Outlook 2007, etc.) otherwise flag modern-widely\n * supported features as partial forever.\n */\n const versions = Object.keys(stats[family][plat]).sort()\n const latest = versions[versions.length - 1]\n if (!latest) continue\n total++\n const v = stripNotes(String(stats[family][plat][latest]).trim())\n if (v === 'y') nY++\n else if (v === 'n') { nN++; familyHasNonY = true }\n else if (v === 'u') { nU++; familyHasNonY = true }\n else { nPartial++; familyHasNonY = true }\n }\n if (familyHasNonY) affectedFamilies.add(family)\n }\n if (!total) return null\n if (nY === total) return null\n const affected = [...affectedFamilies].map(f => familyNicenames[f] ?? f).sort()\n if (nN === total) return { level: 'unsupported', affected }\n if (nU === total) return { level: 'unknown', affected }\n return { level: 'mitigated', affected }\n}\n\n/**\n * Slugs we never report. Fundamental HTML (every email uses these) plus\n * CSS noise that's not actionable (comments, !important usage).\n */\nconst IGNORED_SLUGS = new Set([\n // Required/unavoidable tags\n 'html-doctype', 'html-comments',\n 'html-html', 'html-head', 'html-body', 'html-title',\n 'html-meta', 'html-meta-color-scheme',\n 'html-style', 'html-link',\n 'html-div', 'html-span', 'html-br', 'html-p', 'html-a', 'html-img',\n 'html-table', 'html-tr', 'html-td', 'html-th',\n 'html-thead', 'html-tbody', 'html-tfoot',\n 'html-h1-h6', 'html-lists',\n 'html-strong', 'html-em', 'html-b', 'html-i', 'html-u',\n 'html-semantics',\n // Ubiquitous attributes — always present, caveats aren't actionable.\n 'html-role', 'html-hidden', 'html-width', 'html-height',\n // CSS noise\n 'css-comments', 'css-important',\n /**\n * CSS fundamentals — universally used with known minor caveats; flagging\n * them as \"partial\" is noise rather than signal.\n */\n 'css-margin', 'css-padding', 'css-border',\n 'css-font-size', 'css-font-weight', 'css-font', 'css-font-family',\n 'css-line-height', 'css-letter-spacing', 'css-text-align',\n 'css-text-decoration', 'css-text-transform', 'css-color',\n 'css-background', 'css-background-color',\n 'css-width', 'css-height',\n 'css-display',\n])\n\nfunction classify(f: Feature, idx: Indexes) {\n const slug = f.slug\n /**\n * Retain html-style feature for the body-only detector even though it's\n * blacklisted from the normal html-tag detection path. Title is\n * suffixed so the flag reads as a body-placement warning, not a\n * blanket `<style>`.\n */\n if (slug === 'html-style') {\n idx.htmlStyleInBody = { ...f, title: `${f.title} in <body>` }\n return\n }\n if (IGNORED_SLUGS.has(slug)) return\n\n if (f.category === 'css') return classifyCss(f, slug, idx)\n if (f.category === 'html') return classifyHtml(f, slug, idx)\n if (f.category === 'image') {\n const ext = slug.slice('image-'.length)\n if (ext === 'base64') return\n mpush(idx.imageExt, ext, f)\n }\n // 'others' (amp, bimi) intentionally skipped\n}\n\nfunction classifyCss(f: Feature, slug: string, idx: Indexes) {\n // Specials first\n switch (slug) {\n case 'css-important': idx.cssImportant = f; return\n case 'css-variables': idx.cssVariables = f; return\n case 'css-nesting': idx.cssNesting = f; return\n case 'css-comments': idx.cssComments = f; return\n case 'css-modern-color': idx.cssModernColor = f; return\n case 'css-display-flex': mpushPropValue(idx, 'display', 'flex', f); return\n case 'css-display-grid': mpushPropValue(idx, 'display', 'grid', f); return\n case 'css-display-none': mpushPropValue(idx, 'display', 'none', f); return\n case 'css-rgb': mpush(idx.cssFunction, 'rgb', f); return\n case 'css-rgba': mpush(idx.cssFunction, 'rgba', f); return\n case 'css-linear-gradient': mpush(idx.cssFunction, 'linear-gradient', f); return\n case 'css-radial-gradient': mpush(idx.cssFunction, 'radial-gradient', f); return\n case 'css-conic-gradient': mpush(idx.cssFunction, 'conic-gradient', f); return\n }\n\n if (slug.startsWith('css-at-media-') && slug !== 'css-at-media') {\n mpush(idx.cssMediaFeature, slug.slice('css-at-media-'.length), f)\n return\n }\n if (slug.startsWith('css-at-')) {\n mpush(idx.cssAtRule, slug.slice('css-at-'.length), f)\n return\n }\n if (slug.startsWith('css-pseudo-class-')) {\n mpush(idx.cssPseudoClass, slug.slice('css-pseudo-class-'.length), f)\n return\n }\n if (slug.startsWith('css-pseudo-element-')) {\n mpush(idx.cssPseudoElement, slug.slice('css-pseudo-element-'.length), f)\n return\n }\n if (slug.startsWith('css-unit-')) {\n const u = slug.slice('css-unit-'.length)\n if (u === 'calc') { mpush(idx.cssFunction, 'calc', f); return }\n if (u === 'initial') return // keyword detection is noisy; skip\n const unit = u === 'percent' ? '%' : u\n mpush(idx.cssUnit, unit, f)\n return\n }\n if (slug.startsWith('css-function-')) {\n mpush(idx.cssFunction, slug.slice('css-function-'.length), f)\n return\n }\n // css-selector-* — skip (too broad to detect meaningfully)\n if (slug.startsWith('css-selector-')) return\n\n // Fallback: treat as property name\n mpush(idx.cssProp, slug.slice('css-'.length), f)\n}\n\nfunction mpushPropValue(idx: Indexes, prop: string, value: string, f: Feature) {\n const arr = idx.cssPropValue.get(prop)\n if (arr) arr.push({ value, feature: f })\n else idx.cssPropValue.set(prop, [{ value, feature: f }])\n}\n\nconst HTML_ATTR_SLUGS = new Set([\n 'align', 'background', 'cellpadding', 'cellspacing', 'height', 'width',\n 'valign', 'target', 'srcset', 'lang', 'dir', 'role', 'required', 'hidden',\n])\n\nfunction classifyHtml(f: Feature, slug: string, idx: Indexes) {\n // Specials\n switch (slug) {\n case 'html-doctype': idx.htmlDoctype = f; return\n case 'html-comments': idx.htmlComments = f; return\n case 'html-anchor-links': idx.htmlAnchorLinks = f; return\n case 'html-mailto-links': idx.htmlMailtoLinks = f; return\n case 'html-meta-color-scheme': idx.htmlMetaColorScheme = f; return\n case 'html-semantics': idx.htmlSemantics = f; return\n case 'html-loading-attribute': mpush(idx.htmlAttr, 'loading', f); return\n case 'html-image-maps':\n mpush(idx.htmlTag, 'map', f); mpush(idx.htmlTag, 'area', f); mpush(idx.htmlAttr, 'usemap', f); return\n case 'html-lists':\n for (const t of ['ul', 'ol', 'li', 'dl', 'dt', 'dd']) mpush(idx.htmlTag, t, f)\n return\n case 'html-h1-h6':\n for (const t of ['h1', 'h2', 'h3', 'h4', 'h5', 'h6']) mpush(idx.htmlTag, t, f)\n return\n }\n\n if (slug.startsWith('html-input-')) {\n mpush(idx.htmlInputType, slug.slice('html-input-'.length), f)\n return\n }\n if (slug.startsWith('html-button-')) {\n mpush(idx.htmlButtonType, slug.slice('html-button-'.length), f)\n return\n }\n if (slug.startsWith('html-aria-')) {\n mpush(idx.htmlAttr, slug.slice('html-'.length), f)\n return\n }\n const name = slug.slice('html-'.length)\n if (HTML_ATTR_SLUGS.has(name)) {\n mpush(idx.htmlAttr, name, f)\n return\n }\n mpush(idx.htmlTag, name, f)\n}\n\nexport async function initCompatibility(): Promise<Indexes | null> {\n if (indexes) return indexes\n if (initPromise) return initPromise\n initPromise = (async () => {\n try {\n const res = await fetch(API_URL)\n if (!res.ok) return null\n const data = await res.json()\n const idx = emptyIndexes(data.nicenames?.support ?? {}, data.nicenames?.family ?? {})\n for (const item of data.data ?? []) {\n /**\n * Record every slug's title/url so lint can look up caniemail\n * pages for issues that map to a known feature, even ignored.\n */\n if (item.slug && item.url) idx.bySlug.set(item.slug, { title: item.title, url: item.url })\n /**\n * Index the feature if any cell anywhere in the matrix is non-y.\n * Per-request aggregation (with the active client filter)\n * decides whether to actually surface the issue.\n */\n if (!hasAnyNonY(item.stats)) continue\n const f: Feature = {\n slug: item.slug,\n title: item.title,\n url: item.url,\n category: item.category,\n stats: item.stats,\n }\n classify(f, idx)\n }\n indexes = idx\n return idx\n } catch {\n return null\n }\n })()\n return initPromise\n}\n\n/**\n * Note: fetch of the caniemail dataset is lazy — it fires on the first\n * check request, not at module load, so `server.checks: false` pays\n * no network cost.\n */\n\ninterface FileStreams {\n path: string\n source: string\n template: SfcBlock | null\n styles: SfcBlock[]\n classes: Set<string>\n}\n\nfunction collectStreams(\n filePath: string,\n componentMap: Map<string, string>,\n visited: Set<string>,\n out: FileStreams[],\n) {\n if (visited.has(filePath)) return\n visited.add(filePath)\n\n let source: string\n try {\n source = readFileSync(filePath, 'utf-8')\n } catch { return }\n\n const { template, styles } = parseSfcBlocks(source)\n const classes = new Set<string>()\n if (template) extractClasses(template.content, classes)\n\n out.push({ path: filePath, source, template, styles, classes })\n\n if (template) {\n for (const tag of findComponentTags(template.content)) {\n const cp = componentMap.get(tag.toLowerCase())\n if (cp) collectStreams(cp, componentMap, visited, out)\n }\n }\n}\n\nfunction extractClasses(html: string, out: Set<string>) {\n const parser = new Parser({\n onopentag(_tag, attrs) {\n const c = attrs.class\n if (!c) return\n for (const t of c.split(/\\s+/)) if (t) out.add(t)\n },\n }, { decodeEntities: true })\n parser.write(html)\n parser.end()\n}\n\nfunction parseWithIndices(html: string): ChildNode[] {\n const handler = new DomHandler(undefined, { withStartIndices: true })\n const parser = new Parser(handler)\n parser.write(html)\n parser.end()\n return handler.dom\n}\n\nfunction findStyleNodes(nodes: ChildNode[], out: Element[] = []): Element[] {\n for (const n of nodes) {\n const el = n as Element\n if (el.name === 'style') out.push(el)\n if (el.children?.length) findStyleNodes(el.children as ChildNode[], out)\n }\n return out\n}\n\n/**\n * Parse each file's template, collect every `<style>` node with its source\n * line (via htmlparser2 start indices), then pass the combined DOM through\n * the framework's real Tailwind pipeline. The pipeline resolves imports\n * (@maizzle/tailwindcss), compiles utilities from class attrs, lowers modern\n * CSS via lightningcss, and resolves static calc() — so what we walk matches\n * what ships.\n */\nasync function compileViaPipeline(\n streams: FileStreams[],\n config: MaizzleConfig,\n rootFile: string,\n): Promise<Array<{ file: string, css: string, line: number }>> {\n const all: ChildNode[] = []\n const tracked: Array<{ node: Element, file: string, line: number }> = []\n\n for (const s of streams) {\n if (!s.template) continue\n const templateStart = s.source.indexOf(s.template.content)\n const nodes = parseWithIndices(s.template.content)\n for (const styleNode of findStyleNodes(nodes)) {\n const startIdx = (styleNode as any).startIndex ?? 0\n const line = offsetToLine(s.source, templateStart + startIdx)\n tracked.push({ node: styleNode, file: s.path, line })\n }\n for (const n of nodes) all.push(n)\n }\n\n if (!tracked.length) return []\n\n try {\n await compileWithPipeline(all, config, rootFile)\n } catch { return [] }\n\n return tracked\n .map(t => {\n const txt = t.node.children?.find(c => (c as any).type === 'text') as any\n return txt?.data ? { file: t.file, css: txt.data as string, line: t.line } : null\n })\n .filter((x): x is { file: string, css: string, line: number } => x !== null)\n}\n\n/**\n * Walk CSS AST with detectors. Calls onHit per feature hit.\n * `selector` is the containing rule's selector (undefined if no rule ancestor).\n */\nfunction walkCss(\n css: string,\n idx: Indexes,\n onHit: (feature: Feature, node: { line?: number, selector?: string }) => void,\n) {\n let root: postcss.Root\n try { root = safeParser(css) } catch { return }\n\n const containingSelector = (n: postcss.Node | undefined): string | undefined => {\n let p = n?.parent\n while (p && p.type !== 'root') {\n if (p.type === 'rule') return (p as Rule).selector\n p = p.parent\n }\n return undefined\n }\n\n if (idx.cssComments) {\n root.walkComments((c) => { onHit(idx.cssComments!, { line: c.source?.start?.line, selector: containingSelector(c) }) })\n }\n\n root.walkAtRules((atRule: AtRule) => {\n const line = atRule.source?.start?.line\n let sel = containingSelector(atRule)\n if (atRule.name === 'media' && !sel) {\n const innerSelectors: string[] = []\n atRule.walkRules((r) => { innerSelectors.push(r.selector) })\n if (innerSelectors.length) sel = innerSelectors.join(', ')\n }\n\n if (atRule.name === 'media') {\n /**\n * Pick the most specific media-feature match (prefers-color-scheme,\n * hover, orientation, …). If one matches, skip the generic\n * `css-at-media` to avoid duplicate rows on the same line.\n */\n const specific: Feature[] = []\n if (idx.cssMediaFeature.size) {\n for (const [feat, fs2] of idx.cssMediaFeature) {\n if (atRule.params.includes(`(${feat}`) || atRule.params.includes(feat)) {\n specific.push(...fs2)\n }\n }\n }\n if (specific.length) {\n for (const f of specific) onHit(f, { line, selector: sel })\n } else {\n const fs = idx.cssAtRule.get('media')\n if (fs) for (const f of fs) onHit(f, { line, selector: sel })\n }\n } else {\n const fs = idx.cssAtRule.get(atRule.name)\n if (fs) for (const f of fs) onHit(f, { line, selector: sel })\n }\n })\n\n root.walkRules((rule: Rule) => {\n const line = rule.source?.start?.line\n const sel = rule.selector\n if (idx.cssPseudoClass.size) {\n for (const [name, fs] of idx.cssPseudoClass) {\n const re = new RegExp(`(^|[^:]):${escapeRe(name)}(\\\\b|\\\\()`)\n if (re.test(sel)) for (const f of fs) onHit(f, { line, selector: sel })\n }\n }\n if (idx.cssPseudoElement.size) {\n for (const [name, fs] of idx.cssPseudoElement) {\n const re = new RegExp(`::${escapeRe(name)}\\\\b`)\n if (re.test(sel)) for (const f of fs) onHit(f, { line, selector: sel })\n }\n }\n })\n\n root.walkDecls((decl: Declaration) => {\n const line = decl.source?.start?.line\n const sel = containingSelector(decl)\n const prop = decl.prop\n\n if (idx.cssImportant && decl.important) onHit(idx.cssImportant, { line, selector: sel })\n if (idx.cssVariables && prop.startsWith('--')) onHit(idx.cssVariables, { line, selector: sel })\n\n const fs = idx.cssProp.get(prop)\n if (fs) for (const f of fs) onHit(f, { line, selector: sel })\n\n const pvs = idx.cssPropValue.get(prop)\n if (pvs) {\n const v = decl.value.trim().toLowerCase()\n for (const pv of pvs) if (v === pv.value) onHit(pv.feature, { line, selector: sel })\n }\n\n if (idx.cssFunction.size || idx.cssUnit.size || idx.cssVariables || idx.cssModernColor) {\n try {\n valueParser(decl.value).walk((n) => {\n if (n.type === 'function') {\n const fname = n.value.toLowerCase()\n const fs2 = idx.cssFunction.get(fname)\n if (fs2) for (const f of fs2) onHit(f, { line, selector: sel })\n if (idx.cssVariables && fname === 'var') onHit(idx.cssVariables, { line, selector: sel })\n if (idx.cssModernColor && MODERN_COLOR_FNS.has(fname)) onHit(idx.cssModernColor, { line, selector: sel })\n } else if (n.type === 'word') {\n const m = /^-?\\d*\\.?\\d+([a-z%]+)$/i.exec(n.value)\n if (m) {\n const unit = m[1].toLowerCase()\n const fs2 = idx.cssUnit.get(unit)\n if (fs2) for (const f of fs2) onHit(f, { line, selector: sel })\n }\n }\n })\n } catch {}\n }\n })\n}\n\nconst MODERN_COLOR_FNS = new Set(['oklch', 'oklab', 'lch', 'lab', 'color', 'color-mix', 'hwb'])\n\nfunction escapeRe(s: string): string {\n return s.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&')\n}\n\nfunction offsetToLine(source: string, offset: number): number {\n let line = 1\n for (let i = 0; i < offset && i < source.length; i++) {\n if (source.charCodeAt(i) === 10) line++\n }\n return line\n}\n\nfunction walkTemplate(\n html: string,\n idx: Indexes,\n fileLineOffset: number,\n source: string,\n templateStartOffset: number,\n onHit: (feature: Feature, line: number) => void,\n) {\n const semanticTags = new Set(['article', 'aside', 'details', 'figcaption', 'figure',\n 'footer', 'header', 'main', 'mark', 'nav', 'section', 'time', 'summary'])\n\n /**\n * Stack of tags that opened a body-scope: a literal <body> or a\n * <Teleport to=\"body...\"> whose rendered contents land inside body.\n */\n const bodyScopeStack: string[] = []\n const parser = new Parser({\n onopentag(tag, attrs) {\n const startIdx = (parser as any).startIndex as number\n const line = offsetToLine(source, templateStartOffset + startIdx)\n\n const tagFs = idx.htmlTag.get(tag)\n if (tagFs) for (const f of tagFs) onHit(f, line)\n\n if (idx.htmlSemantics && semanticTags.has(tag)) onHit(idx.htmlSemantics, line)\n\n if (tag === 'style' && bodyScopeStack.length > 0 && idx.htmlStyleInBody) {\n onHit(idx.htmlStyleInBody, line)\n }\n if (tag === 'body') bodyScopeStack.push(tag)\n else if (tag === 'teleport' && /body/i.test(attrs.to ?? '')) bodyScopeStack.push(tag)\n\n for (const attr in attrs) {\n const attrFs = idx.htmlAttr.get(attr)\n if (attrFs) for (const f of attrFs) onHit(f, line)\n }\n\n if (tag === 'input' && attrs.type) {\n const fs = idx.htmlInputType.get(attrs.type.toLowerCase())\n if (fs) for (const f of fs) onHit(f, line)\n }\n if (tag === 'button' && attrs.type) {\n const fs = idx.htmlButtonType.get(attrs.type.toLowerCase())\n if (fs) for (const f of fs) onHit(f, line)\n }\n if (tag === 'a' && attrs.href) {\n const h = attrs.href.trim()\n if (idx.htmlMailtoLinks && /^mailto:/i.test(h)) onHit(idx.htmlMailtoLinks, line)\n else if (idx.htmlAnchorLinks && h.startsWith('#')) onHit(idx.htmlAnchorLinks, line)\n }\n if (tag === 'meta' && idx.htmlMetaColorScheme\n && attrs.name?.toLowerCase() === 'color-scheme') onHit(idx.htmlMetaColorScheme, line)\n\n // Image formats via src / srcset\n if (idx.imageExt.size && (attrs.src || attrs.srcset)) {\n const urls: string[] = []\n if (attrs.src) urls.push(attrs.src)\n if (attrs.srcset) for (const part of attrs.srcset.split(',')) urls.push(part.trim().split(/\\s+/)[0])\n for (const url of urls) {\n const m = /\\.([a-z0-9]+)(?:\\?|#|$)/i.exec(url)\n if (!m) continue\n const fs = idx.imageExt.get(m[1].toLowerCase())\n if (fs) for (const f of fs) onHit(f, line)\n }\n }\n\n // inline style attribute → scan as CSS decl list\n if (attrs.style) scanInlineStyle(attrs.style, idx, line, onHit)\n },\n onclosetag(tag) {\n const top = bodyScopeStack[bodyScopeStack.length - 1]\n if (top === tag) bodyScopeStack.pop()\n },\n onprocessinginstruction(name) {\n if (idx.htmlDoctype && name.toLowerCase() === '!doctype') {\n const startIdx = (parser as any).startIndex as number\n onHit(idx.htmlDoctype, offsetToLine(source, templateStartOffset + startIdx))\n }\n },\n oncomment() {\n if (idx.htmlComments) {\n const startIdx = (parser as any).startIndex as number\n onHit(idx.htmlComments, offsetToLine(source, templateStartOffset + startIdx))\n }\n },\n }, { decodeEntities: false, lowerCaseTags: true, lowerCaseAttributeNames: true })\n\n parser.write(html)\n parser.end()\n}\n\nfunction scanInlineStyle(\n style: string,\n idx: Indexes,\n line: number,\n onHit: (feature: Feature, line: number) => void,\n) {\n // Wrap in a rule so safeParser produces a Root with declarations\n const wrapped = `*{${style}}`\n try {\n const root = safeParser(wrapped)\n root.walkDecls((decl) => {\n if (idx.cssImportant && decl.important) onHit(idx.cssImportant, line)\n const fs = idx.cssProp.get(decl.prop)\n if (fs) for (const f of fs) onHit(f, line)\n if (idx.cssVariables && decl.prop.startsWith('--')) onHit(idx.cssVariables, line)\n const pvs = idx.cssPropValue.get(decl.prop)\n if (pvs) {\n const v = decl.value.trim().toLowerCase()\n for (const pv of pvs) if (v === pv.value) onHit(pv.feature, line)\n }\n if (idx.cssFunction.size || idx.cssUnit.size || idx.cssVariables || idx.cssModernColor) {\n try {\n valueParser(decl.value).walk((n) => {\n if (n.type === 'function') {\n const fname = n.value.toLowerCase()\n const fs2 = idx.cssFunction.get(fname)\n if (fs2) for (const f of fs2) onHit(f, line)\n if (idx.cssVariables && fname === 'var') onHit(idx.cssVariables, line)\n if (idx.cssModernColor && MODERN_COLOR_FNS.has(fname)) onHit(idx.cssModernColor, line)\n } else if (n.type === 'word') {\n const m = /^-?\\d*\\.?\\d+([a-z%]+)$/i.exec(n.value)\n if (m) {\n const fs2 = idx.cssUnit.get(m[1].toLowerCase())\n if (fs2) for (const f of fs2) onHit(f, line)\n }\n }\n })\n } catch {}\n }\n })\n } catch {}\n}\n\nfunction labelFor(idx: Indexes, level: SupportLevel): string {\n const n = idx.nicenames\n if (level === 'unsupported') return n.unsupported ?? 'Not supported'\n if (level === 'mitigated') return n.mitigated ?? 'Partially supported'\n return n.unknown ?? 'Support unknown'\n}\n\nasync function scan(\n rootFile: string,\n config: MaizzleConfig,\n componentDirs: NormalizedComponentSource[],\n allowedClients: Set<string> | 'all',\n): Promise<Issue[]> {\n const idx = await initCompatibility()\n if (!idx) return []\n\n const root = config.root ?? process.cwd()\n const componentMap = await buildComponentMap(root, componentDirs)\n const streams: FileStreams[] = []\n collectStreams(rootFile, componentMap, new Set(), streams)\n\n const issues: Issue[] = []\n const seen = new Set<string>()\n const resolvedCache = new Map<string, { level: SupportLevel, affected: string[] } | null>()\n const resolveSupport = (f: Feature) => {\n let cached = resolvedCache.get(f.slug)\n if (cached === undefined) {\n cached = computeSupport(f.stats, idx.familyNicenames, allowedClients)\n resolvedCache.set(f.slug, cached)\n }\n return cached\n }\n const add = (f: Feature, file: string, line?: number) => {\n const key = `${f.slug}|${file}|${line ?? 0}`\n if (seen.has(key)) return\n const support = resolveSupport(f)\n if (!support) return\n seen.add(key)\n issues.push({\n kind: 'compat',\n slug: f.slug, title: f.title, url: f.url, category: f.category,\n supportLevel: support.level, supportLabel: labelFor(idx, support.level),\n affectedClients: support.affected,\n line, file,\n })\n }\n\n /**\n * Stream A: compiled CSS from real pipeline — reflects shipped output\n * (Tailwind utilities resolved, @maizzle/tailwindcss imported, calc\n * resolved, modern CSS lowered). Filter hits whose containing\n * selector doesn't reference a user class — drops Tailwind\n * preflight noise. For hits without a class selector\n * (e.g. @media, user-written rules), attribute to the\n * file that owned the style block.\n */\n const compiledBlocks = await compileViaPipeline(streams, config, rootFile)\n for (const block of compiledBlocks) {\n walkCss(block.css, idx, (feature, node) => {\n const locations = classLocations(node.selector, streams)\n if (!locations.length) {\n add(feature, block.file, block.line)\n return\n }\n /**\n * @media features collapse to a single source line: the first use\n * of whatever class/variant triggered the wrapper. Other\n * features show up for every occurrence.\n */\n if (feature.slug.startsWith('css-at-media')) {\n add(feature, locations[0].file, locations[0].line)\n } else {\n for (const { file, line } of locations) add(feature, file, line)\n }\n })\n }\n\n // Stream C: source template per file\n for (const s of streams) {\n if (!s.template) continue\n walkTemplate(s.template.content, idx, s.template.offset, s.source,\n s.source.indexOf(s.template.content),\n (feature, line) => add(feature, s.path, line))\n }\n\n return issues\n}\n\n/**\n * Return every (file, line) where any class from the selector appears in a\n * template. Scans every stream so a shared utility class used in multiple\n * components surfaces once per occurrence.\n */\nfunction classLocations(\n selector: string | undefined,\n streams: FileStreams[],\n): Array<{ file: string, line: number }> {\n if (!selector) return []\n const classNames = extractSelectorClasses(selector)\n if (!classNames.length) return []\n const out: Array<{ file: string, line: number }> = []\n const seen = new Set<string>()\n for (const cn of classNames) {\n for (const s of streams) {\n if (!s.classes.has(cn) || !s.template) continue\n const tpl = s.template.content\n const tplStart = s.source.indexOf(tpl)\n let pos = 0\n while (true) {\n const i = tpl.indexOf(cn, pos)\n if (i < 0) break\n pos = i + cn.length\n // Whole-word boundary: adjacent char must be whitespace or quote\n const before = i > 0 ? tpl[i - 1] : ' '\n const after = i + cn.length < tpl.length ? tpl[i + cn.length] : ' '\n if (!isClassBoundary(before) || !isClassBoundary(after)) continue\n const line = offsetToLine(s.source, tplStart + i)\n const key = `${s.path}|${line}`\n if (seen.has(key)) continue\n seen.add(key)\n out.push({ file: s.path, line })\n }\n }\n }\n return out\n}\n\nfunction isClassBoundary(c: string): boolean {\n return c === ' ' || c === '\\t' || c === '\\n' || c === '\\r' || c === '\"' || c === \"'\"\n}\n\nfunction extractSelectorClasses(selector: string): string[] {\n const out: string[] = []\n const re = /\\.((?:\\\\.|[\\w-])+)/g\n let m\n while ((m = re.exec(selector)) !== null) {\n out.push(m[1].replace(/\\\\(.)/g, '$1'))\n }\n return out\n}\n\nconst CATEGORY_ORDER = ['css', 'html', 'image', 'others']\nconst LEVEL_ORDER: Record<string, number> = { error: 0, unsupported: 1, warning: 2, mitigated: 3, unknown: 4 }\n\nfunction orderKey(i: Issue): number {\n if (i.kind === 'lint') return LEVEL_ORDER[i.severity!] ?? 99\n return LEVEL_ORDER[i.supportLevel!] ?? 99\n}\n\nfunction resolveChecksConfig(config: MaizzleConfig) {\n const raw = (config as any).server?.checks\n if (raw === false) return null\n const clients: Set<string> | 'all' = raw?.clients === 'all'\n ? 'all'\n : Array.isArray(raw?.clients) && raw.clients.length\n ? new Set(raw.clients as string[])\n : DEFAULT_CLIENTS\n const level: 'error' | 'warning' | 'lint' | null = raw?.level ?? null\n return { clients, level }\n}\n\nfunction passesLevelFilter(issue: Issue, level: 'error' | 'warning' | 'lint' | null): boolean {\n if (!level) return true\n if (level === 'lint') return issue.kind === 'lint'\n if (issue.kind === 'lint') {\n return level === 'error' ? issue.severity === 'error' : issue.severity === 'warning'\n }\n // compat\n return level === 'error'\n ? issue.supportLevel === 'unsupported'\n : issue.supportLevel === 'mitigated' || issue.supportLevel === 'unknown'\n}\n\nexport async function serveCompatibility(\n url: string,\n res: any,\n config: MaizzleConfig,\n componentDirs: NormalizedComponentSource[],\n) {\n const filePath = url.replace('/__maizzle/compatibility/', '').replace(/\\?.*$/, '')\n const checksCfg = resolveChecksConfig(config)\n try {\n res.setHeader('Content-Type', 'application/json')\n if (!checksCfg) {\n /**\n * Defensive: UI hides the tab using window.__MAIZZLE_CONFIG__ so\n * it shouldn't reach this endpoint when disabled, but if\n * something else does, return an empty list.\n */\n res.end(JSON.stringify([]))\n return\n }\n const absolutePath = resolve(filePath)\n const [compatIssues, lintIssues] = await Promise.all([\n scan(absolutePath, config, componentDirs, checksCfg.clients),\n scanLint(absolutePath, config, componentDirs),\n ])\n\n const idx = await initCompatibility()\n const lintAsIssues: Issue[] = lintIssues.map((li) => {\n const info = li.slug ? idx?.bySlug.get(li.slug) : undefined\n return {\n kind: 'lint',\n slug: li.slug,\n title: li.title,\n url: info?.url,\n category: li.category,\n severity: li.type,\n message: li.message,\n line: li.line,\n file: li.file,\n }\n })\n\n let issues: Issue[] = [...compatIssues, ...lintAsIssues]\n issues = issues.filter((i) => !isFrameworkComponent(i.file))\n if (checksCfg.level) issues = issues.filter((i) => passesLevelFilter(i, checksCfg.level))\n issues.sort((a, b) => {\n const c = CATEGORY_ORDER.indexOf(a.category) - CATEGORY_ORDER.indexOf(b.category)\n if (c) return c\n const l = orderKey(a) - orderKey(b)\n if (l) return l\n return (a.slug ?? a.title).localeCompare(b.slug ?? b.title)\n })\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"],"mappings":"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"}
@@ -23,7 +23,8 @@ function tableRoleAutoAdded(config) {
23
23
  return true;
24
24
  }
25
25
  async function scanLint(rootFile, config, componentDirs) {
26
- const componentMap = await buildComponentMap(config.root ?? process.cwd(), componentDirs);
26
+ const root = config.root ?? process.cwd();
27
+ const componentMap = await buildComponentMap(root, componentDirs);
27
28
  const visited = /* @__PURE__ */ new Set();
28
29
  const presence = {
29
30
  html: false,