markopress 0.0.2 → 0.0.4
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/index.d.ts +0 -1
- package/dist/build/index.js +1 -1627
- package/dist/build/types.d.ts +0 -1
- package/dist/build/types.js +1 -5
- package/dist/build/vite-markdown-plugin.d.ts +0 -1
- package/dist/build/vite-markdown-plugin.js +1 -147
- package/dist/cli/index.d.ts +0 -1
- package/dist/cli/index.js +1 -74
- package/dist/config/app-root.d.ts +0 -1
- package/dist/config/app-root.js +1 -24
- package/dist/config/index.d.ts +0 -1
- package/dist/config/index.js +1 -6
- package/dist/config/loader.d.ts +0 -1
- package/dist/config/loader.js +1 -188
- package/dist/config/types.d.ts +0 -1
- package/dist/config/types.js +1 -5
- package/dist/config/validation.d.ts +0 -1
- package/dist/config/validation.js +1 -139
- package/dist/content/index.d.ts +0 -1
- package/dist/content/index.js +1 -6
- package/dist/content/registry.d.ts +0 -1
- package/dist/content/registry.js +1 -45
- package/dist/content/types.d.ts +0 -1
- package/dist/content/types.js +1 -5
- package/dist/dev/index.d.ts +0 -1
- package/dist/dev/index.js +1 -93
- package/dist/index.d.ts +0 -1
- package/dist/index.js +1 -17
- package/dist/markdown/base-path-plugin.d.ts +16 -0
- package/dist/markdown/base-path-plugin.js +1 -0
- package/dist/markdown/code.d.ts +0 -1
- package/dist/markdown/code.js +1 -305
- package/dist/markdown/containers.d.ts +0 -1
- package/dist/markdown/containers.js +1 -143
- package/dist/markdown/includes.d.ts +0 -1
- package/dist/markdown/includes.js +1 -9
- package/dist/markdown/index.d.ts +0 -1
- package/dist/markdown/index.js +1 -8
- package/dist/markdown/loader.d.ts +0 -1
- package/dist/markdown/loader.js +1 -325
- package/dist/markdown/md-link-plugin.d.ts +14 -0
- package/dist/markdown/md-link-plugin.js +1 -0
- package/dist/markdown/preserve-tags.d.ts +0 -1
- package/dist/markdown/preserve-tags.js +1 -233
- package/dist/markdown/renderer.d.ts +0 -1
- package/dist/markdown/renderer.js +1 -146
- package/dist/markdown/tag-validator.d.ts +0 -1
- package/dist/markdown/tag-validator.js +1 -118
- package/dist/markdown/types.d.ts +2 -1
- package/dist/markdown/types.js +1 -5
- package/dist/plugin/compat.d.ts +0 -1
- package/dist/plugin/compat.js +1 -78
- package/dist/plugin/context.d.ts +0 -1
- package/dist/plugin/context.js +1 -103
- package/dist/plugin/index.d.ts +0 -1
- package/dist/plugin/index.js +1 -6
- package/dist/plugin/manager.d.ts +0 -1
- package/dist/plugin/manager.js +1 -385
- package/dist/plugin/types.d.ts +1 -1
- package/dist/plugin/types.js +1 -5
- package/dist/plugins/blog-index/index.d.ts +0 -1
- package/dist/plugins/blog-index/index.js +1 -158
- package/dist/plugins/sidenav/index.d.ts +0 -1
- package/dist/plugins/sidenav/index.js +1 -86
- package/dist/plugins/toc/index.d.ts +0 -1
- package/dist/plugins/toc/index.js +1 -79
- package/dist/preview/index.d.ts +0 -1
- package/dist/preview/index.js +1 -25
- package/dist/theme/default/design-systems/default.d.ts +0 -1
- package/dist/theme/default/design-systems/default.js +1 -289
- package/dist/theme/default/design-systems/docusaurus.d.ts +0 -1
- package/dist/theme/default/design-systems/docusaurus.js +1 -299
- package/dist/theme/default/design-systems/index.d.ts +0 -1
- package/dist/theme/default/design-systems/index.js +1 -54
- package/dist/theme/default/design-systems/rspress.d.ts +0 -1
- package/dist/theme/default/design-systems/rspress.js +1 -299
- package/dist/theme/default/design-systems/types.d.ts +0 -1
- package/dist/theme/default/design-systems/types.js +1 -6
- package/dist/theme/default/design-systems/vitepress.d.ts +0 -1
- package/dist/theme/default/design-systems/vitepress.js +1 -299
- package/dist/theme/default/index.d.ts +0 -1
- package/dist/theme/default/index.js +1 -44
- package/dist/theme/default/theme.d.ts +0 -1
- package/dist/theme/default/theme.js +1 -58
- package/dist/theme/index.d.ts +0 -1
- package/dist/theme/index.js +1 -6
- package/dist/theme/loader.d.ts +0 -1
- package/dist/theme/loader.js +1 -125
- package/dist/theme/types.d.ts +1 -1
- package/dist/theme/types.js +1 -5
- package/dist/vite/index.d.ts +0 -1
- package/dist/vite/index.js +1 -6
- package/dist/vite/markdownPlugin.d.ts +0 -1
- package/dist/vite/markdownPlugin.js +1 -111
- package/dist/vite/plugin.d.ts +0 -1
- package/dist/vite/plugin.js +1 -94
- package/package.json +3 -2
- package/src/theme/default/layouts/blog.marko +1 -1
- package/src/theme/default/layouts/default.marko +5 -5
- package/src/theme/default/layouts/docs.marko +6 -6
- package/src/theme/default/layouts/page.marko +1 -1
- package/templates/catch-all-handler.js.template +2 -17
- package/dist/build/index.d.ts.map +0 -1
- package/dist/build/index.js.map +0 -1
- package/dist/build/manifest-generator.d.ts +0 -34
- package/dist/build/manifest-generator.d.ts.map +0 -1
- package/dist/build/manifest-generator.js +0 -86
- package/dist/build/manifest-generator.js.map +0 -1
- package/dist/build/security.test.d.ts +0 -6
- package/dist/build/security.test.d.ts.map +0 -1
- package/dist/build/security.test.js +0 -88
- package/dist/build/security.test.js.map +0 -1
- package/dist/build/types.d.ts.map +0 -1
- package/dist/build/types.js.map +0 -1
- package/dist/build/vite-config.test.d.ts +0 -2
- package/dist/build/vite-config.test.d.ts.map +0 -1
- package/dist/build/vite-config.test.js +0 -53
- package/dist/build/vite-config.test.js.map +0 -1
- package/dist/build/vite-markdown-plugin.d.ts.map +0 -1
- package/dist/build/vite-markdown-plugin.js.map +0 -1
- package/dist/build/vite-markdown-plugin.test.d.ts +0 -2
- package/dist/build/vite-markdown-plugin.test.d.ts.map +0 -1
- package/dist/build/vite-markdown-plugin.test.js +0 -41
- package/dist/build/vite-markdown-plugin.test.js.map +0 -1
- package/dist/cli/index.d.ts.map +0 -1
- package/dist/cli/index.js.map +0 -1
- package/dist/config/app-root.d.ts.map +0 -1
- package/dist/config/app-root.js.map +0 -1
- package/dist/config/app-root.test.d.ts +0 -2
- package/dist/config/app-root.test.d.ts.map +0 -1
- package/dist/config/app-root.test.js +0 -71
- package/dist/config/app-root.test.js.map +0 -1
- package/dist/config/index.d.ts.map +0 -1
- package/dist/config/index.js.map +0 -1
- package/dist/config/loader.d.ts.map +0 -1
- package/dist/config/loader.js.map +0 -1
- package/dist/config/loader.test.d.ts +0 -2
- package/dist/config/loader.test.d.ts.map +0 -1
- package/dist/config/loader.test.js +0 -24
- package/dist/config/loader.test.js.map +0 -1
- package/dist/config/types.d.ts.map +0 -1
- package/dist/config/types.js.map +0 -1
- package/dist/config/validation.d.ts.map +0 -1
- package/dist/config/validation.js.map +0 -1
- package/dist/content/index.d.ts.map +0 -1
- package/dist/content/index.js.map +0 -1
- package/dist/content/registry.d.ts.map +0 -1
- package/dist/content/registry.js.map +0 -1
- package/dist/content/scanner.d.ts +0 -9
- package/dist/content/scanner.d.ts.map +0 -1
- package/dist/content/scanner.js +0 -115
- package/dist/content/scanner.js.map +0 -1
- package/dist/content/types.d.ts.map +0 -1
- package/dist/content/types.js.map +0 -1
- package/dist/dev/index.d.ts.map +0 -1
- package/dist/dev/index.js.map +0 -1
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/markdown/code.d.ts.map +0 -1
- package/dist/markdown/code.js.map +0 -1
- package/dist/markdown/containers.d.ts.map +0 -1
- package/dist/markdown/containers.js.map +0 -1
- package/dist/markdown/includes.d.ts.map +0 -1
- package/dist/markdown/includes.js.map +0 -1
- package/dist/markdown/index.d.ts.map +0 -1
- package/dist/markdown/index.js.map +0 -1
- package/dist/markdown/loader.d.ts.map +0 -1
- package/dist/markdown/loader.js.map +0 -1
- package/dist/markdown/preserve-tags.d.ts.map +0 -1
- package/dist/markdown/preserve-tags.js.map +0 -1
- package/dist/markdown/renderer.d.ts.map +0 -1
- package/dist/markdown/renderer.js.map +0 -1
- package/dist/markdown/tag-validator.d.ts.map +0 -1
- package/dist/markdown/tag-validator.js.map +0 -1
- package/dist/markdown/types.d.ts.map +0 -1
- package/dist/markdown/types.js.map +0 -1
- package/dist/plugin/compat.d.ts.map +0 -1
- package/dist/plugin/compat.js.map +0 -1
- package/dist/plugin/context.d.ts.map +0 -1
- package/dist/plugin/context.js.map +0 -1
- package/dist/plugin/index.d.ts.map +0 -1
- package/dist/plugin/index.js.map +0 -1
- package/dist/plugin/manager.d.ts.map +0 -1
- package/dist/plugin/manager.js.map +0 -1
- package/dist/plugin/types.d.ts.map +0 -1
- package/dist/plugin/types.js.map +0 -1
- package/dist/plugins/blog-index/index.d.ts.map +0 -1
- package/dist/plugins/blog-index/index.js.map +0 -1
- package/dist/plugins/sidenav/index.d.ts.map +0 -1
- package/dist/plugins/sidenav/index.js.map +0 -1
- package/dist/plugins/toc/index.d.ts.map +0 -1
- package/dist/plugins/toc/index.js.map +0 -1
- package/dist/preview/index.d.ts.map +0 -1
- package/dist/preview/index.js.map +0 -1
- package/dist/theme/default/build/generate-all.d.ts +0 -9
- package/dist/theme/default/build/generate-all.d.ts.map +0 -1
- package/dist/theme/default/build/generate-all.js +0 -85
- package/dist/theme/default/build/generate-all.js.map +0 -1
- package/dist/theme/default/build/generate-css.d.ts +0 -19
- package/dist/theme/default/build/generate-css.d.ts.map +0 -1
- package/dist/theme/default/build/generate-css.js +0 -199
- package/dist/theme/default/build/generate-css.js.map +0 -1
- package/dist/theme/default/build/index.d.ts +0 -5
- package/dist/theme/default/build/index.d.ts.map +0 -1
- package/dist/theme/default/build/index.js +0 -5
- package/dist/theme/default/build/index.js.map +0 -1
- package/dist/theme/default/design-systems/default.d.ts.map +0 -1
- package/dist/theme/default/design-systems/default.js.map +0 -1
- package/dist/theme/default/design-systems/docusaurus.d.ts.map +0 -1
- package/dist/theme/default/design-systems/docusaurus.js.map +0 -1
- package/dist/theme/default/design-systems/index.d.ts.map +0 -1
- package/dist/theme/default/design-systems/index.js.map +0 -1
- package/dist/theme/default/design-systems/rspress.d.ts.map +0 -1
- package/dist/theme/default/design-systems/rspress.js.map +0 -1
- package/dist/theme/default/design-systems/types.d.ts.map +0 -1
- package/dist/theme/default/design-systems/types.js.map +0 -1
- package/dist/theme/default/design-systems/vitepress.d.ts.map +0 -1
- package/dist/theme/default/design-systems/vitepress.js.map +0 -1
- package/dist/theme/default/index.d.ts.map +0 -1
- package/dist/theme/default/index.js.map +0 -1
- package/dist/theme/default/theme.d.ts.map +0 -1
- package/dist/theme/default/theme.js.map +0 -1
- package/dist/theme/index.d.ts.map +0 -1
- package/dist/theme/index.js.map +0 -1
- package/dist/theme/loader.d.ts.map +0 -1
- package/dist/theme/loader.js.map +0 -1
- package/dist/theme/types.d.ts.map +0 -1
- package/dist/theme/types.js.map +0 -1
- package/dist/vite/index.d.ts.map +0 -1
- package/dist/vite/index.js.map +0 -1
- package/dist/vite/markdownPlugin.d.ts.map +0 -1
- package/dist/vite/markdownPlugin.js.map +0 -1
- package/dist/vite/plugin.d.ts.map +0 -1
- package/dist/vite/plugin.js.map +0 -1
- package/src/theme/default/build/generate-all.ts +0 -99
- package/src/theme/default/build/generate-css.ts +0 -234
- package/src/theme/default/build/index.ts +0 -5
- package/src/theme/default/components/doc-footer.marko +0 -180
- package/src/theme/default/components/footer.marko +0 -32
- package/src/theme/default/components/header.marko +0 -49
- package/src/theme/default/components/nav-bar.marko +0 -191
- package/src/theme/default/components/page-header.marko +0 -20
- package/src/theme/default/components/reading-progress.marko +0 -36
- package/src/theme/default/components/search.marko +0 -239
- package/src/theme/default/components/sidebar.marko +0 -211
- package/src/theme/default/components/site-footer.marko +0 -211
- package/src/theme/default/components/skip-link.marko +0 -49
- package/src/theme/default/components/theme/theme-aside-bottom.marko +0 -1
- package/src/theme/default/components/theme/theme-aside-top.marko +0 -1
- package/src/theme/default/components/theme/theme-body-bottom.marko +0 -1
- package/src/theme/default/components/theme/theme-body-top.marko +0 -1
- package/src/theme/default/components/theme/theme-doc-bottom.marko +0 -1
- package/src/theme/default/components/theme/theme-doc-footer-after.marko +0 -1
- package/src/theme/default/components/theme/theme-doc-footer-before.marko +0 -1
- package/src/theme/default/components/theme/theme-doc-top.marko +0 -1
- package/src/theme/default/components/theme/theme-head-bottom.marko +0 -1
- package/src/theme/default/components/theme/theme-head-top.marko +0 -1
- package/src/theme/default/components/theme/theme-home-features-after.marko +0 -1
- package/src/theme/default/components/theme/theme-home-hero-after.marko +0 -1
- package/src/theme/default/components/theme/theme-home-hero-before.marko +0 -1
- package/src/theme/default/components/theme/theme-navbar-center.marko +0 -5
- package/src/theme/default/components/theme/theme-navbar-end.marko +0 -30
- package/src/theme/default/components/theme/theme-navbar-start.marko +0 -1
- package/src/theme/default/components/theme/theme-page-bottom.marko +0 -1
- package/src/theme/default/components/theme/theme-page-top.marko +0 -1
- package/src/theme/default/components/theme/theme-sidebar-bottom.marko +0 -1
- package/src/theme/default/components/theme/theme-sidebar-top.marko +0 -1
- package/src/theme/default/components/theme/theme-toc-item.marko +0 -1
- package/src/theme/default/components/theme-toggle.marko +0 -122
- package/src/theme/default/components/toc.marko +0 -140
- package/src/theme/default/design-systems/default.ts +0 -331
- package/src/theme/default/design-systems/docusaurus.ts +0 -341
- package/src/theme/default/design-systems/index.ts +0 -67
- package/src/theme/default/design-systems/rspress.ts +0 -341
- package/src/theme/default/design-systems/types.ts +0 -296
- package/src/theme/default/design-systems/vitepress.ts +0 -341
- package/src/theme/default/index.ts +0 -107
- package/src/theme/default/theme.ts +0 -83
- package/templates/example-tags/README.md +0 -212
- package/templates/example-tags/alert-box.marko +0 -98
- package/templates/example-tags/button-primary.marko +0 -28
- package/templates/example-tags/button-secondary.marko +0 -28
- package/templates/example-tags/button.marko +0 -6
- package/templates/example-tags/card-body.marko +0 -8
- package/templates/example-tags/card-footer.marko +0 -7
- package/templates/example-tags/card-header.marko +0 -7
- package/templates/example-tags/card.marko +0 -20
- package/templates/example-tags/icon.marko +0 -149
package/dist/build/types.d.ts
CHANGED
package/dist/build/types.js
CHANGED
|
@@ -1,147 +1 @@
|
|
|
1
|
-
import path from
|
|
2
|
-
import { existsSync } from 'node:fs';
|
|
3
|
-
const GLOBAL_COMPONENTS_KEY = '__MARKOPRESS_MARKDOWN_COMPONENTS__';
|
|
4
|
-
const markdownComponents = globalThis[GLOBAL_COMPONENTS_KEY] ??= new Map();
|
|
5
|
-
const virtualIds = new Map();
|
|
6
|
-
const VIRTUAL_PREFIX = 'virtual:markdown-content/';
|
|
7
|
-
const MARKO_SUFFIX = '.marko';
|
|
8
|
-
export function registerMarkdownContent(id, html) {
|
|
9
|
-
markdownComponents.set(id, html);
|
|
10
|
-
}
|
|
11
|
-
export function getMarkdownContent(id) {
|
|
12
|
-
return markdownComponents.get(id);
|
|
13
|
-
}
|
|
14
|
-
export function markdownContentPlugin() {
|
|
15
|
-
const virtualModuleId = 'virtual:markdown-content';
|
|
16
|
-
const resolvedVirtualModuleId = '\0' + virtualModuleId;
|
|
17
|
-
let rootDir = process.cwd();
|
|
18
|
-
let generatedDir = toPosixPath(path.join(rootDir, 'src', '.generated', 'markdown'));
|
|
19
|
-
const debug = (msg, data) => {
|
|
20
|
-
try {
|
|
21
|
-
const fs = require('node:fs');
|
|
22
|
-
fs.appendFileSync('/tmp/markopress-plugin-debug.log', `${msg}: ${JSON.stringify(data)}\n`);
|
|
23
|
-
}
|
|
24
|
-
catch {
|
|
25
|
-
// Ignore
|
|
26
|
-
}
|
|
27
|
-
};
|
|
28
|
-
debug('PLUGIN_FUNCTION_CALLED', { timestamp: Date.now() });
|
|
29
|
-
return {
|
|
30
|
-
name: 'markopress-markdown-content',
|
|
31
|
-
enforce: 'pre',
|
|
32
|
-
configResolved(config) {
|
|
33
|
-
rootDir = config.root || process.cwd();
|
|
34
|
-
generatedDir = toPosixPath(path.join(rootDir, 'src', '.generated', 'markdown'));
|
|
35
|
-
},
|
|
36
|
-
resolveId(id, importer) {
|
|
37
|
-
debug('resolveId', { id, importer });
|
|
38
|
-
if (id.startsWith(VIRTUAL_PREFIX)) {
|
|
39
|
-
const moduleId = id.slice(VIRTUAL_PREFIX.length);
|
|
40
|
-
const normalizedId = moduleId.endsWith(MARKO_SUFFIX)
|
|
41
|
-
? moduleId
|
|
42
|
-
: `${moduleId}${MARKO_SUFFIX}`;
|
|
43
|
-
const resolved = toPosixPath(path.join(generatedDir, normalizedId));
|
|
44
|
-
const contentId = moduleId.endsWith(MARKO_SUFFIX)
|
|
45
|
-
? moduleId.slice(0, -MARKO_SUFFIX.length)
|
|
46
|
-
: moduleId;
|
|
47
|
-
virtualIds.set(resolved, contentId);
|
|
48
|
-
debug('resolveId_MATCH', { id, resolved });
|
|
49
|
-
return resolved;
|
|
50
|
-
}
|
|
51
|
-
return undefined;
|
|
52
|
-
},
|
|
53
|
-
load(id) {
|
|
54
|
-
debug('load', { id });
|
|
55
|
-
const contentId = resolveContentId(id, generatedDir);
|
|
56
|
-
if (!contentId) {
|
|
57
|
-
return undefined;
|
|
58
|
-
}
|
|
59
|
-
// If the file exists on disk (pre-rendered during build), let Vite handle it normally
|
|
60
|
-
const cleanPath = id.split('?', 1)[0];
|
|
61
|
-
if (existsSync(cleanPath)) {
|
|
62
|
-
debug('load_FILE_EXISTS', { contentId, cleanPath });
|
|
63
|
-
return undefined;
|
|
64
|
-
}
|
|
65
|
-
debug('load_MATCH', { contentId, storedKeys: Array.from(markdownComponents.keys()) });
|
|
66
|
-
const html = markdownComponents.get(contentId);
|
|
67
|
-
if (!html) {
|
|
68
|
-
debug('load_NO_HTML', { contentId });
|
|
69
|
-
return `<div class="markdown-content">\n <div class="markdown-placeholder">Content not found: ${escapeHtml(contentId)}</div>\n</div>`;
|
|
70
|
-
}
|
|
71
|
-
debug('load_FOUND_HTML', { contentId, htmlLength: html.length });
|
|
72
|
-
// Return rendered HTML as Marko template source so kebab-case tags
|
|
73
|
-
// (e.g. <alert-box>) compile as Marko components instead of raw HTML.
|
|
74
|
-
const markoSource = escapeMarkoText(html);
|
|
75
|
-
return `<div class="markdown-content">
|
|
76
|
-
${markoSource}
|
|
77
|
-
</div>`;
|
|
78
|
-
},
|
|
79
|
-
};
|
|
80
|
-
}
|
|
81
|
-
export async function loadMarkdownModule(id) {
|
|
82
|
-
const devGlobal = globalThis.__marko_run_dev__;
|
|
83
|
-
const devServer = devGlobal?.devServers?.values().next().value;
|
|
84
|
-
if (devServer?.ssrLoadModule) {
|
|
85
|
-
return devServer.ssrLoadModule(id);
|
|
86
|
-
}
|
|
87
|
-
return import(/* @vite-ignore */ id);
|
|
88
|
-
}
|
|
89
|
-
function escapeHtml(value) {
|
|
90
|
-
return String(value)
|
|
91
|
-
.replace(/&/g, '&')
|
|
92
|
-
.replace(/</g, '<')
|
|
93
|
-
.replace(/>/g, '>')
|
|
94
|
-
.replace(/"/g, '"')
|
|
95
|
-
.replace(/'/g, ''');
|
|
96
|
-
}
|
|
97
|
-
export function escapeMarkoText(value) {
|
|
98
|
-
const input = String(value);
|
|
99
|
-
let output = '';
|
|
100
|
-
let inTag = false;
|
|
101
|
-
for (let i = 0; i < input.length; i++) {
|
|
102
|
-
const char = input[i];
|
|
103
|
-
if (char === '<') {
|
|
104
|
-
inTag = true;
|
|
105
|
-
output += char;
|
|
106
|
-
continue;
|
|
107
|
-
}
|
|
108
|
-
if (char === '>') {
|
|
109
|
-
inTag = false;
|
|
110
|
-
output += char;
|
|
111
|
-
continue;
|
|
112
|
-
}
|
|
113
|
-
if (!inTag && char === '$' && input[i + 1] === '{') {
|
|
114
|
-
output += '${';
|
|
115
|
-
i++;
|
|
116
|
-
continue;
|
|
117
|
-
}
|
|
118
|
-
// Escape // in text content - Marko treats it as a JS comment
|
|
119
|
-
if (!inTag && char === '/' && input[i + 1] === '/') {
|
|
120
|
-
output += '//';
|
|
121
|
-
i++;
|
|
122
|
-
continue;
|
|
123
|
-
}
|
|
124
|
-
output += char;
|
|
125
|
-
}
|
|
126
|
-
return output;
|
|
127
|
-
}
|
|
128
|
-
function resolveContentId(id, generatedDir) {
|
|
129
|
-
const cleanId = toPosixPath(id.split('?', 1)[0]);
|
|
130
|
-
const mapped = virtualIds.get(cleanId);
|
|
131
|
-
if (mapped) {
|
|
132
|
-
return mapped;
|
|
133
|
-
}
|
|
134
|
-
if (cleanId.startsWith(generatedDir)) {
|
|
135
|
-
const relative = cleanId.slice(generatedDir.length + 1);
|
|
136
|
-
if (relative) {
|
|
137
|
-
return relative.endsWith(MARKO_SUFFIX)
|
|
138
|
-
? relative.slice(0, -MARKO_SUFFIX.length)
|
|
139
|
-
: relative;
|
|
140
|
-
}
|
|
141
|
-
}
|
|
142
|
-
return null;
|
|
143
|
-
}
|
|
144
|
-
function toPosixPath(value) {
|
|
145
|
-
return value.split(path.sep).join('/');
|
|
146
|
-
}
|
|
147
|
-
//# sourceMappingURL=vite-markdown-plugin.js.map
|
|
1
|
+
import e from"node:path";import{existsSync as n}from"node:fs";const t=globalThis.__MARKOPRESS_MARKDOWN_COMPONENTS__??=new Map,o=new Map,r=".marko";export function registerMarkdownContent(e,n){t.set(e,n)}export function getMarkdownContent(e){return t.get(e)}export function markdownContentPlugin(){let a=process.cwd(),d=s(e.join(a,"src",".generated","markdown"));const i=(e,n)=>{try{require("node:fs").appendFileSync("/tmp/markopress-plugin-debug.log",`${e}: ${JSON.stringify(n)}\n`)}catch{}};return i("PLUGIN_FUNCTION_CALLED",{timestamp:Date.now()}),{name:"markopress-markdown-content",enforce:"pre",configResolved(n){a=n.root||process.cwd(),d=s(e.join(a,"src",".generated","markdown"))},resolveId(n,t){if(i("resolveId",{id:n,importer:t}),n.startsWith("virtual:markdown-content/")){const t=n.slice(25),a=t.endsWith(r)?t:`${t}${r}`,c=s(e.join(d,a)),l=t.endsWith(r)?t.slice(0,-6):t;return o.set(c,l),i("resolveId_MATCH",{id:n,resolved:c}),c}},load(e){i("load",{id:e});const a=function(e,n){const t=s(e.split("?",1)[0]),a=o.get(t);if(a)return a;if(t.startsWith(n)){const e=t.slice(n.length+1);if(e)return e.endsWith(r)?e.slice(0,-6):e}return null}(e,d);if(!a)return;const c=e.split("?",1)[0];if(n(c))return void i("load_FILE_EXISTS",{contentId:a,cleanPath:c});i("load_MATCH",{contentId:a,storedKeys:Array.from(t.keys())});const l=t.get(a);return l?(i("load_FOUND_HTML",{contentId:a,htmlLength:l.length}),`<div class="markdown-content">\n${escapeMarkoText(l)}\n</div>`):(i("load_NO_HTML",{contentId:a}),`<div class="markdown-content">\n <div class="markdown-placeholder">Content not found: ${p=a,(p+"").replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""").replace(/'/g,"'")}</div>\n</div>`);var p}}}export async function loadMarkdownModule(e){const n=globalThis.__marko_run_dev__,t=n?.devServers?.values().next().value;return t?.ssrLoadModule?t.ssrLoadModule(e):import(e)}export function escapeMarkoText(e){const n=e+"";let t="",o=!1;for(let e=0;e<n.length;e++){const r=n[e];"<"!==r?">"!==r?o||"$"!==r||"{"!==n[e+1]?o||"/"!==r||"/"!==n[e+1]?t+=r:(t+="//",e++):(t+="${",e++):(o=!1,t+=r):(o=!0,t+=r)}return t}function s(n){return n.split(e.sep).join("/")}
|
package/dist/cli/index.d.ts
CHANGED
package/dist/cli/index.js
CHANGED
|
@@ -1,75 +1,2 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
|
|
3
|
-
* MarkoPress CLI
|
|
4
|
-
*/
|
|
5
|
-
import { Command } from 'commander';
|
|
6
|
-
import { resolveAppRoot } from '../config/app-root.js';
|
|
7
|
-
import { startDevServer } from '../dev/index.js';
|
|
8
|
-
import { build } from '../build/index.js';
|
|
9
|
-
import { preview } from '../preview/index.js';
|
|
10
|
-
// Resolve the app root (e.g., website/.markopress)
|
|
11
|
-
const appRoot = resolveAppRoot();
|
|
12
|
-
const program = new Command();
|
|
13
|
-
program
|
|
14
|
-
.name('markopress')
|
|
15
|
-
.description('A general-purpose static site generator using Marko.js v6')
|
|
16
|
-
.version('0.1.0');
|
|
17
|
-
program
|
|
18
|
-
.command('dev')
|
|
19
|
-
.description('Start development server')
|
|
20
|
-
.option('-p, --port <port>', 'Port to run server on', '3000')
|
|
21
|
-
.option('--host <host>', 'Host to run server on', 'localhost')
|
|
22
|
-
.option('--open', 'Open browser automatically', false)
|
|
23
|
-
.option('--catch-all', 'Use catch-all dynamic routes')
|
|
24
|
-
.action(async (options) => {
|
|
25
|
-
await startDevServer({
|
|
26
|
-
port: parseInt(options.port),
|
|
27
|
-
host: options.host,
|
|
28
|
-
open: options.open,
|
|
29
|
-
useCatchAllRoutes: options.catchAll,
|
|
30
|
-
root: appRoot,
|
|
31
|
-
});
|
|
32
|
-
});
|
|
33
|
-
program
|
|
34
|
-
.command('build')
|
|
35
|
-
.description('Build for production')
|
|
36
|
-
.option('--debug', 'Debug mode', false)
|
|
37
|
-
.option('-o, --output <dir>', 'Output directory', 'dist')
|
|
38
|
-
.option('--catch-all', 'Use catch-all dynamic routes')
|
|
39
|
-
.action(async (options) => {
|
|
40
|
-
const result = await build({
|
|
41
|
-
debug: options.debug,
|
|
42
|
-
outDir: options.output,
|
|
43
|
-
useCatchAllRoutes: options.catchAll,
|
|
44
|
-
root: appRoot,
|
|
45
|
-
});
|
|
46
|
-
if (!result.success) {
|
|
47
|
-
console.error('\n❌ Build failed!');
|
|
48
|
-
result.errors.forEach((error) => console.error(` ${error}`));
|
|
49
|
-
process.exit(1);
|
|
50
|
-
}
|
|
51
|
-
});
|
|
52
|
-
program
|
|
53
|
-
.command('preview')
|
|
54
|
-
.description('Preview production build')
|
|
55
|
-
.option('-p, --port <port>', 'Port to run server on', '4173')
|
|
56
|
-
.option('--host <host>', 'Host to run server on', 'localhost')
|
|
57
|
-
.action(async (options) => {
|
|
58
|
-
await preview({
|
|
59
|
-
port: parseInt(options.port),
|
|
60
|
-
host: options.host,
|
|
61
|
-
root: appRoot,
|
|
62
|
-
});
|
|
63
|
-
});
|
|
64
|
-
program
|
|
65
|
-
.command('init [site-dir]')
|
|
66
|
-
.description('Create a new MarkoPress site')
|
|
67
|
-
.option('-t, --template <template>', 'Template to use', 'default')
|
|
68
|
-
.action(async (siteDir, options) => {
|
|
69
|
-
const dir = siteDir || '.';
|
|
70
|
-
console.log(`Initializing MarkoPress site in ${dir}...`);
|
|
71
|
-
console.log(`Template: ${options.template}`);
|
|
72
|
-
// TODO: Implement init
|
|
73
|
-
});
|
|
74
|
-
program.parse();
|
|
75
|
-
//# sourceMappingURL=index.js.map
|
|
2
|
+
import{Command as o}from"commander";import{resolveAppRoot as t}from"../config/app-root.js";import{startDevServer as e}from"../dev/index.js";import{build as r}from"../build/index.js";import{preview as s}from"../preview/index.js";const i=t(),n=new o;n.name("markopress").description("A general-purpose static site generator using Marko.js v6").version("0.1.0"),n.command("dev").description("Start development server").option("-p, --port <port>","Port to run server on","3000").option("--host <host>","Host to run server on","localhost").option("--open","Open browser automatically",!1).option("--catch-all","Use catch-all dynamic routes").action(async o=>{await e({port:parseInt(o.port),host:o.host,open:o.open,useCatchAllRoutes:o.catchAll,root:i})}),n.command("build").description("Build for production").option("--debug","Debug mode",!1).option("-o, --output <dir>","Output directory","dist").option("--catch-all","Use catch-all dynamic routes").action(async o=>{const t=await r({debug:o.debug,outDir:o.output,useCatchAllRoutes:o.catchAll,root:i});t.success||(console.error("\n❌ Build failed!"),t.errors.forEach(o=>console.error(" "+o)),process.exit(1))}),n.command("preview").description("Preview production build").option("-p, --port <port>","Port to run server on","4173").option("--host <host>","Host to run server on","localhost").action(async o=>{await s({port:parseInt(o.port),host:o.host,root:i})}),n.command("init [site-dir]").description("Create a new MarkoPress site").option("-t, --template <template>","Template to use","default").action(async(o,t)=>{console.log(`Initializing MarkoPress site in ${o||"."}...`),console.log("Template: "+t.template)}),n.parse();
|
package/dist/config/app-root.js
CHANGED
|
@@ -1,24 +1 @@
|
|
|
1
|
-
import
|
|
2
|
-
import fs from 'node:fs';
|
|
3
|
-
/**
|
|
4
|
-
* Resolve the app root directory.
|
|
5
|
-
* If appDirName exists as a directory under cwd, returns that path.
|
|
6
|
-
* Otherwise returns cwd.
|
|
7
|
-
*/
|
|
8
|
-
export function resolveAppRoot(options = {}) {
|
|
9
|
-
const cwd = options.cwd ?? process.cwd();
|
|
10
|
-
const appDirName = options.appDirName ?? '.markopress';
|
|
11
|
-
const candidate = path.join(cwd, appDirName);
|
|
12
|
-
// Check if candidate exists and is a directory
|
|
13
|
-
try {
|
|
14
|
-
const stat = fs.statSync(candidate);
|
|
15
|
-
if (stat.isDirectory()) {
|
|
16
|
-
return candidate;
|
|
17
|
-
}
|
|
18
|
-
}
|
|
19
|
-
catch {
|
|
20
|
-
// Doesn't exist or isn't accessible, fall through to returning cwd
|
|
21
|
-
}
|
|
22
|
-
return cwd;
|
|
23
|
-
}
|
|
24
|
-
//# sourceMappingURL=app-root.js.map
|
|
1
|
+
import r from"node:path";import o from"node:fs";export function resolveAppRoot(t={}){const e=t.cwd??process.cwd(),p=t.appDirName??".markopress",c=r.join(e,p);try{if(o.statSync(c).isDirectory())return c}catch{}return e}
|
package/dist/config/index.d.ts
CHANGED
package/dist/config/index.js
CHANGED
package/dist/config/loader.d.ts
CHANGED
|
@@ -22,4 +22,3 @@ export declare function loadConfig(root?: string, env?: ConfigEnv): Promise<Reso
|
|
|
22
22
|
*/
|
|
23
23
|
export declare function defineConfig(config: UserConfig): UserConfig;
|
|
24
24
|
export declare function defineConfigWithCallback(config: (env: ConfigEnv) => UserConfig | Promise<UserConfig>): (env: ConfigEnv) => UserConfig | Promise<UserConfig>;
|
|
25
|
-
//# sourceMappingURL=loader.d.ts.map
|
package/dist/config/loader.js
CHANGED
|
@@ -1,188 +1 @@
|
|
|
1
|
-
|
|
2
|
-
* Configuration loader for MarkoPress
|
|
3
|
-
*/
|
|
4
|
-
import path from 'node:path';
|
|
5
|
-
import fs from 'node:fs/promises';
|
|
6
|
-
import { pathToFileURL } from 'node:url';
|
|
7
|
-
import { ZodError } from 'zod';
|
|
8
|
-
import { validateConfigSafe } from './validation.js';
|
|
9
|
-
const DEFAULT_CONFIG = {
|
|
10
|
-
site: {
|
|
11
|
-
title: 'MarkoPress Site',
|
|
12
|
-
description: '',
|
|
13
|
-
base: '/',
|
|
14
|
-
lang: 'en-US',
|
|
15
|
-
head: [],
|
|
16
|
-
},
|
|
17
|
-
content: {
|
|
18
|
-
pages: '../content/pages',
|
|
19
|
-
// No default 'docs' - users should use generic module names
|
|
20
|
-
blog: '../content/blog',
|
|
21
|
-
},
|
|
22
|
-
theme: {
|
|
23
|
-
name: '@markopress/theme-default',
|
|
24
|
-
options: {},
|
|
25
|
-
},
|
|
26
|
-
markdown: {
|
|
27
|
-
lineNumbers: false, // Changed default to false to avoid Marko parser issues
|
|
28
|
-
theme: {
|
|
29
|
-
light: 'github-light',
|
|
30
|
-
dark: 'github-dark',
|
|
31
|
-
},
|
|
32
|
-
},
|
|
33
|
-
build: {
|
|
34
|
-
useCatchAllRoutes: false,
|
|
35
|
-
outDir: 'dist',
|
|
36
|
-
assetsDir: 'assets',
|
|
37
|
-
},
|
|
38
|
-
plugins: [],
|
|
39
|
-
};
|
|
40
|
-
/**
|
|
41
|
-
* Deep merge two objects
|
|
42
|
-
*/
|
|
43
|
-
function deepMerge(target, source) {
|
|
44
|
-
const result = { ...target };
|
|
45
|
-
for (const key in source) {
|
|
46
|
-
const sourceValue = source[key];
|
|
47
|
-
const targetValue = result[key];
|
|
48
|
-
if (sourceValue === undefined) {
|
|
49
|
-
continue;
|
|
50
|
-
}
|
|
51
|
-
if (isObject(targetValue) && isObject(sourceValue)) {
|
|
52
|
-
result[key] = deepMerge(targetValue, sourceValue);
|
|
53
|
-
}
|
|
54
|
-
else {
|
|
55
|
-
result[key] = sourceValue;
|
|
56
|
-
}
|
|
57
|
-
}
|
|
58
|
-
return result;
|
|
59
|
-
}
|
|
60
|
-
function isObject(value) {
|
|
61
|
-
return value !== null && typeof value === 'object' && !Array.isArray(value);
|
|
62
|
-
}
|
|
63
|
-
/**
|
|
64
|
-
* Validate configuration using Zod schema
|
|
65
|
-
* @returns Validated configuration or errors
|
|
66
|
-
*/
|
|
67
|
-
function validateConfig(config) {
|
|
68
|
-
const result = validateConfigSafe(config);
|
|
69
|
-
if (!result.success) {
|
|
70
|
-
return {
|
|
71
|
-
valid: false,
|
|
72
|
-
errors: result.errors.map((err) => `${err.path}: ${err.message}`),
|
|
73
|
-
};
|
|
74
|
-
}
|
|
75
|
-
return {
|
|
76
|
-
valid: true,
|
|
77
|
-
errors: [],
|
|
78
|
-
data: result.data, // Cast to UserConfig to handle Zod's passthrough index signature
|
|
79
|
-
};
|
|
80
|
-
}
|
|
81
|
-
/**
|
|
82
|
-
* Find and load the configuration file
|
|
83
|
-
*/
|
|
84
|
-
export async function loadConfigFromFile(root, env) {
|
|
85
|
-
// Check for config files at the root level
|
|
86
|
-
// When root is already the app root (e.g., website/.markopress), look for config.*
|
|
87
|
-
// When root is the project root (e.g., website/), look for .markopress/config.*
|
|
88
|
-
const configFiles = [
|
|
89
|
-
'config.ts',
|
|
90
|
-
'config.js',
|
|
91
|
-
'config.mjs',
|
|
92
|
-
'.markopress/config.ts',
|
|
93
|
-
'.markopress/config.js',
|
|
94
|
-
'.markopress/config.mjs',
|
|
95
|
-
];
|
|
96
|
-
for (const file of configFiles) {
|
|
97
|
-
const filePath = path.resolve(root, file);
|
|
98
|
-
try {
|
|
99
|
-
await fs.access(filePath);
|
|
100
|
-
// Use pathToFileURL for better cross-platform support
|
|
101
|
-
const fileUrl = pathToFileURL(filePath).href;
|
|
102
|
-
// Add timestamp to bypass module cache during development
|
|
103
|
-
const importUrl = `${fileUrl}?t=${Date.now()}`;
|
|
104
|
-
const configModule = await import(importUrl);
|
|
105
|
-
const configExport = configModule.default;
|
|
106
|
-
if (!configExport) {
|
|
107
|
-
throw new Error(`Config file ${file} must have a default export`);
|
|
108
|
-
}
|
|
109
|
-
let config;
|
|
110
|
-
if (typeof configExport === 'function') {
|
|
111
|
-
config = await configExport(env);
|
|
112
|
-
}
|
|
113
|
-
else {
|
|
114
|
-
config = configExport;
|
|
115
|
-
}
|
|
116
|
-
// Validate the loaded config
|
|
117
|
-
const validation = validateConfig(config);
|
|
118
|
-
if (!validation.valid) {
|
|
119
|
-
throw new Error(`Invalid configuration in ${file}:\n${validation.errors.map((e) => ` - ${e}`).join('\n')}`);
|
|
120
|
-
}
|
|
121
|
-
console.log(`✓ Loaded config from ${file}`);
|
|
122
|
-
return { file: filePath, config: validation.data };
|
|
123
|
-
}
|
|
124
|
-
catch (error) {
|
|
125
|
-
// Only throw if file exists but failed to load/parse
|
|
126
|
-
if (error && typeof error === 'object' && 'code' in error && error.code !== 'ENOENT') {
|
|
127
|
-
throw new Error(`Failed to load config from ${file}: ${error instanceof Error ? error.message : String(error)}`);
|
|
128
|
-
}
|
|
129
|
-
// File doesn't exist, continue to next option
|
|
130
|
-
}
|
|
131
|
-
}
|
|
132
|
-
return null;
|
|
133
|
-
}
|
|
134
|
-
/**
|
|
135
|
-
* Resolve the configuration with defaults
|
|
136
|
-
*/
|
|
137
|
-
export function resolveConfig(userConfig, root) {
|
|
138
|
-
// For content and build, use user config directly if provided, otherwise use defaults
|
|
139
|
-
// This allows arbitrary module names (not just pages/docs/blog) and custom build options
|
|
140
|
-
const content = userConfig.content ? { ...userConfig.content } : DEFAULT_CONFIG.content;
|
|
141
|
-
const build = userConfig.build ? { ...userConfig.build } : DEFAULT_CONFIG.build;
|
|
142
|
-
// Use deep merge for other nested configurations
|
|
143
|
-
const site = deepMerge(DEFAULT_CONFIG.site, userConfig.site || {});
|
|
144
|
-
const theme = deepMerge(DEFAULT_CONFIG.theme, userConfig.theme || {});
|
|
145
|
-
const markdown = deepMerge(DEFAULT_CONFIG.markdown, userConfig.markdown || {});
|
|
146
|
-
// Plugins need special handling - don't merge, just replace
|
|
147
|
-
const plugins = userConfig.plugins || DEFAULT_CONFIG.plugins;
|
|
148
|
-
// Add theme CSS based on style option
|
|
149
|
-
const style = theme.options?.style || 'default';
|
|
150
|
-
const base = (site.base || '/').replace(/\/$/, '');
|
|
151
|
-
const themeCssPath = `${base}/_markopress/theme/theme-${style}.css`;
|
|
152
|
-
// Inject theme CSS link into head
|
|
153
|
-
const themeCssHeadTag = ['link', {
|
|
154
|
-
rel: 'stylesheet',
|
|
155
|
-
href: themeCssPath,
|
|
156
|
-
}];
|
|
157
|
-
site.head = [...(site.head || []), themeCssHeadTag];
|
|
158
|
-
return {
|
|
159
|
-
root,
|
|
160
|
-
site,
|
|
161
|
-
content,
|
|
162
|
-
theme,
|
|
163
|
-
markdown,
|
|
164
|
-
build,
|
|
165
|
-
plugins,
|
|
166
|
-
};
|
|
167
|
-
}
|
|
168
|
-
/**
|
|
169
|
-
* Load the configuration from a directory
|
|
170
|
-
*/
|
|
171
|
-
export async function loadConfig(root = process.cwd(), env = { mode: 'development', command: 'dev' }) {
|
|
172
|
-
const loaded = await loadConfigFromFile(root, env);
|
|
173
|
-
if (!loaded) {
|
|
174
|
-
// Return default config if no config file found
|
|
175
|
-
return resolveConfig({ site: DEFAULT_CONFIG.site }, root);
|
|
176
|
-
}
|
|
177
|
-
return resolveConfig(loaded.config, root);
|
|
178
|
-
}
|
|
179
|
-
/**
|
|
180
|
-
* Define configuration helper with type safety
|
|
181
|
-
*/
|
|
182
|
-
export function defineConfig(config) {
|
|
183
|
-
return config;
|
|
184
|
-
}
|
|
185
|
-
export function defineConfigWithCallback(config) {
|
|
186
|
-
return config;
|
|
187
|
-
}
|
|
188
|
-
//# sourceMappingURL=loader.js.map
|
|
1
|
+
import o from"node:path";import e from"node:fs/promises";import{pathToFileURL as t}from"node:url";import{ZodError as n}from"zod";import{validateConfigSafe as r}from"./validation.js";const i={site:{title:"MarkoPress Site",description:"",base:"/",lang:"en-US",head:[]},content:{pages:"../content/pages",blog:"../content/blog"},theme:{name:"@markopress/theme-default",options:{}},markdown:{lineNumbers:!1,theme:{light:"github-light",dark:"github-dark"}},build:{useCatchAllRoutes:!1,outDir:"dist",assetsDir:"assets"},plugins:[]};function s(o,e){const t={...o};for(const o in e){const n=e[o],r=t[o];void 0!==n&&(a(r)&&a(n)?t[o]=s(r,n):t[o]=n)}return t}function a(o){return null!==o&&"object"==typeof o&&!Array.isArray(o)}function c(o){const e=r(o);return e.success?{valid:!0,errors:[],data:e.data}:{valid:!1,errors:e.errors.map(o=>`${o.path}: ${o.message}`)}}export async function loadConfigFromFile(n,r){const i=["config.ts","config.js","config.mjs",".markopress/config.ts",".markopress/config.js",".markopress/config.mjs"];for(const s of i){const i=o.resolve(n,s);try{await e.access(i);const o=`${t(i).href}?t=${Date.now()}`,n=(await import(o)).default;if(!n)throw Error(`Config file ${s} must have a default export`);let a;a="function"==typeof n?await n(r):n;const f=c(a);if(!f.valid)throw Error(`Invalid configuration in ${s}:\n${f.errors.map(o=>" - "+o).join("\n")}`);return console.log("✓ Loaded config from "+s),{file:i,config:f.data}}catch(o){if(o&&"object"==typeof o&&"code"in o&&"ENOENT"!==o.code)throw Error(`Failed to load config from ${s}: ${o instanceof Error?o.message:o+""}`)}}return null}export function resolveConfig(o,e){const t=o.content?{...o.content}:i.content,n=o.build?{...o.build}:i.build,r=s(i.site,o.site||{}),a=s(i.theme,o.theme||{}),c=s(i.markdown,o.markdown||{}),f=o.plugins||i.plugins,l=a.options?.style||"default",d=["link",{rel:"stylesheet",href:`${(r.base||"/").replace(/\/$/,"")}/_markopress/theme/theme-${l}.css`}];return r.head=[...r.head||[],d],{root:e,site:r,content:t,theme:a,markdown:c,build:n,plugins:f}}export async function loadConfig(o=process.cwd(),e={mode:"development",command:"dev"}){const t=await loadConfigFromFile(o,e);return resolveConfig(t?t.config:{site:i.site},o)}export function defineConfig(o){return o}export function defineConfigWithCallback(o){return o}
|
package/dist/config/types.d.ts
CHANGED
package/dist/config/types.js
CHANGED
|
@@ -1,139 +1 @@
|
|
|
1
|
-
|
|
2
|
-
* Configuration validation using Zod
|
|
3
|
-
* Provides runtime validation and type safety for user config
|
|
4
|
-
*/
|
|
5
|
-
import { z } from 'zod';
|
|
6
|
-
/**
|
|
7
|
-
* Site configuration schema
|
|
8
|
-
*/
|
|
9
|
-
const SiteConfigSchema = z.object({
|
|
10
|
-
title: z.string().min(1, { message: 'Site title is required' }).max(100, { message: 'Site title too long' }),
|
|
11
|
-
description: z.string().max(500, { message: 'Description too long' }).optional(),
|
|
12
|
-
base: z.string().startsWith('/', { message: 'Base must start with /' }).optional(),
|
|
13
|
-
lang: z.string().regex(/^[a-z]{2}(-[A-Z]{2})?$/, { message: 'Invalid language code' }).optional(),
|
|
14
|
-
head: z.array(z.tuple([z.string(), z.record(z.string(), z.string())])).optional(),
|
|
15
|
-
});
|
|
16
|
-
/**
|
|
17
|
-
* Content configuration schema
|
|
18
|
-
* Allows arbitrary module names (e.g., pages, guides, docs, blog, tutorials, etc.)
|
|
19
|
-
*/
|
|
20
|
-
const ContentConfigSchema = z.object({
|
|
21
|
-
pages: z.string().optional(),
|
|
22
|
-
docs: z.string().optional(),
|
|
23
|
-
blog: z.string().optional(),
|
|
24
|
-
}).passthrough(); // Allow additional properties (like 'guides', 'tutorials', etc.)
|
|
25
|
-
/**
|
|
26
|
-
* Navigation item schema
|
|
27
|
-
*/
|
|
28
|
-
const NavItemSchema = z.object({
|
|
29
|
-
text: z.string().min(1, { message: 'Nav item text is required' }),
|
|
30
|
-
link: z.string().min(1, { message: 'Nav item link is required' }),
|
|
31
|
-
});
|
|
32
|
-
/**
|
|
33
|
-
* Sidebar item schema
|
|
34
|
-
*/
|
|
35
|
-
const SidebarItemSchema = z.object({
|
|
36
|
-
text: z.string().min(1, { message: 'Sidebar item text is required' }),
|
|
37
|
-
link: z.string().min(1, { message: 'Sidebar item link is required' }),
|
|
38
|
-
});
|
|
39
|
-
/**
|
|
40
|
-
* Sidebar configuration schema
|
|
41
|
-
*/
|
|
42
|
-
const SidebarConfigSchema = z.record(z.string(), z.union([
|
|
43
|
-
z.array(SidebarItemSchema),
|
|
44
|
-
z.object({ autoGenerate: z.boolean() }),
|
|
45
|
-
]));
|
|
46
|
-
/**
|
|
47
|
-
* Theme options schema
|
|
48
|
-
*/
|
|
49
|
-
const ThemeOptionsSchema = z.object({
|
|
50
|
-
navbar: z.array(NavItemSchema).optional(),
|
|
51
|
-
sidebar: SidebarConfigSchema.optional(),
|
|
52
|
-
}).passthrough(); // Allow additional properties
|
|
53
|
-
/**
|
|
54
|
-
* Theme configuration schema
|
|
55
|
-
*/
|
|
56
|
-
const ThemeConfigSchema = z.object({
|
|
57
|
-
name: z.string()
|
|
58
|
-
.regex(/^(@[a-z0-9-~][a-z0-9-._~]*\/)?[a-z0-9-~][a-z0-9-._~]*$/, { message: 'Invalid theme name' })
|
|
59
|
-
.refine((name) => !name.includes('..'), { message: 'Theme name cannot contain path traversal' })
|
|
60
|
-
.optional(),
|
|
61
|
-
designSystem: z.enum(['vitepress', 'docusaurus', 'rspress']).optional(),
|
|
62
|
-
options: ThemeOptionsSchema.optional(),
|
|
63
|
-
});
|
|
64
|
-
/**
|
|
65
|
-
* Markdown configuration schema
|
|
66
|
-
*/
|
|
67
|
-
const MarkdownConfigSchema = z.object({
|
|
68
|
-
lineNumbers: z.boolean().optional(),
|
|
69
|
-
theme: z.object({
|
|
70
|
-
light: z.string().optional(),
|
|
71
|
-
dark: z.string().optional(),
|
|
72
|
-
}).optional(),
|
|
73
|
-
});
|
|
74
|
-
/**
|
|
75
|
-
* Build configuration schema
|
|
76
|
-
*/
|
|
77
|
-
const BuildConfigSchema = z.object({
|
|
78
|
-
useCatchAllRoutes: z.boolean().optional(),
|
|
79
|
-
outDir: z.string().optional(),
|
|
80
|
-
assetsDir: z.string().optional(),
|
|
81
|
-
sourcemap: z.boolean().optional(),
|
|
82
|
-
minify: z.boolean().optional(),
|
|
83
|
-
clean: z.boolean().optional(),
|
|
84
|
-
}).passthrough();
|
|
85
|
-
/**
|
|
86
|
-
* Plugin configuration schema
|
|
87
|
-
* Supports: string | [string, options] | { name, options }
|
|
88
|
-
*/
|
|
89
|
-
const PluginConfigSchema = z.union([
|
|
90
|
-
z.string(),
|
|
91
|
-
z.tuple([z.string(), z.record(z.string(), z.unknown()).optional()]),
|
|
92
|
-
z.object({
|
|
93
|
-
name: z.string().min(1, { message: 'Plugin name is required' }),
|
|
94
|
-
options: z.record(z.string(), z.unknown()).optional(),
|
|
95
|
-
}),
|
|
96
|
-
]);
|
|
97
|
-
/**
|
|
98
|
-
* Main MarkoPress configuration schema
|
|
99
|
-
*/
|
|
100
|
-
export const MarkoPressConfigSchema = z.object({
|
|
101
|
-
site: SiteConfigSchema,
|
|
102
|
-
content: ContentConfigSchema.optional(),
|
|
103
|
-
theme: ThemeConfigSchema.optional(),
|
|
104
|
-
markdown: MarkdownConfigSchema.optional(),
|
|
105
|
-
build: BuildConfigSchema.optional(),
|
|
106
|
-
plugins: z.array(PluginConfigSchema).optional(),
|
|
107
|
-
});
|
|
108
|
-
/**
|
|
109
|
-
* Validate user configuration
|
|
110
|
-
* @param config - User configuration to validate
|
|
111
|
-
* @returns Validated configuration
|
|
112
|
-
* @throws {z.ZodError} If validation fails
|
|
113
|
-
*/
|
|
114
|
-
export function validateConfig(config) {
|
|
115
|
-
return MarkoPressConfigSchema.parse(config);
|
|
116
|
-
}
|
|
117
|
-
/**
|
|
118
|
-
* Validate user configuration with detailed error messages
|
|
119
|
-
* @param config - User configuration to validate
|
|
120
|
-
* @returns Result with success status and data or errors
|
|
121
|
-
*/
|
|
122
|
-
export function validateConfigSafe(config) {
|
|
123
|
-
const result = MarkoPressConfigSchema.safeParse(config);
|
|
124
|
-
if (!result.success) {
|
|
125
|
-
const errors = result.error.issues.map((err) => ({
|
|
126
|
-
path: err.path.join('.'),
|
|
127
|
-
message: err.message,
|
|
128
|
-
}));
|
|
129
|
-
return {
|
|
130
|
-
success: false,
|
|
131
|
-
errors,
|
|
132
|
-
};
|
|
133
|
-
}
|
|
134
|
-
return {
|
|
135
|
-
success: true,
|
|
136
|
-
data: result.data,
|
|
137
|
-
};
|
|
138
|
-
}
|
|
139
|
-
//# sourceMappingURL=validation.js.map
|
|
1
|
+
import{z as e}from"zod";const t=e.object({title:e.string().min(1,{message:"Site title is required"}).max(100,{message:"Site title too long"}),description:e.string().max(500,{message:"Description too long"}).optional(),base:e.string().startsWith("/",{message:"Base must start with /"}).optional(),lang:e.string().regex(/^[a-z]{2}(-[A-Z]{2})?$/,{message:"Invalid language code"}).optional(),head:e.array(e.tuple([e.string(),e.record(e.string(),e.string())])).optional()}),o=e.object({pages:e.string().optional(),docs:e.string().optional(),blog:e.string().optional()}).passthrough(),n=e.object({text:e.string().min(1,{message:"Nav item text is required"}),link:e.string().min(1,{message:"Nav item link is required"})}),i=e.object({text:e.string().min(1,{message:"Sidebar item text is required"}),link:e.string().min(1,{message:"Sidebar item link is required"})}),a=e.record(e.string(),e.union([e.array(i),e.object({autoGenerate:e.boolean()})])),s=e.object({navbar:e.array(n).optional(),sidebar:a.optional()}).passthrough(),r=e.object({name:e.string().regex(/^(@[a-z0-9-~][a-z0-9-._~]*\/)?[a-z0-9-~][a-z0-9-._~]*$/,{message:"Invalid theme name"}).refine(e=>!e.includes(".."),{message:"Theme name cannot contain path traversal"}).optional(),designSystem:e.enum(["vitepress","docusaurus","rspress"]).optional(),options:s.optional()}),l=e.object({lineNumbers:e.boolean().optional(),theme:e.object({light:e.string().optional(),dark:e.string().optional()}).optional()}),g=e.object({useCatchAllRoutes:e.boolean().optional(),outDir:e.string().optional(),assetsDir:e.string().optional(),sourcemap:e.boolean().optional(),minify:e.boolean().optional(),clean:e.boolean().optional()}).passthrough(),p=e.union([e.string(),e.tuple([e.string(),e.record(e.string(),e.unknown()).optional()]),e.object({name:e.string().min(1,{message:"Plugin name is required"}),options:e.record(e.string(),e.unknown()).optional()})]);export const MarkoPressConfigSchema=e.object({site:t,content:o.optional(),theme:r.optional(),markdown:l.optional(),build:g.optional(),plugins:e.array(p).optional()});export function validateConfig(e){return MarkoPressConfigSchema.parse(e)}export function validateConfigSafe(e){const t=MarkoPressConfigSchema.safeParse(e);return t.success?{success:!0,data:t.data}:{success:!1,errors:t.error.issues.map(e=>({path:e.path.join("."),message:e.message}))}}
|