@maizzle/framework 6.0.0-rc.15 → 6.0.0-rc.17
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/README.md +3 -3
- package/dist/{build.d.mts → build.d.ts} +2 -2
- package/dist/build.d.ts.map +1 -0
- package/dist/build.mjs +1 -1
- package/dist/build.mjs.map +1 -1
- package/dist/components/Body.vue +9 -2
- package/dist/components/Button.vue +13 -8
- package/dist/components/Column.vue +22 -8
- package/dist/components/Container.vue +9 -5
- package/dist/components/Html.vue +7 -2
- package/dist/components/Layout.vue +30 -15
- package/dist/components/Overlap.vue +8 -3
- package/dist/components/Raw.vue +28 -0
- package/dist/components/Row.vue +23 -11
- package/dist/components/Section.vue +9 -5
- package/dist/components/Spacer.vue +9 -4
- package/dist/components/Tailwind.vue +43 -0
- package/dist/components/{utils.d.mts → utils.d.ts} +12 -2
- package/dist/components/utils.d.ts.map +1 -0
- package/dist/components/utils.mjs +11 -1
- package/dist/components/utils.mjs.map +1 -1
- package/dist/components/utils.ts +12 -0
- package/dist/composables/{defineConfig.d.mts → defineConfig.d.ts} +2 -2
- package/dist/composables/defineConfig.d.ts.map +1 -0
- package/dist/composables/{renderContext.d.mts → renderContext.d.ts} +11 -5
- package/dist/composables/renderContext.d.ts.map +1 -0
- package/dist/composables/renderContext.mjs.map +1 -1
- package/dist/composables/{useConfig.d.mts → useConfig.d.ts} +2 -2
- package/dist/composables/useConfig.d.ts.map +1 -0
- package/dist/composables/{useDoctype.d.mts → useDoctype.d.ts} +1 -1
- package/dist/composables/useDoctype.d.ts.map +1 -0
- package/dist/composables/{useEvent.d.mts → useEvent.d.ts} +2 -2
- package/dist/composables/useEvent.d.ts.map +1 -0
- package/dist/composables/{useFont.d.mts → useFont.d.ts} +1 -1
- package/dist/composables/useFont.d.ts.map +1 -0
- package/dist/composables/useOutlookFallback.d.ts +21 -0
- package/dist/composables/useOutlookFallback.d.ts.map +1 -0
- package/dist/composables/useOutlookFallback.mjs +30 -0
- package/dist/composables/useOutlookFallback.mjs.map +1 -0
- package/dist/composables/{usePlaintext.d.mts → usePlaintext.d.ts} +1 -1
- package/dist/composables/usePlaintext.d.ts.map +1 -0
- package/dist/composables/{usePreheader.d.mts → usePreheader.d.ts} +1 -1
- package/dist/composables/usePreheader.d.ts.map +1 -0
- package/dist/config/{defaults.d.mts → defaults.d.ts} +2 -2
- package/dist/config/defaults.d.ts.map +1 -0
- package/dist/config/{index.d.mts → index.d.ts} +4 -4
- package/dist/config/index.d.ts.map +1 -0
- package/dist/events/{index.d.mts → index.d.ts} +2 -2
- package/dist/events/index.d.ts.map +1 -0
- package/dist/index.d.ts +34 -0
- package/dist/index.mjs +2 -1
- package/dist/{plaintext.d.mts → plaintext.d.ts} +1 -1
- package/dist/plaintext.d.ts.map +1 -0
- package/dist/{plugin.d.mts → plugin.d.ts} +2 -2
- package/dist/plugin.d.ts.map +1 -0
- package/dist/plugins/postcss/{mergeMediaQueries.d.mts → mergeMediaQueries.d.ts} +2 -2
- package/dist/plugins/postcss/mergeMediaQueries.d.ts.map +1 -0
- package/dist/plugins/postcss/{pruneVars.d.mts → pruneVars.d.ts} +1 -1
- package/dist/plugins/postcss/pruneVars.d.ts.map +1 -0
- package/dist/plugins/postcss/{quoteFontFamilies.d.mts → quoteFontFamilies.d.ts} +1 -1
- package/dist/plugins/postcss/quoteFontFamilies.d.ts.map +1 -0
- package/dist/plugins/postcss/{removeDeclarations.d.mts → removeDeclarations.d.ts} +1 -1
- package/dist/plugins/postcss/removeDeclarations.d.ts.map +1 -0
- package/dist/plugins/postcss/resolveMaizzleImports.d.ts +16 -0
- package/dist/plugins/postcss/resolveMaizzleImports.d.ts.map +1 -0
- package/dist/plugins/postcss/resolveMaizzleImports.mjs +40 -0
- package/dist/plugins/postcss/resolveMaizzleImports.mjs.map +1 -0
- package/dist/plugins/postcss/{resolveProps.d.mts → resolveProps.d.ts} +1 -1
- package/dist/plugins/postcss/resolveProps.d.ts.map +1 -0
- package/dist/plugins/postcss/{tailwindCleanup.d.mts → tailwindCleanup.d.ts} +2 -2
- package/dist/plugins/postcss/tailwindCleanup.d.ts.map +1 -0
- package/dist/{prepare.d.mts → prepare.d.ts} +1 -1
- package/dist/prepare.d.ts.map +1 -0
- package/dist/render/{createRenderer.d.mts → createRenderer.d.ts} +4 -3
- package/dist/render/createRenderer.d.ts.map +1 -0
- package/dist/render/createRenderer.mjs +9 -76
- package/dist/render/createRenderer.mjs.map +1 -1
- package/dist/render/index.d.ts +18 -0
- package/dist/render/index.d.ts.map +1 -0
- package/dist/render/index.mjs +13 -14
- package/dist/render/index.mjs.map +1 -1
- package/dist/render/{injectFonts.d.mts → injectFonts.d.ts} +2 -2
- package/dist/render/injectFonts.d.ts.map +1 -0
- package/dist/render/plugins/codeBlockExtract.d.ts +14 -0
- package/dist/render/plugins/codeBlockExtract.d.ts.map +1 -0
- package/dist/render/plugins/codeBlockExtract.mjs +34 -0
- package/dist/render/plugins/codeBlockExtract.mjs.map +1 -0
- package/dist/render/plugins/markdownExtract.d.ts +12 -0
- package/dist/render/plugins/markdownExtract.d.ts.map +1 -0
- package/dist/render/plugins/markdownExtract.mjs +50 -0
- package/dist/render/plugins/markdownExtract.mjs.map +1 -0
- package/dist/render/plugins/rawExtract.d.ts +14 -0
- package/dist/render/plugins/rawExtract.d.ts.map +1 -0
- package/dist/render/plugins/rawExtract.mjs +34 -0
- package/dist/render/plugins/rawExtract.mjs.map +1 -0
- package/dist/render/plugins/{rowSourceLocation.d.mts → rowSourceLocation.d.ts} +1 -1
- package/dist/render/plugins/rowSourceLocation.d.ts.map +1 -0
- package/dist/{serve.d.mts → serve.d.ts} +2 -2
- package/dist/serve.d.ts.map +1 -0
- package/dist/serve.mjs +15 -6
- package/dist/serve.mjs.map +1 -1
- package/dist/server/{compatibility.d.mts → compatibility.d.ts} +2 -2
- package/dist/server/compatibility.d.ts.map +1 -0
- package/dist/server/{email.d.mts → email.d.ts} +2 -2
- package/dist/server/email.d.ts.map +1 -0
- package/dist/server/{linter.d.mts → linter.d.ts} +2 -2
- package/dist/server/linter.d.ts.map +1 -0
- package/dist/server/{sfc-utils.d.mts → sfc-utils.d.ts} +1 -1
- package/dist/server/sfc-utils.d.ts.map +1 -0
- package/dist/server/ui/App.vue +47 -2
- package/dist/server/ui/pages/Preview.vue +110 -22
- package/dist/transformers/{addAttributes.d.mts → addAttributes.d.ts} +2 -2
- package/dist/transformers/addAttributes.d.ts.map +1 -0
- package/dist/transformers/{attributeToStyle.d.mts → attributeToStyle.d.ts} +2 -2
- package/dist/transformers/attributeToStyle.d.ts.map +1 -0
- package/dist/transformers/{base.d.mts → base.d.ts} +2 -2
- package/dist/transformers/base.d.ts.map +1 -0
- package/dist/transformers/{columnWidth.d.mts → columnWidth.d.ts} +10 -10
- package/dist/transformers/columnWidth.d.ts.map +1 -0
- package/dist/transformers/columnWidth.mjs +422 -41
- package/dist/transformers/columnWidth.mjs.map +1 -1
- package/dist/transformers/{entities.d.mts → entities.d.ts} +2 -2
- package/dist/transformers/entities.d.ts.map +1 -0
- package/dist/transformers/filters/{defaults.d.mts → defaults.d.ts} +1 -1
- package/dist/transformers/filters/defaults.d.ts.map +1 -0
- package/dist/transformers/filters/{index.d.mts → index.d.ts} +2 -2
- package/dist/transformers/filters/index.d.ts.map +1 -0
- package/dist/transformers/{format.d.mts → format.d.ts} +2 -2
- package/dist/transformers/format.d.ts.map +1 -0
- package/dist/transformers/{index.d.mts → index.d.ts} +4 -3
- package/dist/transformers/index.d.ts.map +1 -0
- package/dist/transformers/index.mjs +3 -1
- package/dist/transformers/index.mjs.map +1 -1
- package/dist/transformers/{inlineCSS.d.mts → inlineCSS.d.ts} +2 -2
- package/dist/transformers/inlineCSS.d.ts.map +1 -0
- package/dist/transformers/inlineCSS.mjs +7 -1
- package/dist/transformers/inlineCSS.mjs.map +1 -1
- package/dist/transformers/{inlineLink.d.mts → inlineLink.d.ts} +1 -1
- package/dist/transformers/inlineLink.d.ts.map +1 -0
- package/dist/transformers/{minify.d.mts → minify.d.ts} +2 -2
- package/dist/transformers/minify.d.ts.map +1 -0
- package/dist/transformers/{msoWidthFromClass.d.mts → msoWidthFromClass.d.ts} +1 -1
- package/dist/transformers/msoWidthFromClass.d.ts.map +1 -0
- package/dist/transformers/{purgeCSS.d.mts → purgeCSS.d.ts} +2 -2
- package/dist/transformers/purgeCSS.d.ts.map +1 -0
- package/dist/transformers/purgeCSS.mjs +44 -2
- package/dist/transformers/purgeCSS.mjs.map +1 -1
- package/dist/transformers/{removeAttributes.d.mts → removeAttributes.d.ts} +2 -2
- package/dist/transformers/removeAttributes.d.ts.map +1 -0
- package/dist/transformers/{replaceStrings.d.mts → replaceStrings.d.ts} +2 -2
- package/dist/transformers/replaceStrings.d.ts.map +1 -0
- package/dist/transformers/{safeClassNames.d.mts → safeClassNames.d.ts} +2 -2
- package/dist/transformers/safeClassNames.d.ts.map +1 -0
- package/dist/transformers/{shorthandCSS.d.mts → shorthandCSS.d.ts} +2 -2
- package/dist/transformers/shorthandCSS.d.ts.map +1 -0
- package/dist/transformers/{sixHex.d.mts → sixHex.d.ts} +2 -2
- package/dist/transformers/sixHex.d.ts.map +1 -0
- package/dist/transformers/tailwindComponent.d.ts +16 -0
- package/dist/transformers/tailwindComponent.d.ts.map +1 -0
- package/dist/transformers/tailwindComponent.mjs +93 -0
- package/dist/transformers/tailwindComponent.mjs.map +1 -0
- package/dist/transformers/{tailwindcss.d.mts → tailwindcss.d.ts} +2 -2
- package/dist/transformers/tailwindcss.d.ts.map +1 -0
- package/dist/transformers/tailwindcss.mjs +2 -54
- package/dist/transformers/tailwindcss.mjs.map +1 -1
- package/dist/transformers/{urlQuery.d.mts → urlQuery.d.ts} +2 -2
- package/dist/transformers/urlQuery.d.ts.map +1 -0
- package/dist/types/{config.d.mts → config.d.ts} +2 -2
- package/dist/types/config.d.ts.map +1 -0
- package/dist/types/{index.d.mts → index.d.ts} +1 -1
- package/dist/utils/ast/index.d.ts +4 -0
- package/dist/utils/ast/{parser.d.mts → parser.d.ts} +1 -1
- package/dist/utils/ast/parser.d.ts.map +1 -0
- package/dist/utils/ast/{serializer.d.mts → serializer.d.ts} +1 -1
- package/dist/utils/ast/serializer.d.ts.map +1 -0
- package/dist/utils/ast/{walker.d.mts → walker.d.ts} +1 -1
- package/dist/utils/ast/walker.d.ts.map +1 -0
- package/dist/utils/compileTailwindCss.d.ts +16 -0
- package/dist/utils/compileTailwindCss.d.ts.map +1 -0
- package/dist/utils/compileTailwindCss.mjs +55 -0
- package/dist/utils/compileTailwindCss.mjs.map +1 -0
- package/dist/utils/{decodeStyleEntities.d.mts → decodeStyleEntities.d.ts} +1 -1
- package/dist/utils/decodeStyleEntities.d.ts.map +1 -0
- package/dist/utils/{detect.d.mts → detect.d.ts} +1 -1
- package/dist/utils/detect.d.ts.map +1 -0
- package/dist/utils/{url.d.mts → url.d.ts} +1 -1
- package/dist/utils/url.d.ts.map +1 -0
- package/package.json +13 -6
- package/dist/build.d.mts.map +0 -1
- package/dist/components/utils.d.mts.map +0 -1
- package/dist/composables/defineConfig.d.mts.map +0 -1
- package/dist/composables/renderContext.d.mts.map +0 -1
- package/dist/composables/useConfig.d.mts.map +0 -1
- package/dist/composables/useDoctype.d.mts.map +0 -1
- package/dist/composables/useEvent.d.mts.map +0 -1
- package/dist/composables/useFont.d.mts.map +0 -1
- package/dist/composables/usePlaintext.d.mts.map +0 -1
- package/dist/composables/usePreheader.d.mts.map +0 -1
- package/dist/config/defaults.d.mts.map +0 -1
- package/dist/config/index.d.mts.map +0 -1
- package/dist/events/index.d.mts.map +0 -1
- package/dist/index.d.mts +0 -33
- package/dist/plaintext.d.mts.map +0 -1
- package/dist/plugin.d.mts.map +0 -1
- package/dist/plugins/postcss/mergeMediaQueries.d.mts.map +0 -1
- package/dist/plugins/postcss/pruneVars.d.mts.map +0 -1
- package/dist/plugins/postcss/quoteFontFamilies.d.mts.map +0 -1
- package/dist/plugins/postcss/removeDeclarations.d.mts.map +0 -1
- package/dist/plugins/postcss/resolveProps.d.mts.map +0 -1
- package/dist/plugins/postcss/tailwindCleanup.d.mts.map +0 -1
- package/dist/prepare.d.mts.map +0 -1
- package/dist/render/createRenderer.d.mts.map +0 -1
- package/dist/render/index.d.mts +0 -26
- package/dist/render/index.d.mts.map +0 -1
- package/dist/render/injectFonts.d.mts.map +0 -1
- package/dist/render/plugins/rowSourceLocation.d.mts.map +0 -1
- package/dist/serve.d.mts.map +0 -1
- package/dist/server/compatibility.d.mts.map +0 -1
- package/dist/server/email.d.mts.map +0 -1
- package/dist/server/linter.d.mts.map +0 -1
- package/dist/server/sfc-utils.d.mts.map +0 -1
- package/dist/transformers/addAttributes.d.mts.map +0 -1
- package/dist/transformers/attributeToStyle.d.mts.map +0 -1
- package/dist/transformers/base.d.mts.map +0 -1
- package/dist/transformers/columnWidth.d.mts.map +0 -1
- package/dist/transformers/entities.d.mts.map +0 -1
- package/dist/transformers/filters/defaults.d.mts.map +0 -1
- package/dist/transformers/filters/index.d.mts.map +0 -1
- package/dist/transformers/format.d.mts.map +0 -1
- package/dist/transformers/index.d.mts.map +0 -1
- package/dist/transformers/inlineCSS.d.mts.map +0 -1
- package/dist/transformers/inlineLink.d.mts.map +0 -1
- package/dist/transformers/minify.d.mts.map +0 -1
- package/dist/transformers/msoWidthFromClass.d.mts.map +0 -1
- package/dist/transformers/purgeCSS.d.mts.map +0 -1
- package/dist/transformers/removeAttributes.d.mts.map +0 -1
- package/dist/transformers/replaceStrings.d.mts.map +0 -1
- package/dist/transformers/safeClassNames.d.mts.map +0 -1
- package/dist/transformers/shorthandCSS.d.mts.map +0 -1
- package/dist/transformers/sixHex.d.mts.map +0 -1
- package/dist/transformers/tailwindcss.d.mts.map +0 -1
- package/dist/transformers/urlQuery.d.mts.map +0 -1
- package/dist/types/config.d.mts.map +0 -1
- package/dist/utils/ast/index.d.mts +0 -4
- package/dist/utils/ast/parser.d.mts.map +0 -1
- package/dist/utils/ast/serializer.d.mts.map +0 -1
- package/dist/utils/ast/walker.d.mts.map +0 -1
- package/dist/utils/decodeStyleEntities.d.mts.map +0 -1
- package/dist/utils/detect.d.mts.map +0 -1
- package/dist/utils/url.d.mts.map +0 -1
package/dist/serve.mjs
CHANGED
|
@@ -12,6 +12,7 @@ import { glob } from "tinyglobby";
|
|
|
12
12
|
import { fileURLToPath } from "node:url";
|
|
13
13
|
import { createLogger, createServer } from "vite";
|
|
14
14
|
import vue from "@vitejs/plugin-vue";
|
|
15
|
+
import { renderUnicodeCompact } from "uqr";
|
|
15
16
|
import tailwindcss from "@tailwindcss/vite";
|
|
16
17
|
import { createHighlighter } from "shiki";
|
|
17
18
|
|
|
@@ -70,7 +71,9 @@ async function serve(options = {}) {
|
|
|
70
71
|
"lucide-vue-next",
|
|
71
72
|
"class-variance-authority",
|
|
72
73
|
"clsx",
|
|
73
|
-
"tailwind-merge"
|
|
74
|
+
"tailwind-merge",
|
|
75
|
+
"culori",
|
|
76
|
+
"postcss-safe-parser"
|
|
74
77
|
].map((name) => ({
|
|
75
78
|
find: name,
|
|
76
79
|
replacement: pkg(name)
|
|
@@ -271,7 +274,7 @@ async function serveRenderedTemplate(url, config, renderer, res) {
|
|
|
271
274
|
let html = rendered.html;
|
|
272
275
|
const templateConfig = rendered.templateConfig;
|
|
273
276
|
const doctype = rendered.doctype ?? templateConfig.doctype ?? "<!DOCTYPE html>";
|
|
274
|
-
html = await runTransformers(html, templateConfig, absolutePath, doctype);
|
|
277
|
+
html = await runTransformers(html, templateConfig, absolutePath, doctype, rendered.tailwindBlocks);
|
|
275
278
|
html = `${doctype}\n${html}`;
|
|
276
279
|
res.setHeader("Content-Type", "text/html");
|
|
277
280
|
res.end(html);
|
|
@@ -303,7 +306,7 @@ async function serveHighlightedSource(url, config, renderer, res) {
|
|
|
303
306
|
let html = rendered.html;
|
|
304
307
|
const templateConfig = rendered.templateConfig;
|
|
305
308
|
const doctype = rendered.doctype ?? templateConfig.doctype ?? "<!DOCTYPE html>";
|
|
306
|
-
html = await runTransformers(html, templateConfig, absolutePath, doctype);
|
|
309
|
+
html = await runTransformers(html, templateConfig, absolutePath, doctype, rendered.tailwindBlocks);
|
|
307
310
|
html = `${doctype}\n${html}`;
|
|
308
311
|
const highlighted = (await getHighlighter()).codeToHtml(html, {
|
|
309
312
|
lang: "html",
|
|
@@ -359,7 +362,7 @@ async function servePlaintext(url, config, renderer, res) {
|
|
|
359
362
|
let html = rendered.html;
|
|
360
363
|
const templateConfig = rendered.templateConfig;
|
|
361
364
|
const doctype = rendered.doctype ?? templateConfig.doctype ?? "<!DOCTYPE html>";
|
|
362
|
-
html = await runTransformers(html, templateConfig, absolutePath, doctype);
|
|
365
|
+
html = await runTransformers(html, templateConfig, absolutePath, doctype, rendered.tailwindBlocks);
|
|
363
366
|
const plaintext = createPlaintext(html);
|
|
364
367
|
res.setHeader("Content-Type", "text/plain");
|
|
365
368
|
res.end(plaintext);
|
|
@@ -404,7 +407,7 @@ async function serveStats(url, config, renderer, res) {
|
|
|
404
407
|
let html = rendered.html;
|
|
405
408
|
const templateConfig = rendered.templateConfig;
|
|
406
409
|
const doctype = rendered.doctype ?? templateConfig.doctype ?? "<!DOCTYPE html>";
|
|
407
|
-
html = await runTransformers(html, templateConfig, absolutePath, doctype);
|
|
410
|
+
html = await runTransformers(html, templateConfig, absolutePath, doctype, rendered.tailwindBlocks);
|
|
408
411
|
const sizeBytes = Buffer.byteLength(html, "utf-8");
|
|
409
412
|
const totalImages = (html.match(/<img\b[^>]*>/gi) || []).length + (html.match(/url\s*\([^)]+\)/gi) || []).length;
|
|
410
413
|
const links = (html.match(/<a\b[^>]*href\s*=/gi) || []).length;
|
|
@@ -461,7 +464,7 @@ async function serveEmailEndpoint(url, req, res, config, renderer) {
|
|
|
461
464
|
let html = rendered.html;
|
|
462
465
|
const templateConfig = rendered.templateConfig;
|
|
463
466
|
const doctype = rendered.doctype ?? templateConfig.doctype ?? "<!DOCTYPE html>";
|
|
464
|
-
html = await runTransformers(html, templateConfig, absolutePath, doctype);
|
|
467
|
+
html = await runTransformers(html, templateConfig, absolutePath, doctype, rendered.tailwindBlocks);
|
|
465
468
|
html = `${doctype}\n${html}`;
|
|
466
469
|
const text = createPlaintext(html);
|
|
467
470
|
const result = await sendEmail({
|
|
@@ -493,6 +496,12 @@ function serveEmailConfig(config, res) {
|
|
|
493
496
|
function printBanner(server, startupTime) {
|
|
494
497
|
const info = server.config.logger.info;
|
|
495
498
|
const time = startupTime ?? server._maizzleStartupTime;
|
|
499
|
+
const networkUrl = server.resolvedUrls?.network[0];
|
|
500
|
+
if (networkUrl) {
|
|
501
|
+
const qr = renderUnicodeCompact(networkUrl, { border: 1 });
|
|
502
|
+
info("");
|
|
503
|
+
info(qr.split("\n").map((line) => ` ${line}`).join("\n"));
|
|
504
|
+
}
|
|
496
505
|
info("");
|
|
497
506
|
info(` \x1b[32m\x1b[1mMAIZZLE\x1b[0m\x1b[32m v6.0.0\x1b[0m \x1b[2mready in\x1b[0m \x1b[1m${time}\x1b[0m ms`);
|
|
498
507
|
info("");
|
package/dist/serve.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"serve.mjs","names":[],"sources":["../src/serve.ts"],"sourcesContent":["import { readFileSync } from 'node:fs'\nimport { dirname, resolve, basename, matchesGlob } from 'node:path'\nimport { fileURLToPath } from 'node:url'\nimport { createRequire } from 'node:module'\nimport { createServer, createLogger, type ViteDevServer } from 'vite'\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 { resolveConfig } from './config/index.ts'\nimport { runTransformers } from './transformers/index.ts'\nimport { createRenderer, type Renderer } from './render/createRenderer.ts'\nimport { serveCompatibility } from './server/compatibility.ts'\nimport { serveLint } from './server/linter.ts'\nimport { sendEmail } from './server/email.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)\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\nexport interface ServeOptions {\n config?: Partial<MaizzleConfig> | string\n /** Expose the server on the network (e.g. --host) */\n host?: boolean | string\n /** When true, suppresses the banner/URL output (used by the Vite plugin, which prints its own) */\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 = config.server?.port ?? 3000\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: [config.components?.source ?? []].flat(), vite: config.vite })\n\n const server = await createServer({\n configFile: false,\n plugins: [\n // Vue and Tailwind are only for the dev UI SPA, not for email templates\n vue(),\n tailwindcss(),\n maizzleDevPlugin(config, renderer, 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 ...['vue-router', 'reka-ui', '@vueuse/core', '@vueuse/shared', 'lucide-vue-next', '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-next',\n '@vueuse/core',\n '@vueuse/shared',\n 'reka-ui',\n 'class-variance-authority',\n 'clsx',\n 'tailwind-merge',\n 'culori',\n 'postcss-safe-parser',\n ],\n },\n server: {\n port,\n host: options.host,\n fs: {\n allow: [process.cwd(), config.root ?? process.cwd(), devUIDir, ...['vue', 'vue-router', 'reka-ui', '@vueuse/core', '@vueuse/shared', 'lucide-vue-next', 'class-variance-authority', 'clsx', 'tailwind-merge', 'culori', 'postcss-safe-parser'].map(pkg)],\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 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 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 // Prevent Tailwind/Vue from triggering a full reload for email template files.\n // Maizzle handles these via custom HMR events in the watcher below.\n if (isTemplateFile(file)) {\n return []\n }\n },\n },\n\n configureServer(server: ViteDevServer) {\n // File watching\n const defaultWatchPaths = [\n 'maizzle.config.js',\n 'maizzle.config.ts',\n 'tailwind.config.js',\n 'tailwind.config.ts',\n 'locales/**',\n ]\n\n const userWatchPaths = config.server?.watch ?? []\n const watchPaths = [...defaultWatchPaths, ...userWatchPaths]\n const isWatchedFile = (file: string) => watchPaths.some(p => matchesGlob(file, p))\n\n for (const watchPath of watchPaths) {\n server.watcher.add(watchPath)\n }\n\n server.watcher.on('add', async (file) => {\n if (isTemplateFile(file)) {\n await renderer.invalidateAll()\n server.ws.send({ type: 'custom', event: 'maizzle:templates-changed' })\n }\n })\n\n server.watcher.on('unlink', async (file) => {\n if (isTemplateFile(file)) {\n await renderer.invalidateAll()\n server.ws.send({ type: 'custom', event: 'maizzle:templates-changed' })\n }\n })\n\n server.watcher.on('change', async (file) => {\n if (isWatchedFile(file)) {\n config = await resolveConfig(configInput)\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: [config.components?.source ?? []].flat(), vite: config.vite })\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 inject.\n server.ws.send({ type: 'custom', event: 'maizzle:config-updated', data: buildUiConfig(config) })\n }\n\n // Invalidate all renderer modules so component and config changes\n // are picked up on the next render (Tailwind recompiles with fresh content)\n await renderer.invalidateAll()\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, res)\n }\n\n if (url.startsWith('/__maizzle/source/')) {\n return await serveHighlightedSource(url, config, renderer, res)\n }\n\n if (url.startsWith('/__maizzle/compatibility/')) {\n return await serveCompatibility(url, res, config, [config.components?.source ?? []].flat())\n }\n\n if (url.startsWith('/__maizzle/lint/')) {\n return await serveLint(url, res, config, [config.components?.source ?? []].flat())\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, res)\n }\n\n if (url.startsWith('/__maizzle/stats/')) {\n return await serveStats(url, config, renderer, res)\n }\n\n if (url.startsWith('/__maizzle/email/') && req.method === 'POST') {\n return await serveEmailEndpoint(url, req, res, config, renderer)\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\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, 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 try {\n const absolutePath = resolve(match)\n\n // Invalidate all modules so template + component changes are picked up\n await renderer.invalidateAll()\n\n const rendered = await renderer.render(absolutePath, config)\n let html = rendered.html\n\n const templateConfig = rendered.templateConfig\n const doctype = rendered.doctype ?? templateConfig.doctype ?? '<!DOCTYPE html>'\n\n html = await runTransformers(html, templateConfig, absolutePath, doctype)\n html = `${doctype}\\n${html}`\n\n res.setHeader('Content-Type', 'text/html')\n res.end(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, 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 try {\n const absolutePath = resolve(match)\n\n await renderer.invalidateAll()\n\n const rendered = await renderer.render(absolutePath, config)\n let html = rendered.html\n\n const templateConfig = rendered.templateConfig\n const doctype = rendered.doctype ?? templateConfig.doctype ?? '<!DOCTYPE html>'\n html = await runTransformers(html, templateConfig, absolutePath, doctype)\n\n html = `${doctype}\\n${html}`\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, 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 try {\n const absolutePath = resolve(match)\n await renderer.invalidateAll()\n\n const rendered = await renderer.render(absolutePath, config)\n let html = rendered.html\n const templateConfig = rendered.templateConfig\n const doctype = rendered.doctype ?? templateConfig.doctype ?? '<!DOCTYPE html>'\n html = await runTransformers(html, templateConfig, absolutePath, doctype)\n\n const plaintext = createPlaintext(html)\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, 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 try {\n const absolutePath = resolve(match)\n await renderer.invalidateAll()\n\n const rendered = await renderer.render(absolutePath, config)\n let html = rendered.html\n const templateConfig = rendered.templateConfig\n const doctype = rendered.doctype ?? templateConfig.doctype ?? '<!DOCTYPE html>'\n html = await runTransformers(html, templateConfig, absolutePath, doctype)\n\n const sizeBytes = Buffer.byteLength(html, 'utf-8')\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) {\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 try {\n const absolutePath = resolve(match)\n await renderer.invalidateAll()\n\n const rendered = await renderer.render(absolutePath, config)\n let html = rendered.html\n const templateConfig = rendered.templateConfig\n const doctype = rendered.doctype ?? templateConfig.doctype ?? '<!DOCTYPE html>'\n html = await runTransformers(html, templateConfig, absolutePath, doctype)\n html = `${doctype}\\n${html}`\n\n const text = createPlaintext(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 info('')\n info(` \\x1b[32m\\x1b[1mMAIZZLE\\x1b[0m\\x1b[32m v6.0.0\\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.mjs","names":[],"sources":["../src/serve.ts"],"sourcesContent":["import { readFileSync } from 'node:fs'\nimport { dirname, resolve, basename, matchesGlob } 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 { resolveConfig } from './config/index.ts'\nimport { runTransformers } from './transformers/index.ts'\nimport { createRenderer, type Renderer } from './render/createRenderer.ts'\nimport { serveCompatibility } from './server/compatibility.ts'\nimport { serveLint } from './server/linter.ts'\nimport { sendEmail } from './server/email.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)\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\nexport interface ServeOptions {\n config?: Partial<MaizzleConfig> | string\n /** Expose the server on the network (e.g. --host) */\n host?: boolean | string\n /** When true, suppresses the banner/URL output (used by the Vite plugin, which prints its own) */\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 = config.server?.port ?? 3000\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: [config.components?.source ?? []].flat(), vite: config.vite })\n\n const server = await createServer({\n configFile: false,\n plugins: [\n // Vue and Tailwind are only for the dev UI SPA, not for email templates\n vue(),\n tailwindcss(),\n maizzleDevPlugin(config, renderer, 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 ...['vue-router', 'reka-ui', '@vueuse/core', '@vueuse/shared', 'lucide-vue-next', 'class-variance-authority', 'clsx', 'tailwind-merge', 'culori', 'postcss-safe-parser']\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-next',\n '@vueuse/core',\n '@vueuse/shared',\n 'reka-ui',\n 'class-variance-authority',\n 'clsx',\n 'tailwind-merge',\n 'culori',\n 'postcss-safe-parser',\n ],\n },\n server: {\n port,\n host: options.host,\n fs: {\n allow: [process.cwd(), config.root ?? process.cwd(), devUIDir, ...['vue', 'vue-router', 'reka-ui', '@vueuse/core', '@vueuse/shared', 'lucide-vue-next', 'class-variance-authority', 'clsx', 'tailwind-merge', 'culori', 'postcss-safe-parser'].map(pkg)],\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 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 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 // Prevent Tailwind/Vue from triggering a full reload for email template files.\n // Maizzle handles these via custom HMR events in the watcher below.\n if (isTemplateFile(file)) {\n return []\n }\n },\n },\n\n configureServer(server: ViteDevServer) {\n // File watching\n const defaultWatchPaths = [\n 'maizzle.config.js',\n 'maizzle.config.ts',\n 'tailwind.config.js',\n 'tailwind.config.ts',\n 'locales/**',\n ]\n\n const userWatchPaths = config.server?.watch ?? []\n const watchPaths = [...defaultWatchPaths, ...userWatchPaths]\n const isWatchedFile = (file: string) => watchPaths.some(p => matchesGlob(file, p))\n\n for (const watchPath of watchPaths) {\n server.watcher.add(watchPath)\n }\n\n server.watcher.on('add', async (file) => {\n if (isTemplateFile(file)) {\n await renderer.invalidateAll()\n server.ws.send({ type: 'custom', event: 'maizzle:templates-changed' })\n }\n })\n\n server.watcher.on('unlink', async (file) => {\n if (isTemplateFile(file)) {\n await renderer.invalidateAll()\n server.ws.send({ type: 'custom', event: 'maizzle:templates-changed' })\n }\n })\n\n server.watcher.on('change', async (file) => {\n if (isWatchedFile(file)) {\n config = await resolveConfig(configInput)\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: [config.components?.source ?? []].flat(), vite: config.vite })\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 inject.\n server.ws.send({ type: 'custom', event: 'maizzle:config-updated', data: buildUiConfig(config) })\n }\n\n // Invalidate all renderer modules so component and config changes\n // are picked up on the next render (Tailwind recompiles with fresh content)\n await renderer.invalidateAll()\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, res)\n }\n\n if (url.startsWith('/__maizzle/source/')) {\n return await serveHighlightedSource(url, config, renderer, res)\n }\n\n if (url.startsWith('/__maizzle/compatibility/')) {\n return await serveCompatibility(url, res, config, [config.components?.source ?? []].flat())\n }\n\n if (url.startsWith('/__maizzle/lint/')) {\n return await serveLint(url, res, config, [config.components?.source ?? []].flat())\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, res)\n }\n\n if (url.startsWith('/__maizzle/stats/')) {\n return await serveStats(url, config, renderer, res)\n }\n\n if (url.startsWith('/__maizzle/email/') && req.method === 'POST') {\n return await serveEmailEndpoint(url, req, res, config, renderer)\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\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, 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 try {\n const absolutePath = resolve(match)\n\n // Invalidate all modules so template + component changes are picked up\n await renderer.invalidateAll()\n\n const rendered = await renderer.render(absolutePath, config)\n let html = rendered.html\n\n const templateConfig = rendered.templateConfig\n const doctype = rendered.doctype ?? templateConfig.doctype ?? '<!DOCTYPE html>'\n\n html = await runTransformers(html, templateConfig, absolutePath, doctype, rendered.tailwindBlocks)\n html = `${doctype}\\n${html}`\n\n res.setHeader('Content-Type', 'text/html')\n res.end(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, 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 try {\n const absolutePath = resolve(match)\n\n await renderer.invalidateAll()\n\n const rendered = await renderer.render(absolutePath, config)\n let html = rendered.html\n\n const templateConfig = rendered.templateConfig\n const doctype = rendered.doctype ?? templateConfig.doctype ?? '<!DOCTYPE html>'\n html = await runTransformers(html, templateConfig, absolutePath, doctype, rendered.tailwindBlocks)\n\n html = `${doctype}\\n${html}`\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, 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 try {\n const absolutePath = resolve(match)\n await renderer.invalidateAll()\n\n const rendered = await renderer.render(absolutePath, config)\n let html = rendered.html\n const templateConfig = rendered.templateConfig\n const doctype = rendered.doctype ?? templateConfig.doctype ?? '<!DOCTYPE html>'\n html = await runTransformers(html, templateConfig, absolutePath, doctype, rendered.tailwindBlocks)\n\n const plaintext = createPlaintext(html)\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, 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 try {\n const absolutePath = resolve(match)\n await renderer.invalidateAll()\n\n const rendered = await renderer.render(absolutePath, config)\n let html = rendered.html\n const templateConfig = rendered.templateConfig\n const doctype = rendered.doctype ?? templateConfig.doctype ?? '<!DOCTYPE html>'\n html = await runTransformers(html, templateConfig, absolutePath, doctype, rendered.tailwindBlocks)\n\n const sizeBytes = Buffer.byteLength(html, 'utf-8')\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) {\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 try {\n const absolutePath = resolve(match)\n await renderer.invalidateAll()\n\n const rendered = await renderer.render(absolutePath, config)\n let html = rendered.html\n const templateConfig = rendered.templateConfig\n const doctype = rendered.doctype ?? templateConfig.doctype ?? '<!DOCTYPE html>'\n html = await runTransformers(html, templateConfig, absolutePath, doctype, rendered.tailwindBlocks)\n html = `${doctype}\\n${html}`\n\n const text = createPlaintext(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 v6.0.0\\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,4 +1,4 @@
|
|
|
1
|
-
import { MaizzleConfig } from "../types/config.
|
|
1
|
+
import { MaizzleConfig } from "../types/config.js";
|
|
2
2
|
//#region src/server/compatibility.d.ts
|
|
3
3
|
interface Feature {
|
|
4
4
|
slug: string;
|
|
@@ -54,4 +54,4 @@ declare function initCompatibility(): Promise<Indexes | null>;
|
|
|
54
54
|
declare function serveCompatibility(url: string, res: any, config: MaizzleConfig, componentDirs: string[]): Promise<void>;
|
|
55
55
|
//#endregion
|
|
56
56
|
export { initCompatibility, serveCompatibility };
|
|
57
|
-
//# sourceMappingURL=compatibility.d.
|
|
57
|
+
//# sourceMappingURL=compatibility.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"compatibility.d.ts","names":[],"sources":["../../src/server/compatibility.ts"],"mappings":";;UAiBU,OAAA;EACR,IAAA;EACA,KAAA;EACA,GAAA;EACA,QAAA;EACA,KAAA;AAAA;AAAA,UAoBQ,OAAA;EACR,SAAA;IAAa,SAAA;IAAmB,SAAA;IAAmB,WAAA;IAAqB,OAAA;IAAiB,KAAA;EAAA;EACzF,eAAA,EAAiB,MAAA;EACjB,OAAA,EAAS,GAAA,SAAY,OAAA;EACrB,YAAA,EAAc,GAAA,SAAY,KAAA;IAAQ,KAAA;IAAe,OAAA,EAAS,OAAA;EAAA;EAC1D,SAAA,EAAW,GAAA,SAAY,OAAA;EACvB,eAAA,EAAiB,GAAA,SAAY,OAAA;EAC7B,cAAA,EAAgB,GAAA,SAAY,OAAA;EAC5B,gBAAA,EAAkB,GAAA,SAAY,OAAA;EAC9B,WAAA,EAAa,GAAA,SAAY,OAAA;EACzB,OAAA,EAAS,GAAA,SAAY,OAAA;EACrB,YAAA,GAAe,OAAA;EACf,YAAA,GAAe,OAAA;EACf,UAAA,GAAa,OAAA;EACb,WAAA,GAAc,OAAA;EACd,cAAA,GAAiB,OAAA;EACjB,OAAA,EAAS,GAAA,SAAY,OAAA;EACrB,QAAA,EAAU,GAAA,SAAY,OAAA;EACtB,aAAA,EAAe,GAAA,SAAY,OAAA;EAC3B,cAAA,EAAgB,GAAA,SAAY,OAAA;EAC5B,WAAA,GAAc,OAAA;EACd,YAAA,GAAe,OAAA;EACf,eAAA,GAAkB,OAAA;EAClB,eAAA,GAAkB,OAAA;EAClB,mBAAA,GAAsB,OAAA;EACtB,aAAA,GAAgB,OAAA;EAChB,eAAA,GAAkB,OAAA;EAClB,QAAA,EAAU,GAAA,SAAY,OAAA;EATK;EAW3B,MAAA,EAAQ,GAAA;IAAc,KAAA;IAAe,GAAA;EAAA;AAAA;AAAA,iBAsOjB,iBAAA,CAAA,GAAqB,OAAA,CAAQ,OAAA;AAAA,iBA+jB7B,kBAAA,CACpB,GAAA,UACA,GAAA,OACA,MAAA,EAAQ,aAAA,EACR,aAAA,aAAuB,OAAA"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { MaizzleConfig } from "../types/config.
|
|
1
|
+
import { MaizzleConfig } from "../types/config.js";
|
|
2
2
|
//#region src/server/email.d.ts
|
|
3
3
|
interface SendEmailPayload {
|
|
4
4
|
to: string[];
|
|
@@ -14,4 +14,4 @@ interface SendEmailResponse {
|
|
|
14
14
|
declare function sendEmail(payload: SendEmailPayload, config: MaizzleConfig, templateConfig: MaizzleConfig): Promise<SendEmailResponse>;
|
|
15
15
|
//#endregion
|
|
16
16
|
export { SendEmailPayload, sendEmail };
|
|
17
|
-
//# sourceMappingURL=email.d.
|
|
17
|
+
//# sourceMappingURL=email.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"email.d.ts","names":[],"sources":["../../src/server/email.ts"],"mappings":";;UAGiB,gBAAA;EACf,EAAA;EACA,OAAA;EACA,IAAA;EACA,IAAA;AAAA;AAAA,UAGQ,iBAAA;EACR,OAAA;EACA,OAAA;EACA,UAAA;AAAA;AAAA,iBAGoB,SAAA,CACpB,OAAA,EAAS,gBAAA,EACT,MAAA,EAAQ,aAAA,EACR,cAAA,EAAgB,aAAA,GACf,OAAA,CAAQ,iBAAA"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { MaizzleConfig } from "../types/config.
|
|
1
|
+
import { MaizzleConfig } from "../types/config.js";
|
|
2
2
|
//#region src/server/linter.d.ts
|
|
3
3
|
interface LintIssue {
|
|
4
4
|
type: 'error' | 'warning';
|
|
@@ -15,4 +15,4 @@ declare function scanLint(rootFile: string, config: MaizzleConfig, componentDirs
|
|
|
15
15
|
declare function serveLint(url: string, res: any, config: MaizzleConfig, componentDirs: string[]): Promise<void>;
|
|
16
16
|
//#endregion
|
|
17
17
|
export { LintIssue, scanLint, serveLint };
|
|
18
|
-
//# sourceMappingURL=linter.d.
|
|
18
|
+
//# sourceMappingURL=linter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"linter.d.ts","names":[],"sources":["../../src/server/linter.ts"],"mappings":";;UAKiB,SAAA;EACf,IAAA;EACA,KAAA;EACA,OAAA;EAHwB;EAKxB,QAAA;EALwB;EAOxB,IAAA;EACA,IAAA;EACA,IAAA;AAAA;AAAA,iBA8BoB,QAAA,CACpB,QAAA,UACA,MAAA,EAAQ,aAAA,EACR,aAAA,aACC,OAAA,CAAQ,SAAA;AAAA,iBAeW,SAAA,CAAU,GAAA,UAAa,GAAA,OAAU,MAAA,EAAQ,aAAA,EAAe,aAAA,aAAuB,OAAA"}
|
|
@@ -15,4 +15,4 @@ declare function findComponentTags(templateContent: string): string[];
|
|
|
15
15
|
declare function buildComponentMap(root: string, componentDirs: string[]): Promise<Map<string, string>>;
|
|
16
16
|
//#endregion
|
|
17
17
|
export { HTML_ELEMENTS, SfcBlock, buildComponentMap, findComponentTags, parseSfcBlocks };
|
|
18
|
-
//# sourceMappingURL=sfc-utils.d.
|
|
18
|
+
//# sourceMappingURL=sfc-utils.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sfc-utils.d.ts","names":[],"sources":["../../src/server/sfc-utils.ts"],"mappings":";UAOiB,QAAA;EACf,OAAA;EACA,MAAA;AAAA;AAAA,iBAGc,cAAA,CAAe,MAAA;EAAmB,QAAA,EAAU,QAAA;EAAiB,MAAA,EAAQ,QAAA;AAAA;;;;cA4BxE,aAAA,EAAa,GAAA;AAAA,iBAgBV,iBAAA,CAAkB,eAAA;AAAA,iBAqBZ,iBAAA,CAAkB,IAAA,UAAc,aAAA,aAA0B,OAAA,CAAQ,GAAA"}
|
package/dist/server/ui/App.vue
CHANGED
|
@@ -80,6 +80,10 @@ const deviceMenuOpen = ref(false)
|
|
|
80
80
|
const darkMode = ref(false)
|
|
81
81
|
const panelWidth = ref(0)
|
|
82
82
|
const panelHeight = ref(0)
|
|
83
|
+
const iframeWidth = ref<number | null>(null)
|
|
84
|
+
const iframeHeight = ref<number | null>(null)
|
|
85
|
+
const maxIframeWidth = ref(0)
|
|
86
|
+
const maxIframeHeight = ref(0)
|
|
83
87
|
const isDragging = ref(false)
|
|
84
88
|
const isFullSize = ref(true)
|
|
85
89
|
const resetKey = ref(0)
|
|
@@ -89,6 +93,31 @@ function selectDevice(device: DevicePreset) {
|
|
|
89
93
|
viewMode.value = 'preview'
|
|
90
94
|
}
|
|
91
95
|
|
|
96
|
+
/**
|
|
97
|
+
* Writable proxies for the toolbar's size-indicator inputs. Display falls back
|
|
98
|
+
* to the measured panel size when the iframe dimension is null (the axis
|
|
99
|
+
* hasn't been explicitly set yet — e.g. user only dragged one axis).
|
|
100
|
+
* Setter rejects non-finite/non-positive values and clamps to
|
|
101
|
+
* [200, maxIframeWidth] / [100, maxIframeHeight] so users
|
|
102
|
+
* can't push the drag handles off-screen via the input.
|
|
103
|
+
*/
|
|
104
|
+
const widthInput = computed<number>({
|
|
105
|
+
get: () => Math.round(iframeWidth.value ?? panelWidth.value),
|
|
106
|
+
set: (v) => {
|
|
107
|
+
if (typeof v !== 'number' || !Number.isFinite(v) || v <= 0) return
|
|
108
|
+
const max = maxIframeWidth.value || v
|
|
109
|
+
iframeWidth.value = Math.max(200, Math.min(max, Math.round(v)))
|
|
110
|
+
},
|
|
111
|
+
})
|
|
112
|
+
const heightInput = computed<number>({
|
|
113
|
+
get: () => Math.round(iframeHeight.value ?? panelHeight.value),
|
|
114
|
+
set: (v) => {
|
|
115
|
+
if (typeof v !== 'number' || !Number.isFinite(v) || v <= 0) return
|
|
116
|
+
const max = maxIframeHeight.value || v
|
|
117
|
+
iframeHeight.value = Math.max(100, Math.min(max, Math.round(v)))
|
|
118
|
+
},
|
|
119
|
+
})
|
|
120
|
+
|
|
92
121
|
watch(sidebarOpen, (open) => {
|
|
93
122
|
localStorage.setItem('maizzle:sidebar', open ? 'open' : 'closed')
|
|
94
123
|
})
|
|
@@ -332,7 +361,23 @@ onUnmounted(() => {
|
|
|
332
361
|
v-if="isPreviewRoute && (!isFullSize || selectedDevice) && panelWidth"
|
|
333
362
|
class="hidden min-[430px]:inline text-xs font-medium tabular-nums text-gray-500 dark:text-gray-400 select-none"
|
|
334
363
|
>
|
|
335
|
-
|
|
364
|
+
<input
|
|
365
|
+
v-model.number="widthInput"
|
|
366
|
+
type="number"
|
|
367
|
+
min="200"
|
|
368
|
+
:max="maxIframeWidth || undefined"
|
|
369
|
+
aria-label="Preview width"
|
|
370
|
+
class="bg-transparent border-0 outline-none p-0 m-0 text-inherit font-inherit text-center tabular-nums w-[4.5ch] focus:outline-none focus:ring-0 [appearance:textfield] [&::-webkit-inner-spin-button]:appearance-none [&::-webkit-outer-spin-button]:appearance-none"
|
|
371
|
+
>
|
|
372
|
+
<button class="hover:text-gray-700 dark:hover:text-gray-300" @click="selectedDevice = null; isFullSize = true; viewMode = 'preview'; resetKey++">×</button>
|
|
373
|
+
<input
|
|
374
|
+
v-model.number="heightInput"
|
|
375
|
+
type="number"
|
|
376
|
+
min="100"
|
|
377
|
+
:max="maxIframeHeight || undefined"
|
|
378
|
+
aria-label="Preview height"
|
|
379
|
+
class="bg-transparent border-0 outline-none p-0 m-0 text-inherit font-inherit text-center tabular-nums w-[4.5ch] focus:outline-none focus:ring-0 [appearance:textfield] [&::-webkit-inner-spin-button]:appearance-none [&::-webkit-outer-spin-button]:appearance-none"
|
|
380
|
+
>
|
|
336
381
|
</span>
|
|
337
382
|
<div v-if="isPreviewRoute" class="flex items-center gap-1">
|
|
338
383
|
<DropdownMenu v-model:open="deviceMenuOpen" :modal="false">
|
|
@@ -367,7 +412,7 @@ onUnmounted(() => {
|
|
|
367
412
|
<!-- Main content -->
|
|
368
413
|
<div class="flex-1 overflow-hidden">
|
|
369
414
|
<RouterView v-slot="{ Component }">
|
|
370
|
-
<component :is="Component" v-model:view-mode="viewMode" :device="selectedDevice" :reset-key="resetKey" :templates="templates" v-model:panel-width="panelWidth" v-model:panel-height="panelHeight" v-model:is-dragging="isDragging" v-model:is-full-size="isFullSize" v-model:dark-mode="darkMode" @clear-device="selectedDevice = null; isFullSize = false" />
|
|
415
|
+
<component :is="Component" v-model:view-mode="viewMode" :device="selectedDevice" :reset-key="resetKey" :templates="templates" v-model:panel-width="panelWidth" v-model:panel-height="panelHeight" v-model:iframe-width="iframeWidth" v-model:iframe-height="iframeHeight" v-model:max-iframe-width="maxIframeWidth" v-model:max-iframe-height="maxIframeHeight" v-model:is-dragging="isDragging" v-model:is-full-size="isFullSize" v-model:dark-mode="darkMode" @clear-device="selectedDevice = null; isFullSize = false" />
|
|
371
416
|
</RouterView>
|
|
372
417
|
</div>
|
|
373
418
|
</SidebarInset>
|
|
@@ -56,17 +56,29 @@ const copied = ref(false)
|
|
|
56
56
|
const iframeEl = ref<HTMLIFrameElement>()
|
|
57
57
|
const compiledSourceEl = ref<HTMLElement>()
|
|
58
58
|
const vueSourceEl = ref<HTMLElement>()
|
|
59
|
+
const plaintextEl = ref<HTMLElement>()
|
|
59
60
|
const containerEl = ref<HTMLElement>()
|
|
60
61
|
const wrapperEl = ref<HTMLElement>()
|
|
61
62
|
|
|
62
63
|
const panelWidth = defineModel<number>('panelWidth', { default: 0 })
|
|
63
64
|
const panelHeight = defineModel<number>('panelHeight', { default: 0 })
|
|
65
|
+
/**
|
|
66
|
+
* Container's available area, exposed to the toolbar so size inputs can
|
|
67
|
+
* clamp typed values without paying a layout-recalc cost on
|
|
68
|
+
* every drag tick. Kept in sync via a ResizeObserver.
|
|
69
|
+
*/
|
|
70
|
+
const maxIframeWidth = defineModel<number>('maxIframeWidth', { default: 0 })
|
|
71
|
+
const maxIframeHeight = defineModel<number>('maxIframeHeight', { default: 0 })
|
|
64
72
|
const isDragging = defineModel<boolean>('isDragging', { default: false })
|
|
65
73
|
const isFullSize = defineModel<boolean>('isFullSize', { default: true })
|
|
66
74
|
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
75
|
+
/**
|
|
76
|
+
* Custom resizable: width/height of the iframe wrapper (null = fill the
|
|
77
|
+
* container). Exposed as v-models so the toolbar's size indicator
|
|
78
|
+
* can drive these too, alongside the drag handles.
|
|
79
|
+
*/
|
|
80
|
+
const iframeWidth = defineModel<number | null>('iframeWidth', { default: null })
|
|
81
|
+
const iframeHeight = defineModel<number | null>('iframeHeight', { default: null })
|
|
70
82
|
const iframeContentHeight = ref<number | null>(null)
|
|
71
83
|
|
|
72
84
|
function copySource() {
|
|
@@ -271,19 +283,52 @@ async function fetchTemplate() {
|
|
|
271
283
|
}
|
|
272
284
|
}
|
|
273
285
|
|
|
286
|
+
const sourceLoading = ref(false)
|
|
287
|
+
const vueSourceLoading = ref(false)
|
|
288
|
+
const plaintextLoading = ref(false)
|
|
289
|
+
|
|
274
290
|
async function fetchSource() {
|
|
275
|
-
|
|
276
|
-
|
|
291
|
+
if (sourceLoading.value) return
|
|
292
|
+
sourceLoading.value = true
|
|
293
|
+
try {
|
|
294
|
+
const res = await fetch(`/__maizzle/source/${route.params.template}`)
|
|
295
|
+
sourceHtml.value = await res.text()
|
|
296
|
+
} finally {
|
|
297
|
+
sourceLoading.value = false
|
|
298
|
+
}
|
|
277
299
|
}
|
|
278
300
|
|
|
279
301
|
async function fetchVueSource() {
|
|
280
|
-
|
|
281
|
-
|
|
302
|
+
if (vueSourceLoading.value) return
|
|
303
|
+
vueSourceLoading.value = true
|
|
304
|
+
try {
|
|
305
|
+
const res = await fetch(`/__maizzle/vue-source/${route.params.template}`)
|
|
306
|
+
vueSourceHtml.value = await res.text()
|
|
307
|
+
} finally {
|
|
308
|
+
vueSourceLoading.value = false
|
|
309
|
+
}
|
|
282
310
|
}
|
|
283
311
|
|
|
284
312
|
async function fetchPlaintext() {
|
|
285
|
-
|
|
286
|
-
|
|
313
|
+
if (plaintextLoading.value) return
|
|
314
|
+
plaintextLoading.value = true
|
|
315
|
+
try {
|
|
316
|
+
const res = await fetch(`/__maizzle/plaintext/${route.params.template}`)
|
|
317
|
+
plaintextContent.value = await res.text()
|
|
318
|
+
} finally {
|
|
319
|
+
plaintextLoading.value = false
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
/**
|
|
324
|
+
* Warm the three source views in the background so switching from the
|
|
325
|
+
* preview is instant. Single-flight guards above prevent duplication
|
|
326
|
+
* with any in-flight fetch from a view-switch watcher.
|
|
327
|
+
*/
|
|
328
|
+
function prefetchSources() {
|
|
329
|
+
if (!sourceHtml.value) fetchSource()
|
|
330
|
+
if (!vueSourceHtml.value) fetchVueSource()
|
|
331
|
+
if (!plaintextContent.value) fetchPlaintext()
|
|
287
332
|
}
|
|
288
333
|
|
|
289
334
|
async function fetchStats() {
|
|
@@ -357,7 +402,7 @@ watch(() => route.params.template, () => {
|
|
|
357
402
|
stats.value = null
|
|
358
403
|
emailResult.value = null
|
|
359
404
|
sourceView.value = 'compiled'
|
|
360
|
-
fetchTemplate()
|
|
405
|
+
fetchTemplate().then(prefetchSources)
|
|
361
406
|
fetchCompatibility()
|
|
362
407
|
fetchStats()
|
|
363
408
|
fetchEmailConfig()
|
|
@@ -385,23 +430,47 @@ watch(sourceView, (view) => {
|
|
|
385
430
|
if (view === 'plaintext' && !plaintextContent.value) fetchPlaintext()
|
|
386
431
|
})
|
|
387
432
|
|
|
433
|
+
/**
|
|
434
|
+
* Preserve scrollTop across in-place content updates (HMR refetch).
|
|
435
|
+
* Vue's default `flush: 'pre'` runs the watcher BEFORE the DOM is
|
|
436
|
+
* updated — so we read the current scrollTop, then restore it on the
|
|
437
|
+
* next tick after the new content has rendered. Skip the case where
|
|
438
|
+
* the value transitions from empty (first paint / route change) so a
|
|
439
|
+
* fresh template doesn't snap to a stale offset.
|
|
440
|
+
*/
|
|
441
|
+
function viewportFor(el: HTMLElement | undefined): HTMLElement | null {
|
|
442
|
+
return (el?.closest('[data-slot="scroll-area-viewport"]') as HTMLElement | null) ?? null
|
|
443
|
+
}
|
|
444
|
+
|
|
445
|
+
function preserveScroll(getEl: () => HTMLElement | undefined) {
|
|
446
|
+
return async (newVal: string, oldVal: string) => {
|
|
447
|
+
if (!oldVal || !newVal) return
|
|
448
|
+
const vp = viewportFor(getEl())
|
|
449
|
+
if (!vp) return
|
|
450
|
+
const top = vp.scrollTop
|
|
451
|
+
await nextTick()
|
|
452
|
+
vp.scrollTop = top
|
|
453
|
+
}
|
|
454
|
+
}
|
|
455
|
+
|
|
456
|
+
watch(sourceHtml, preserveScroll(() => compiledSourceEl.value))
|
|
457
|
+
watch(vueSourceHtml, preserveScroll(() => vueSourceEl.value))
|
|
458
|
+
watch(plaintextContent, preserveScroll(() => plaintextEl.value))
|
|
459
|
+
|
|
388
460
|
if ((import.meta as any).hot) {
|
|
389
461
|
;(import.meta as any).hot.on('maizzle:template-updated', () => {
|
|
390
|
-
fetchTemplate()
|
|
391
462
|
fetchCompatibility()
|
|
392
463
|
fetchStats()
|
|
393
464
|
|
|
394
|
-
//
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
if (sourceView.value === 'plaintext') fetchPlaintext()
|
|
404
|
-
}
|
|
465
|
+
// Refetch in place — don't clear the previous values first. v-html
|
|
466
|
+
// replaces the highlighted block atomically when the new content
|
|
467
|
+
// arrives, and the ScrollArea viewport keeps its scrollTop as long
|
|
468
|
+
// as the new content's height is similar. Plaintext interpolation
|
|
469
|
+
// updates a single text node, so scroll is naturally preserved.
|
|
470
|
+
fetchTemplate()
|
|
471
|
+
fetchSource()
|
|
472
|
+
fetchVueSource()
|
|
473
|
+
fetchPlaintext()
|
|
405
474
|
})
|
|
406
475
|
|
|
407
476
|
// Keep the UI in sync with live config edits. Payload is the same shape
|
|
@@ -508,6 +577,7 @@ function updateFullSize() {
|
|
|
508
577
|
&& (iframeHeight.value === null || iframeHeight.value >= rect.height - gutter - 2)
|
|
509
578
|
}
|
|
510
579
|
|
|
580
|
+
|
|
511
581
|
function applyDeviceSize(device: Device | null | undefined) {
|
|
512
582
|
if (!device) {
|
|
513
583
|
iframeWidth.value = null
|
|
@@ -544,6 +614,7 @@ watch(viewMode, async (mode) => {
|
|
|
544
614
|
})
|
|
545
615
|
|
|
546
616
|
let observer: ResizeObserver | null = null
|
|
617
|
+
let containerObserver: ResizeObserver | null = null
|
|
547
618
|
|
|
548
619
|
function forwardIframeKeys(iframe: HTMLIFrameElement) {
|
|
549
620
|
try {
|
|
@@ -580,6 +651,21 @@ onMounted(() => {
|
|
|
580
651
|
observer.observe(wrapper)
|
|
581
652
|
}
|
|
582
653
|
|
|
654
|
+
const container = containerEl.value
|
|
655
|
+
if (container) {
|
|
656
|
+
const gutter = 40
|
|
657
|
+
const rect = container.getBoundingClientRect()
|
|
658
|
+
maxIframeWidth.value = Math.max(0, Math.round(rect.width - gutter))
|
|
659
|
+
maxIframeHeight.value = Math.max(0, Math.round(rect.height - gutter))
|
|
660
|
+
containerObserver = new ResizeObserver((entries) => {
|
|
661
|
+
for (const entry of entries) {
|
|
662
|
+
maxIframeWidth.value = Math.max(0, Math.round(entry.contentRect.width - gutter))
|
|
663
|
+
maxIframeHeight.value = Math.max(0, Math.round(entry.contentRect.height - gutter))
|
|
664
|
+
}
|
|
665
|
+
})
|
|
666
|
+
containerObserver.observe(container)
|
|
667
|
+
}
|
|
668
|
+
|
|
583
669
|
const el = iframeEl.value
|
|
584
670
|
if (el) {
|
|
585
671
|
el.addEventListener('load', () => forwardIframeKeys(el))
|
|
@@ -588,6 +674,7 @@ onMounted(() => {
|
|
|
588
674
|
|
|
589
675
|
onUnmounted(() => {
|
|
590
676
|
observer?.disconnect()
|
|
677
|
+
containerObserver?.disconnect()
|
|
591
678
|
})
|
|
592
679
|
|
|
593
680
|
const bottomPanelOpen = ref(false)
|
|
@@ -718,6 +805,7 @@ const stripeBg = {
|
|
|
718
805
|
</ScrollArea>
|
|
719
806
|
<ScrollArea v-show="sourceView === 'plaintext'" class="h-full [&_[data-slot=scroll-area-viewport]>div]:flex [&_[data-slot=scroll-area-viewport]>div]:flex-col [&_[data-slot=scroll-area-viewport]>div]:min-h-full">
|
|
720
807
|
<pre
|
|
808
|
+
ref="plaintextEl"
|
|
721
809
|
class="p-6 pt-14 text-sm leading-6 flex-1 text-gray-300 bg-[#27212e] dark:bg-gray-950 whitespace-pre-wrap break-words"
|
|
722
810
|
>{{ plaintextContent }}</pre>
|
|
723
811
|
</ScrollArea>
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { AttributesConfig } from "../types/config.
|
|
1
|
+
import { AttributesConfig } from "../types/config.js";
|
|
2
2
|
import { ChildNode } from "domhandler";
|
|
3
3
|
|
|
4
4
|
//#region src/transformers/addAttributes.d.ts
|
|
@@ -29,4 +29,4 @@ import { ChildNode } from "domhandler";
|
|
|
29
29
|
declare function addAttributes(dom: ChildNode[], config?: AttributesConfig): ChildNode[];
|
|
30
30
|
//#endregion
|
|
31
31
|
export { addAttributes };
|
|
32
|
-
//# sourceMappingURL=addAttributes.d.
|
|
32
|
+
//# sourceMappingURL=addAttributes.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"addAttributes.d.ts","names":[],"sources":["../../src/transformers/addAttributes.ts"],"mappings":";;;;;;AA2CA;;;;;;;;;;;;;;;;;;;;;;iBAAgB,aAAA,CAAc,GAAA,EAAK,SAAA,IAAa,MAAA,GAAQ,gBAAA,GAAwB,SAAA"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { CssConfig } from "../types/config.
|
|
1
|
+
import { CssConfig } from "../types/config.js";
|
|
2
2
|
import { ChildNode } from "domhandler";
|
|
3
3
|
|
|
4
4
|
//#region src/transformers/attributeToStyle.d.ts
|
|
@@ -22,4 +22,4 @@ import { ChildNode } from "domhandler";
|
|
|
22
22
|
declare function attributeToStyle(dom: ChildNode[], config?: CssConfig): ChildNode[];
|
|
23
23
|
//#endregion
|
|
24
24
|
export { attributeToStyle };
|
|
25
|
-
//# sourceMappingURL=attributeToStyle.d.
|
|
25
|
+
//# sourceMappingURL=attributeToStyle.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"attributeToStyle.d.ts","names":[],"sources":["../../src/transformers/attributeToStyle.ts"],"mappings":";;;;;;AA0BA;;;;;;;;;;;;;;;iBAAgB,gBAAA,CAAiB,GAAA,EAAK,SAAA,IAAa,MAAA,GAAQ,SAAA,GAAiB,SAAA"}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { UrlConfig } from "../types/config.
|
|
1
|
+
import { UrlConfig } from "../types/config.js";
|
|
2
2
|
import { ChildNode } from "domhandler";
|
|
3
3
|
|
|
4
4
|
//#region src/transformers/base.d.ts
|
|
5
5
|
declare function base(dom: ChildNode[], config?: UrlConfig): ChildNode[];
|
|
6
6
|
//#endregion
|
|
7
7
|
export { base };
|
|
8
|
-
//# sourceMappingURL=base.d.
|
|
8
|
+
//# sourceMappingURL=base.d.ts.map
|