@maizzle/framework 6.1.3 → 6.1.5
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.
- package/dist/build.d.ts +3 -4
- package/dist/build.d.ts.map +1 -1
- package/dist/build.js +1 -5
- package/dist/build.js.map +1 -1
- package/dist/components/Outlook.vue +8 -2
- package/dist/components/utils.d.ts +10 -11
- package/dist/components/utils.d.ts.map +1 -1
- package/dist/composables/defineConfig.d.ts +1 -2
- package/dist/composables/defineConfig.d.ts.map +1 -1
- package/dist/composables/renderContext.d.ts +4 -5
- package/dist/composables/renderContext.d.ts.map +1 -1
- package/dist/composables/useBaseUrl.d.ts +1 -2
- package/dist/composables/useBaseUrl.d.ts.map +1 -1
- package/dist/composables/useConfig.d.ts +2 -3
- package/dist/composables/useConfig.d.ts.map +1 -1
- package/dist/composables/useCurrentTemplate.d.ts +2 -3
- package/dist/composables/useCurrentTemplate.d.ts.map +1 -1
- package/dist/composables/useDoctype.d.ts +1 -2
- package/dist/composables/useDoctype.d.ts.map +1 -1
- package/dist/composables/useEvent.d.ts +1 -2
- package/dist/composables/useEvent.d.ts.map +1 -1
- package/dist/composables/useFont.d.ts +3 -4
- package/dist/composables/useFont.d.ts.map +1 -1
- package/dist/composables/useOutlookFallback.d.ts +1 -2
- package/dist/composables/useOutlookFallback.d.ts.map +1 -1
- package/dist/composables/useOutputPath.d.ts +1 -2
- package/dist/composables/useOutputPath.d.ts.map +1 -1
- package/dist/composables/usePlaintext.d.ts +2 -3
- package/dist/composables/usePlaintext.d.ts.map +1 -1
- package/dist/composables/usePreheader.d.ts +2 -3
- package/dist/composables/usePreheader.d.ts.map +1 -1
- package/dist/composables/useTransformers.d.ts +1 -2
- package/dist/composables/useTransformers.d.ts.map +1 -1
- package/dist/composables/useUrlQuery.d.ts +1 -2
- package/dist/composables/useUrlQuery.d.ts.map +1 -1
- package/dist/config/defaults.d.ts +1 -2
- package/dist/config/defaults.d.ts.map +1 -1
- package/dist/config/index.d.ts +4 -4
- package/dist/config/index.d.ts.map +1 -1
- package/dist/events/index.d.ts +4 -5
- package/dist/events/index.d.ts.map +1 -1
- package/dist/plaintext.d.ts +1 -2
- package/dist/plaintext.d.ts.map +1 -1
- package/dist/plugin.d.ts +1 -2
- package/dist/plugin.d.ts.map +1 -1
- package/dist/plugins/postcss/flattenGradients.d.ts +3 -3
- package/dist/plugins/postcss/flattenGradients.d.ts.map +1 -1
- package/dist/plugins/postcss/mergeMediaQueries.d.ts +1 -2
- package/dist/plugins/postcss/mergeMediaQueries.d.ts.map +1 -1
- package/dist/plugins/postcss/pruneVars.d.ts +2 -2
- package/dist/plugins/postcss/pruneVars.d.ts.map +1 -1
- package/dist/plugins/postcss/quoteFontFamilies.d.ts +2 -3
- package/dist/plugins/postcss/quoteFontFamilies.d.ts.map +1 -1
- package/dist/plugins/postcss/removeDeclarations.d.ts +4 -4
- package/dist/plugins/postcss/removeDeclarations.d.ts.map +1 -1
- package/dist/plugins/postcss/resolveMaizzleImports.d.ts +1 -2
- package/dist/plugins/postcss/resolveMaizzleImports.d.ts.map +1 -1
- package/dist/plugins/postcss/resolveProps.d.ts +2 -2
- package/dist/plugins/postcss/resolveProps.d.ts.map +1 -1
- package/dist/plugins/postcss/tailwindCleanup.d.ts +1 -2
- package/dist/plugins/postcss/tailwindCleanup.d.ts.map +1 -1
- package/dist/prepare.d.ts +2 -3
- package/dist/prepare.d.ts.map +1 -1
- package/dist/render/active.d.ts +2 -3
- package/dist/render/active.d.ts.map +1 -1
- package/dist/render/buildTemplate.d.ts +5 -6
- package/dist/render/buildTemplate.d.ts.map +1 -1
- package/dist/render/buildTemplate.js +1 -1
- package/dist/render/buildTemplate.js.map +1 -1
- package/dist/render/createRenderer.d.ts +4 -5
- package/dist/render/createRenderer.d.ts.map +1 -1
- package/dist/render/index.d.ts +3 -3
- package/dist/render/index.d.ts.map +1 -1
- package/dist/render/index.js +1 -1
- package/dist/render/index.js.map +1 -1
- package/dist/render/injectFonts.d.ts +1 -2
- package/dist/render/injectFonts.d.ts.map +1 -1
- package/dist/render/parallel/buildWorker.d.ts +3 -4
- package/dist/render/parallel/buildWorker.d.ts.map +1 -1
- package/dist/render/plugins/codeBlockExtract.d.ts +1 -2
- package/dist/render/plugins/codeBlockExtract.d.ts.map +1 -1
- package/dist/render/plugins/markdownExtract.d.ts +1 -2
- package/dist/render/plugins/markdownExtract.d.ts.map +1 -1
- package/dist/render/plugins/rawExtract.d.ts +1 -2
- package/dist/render/plugins/rawExtract.d.ts.map +1 -1
- package/dist/render/plugins/rowSourceLocation.d.ts +1 -2
- package/dist/render/plugins/rowSourceLocation.d.ts.map +1 -1
- package/dist/serve.d.ts +3 -4
- package/dist/serve.d.ts.map +1 -1
- package/dist/serve.js +47 -4
- package/dist/serve.js.map +1 -1
- package/dist/server/compatibility.d.ts +2 -3
- package/dist/server/compatibility.d.ts.map +1 -1
- package/dist/server/email.d.ts +2 -3
- package/dist/server/email.d.ts.map +1 -1
- package/dist/server/linter.d.ts +3 -4
- package/dist/server/linter.d.ts.map +1 -1
- package/dist/server/sfc-utils.d.ts +6 -7
- package/dist/server/sfc-utils.d.ts.map +1 -1
- package/dist/server/static.d.ts +10 -0
- package/dist/server/static.d.ts.map +1 -0
- package/dist/server/static.js +71 -0
- package/dist/server/static.js.map +1 -0
- package/dist/server/ui/.vite/deps/@lucide_vue.js +1 -1
- package/dist/server/ui/.vite/deps/@vueuse_core.js +1 -1
- package/dist/server/ui/.vite/deps/@vueuse_shared.js +1 -1
- package/dist/server/ui/.vite/deps/_metadata.json +15 -15
- package/dist/server/ui/.vite/deps/reka-ui.js +1 -2
- package/dist/server/ui/.vite/deps/reka-ui.js.map +1 -1
- package/dist/server/ui/.vite/deps/vue-router.js +1 -1
- package/dist/server/ui/.vite/deps/vue.js +1 -1
- package/dist/server/ui/.vite/deps/{vue.runtime.esm-bundler-S54atuNJ.js → vue.runtime.esm-bundler-Dq07uCLt.js} +174 -53
- package/dist/server/ui/.vite/deps/vue.runtime.esm-bundler-Dq07uCLt.js.map +1 -0
- package/dist/tests/render/_helpers.d.ts +2 -3
- package/dist/tests/render/_helpers.d.ts.map +1 -1
- package/dist/transformers/addAttributes.d.ts +2 -3
- package/dist/transformers/addAttributes.d.ts.map +1 -1
- package/dist/transformers/attributeToStyle.d.ts +2 -3
- package/dist/transformers/attributeToStyle.d.ts.map +1 -1
- package/dist/transformers/base.d.ts +3 -4
- package/dist/transformers/base.d.ts.map +1 -1
- package/dist/transformers/columnWidth.d.ts +1 -2
- package/dist/transformers/columnWidth.d.ts.map +1 -1
- package/dist/transformers/entities.d.ts +3 -4
- package/dist/transformers/entities.d.ts.map +1 -1
- package/dist/transformers/filters/defaults.d.ts +2 -3
- package/dist/transformers/filters/defaults.d.ts.map +1 -1
- package/dist/transformers/filters/index.d.ts +4 -4
- package/dist/transformers/filters/index.d.ts.map +1 -1
- package/dist/transformers/format.d.ts +2 -2
- package/dist/transformers/format.d.ts.map +1 -1
- package/dist/transformers/imgWidth.d.ts +1 -2
- package/dist/transformers/imgWidth.d.ts.map +1 -1
- package/dist/transformers/index.d.ts +2 -2
- package/dist/transformers/index.d.ts.map +1 -1
- package/dist/transformers/index.js +8 -2
- package/dist/transformers/index.js.map +1 -1
- package/dist/transformers/inlineCss.d.ts +3 -4
- package/dist/transformers/inlineCss.d.ts.map +1 -1
- package/dist/transformers/inlineLink.d.ts +2 -3
- package/dist/transformers/inlineLink.d.ts.map +1 -1
- package/dist/transformers/minify.d.ts +2 -2
- package/dist/transformers/minify.d.ts.map +1 -1
- package/dist/transformers/minifyCodeInline.d.ts +1 -2
- package/dist/transformers/minifyCodeInline.d.ts.map +1 -1
- package/dist/transformers/msoConditionals.d.ts +4 -0
- package/dist/transformers/msoConditionals.d.ts.map +1 -0
- package/dist/transformers/msoConditionals.js +25 -0
- package/dist/transformers/msoConditionals.js.map +1 -0
- package/dist/transformers/msoPlaceholders.d.ts +1 -2
- package/dist/transformers/msoPlaceholders.d.ts.map +1 -1
- package/dist/transformers/purgeCss.d.ts +3 -4
- package/dist/transformers/purgeCss.d.ts.map +1 -1
- package/dist/transformers/removeAttributes.d.ts +4 -5
- package/dist/transformers/removeAttributes.d.ts.map +1 -1
- package/dist/transformers/replaceStrings.d.ts +1 -2
- package/dist/transformers/replaceStrings.d.ts.map +1 -1
- package/dist/transformers/safeSelectors.d.ts +2 -3
- package/dist/transformers/safeSelectors.d.ts.map +1 -1
- package/dist/transformers/shorthandCss.d.ts +3 -4
- package/dist/transformers/shorthandCss.d.ts.map +1 -1
- package/dist/transformers/sixHex.d.ts +2 -3
- package/dist/transformers/sixHex.d.ts.map +1 -1
- package/dist/transformers/tailwindComponent.d.ts +1 -2
- package/dist/transformers/tailwindComponent.d.ts.map +1 -1
- package/dist/transformers/tailwindcss.d.ts +2 -3
- package/dist/transformers/tailwindcss.d.ts.map +1 -1
- package/dist/transformers/urlQuery.d.ts +2 -3
- package/dist/transformers/urlQuery.d.ts.map +1 -1
- package/dist/types/config.d.ts +18 -19
- package/dist/types/config.d.ts.map +1 -1
- package/dist/utils/ast/parser.d.ts +1 -2
- package/dist/utils/ast/parser.d.ts.map +1 -1
- package/dist/utils/ast/serializer.d.ts +1 -2
- package/dist/utils/ast/serializer.d.ts.map +1 -1
- package/dist/utils/ast/walker.d.ts +1 -2
- package/dist/utils/ast/walker.d.ts.map +1 -1
- package/dist/utils/cloneConfig.d.ts +1 -2
- package/dist/utils/cloneConfig.d.ts.map +1 -1
- package/dist/utils/compileTailwindCss.d.ts +4 -5
- package/dist/utils/compileTailwindCss.d.ts.map +1 -1
- package/dist/utils/componentSources.d.ts +4 -5
- package/dist/utils/componentSources.d.ts.map +1 -1
- package/dist/utils/cssBox.d.ts +6 -7
- package/dist/utils/cssBox.d.ts.map +1 -1
- package/dist/utils/decodeStyleEntities.d.ts +1 -2
- package/dist/utils/decodeStyleEntities.d.ts.map +1 -1
- package/dist/utils/detect.d.ts +1 -2
- package/dist/utils/detect.d.ts.map +1 -1
- package/dist/utils/output-markers.d.ts +4 -5
- package/dist/utils/output-markers.d.ts.map +1 -1
- package/dist/utils/staticPaths.d.ts +5 -0
- package/dist/utils/staticPaths.d.ts.map +1 -0
- package/dist/utils/staticPaths.js +11 -0
- package/dist/utils/staticPaths.js.map +1 -0
- package/dist/utils/url.d.ts +4 -5
- package/dist/utils/url.d.ts.map +1 -1
- package/dist/utils/watchPaths.d.ts +2 -3
- package/dist/utils/watchPaths.d.ts.map +1 -1
- package/node_modules/tinyexec/dist/main.d.mts +5 -3
- package/node_modules/tinyexec/dist/main.mjs +256 -232
- package/node_modules/tinyexec/package.json +9 -9
- package/package.json +5 -5
- package/dist/server/ui/.vite/deps/vue.runtime.esm-bundler-S54atuNJ.js.map +0 -1
package/dist/serve.js
CHANGED
|
@@ -2,6 +2,7 @@ import { resolveConfig } from "./config/index.js";
|
|
|
2
2
|
import { EventManager } from "./events/index.js";
|
|
3
3
|
import { normalizeComponentSources } from "./utils/componentSources.js";
|
|
4
4
|
import { createRenderer } from "./render/createRenderer.js";
|
|
5
|
+
import { staticBase } from "./utils/staticPaths.js";
|
|
5
6
|
import { runTransformers } from "./transformers/index.js";
|
|
6
7
|
import { createPlaintext } from "./plaintext.js";
|
|
7
8
|
import { stripForHtml, stripForPlaintext } from "./utils/output-markers.js";
|
|
@@ -11,6 +12,7 @@ import { setActiveRenderer } from "./render/active.js";
|
|
|
11
12
|
import { serveLint } from "./server/linter.js";
|
|
12
13
|
import { serveCompatibility } from "./server/compatibility.js";
|
|
13
14
|
import { sendEmail } from "./server/email.js";
|
|
15
|
+
import { serveStaticFile } from "./server/static.js";
|
|
14
16
|
import { createWatchedFileMatcher, deriveWatchRoots } from "./utils/watchPaths.js";
|
|
15
17
|
import { createRequire } from "node:module";
|
|
16
18
|
import { readFileSync } from "node:fs";
|
|
@@ -250,6 +252,31 @@ function maizzleDevPlugin(config, renderer, events, configInput) {
|
|
|
250
252
|
};
|
|
251
253
|
let isWatchedFile = applyWatchPaths(config);
|
|
252
254
|
/**
|
|
255
|
+
* Serve the `static.source` directories at `/<static.destination>`,
|
|
256
|
+
* mirroring what `build` copies to the output dir, so templates that
|
|
257
|
+
* reference `/images/logo.png` resolve in the preview iframe. Each
|
|
258
|
+
* positive pattern's glob-free prefix is mounted (looked up on disk
|
|
259
|
+
* per request, so files added after startup are served) and added
|
|
260
|
+
* to the watcher so the preview refreshes on changes. Runs again
|
|
261
|
+
* after a config reload; the middleware below reads the current
|
|
262
|
+
* mounts on every request.
|
|
263
|
+
*/
|
|
264
|
+
const applyStaticMounts = (cfg) => {
|
|
265
|
+
const sources = cfg.static?.source ?? ["public/**/*.*"];
|
|
266
|
+
const destination = (cfg.static?.destination ?? "public").replace(/^\/+|\/+$/g, "");
|
|
267
|
+
const prefix = destination ? `/${destination}` : "";
|
|
268
|
+
const bases = [...new Set(sources.filter((s) => !s.startsWith("!")).map(staticBase))];
|
|
269
|
+
for (const base of bases) server.watcher.add(base);
|
|
270
|
+
return {
|
|
271
|
+
mounts: bases.map((base) => ({
|
|
272
|
+
prefix,
|
|
273
|
+
base
|
|
274
|
+
})),
|
|
275
|
+
isStaticFile: createWatchedFileMatcher(sources, process.cwd())
|
|
276
|
+
};
|
|
277
|
+
};
|
|
278
|
+
let { mounts: staticMounts, isStaticFile } = applyStaticMounts(config);
|
|
279
|
+
/**
|
|
253
280
|
* Serialize watcher work onto one chain. The change handler closes and
|
|
254
281
|
* recreates the renderer across awaits; without serialization a second
|
|
255
282
|
* event firing mid-reload closes a stale renderer and leaks the new one.
|
|
@@ -270,7 +297,11 @@ function maizzleDevPlugin(config, renderer, events, configInput) {
|
|
|
270
297
|
type: "custom",
|
|
271
298
|
event: "maizzle:templates-changed"
|
|
272
299
|
});
|
|
273
|
-
}
|
|
300
|
+
} else if (isStaticFile(file)) server.ws.send({
|
|
301
|
+
type: "custom",
|
|
302
|
+
event: "maizzle:template-updated",
|
|
303
|
+
data: { file }
|
|
304
|
+
});
|
|
274
305
|
}));
|
|
275
306
|
server.watcher.on("unlink", (file) => enqueue(async () => {
|
|
276
307
|
if (isTemplateFile(file)) {
|
|
@@ -280,7 +311,11 @@ function maizzleDevPlugin(config, renderer, events, configInput) {
|
|
|
280
311
|
type: "custom",
|
|
281
312
|
event: "maizzle:templates-changed"
|
|
282
313
|
});
|
|
283
|
-
}
|
|
314
|
+
} else if (isStaticFile(file)) server.ws.send({
|
|
315
|
+
type: "custom",
|
|
316
|
+
event: "maizzle:template-updated",
|
|
317
|
+
data: { file }
|
|
318
|
+
});
|
|
284
319
|
}));
|
|
285
320
|
server.watcher.on("change", (file) => enqueue(async () => {
|
|
286
321
|
if (isWatchedFile(file)) {
|
|
@@ -298,6 +333,7 @@ function maizzleDevPlugin(config, renderer, events, configInput) {
|
|
|
298
333
|
});
|
|
299
334
|
setActiveRenderer(renderer);
|
|
300
335
|
isWatchedFile = applyWatchPaths(config);
|
|
336
|
+
({mounts: staticMounts, isStaticFile} = applyStaticMounts(config));
|
|
301
337
|
/**
|
|
302
338
|
* Push UI-relevant config bits so the dev UI reacts to live edits
|
|
303
339
|
* without a page reload. Uses the same shape as the initial
|
|
@@ -316,7 +352,7 @@ function maizzleDevPlugin(config, renderer, events, configInput) {
|
|
|
316
352
|
*/
|
|
317
353
|
await renderer.invalidateAll();
|
|
318
354
|
bumpGeneration();
|
|
319
|
-
if (isTemplateFile(file) || isWatchedFile(file)) server.ws.send({
|
|
355
|
+
if (isTemplateFile(file) || isWatchedFile(file) || isStaticFile(file)) server.ws.send({
|
|
320
356
|
type: "custom",
|
|
321
357
|
event: "maizzle:template-updated",
|
|
322
358
|
data: { file }
|
|
@@ -336,6 +372,13 @@ function maizzleDevPlugin(config, renderer, events, configInput) {
|
|
|
336
372
|
if (url === "/__maizzle/email-config") return serveEmailConfig(config, res);
|
|
337
373
|
next();
|
|
338
374
|
});
|
|
375
|
+
server.middlewares.use((req, res, next) => {
|
|
376
|
+
const url = req.url || "/";
|
|
377
|
+
for (const { prefix, base } of staticMounts) if (url === prefix || url.startsWith(`${prefix}/`) || url.startsWith(`${prefix}?`)) {
|
|
378
|
+
if (serveStaticFile(base, url.slice(prefix.length) || "/", res)) return;
|
|
379
|
+
}
|
|
380
|
+
next();
|
|
381
|
+
});
|
|
339
382
|
return () => {
|
|
340
383
|
server.middlewares.use(async (req, res, next) => {
|
|
341
384
|
if (isNavigationRequest(req)) return await serveDevUI(server, res, req.url || "/", config);
|
|
@@ -428,7 +471,7 @@ function getRendered(absolutePath, config, renderer, events) {
|
|
|
428
471
|
html: rendered.html
|
|
429
472
|
});
|
|
430
473
|
const doctype = rendered.doctype ?? templateConfig.doctype ?? "<!DOCTYPE html>";
|
|
431
|
-
|
|
474
|
+
html = await runTransformers(html, templateConfig, absolutePath, doctype, rendered.tailwindBlocks, rendered.sourceFiles);
|
|
432
475
|
return {
|
|
433
476
|
rawHtml: await events.fireAfterTransform({
|
|
434
477
|
config: templateConfig,
|
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, deriveWatchRoots } 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 /**\n * Root at the dev UI directory, not process.cwd(). With the host\n * project as Vite root, the watcher recursively watches the entire\n * host tree (vendor dirs, build output, …) — on large projects this\n * exhausts inotify watch limits — and the host's own\n * `server.watch.ignored` cannot reach this server. The UI is served\n * via middleware + /@fs/ URLs and never needed the cwd root.\n * `appType: 'custom'` keeps Vite from serving devUIDir/index.html\n * itself, which would bypass the config-injecting middleware.\n * The paths Maizzle actually reacts to are added explicitly in\n * maizzleDevPlugin's configureServer.\n */\n root: devUIDir,\n appType: 'custom',\n /**\n * Vite derives `publicDir` from `root`, so keep serving the project's\n * `public/` directory: templates reference images as `/logo.png`\n * (the default `static.source` copies `public/**` on build) and\n * the preview iframe resolves those against this server.\n */\n publicDir: resolve(process.cwd(), 'public'),\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 /**\n * (Re)establish file watching for a resolved config: the matcher used\n * by the change handler below, and — with the dev UI directory as Vite\n * root, the host cwd is no longer watched wholesale — the directories\n * the watch globs and the template content live in (see\n * deriveWatchRoots). Only derived roots are added to the watcher: the\n * server runs with Vite's default `disableGlobbing`, so raw glob\n * patterns would be treated as literal paths, and plain file paths\n * survive derivation as themselves. Runs once here and again after a\n * config reload, so content, components.source, root, and server.watch\n * edits take effect without a server restart. Roots a reload leaves\n * behind stay watched until restart — superfluous but harmless.\n *\n * Match against cwd, not config.root: the watched paths (maizzle/tailwind\n * configs, locales) are project-root relative, and `watcher.add`\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 */\n const applyWatchPaths = (cfg: MaizzleConfig) => {\n const watchPaths = [...defaultWatchPaths, ...(cfg.server?.watch ?? [])]\n const watchRoots = deriveWatchRoots({\n content: cfg.content ?? ['emails/**/*.vue'],\n componentDirs: normalizeComponentSources(cfg.components?.source, process.cwd()).map(s => s.path),\n root: cfg.root,\n watchPaths,\n cwd: process.cwd(),\n })\n\n for (const watchRoot of watchRoots) {\n server.watcher.add(watchRoot)\n }\n\n return createWatchedFileMatcher(watchPaths, process.cwd())\n }\n\n let isWatchedFile = applyWatchPaths(config)\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 // Re-establish watching against the reloaded config so moved\n // content, components.source, root, or server.watch values keep\n // emitting events without a server restart.\n isWatchedFile = applyWatchPaths(config)\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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"}
|
|
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 { serveStaticFile } from './server/static.ts'\nimport { normalizeComponentSources } from './utils/componentSources.ts'\nimport { createWatchedFileMatcher, deriveWatchRoots } from './utils/watchPaths.ts'\nimport { staticBase } from './utils/staticPaths.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 /**\n * Root at the dev UI directory, not process.cwd(). With the host\n * project as Vite root, the watcher recursively watches the entire\n * host tree (vendor dirs, build output, …) — on large projects this\n * exhausts inotify watch limits — and the host's own\n * `server.watch.ignored` cannot reach this server. The UI is served\n * via middleware + /@fs/ URLs and never needed the cwd root.\n * `appType: 'custom'` keeps Vite from serving devUIDir/index.html\n * itself, which would bypass the config-injecting middleware.\n * The paths Maizzle actually reacts to are added explicitly in\n * maizzleDevPlugin's configureServer.\n */\n root: devUIDir,\n appType: 'custom',\n /**\n * Vite derives `publicDir` from `root`, so keep serving the project's\n * `public/` directory: templates reference images as `/logo.png`\n * (the default `static.source` copies `public/**` on build) and\n * the preview iframe resolves those against this server.\n */\n publicDir: resolve(process.cwd(), 'public'),\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 /**\n * (Re)establish file watching for a resolved config: the matcher used\n * by the change handler below, and — with the dev UI directory as Vite\n * root, the host cwd is no longer watched wholesale — the directories\n * the watch globs and the template content live in (see\n * deriveWatchRoots). Only derived roots are added to the watcher: the\n * server runs with Vite's default `disableGlobbing`, so raw glob\n * patterns would be treated as literal paths, and plain file paths\n * survive derivation as themselves. Runs once here and again after a\n * config reload, so content, components.source, root, and server.watch\n * edits take effect without a server restart. Roots a reload leaves\n * behind stay watched until restart — superfluous but harmless.\n *\n * Match against cwd, not config.root: the watched paths (maizzle/tailwind\n * configs, locales) are project-root relative, and `watcher.add`\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 */\n const applyWatchPaths = (cfg: MaizzleConfig) => {\n const watchPaths = [...defaultWatchPaths, ...(cfg.server?.watch ?? [])]\n const watchRoots = deriveWatchRoots({\n content: cfg.content ?? ['emails/**/*.vue'],\n componentDirs: normalizeComponentSources(cfg.components?.source, process.cwd()).map(s => s.path),\n root: cfg.root,\n watchPaths,\n cwd: process.cwd(),\n })\n\n for (const watchRoot of watchRoots) {\n server.watcher.add(watchRoot)\n }\n\n return createWatchedFileMatcher(watchPaths, process.cwd())\n }\n\n let isWatchedFile = applyWatchPaths(config)\n\n /**\n * Serve the `static.source` directories at `/<static.destination>`,\n * mirroring what `build` copies to the output dir, so templates that\n * reference `/images/logo.png` resolve in the preview iframe. Each\n * positive pattern's glob-free prefix is mounted (looked up on disk\n * per request, so files added after startup are served) and added\n * to the watcher so the preview refreshes on changes. Runs again\n * after a config reload; the middleware below reads the current\n * mounts on every request.\n */\n const applyStaticMounts = (cfg: MaizzleConfig) => {\n const sources = cfg.static?.source ?? ['public/**/*.*']\n const destination = (cfg.static?.destination ?? 'public').replace(/^\\/+|\\/+$/g, '')\n const prefix = destination ? `/${destination}` : ''\n const bases = [...new Set(sources.filter(s => !s.startsWith('!')).map(staticBase))]\n\n for (const base of bases) {\n server.watcher.add(base)\n }\n\n return {\n mounts: bases.map(base => ({ prefix, base })),\n isStaticFile: createWatchedFileMatcher(sources, process.cwd()),\n }\n }\n\n let { mounts: staticMounts, isStaticFile } = applyStaticMounts(config)\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 } else if (isStaticFile(file)) {\n server.ws.send({ type: 'custom', event: 'maizzle:template-updated', data: { file } })\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 } else if (isStaticFile(file)) {\n server.ws.send({ type: 'custom', event: 'maizzle:template-updated', data: { file } })\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 // Re-establish watching against the reloaded config so moved\n // content, components.source, root, or server.watch values keep\n // emitting events without a server restart.\n isWatchedFile = applyWatchPaths(config)\n ;({ mounts: staticMounts, isStaticFile } = applyStaticMounts(config))\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 || isStaticFile(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 // Static assets from `static.source`, mounted at `/<static.destination>`\n server.middlewares.use((req: any, res: any, next: any) => {\n const url: string = req.url || '/'\n\n for (const { prefix, base } of staticMounts) {\n if (url === prefix || url.startsWith(`${prefix}/`) || url.startsWith(`${prefix}?`)) {\n if (serveStaticFile(base, url.slice(prefix.length) || '/', res)) return\n }\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 html = await runTransformers(html, templateConfig, absolutePath, doctype, rendered.tailwindBlocks, rendered.sourceFiles)\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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"}
|
|
@@ -52,8 +52,7 @@ interface Indexes {
|
|
|
52
52
|
url: string;
|
|
53
53
|
}>;
|
|
54
54
|
}
|
|
55
|
-
declare function initCompatibility(): Promise<Indexes | null>;
|
|
56
|
-
declare function serveCompatibility(url: string, res: any, config: MaizzleConfig, componentDirs: NormalizedComponentSource[]): Promise<void>;
|
|
55
|
+
export declare function initCompatibility(): Promise<Indexes | null>;
|
|
56
|
+
export declare function serveCompatibility(url: string, res: any, config: MaizzleConfig, componentDirs: NormalizedComponentSource[]): Promise<void>;
|
|
57
57
|
//#endregion
|
|
58
|
-
export { initCompatibility, serveCompatibility };
|
|
59
58
|
//# sourceMappingURL=compatibility.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"compatibility.d.ts","names":[],"sources":["../../src/server/compatibility.ts"],"mappings":";;;;UAkBU;EACR;EACA;EACA;EACA;EACA;;UAoBQ;EACR;IAAa;IAAmB;IAAmB;IAAqB;IAAiB;;EACzF,iBAAiB;EACjB,SAAS,YAAY;EACrB,cAAc,YAAY;IAAQ;IAAe,SAAS;;EAC1D,WAAW,YAAY;EACvB,iBAAiB,YAAY;EAC7B,gBAAgB,YAAY;EAC5B,kBAAkB,YAAY;EAC9B,aAAa,YAAY;EACzB,SAAS,YAAY;EACrB,eAAe;EACf,eAAe;EACf,aAAa;EACb,cAAc;EACd,iBAAiB;EACjB,SAAS,YAAY;EACrB,UAAU,YAAY;EACtB,eAAe,YAAY;EAC3B,gBAAgB,YAAY;EAC5B,cAAc;EACd,eAAe;EACf,kBAAkB;EAClB,kBAAkB;EAClB,sBAAsB;EACtB,gBAAgB;EAChB,kBAAkB;EAClB,UAAU,YAAY;;EAEtB,QAAQ;IAAc;IAAe;;;
|
|
1
|
+
{"version":3,"file":"compatibility.d.ts","names":[],"sources":["../../src/server/compatibility.ts"],"mappings":";;;;UAkBU;EACR;EACA;EACA;EACA;EACA;;UAoBQ;EACR;IAAa;IAAmB;IAAmB;IAAqB;IAAiB;;EACzF,iBAAiB;EACjB,SAAS,YAAY;EACrB,cAAc,YAAY;IAAQ;IAAe,SAAS;;EAC1D,WAAW,YAAY;EACvB,iBAAiB,YAAY;EAC7B,gBAAgB,YAAY;EAC5B,kBAAkB,YAAY;EAC9B,aAAa,YAAY;EACzB,SAAS,YAAY;EACrB,eAAe;EACf,eAAe;EACf,aAAa;EACb,cAAc;EACd,iBAAiB;EACjB,SAAS,YAAY;EACrB,UAAU,YAAY;EACtB,eAAe,YAAY;EAC3B,gBAAgB,YAAY;EAC5B,cAAc;EACd,eAAe;EACf,kBAAkB;EAClB,kBAAkB;EAClB,sBAAsB;EACtB,gBAAgB;EAChB,kBAAkB;EAClB,UAAU,YAAY;;EAEtB,QAAQ;IAAc;IAAe;;;wBA6OjB,qBAAqB,QAAQ;wBA8kB7B,mBACpB,aACA,UACA,QAAQ,eACR,eAAe,8BAA2B"}
|
package/dist/server/email.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { MaizzleConfig } from "../types/config.js";
|
|
2
2
|
import "../types/index.js";
|
|
3
3
|
//#region src/server/email.d.ts
|
|
4
|
-
interface SendEmailPayload {
|
|
4
|
+
export interface SendEmailPayload {
|
|
5
5
|
to: string[];
|
|
6
6
|
subject: string;
|
|
7
7
|
html: string;
|
|
@@ -12,7 +12,6 @@ interface SendEmailResponse {
|
|
|
12
12
|
message: string;
|
|
13
13
|
previewUrl?: string;
|
|
14
14
|
}
|
|
15
|
-
declare function sendEmail(payload: SendEmailPayload, config: MaizzleConfig, templateConfig: MaizzleConfig): Promise<SendEmailResponse>;
|
|
15
|
+
export declare function sendEmail(payload: SendEmailPayload, config: MaizzleConfig, templateConfig: MaizzleConfig): Promise<SendEmailResponse>;
|
|
16
16
|
//#endregion
|
|
17
|
-
export { SendEmailPayload, sendEmail };
|
|
18
17
|
//# sourceMappingURL=email.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"email.d.ts","names":[],"sources":["../../src/server/email.ts"],"mappings":";;;
|
|
1
|
+
{"version":3,"file":"email.d.ts","names":[],"sources":["../../src/server/email.ts"],"mappings":";;;iBAGiB;EACf;EACA;EACA;EACA;;UAGQ;EACR;EACA;EACA;;wBAGoB,UACpB,SAAS,kBACT,QAAQ,eACR,gBAAgB,gBACf,QAAQ"}
|
package/dist/server/linter.d.ts
CHANGED
|
@@ -2,7 +2,7 @@ import { MaizzleConfig } from "../types/config.js";
|
|
|
2
2
|
import "../types/index.js";
|
|
3
3
|
import { NormalizedComponentSource } from "../utils/componentSources.js";
|
|
4
4
|
//#region src/server/linter.d.ts
|
|
5
|
-
interface LintIssue {
|
|
5
|
+
export interface LintIssue {
|
|
6
6
|
type: 'error' | 'warning';
|
|
7
7
|
title: string;
|
|
8
8
|
message: string;
|
|
@@ -13,8 +13,7 @@ interface LintIssue {
|
|
|
13
13
|
line?: number;
|
|
14
14
|
file: string;
|
|
15
15
|
}
|
|
16
|
-
declare function scanLint(rootFile: string, config: MaizzleConfig, componentDirs: NormalizedComponentSource[]): Promise<LintIssue[]>;
|
|
17
|
-
declare function serveLint(url: string, res: any, config: MaizzleConfig, componentDirs: NormalizedComponentSource[]): Promise<void>;
|
|
16
|
+
export declare function scanLint(rootFile: string, config: MaizzleConfig, componentDirs: NormalizedComponentSource[]): Promise<LintIssue[]>;
|
|
17
|
+
export declare function serveLint(url: string, res: any, config: MaizzleConfig, componentDirs: NormalizedComponentSource[]): Promise<void>;
|
|
18
18
|
//#endregion
|
|
19
|
-
export { LintIssue, scanLint, serveLint };
|
|
20
19
|
//# sourceMappingURL=linter.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"linter.d.ts","names":[],"sources":["../../src/server/linter.ts"],"mappings":";;;;
|
|
1
|
+
{"version":3,"file":"linter.d.ts","names":[],"sources":["../../src/server/linter.ts"],"mappings":";;;;iBAMiB;EACf;EACA;EACA;;EAEA;;EAEA;EACA;EACA;;wBA8BoB,SACpB,kBACA,QAAQ,eACR,eAAe,8BACd,QAAQ;wBAeW,UAAU,aAAa,UAAU,QAAQ,eAAe,eAAe,8BAA2B"}
|
|
@@ -1,20 +1,19 @@
|
|
|
1
1
|
import { NormalizedComponentSource } from "../utils/componentSources.js";
|
|
2
2
|
//#region src/server/sfc-utils.d.ts
|
|
3
|
-
declare function isFrameworkComponent(file: string): boolean;
|
|
4
|
-
interface SfcBlock {
|
|
3
|
+
export declare function isFrameworkComponent(file: string): boolean;
|
|
4
|
+
export interface SfcBlock {
|
|
5
5
|
content: string;
|
|
6
6
|
offset: number;
|
|
7
7
|
}
|
|
8
|
-
declare function parseSfcBlocks(source: string): {
|
|
8
|
+
export declare function parseSfcBlocks(source: string): {
|
|
9
9
|
template: SfcBlock | null;
|
|
10
10
|
styles: SfcBlock[];
|
|
11
11
|
};
|
|
12
12
|
/**
|
|
13
13
|
* Standard HTML elements — anything not in this set is treated as a component.
|
|
14
14
|
*/
|
|
15
|
-
declare const HTML_ELEMENTS: Set<string>;
|
|
16
|
-
declare function findComponentTags(templateContent: string): string[];
|
|
17
|
-
declare function buildComponentMap(root: string, componentDirs: NormalizedComponentSource[]): Promise<Map<string, string>>;
|
|
15
|
+
export declare const HTML_ELEMENTS: Set<string>;
|
|
16
|
+
export declare function findComponentTags(templateContent: string): string[];
|
|
17
|
+
export declare function buildComponentMap(root: string, componentDirs: NormalizedComponentSource[]): Promise<Map<string, string>>;
|
|
18
18
|
//#endregion
|
|
19
|
-
export { HTML_ELEMENTS, SfcBlock, buildComponentMap, findComponentTags, isFrameworkComponent, parseSfcBlocks };
|
|
20
19
|
//# sourceMappingURL=sfc-utils.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sfc-utils.d.ts","names":[],"sources":["../../src/server/sfc-utils.ts"],"mappings":";;
|
|
1
|
+
{"version":3,"file":"sfc-utils.d.ts","names":[],"sources":["../../src/server/sfc-utils.ts"],"mappings":";;wBAegB,qBAAqB;iBAIpB;EACf;EACA;;wBAGc,eAAe;EAAmB,UAAU;EAAiB,QAAQ;;;;;qBA4BxE,eAAa;wBAgBV,kBAAkB;wBAqBZ,kBACpB,cACA,eAAe,8BACd,QAAQ"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { ServerResponse } from "node:http";
|
|
2
|
+
//#region src/server/static.d.ts
|
|
3
|
+
/**
|
|
4
|
+
* Stream the file at `urlPath` (mount prefix already stripped) from
|
|
5
|
+
* `base`. Returns false when there is nothing to serve — missing file,
|
|
6
|
+
* directory, or a path escaping `base` — so the caller can fall through.
|
|
7
|
+
*/
|
|
8
|
+
export declare function serveStaticFile(base: string, urlPath: string, res: ServerResponse): boolean;
|
|
9
|
+
//#endregion
|
|
10
|
+
//# sourceMappingURL=static.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"static.d.ts","names":[],"sources":["../../src/server/static.ts"],"mappings":";;;;;;;wBAkCgB,gBAAgB,cAAc,iBAAiB,KAAK"}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import { createReadStream, statSync } from "node:fs";
|
|
2
|
+
import { extname, resolve, sep } from "node:path";
|
|
3
|
+
//#region src/server/static.ts
|
|
4
|
+
const MIME = {
|
|
5
|
+
".png": "image/png",
|
|
6
|
+
".jpg": "image/jpeg",
|
|
7
|
+
".jpeg": "image/jpeg",
|
|
8
|
+
".gif": "image/gif",
|
|
9
|
+
".webp": "image/webp",
|
|
10
|
+
".avif": "image/avif",
|
|
11
|
+
".svg": "image/svg+xml",
|
|
12
|
+
".ico": "image/x-icon",
|
|
13
|
+
".bmp": "image/bmp",
|
|
14
|
+
".css": "text/css",
|
|
15
|
+
".js": "text/javascript",
|
|
16
|
+
".html": "text/html",
|
|
17
|
+
".txt": "text/plain",
|
|
18
|
+
".json": "application/json",
|
|
19
|
+
".pdf": "application/pdf",
|
|
20
|
+
".woff": "font/woff",
|
|
21
|
+
".woff2": "font/woff2",
|
|
22
|
+
".ttf": "font/ttf",
|
|
23
|
+
".otf": "font/otf",
|
|
24
|
+
".mp4": "video/mp4",
|
|
25
|
+
".webm": "video/webm",
|
|
26
|
+
".mp3": "audio/mpeg"
|
|
27
|
+
};
|
|
28
|
+
/**
|
|
29
|
+
* Stream the file at `urlPath` (mount prefix already stripped) from
|
|
30
|
+
* `base`. Returns false when there is nothing to serve — missing file,
|
|
31
|
+
* directory, or a path escaping `base` — so the caller can fall through.
|
|
32
|
+
*/
|
|
33
|
+
function serveStaticFile(base, urlPath, res) {
|
|
34
|
+
let pathname;
|
|
35
|
+
try {
|
|
36
|
+
pathname = decodeURIComponent(urlPath.split("?")[0]);
|
|
37
|
+
} catch {
|
|
38
|
+
return false;
|
|
39
|
+
}
|
|
40
|
+
const file = resolve(base, `.${pathname}`);
|
|
41
|
+
if (file !== base && !file.startsWith(base + sep)) return false;
|
|
42
|
+
let size;
|
|
43
|
+
try {
|
|
44
|
+
const stat = statSync(file);
|
|
45
|
+
if (!stat.isFile()) return false;
|
|
46
|
+
size = stat.size;
|
|
47
|
+
} catch {
|
|
48
|
+
return false;
|
|
49
|
+
}
|
|
50
|
+
res.setHeader("Content-Type", MIME[extname(file).toLowerCase()] ?? "application/octet-stream");
|
|
51
|
+
res.setHeader("Content-Length", size);
|
|
52
|
+
res.setHeader("Cache-Control", "no-cache");
|
|
53
|
+
const stream = createReadStream(file);
|
|
54
|
+
stream.once("error", (error) => {
|
|
55
|
+
if (res.headersSent) {
|
|
56
|
+
res.destroy(error);
|
|
57
|
+
return;
|
|
58
|
+
}
|
|
59
|
+
res.removeHeader("Content-Type");
|
|
60
|
+
res.removeHeader("Content-Length");
|
|
61
|
+
res.removeHeader("Cache-Control");
|
|
62
|
+
res.statusCode = 404;
|
|
63
|
+
res.end();
|
|
64
|
+
});
|
|
65
|
+
stream.pipe(res);
|
|
66
|
+
return true;
|
|
67
|
+
}
|
|
68
|
+
//#endregion
|
|
69
|
+
export { serveStaticFile };
|
|
70
|
+
|
|
71
|
+
//# sourceMappingURL=static.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"static.js","names":[],"sources":["../../src/server/static.ts"],"sourcesContent":["import { createReadStream, statSync } from 'node:fs'\nimport { extname, resolve, sep } from 'node:path'\nimport type { ServerResponse } from 'node:http'\n\nconst MIME: Record<string, string> = {\n '.png': 'image/png',\n '.jpg': 'image/jpeg',\n '.jpeg': 'image/jpeg',\n '.gif': 'image/gif',\n '.webp': 'image/webp',\n '.avif': 'image/avif',\n '.svg': 'image/svg+xml',\n '.ico': 'image/x-icon',\n '.bmp': 'image/bmp',\n '.css': 'text/css',\n '.js': 'text/javascript',\n '.html': 'text/html',\n '.txt': 'text/plain',\n '.json': 'application/json',\n '.pdf': 'application/pdf',\n '.woff': 'font/woff',\n '.woff2': 'font/woff2',\n '.ttf': 'font/ttf',\n '.otf': 'font/otf',\n '.mp4': 'video/mp4',\n '.webm': 'video/webm',\n '.mp3': 'audio/mpeg',\n}\n\n/**\n * Stream the file at `urlPath` (mount prefix already stripped) from\n * `base`. Returns false when there is nothing to serve — missing file,\n * directory, or a path escaping `base` — so the caller can fall through.\n */\nexport function serveStaticFile(base: string, urlPath: string, res: ServerResponse): boolean {\n let pathname: string\n\n try {\n pathname = decodeURIComponent(urlPath.split('?')[0])\n } catch {\n return false\n }\n\n const file = resolve(base, `.${pathname}`)\n\n if (file !== base && !file.startsWith(base + sep)) {\n return false\n }\n\n let size: number\n\n try {\n const stat = statSync(file)\n if (!stat.isFile()) return false\n size = stat.size\n } catch {\n return false\n }\n\n res.setHeader('Content-Type', MIME[extname(file).toLowerCase()] ?? 'application/octet-stream')\n res.setHeader('Content-Length', size)\n res.setHeader('Cache-Control', 'no-cache')\n const stream = createReadStream(file)\n stream.once('error', (error) => {\n if (res.headersSent) {\n res.destroy(error)\n return\n }\n\n res.removeHeader('Content-Type')\n res.removeHeader('Content-Length')\n res.removeHeader('Cache-Control')\n res.statusCode = 404\n res.end()\n })\n stream.pipe(res)\n\n return true\n}\n"],"mappings":";;;AAIA,MAAM,OAA+B;CACnC,QAAQ;CACR,QAAQ;CACR,SAAS;CACT,QAAQ;CACR,SAAS;CACT,SAAS;CACT,QAAQ;CACR,QAAQ;CACR,QAAQ;CACR,QAAQ;CACR,OAAO;CACP,SAAS;CACT,QAAQ;CACR,SAAS;CACT,QAAQ;CACR,SAAS;CACT,UAAU;CACV,QAAQ;CACR,QAAQ;CACR,QAAQ;CACR,SAAS;CACT,QAAQ;AACV;;;;;;AAOA,SAAgB,gBAAgB,MAAc,SAAiB,KAA8B;CAC3F,IAAI;CAEJ,IAAI;EACF,WAAW,mBAAmB,QAAQ,MAAM,GAAG,CAAC,CAAC,EAAE;CACrD,QAAQ;EACN,OAAO;CACT;CAEA,MAAM,OAAO,QAAQ,MAAM,IAAI,UAAU;CAEzC,IAAI,SAAS,QAAQ,CAAC,KAAK,WAAW,OAAO,GAAG,GAC9C,OAAO;CAGT,IAAI;CAEJ,IAAI;EACF,MAAM,OAAO,SAAS,IAAI;EAC1B,IAAI,CAAC,KAAK,OAAO,GAAG,OAAO;EAC3B,OAAO,KAAK;CACd,QAAQ;EACN,OAAO;CACT;CAEA,IAAI,UAAU,gBAAgB,KAAK,QAAQ,IAAI,CAAC,CAAC,YAAY,MAAM,0BAA0B;CAC7F,IAAI,UAAU,kBAAkB,IAAI;CACpC,IAAI,UAAU,iBAAiB,UAAU;CACzC,MAAM,SAAS,iBAAiB,IAAI;CACpC,OAAO,KAAK,UAAU,UAAU;EAC9B,IAAI,IAAI,aAAa;GACnB,IAAI,QAAQ,KAAK;GACjB;EACF;EAEA,IAAI,aAAa,cAAc;EAC/B,IAAI,aAAa,gBAAgB;EACjC,IAAI,aAAa,eAAe;EAChC,IAAI,aAAa;EACjB,IAAI,IAAI;CACV,CAAC;CACD,OAAO,KAAK,GAAG;CAEf,OAAO;AACT"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { n as __exportAll } from "./rolldown-runtime-EAsCxrDo.js";
|
|
2
|
-
import { St as inject, W as computed, Wt as provide, mt as h } from "./vue.runtime.esm-bundler-
|
|
2
|
+
import { St as inject, W as computed, Wt as provide, mt as h } from "./vue.runtime.esm-bundler-Dq07uCLt.js";
|
|
3
3
|
//#region ../../home/cosmin/Work/maizzle/framework/node_modules/@lucide/vue/dist/esm/shared/src/utils/isEmptyString.mjs
|
|
4
4
|
/**
|
|
5
5
|
* @license @lucide/vue v1.33.0 - ISC
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Gn as reactive, It as onMounted, Jn as shallowReactive, Kn as readonly, N as Fragment, Nt as onBeforeUpdate, Pn as getCurrentScope, Qn as toRaw, Rn as isReadonly, St as inject, Vn as markRaw, Vt as onUpdated, W as computed, Xn as shallowRef, Yn as shallowReadonly, _n as watch, dt as getCurrentInstance, gt as hasInjectionContext, i as TransitionGroup, jn as customRef, kt as nextTick, mt as h, qn as ref, rr as unref, rt as defineComponent, tr as toValue, vn as watchEffect, zn as isRef } from "./vue.runtime.esm-bundler-
|
|
1
|
+
import { Gn as reactive, It as onMounted, Jn as shallowReactive, Kn as readonly, N as Fragment, Nt as onBeforeUpdate, Pn as getCurrentScope, Qn as toRaw, Rn as isReadonly, St as inject, Vn as markRaw, Vt as onUpdated, W as computed, Xn as shallowRef, Yn as shallowReadonly, _n as watch, dt as getCurrentInstance, gt as hasInjectionContext, i as TransitionGroup, jn as customRef, kt as nextTick, mt as h, qn as ref, rr as unref, rt as defineComponent, tr as toValue, vn as watchEffect, zn as isRef } from "./vue.runtime.esm-bundler-Dq07uCLt.js";
|
|
2
2
|
import { assert, autoResetRef, bypassFilter, camelize, clamp, computedEager, computedWithControl, containsProp, controlledComputed, controlledRef, createDisposableDirective, createEventHook, createFilterWrapper, createGlobalState, createInjectionState, createReactiveFn, createRef, createSharedComposable, createSingletonPromise, debounceFilter, debouncedRef, debouncedWatch, eagerComputed, extendRef, formatDate, get, getLifeCycleTarget, hasOwn, hyphenate, identity, ignorableWatch, increaseWithUnit, injectLocal, invoke, isClient, isDef, isDefined, isIOS, isObject, isWorker, makeDestructurable, noop, normalizeDate, notNullish, now, objectEntries, objectOmit, objectPick, pausableFilter, pausableWatch, promiseTimeout, provideLocal, pxValue, rand, reactify, reactifyObject, reactiveComputed, reactiveOmit, reactivePick, refAutoReset, refDebounced, refDefault, refManualReset, refThrottled, refWithControl, set, syncRef, syncRefs, throttleFilter, throttledRef, throttledWatch, timestamp, toArray, toReactive, toRef, toRefs, tryOnBeforeMount, tryOnBeforeUnmount, tryOnMounted, tryOnScopeDispose, tryOnUnmounted, until, useArrayDifference, useArrayEvery, useArrayFilter, useArrayFind, useArrayFindIndex, useArrayFindLast, useArrayIncludes, useArrayJoin, useArrayMap, useArrayReduce, useArraySome, useArrayUnique, useCounter, useDateFormat, useDebounce, useDebounceFn, useInterval, useIntervalFn, useLastChanged, useThrottle, useThrottleFn, useTimeout, useTimeoutFn, useToNumber, useToString, useToggle, watchArray, watchAtMost, watchDebounced, watchDeep, watchIgnorable, watchImmediate, watchOnce, watchPausable, watchThrottled, watchTriggerable, watchWithFilter, whenever } from "./@vueuse_shared.js";
|
|
3
3
|
//#region ../../home/cosmin/Work/maizzle/framework/node_modules/@vueuse/core/dist/index.js
|
|
4
4
|
function computedAsync(evaluationCallback, initialState, optionsOrRef) {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { $n as toRef$1, Bt as onUnmounted, Gn as reactive, Hn as onScopeDispose, It as onMounted, Kn as readonly, Ln as isReactive, Mt as onBeforeUnmount, Nn as effectScope, Pn as getCurrentScope, St as inject, W as computed, Wt as provide, Xn as shallowRef, Yn as shallowReadonly, _n as watch, dt as getCurrentInstance, er as toRefs$1, gt as hasInjectionContext, jn as customRef, jt as onBeforeMount, kt as nextTick, qn as ref, rr as unref, tr as toValue, vn as watchEffect, zn as isRef } from "./vue.runtime.esm-bundler-
|
|
1
|
+
import { $n as toRef$1, Bt as onUnmounted, Gn as reactive, Hn as onScopeDispose, It as onMounted, Kn as readonly, Ln as isReactive, Mt as onBeforeUnmount, Nn as effectScope, Pn as getCurrentScope, St as inject, W as computed, Wt as provide, Xn as shallowRef, Yn as shallowReadonly, _n as watch, dt as getCurrentInstance, er as toRefs$1, gt as hasInjectionContext, jn as customRef, jt as onBeforeMount, kt as nextTick, qn as ref, rr as unref, tr as toValue, vn as watchEffect, zn as isRef } from "./vue.runtime.esm-bundler-Dq07uCLt.js";
|
|
2
2
|
//#region ../../home/cosmin/Work/maizzle/framework/node_modules/@vueuse/shared/dist/index.js
|
|
3
3
|
/**
|
|
4
4
|
*
|