mdsvr 2.4.0 → 2.5.0
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/directory.d.ts +11 -0
- package/dist/directory.d.ts.map +1 -1
- package/dist/directory.js +31 -115
- package/dist/directory.js.map +1 -1
- package/dist/generators/feed.d.ts.map +1 -1
- package/dist/generators/feed.js +9 -2
- package/dist/generators/feed.js.map +1 -1
- package/dist/generators/robots.d.ts +11 -0
- package/dist/generators/robots.d.ts.map +1 -0
- package/dist/generators/robots.js +32 -0
- package/dist/generators/robots.js.map +1 -0
- package/dist/generators/search-index.d.ts.map +1 -1
- package/dist/generators/search-index.js +6 -5
- package/dist/generators/search-index.js.map +1 -1
- package/dist/generators/sitemap.d.ts +17 -1
- package/dist/generators/sitemap.d.ts.map +1 -1
- package/dist/generators/sitemap.js +119 -59
- package/dist/generators/sitemap.js.map +1 -1
- package/dist/generators/static-export.d.ts.map +1 -1
- package/dist/generators/static-export.js +66 -11
- package/dist/generators/static-export.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js.map +1 -1
- package/dist/link-transform.d.ts +37 -5
- package/dist/link-transform.d.ts.map +1 -1
- package/dist/link-transform.js +120 -13
- package/dist/link-transform.js.map +1 -1
- package/dist/render-page.d.ts +1 -2
- package/dist/render-page.d.ts.map +1 -1
- package/dist/render-page.js +56 -40
- package/dist/render-page.js.map +1 -1
- package/dist/renderer/markdown.d.ts +0 -16
- package/dist/renderer/markdown.d.ts.map +1 -1
- package/dist/renderer/markdown.js +6 -63
- package/dist/renderer/markdown.js.map +1 -1
- package/dist/router.d.ts.map +1 -1
- package/dist/router.js +19 -1
- package/dist/router.js.map +1 -1
- package/dist/seo/extract.d.ts +26 -0
- package/dist/seo/extract.d.ts.map +1 -0
- package/dist/seo/extract.js +159 -0
- package/dist/seo/extract.js.map +1 -0
- package/dist/seo/index.d.ts +5 -0
- package/dist/seo/index.d.ts.map +1 -0
- package/dist/seo/index.js +5 -0
- package/dist/seo/index.js.map +1 -0
- package/dist/seo/jsonld.d.ts +15 -0
- package/dist/seo/jsonld.d.ts.map +1 -0
- package/dist/seo/jsonld.js +93 -0
- package/dist/seo/jsonld.js.map +1 -0
- package/dist/seo/metadata.d.ts +60 -0
- package/dist/seo/metadata.d.ts.map +1 -0
- package/dist/seo/metadata.js +144 -0
- package/dist/seo/metadata.js.map +1 -0
- package/dist/seo/url.d.ts +27 -0
- package/dist/seo/url.d.ts.map +1 -0
- package/dist/seo/url.js +76 -0
- package/dist/seo/url.js.map +1 -0
- package/dist/settings/defaults.d.ts.map +1 -1
- package/dist/settings/defaults.js +0 -2
- package/dist/settings/defaults.js.map +1 -1
- package/dist/settings/index.d.ts +1 -1
- package/dist/settings/index.d.ts.map +1 -1
- package/dist/settings/index.js +15 -0
- package/dist/settings/index.js.map +1 -1
- package/dist/settings/schema.d.ts +317 -5
- package/dist/settings/schema.d.ts.map +1 -1
- package/dist/settings/schema.js +45 -1
- package/dist/settings/schema.js.map +1 -1
- package/dist/template/analytics.d.ts +18 -0
- package/dist/template/analytics.d.ts.map +1 -0
- package/dist/template/analytics.js +83 -0
- package/dist/template/analytics.js.map +1 -0
- package/dist/template/index.d.ts +5 -0
- package/dist/template/index.d.ts.map +1 -1
- package/dist/template/index.js +59 -59
- package/dist/template/index.js.map +1 -1
- package/dist/template/search.d.ts.map +1 -1
- package/dist/template/search.js +9 -2
- package/dist/template/search.js.map +1 -1
- package/dist/template/seo.d.ts +7 -10
- package/dist/template/seo.d.ts.map +1 -1
- package/dist/template/seo.js +57 -33
- package/dist/template/seo.js.map +1 -1
- package/dist/template/sidebar.d.ts.map +1 -1
- package/dist/template/sidebar.js +11 -8
- package/dist/template/sidebar.js.map +1 -1
- package/dist/validator/index.d.ts +1 -1
- package/dist/validator/index.d.ts.map +1 -1
- package/dist/validator/index.js +21 -0
- package/dist/validator/index.js.map +1 -1
- package/package.json +1 -1
package/dist/directory.d.ts
CHANGED
|
@@ -1,6 +1,17 @@
|
|
|
1
1
|
import type { Dirent } from "node:fs";
|
|
2
|
+
/**
|
|
3
|
+
* Render a directory listing as a body fragment for auto-index pages.
|
|
4
|
+
* The surrounding document (head, navigation, styles) comes from the page
|
|
5
|
+
* template — this returns only `<h1>` + the listing table.
|
|
6
|
+
*
|
|
7
|
+
* File links use the canonical clean-URL form: `.md`/`.mdx` entries point to
|
|
8
|
+
* the trailing-slash doc route; index files (README/index) are hidden because
|
|
9
|
+
* they are the page itself.
|
|
10
|
+
*/
|
|
2
11
|
export declare function renderDirectory(params: {
|
|
3
12
|
urlPath: string;
|
|
4
13
|
entries: Dirent[];
|
|
14
|
+
/** Heading text; defaults to a humanized form of the last URL segment. */
|
|
15
|
+
title?: string;
|
|
5
16
|
}): string;
|
|
6
17
|
//# sourceMappingURL=directory.d.ts.map
|
package/dist/directory.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"directory.d.ts","sourceRoot":"","sources":["../src/directory.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AAEtC,wBAAgB,eAAe,CAAC,MAAM,EAAE;IACtC,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,EAAE,CAAC;
|
|
1
|
+
{"version":3,"file":"directory.d.ts","sourceRoot":"","sources":["../src/directory.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AAEtC;;;;;;;;GAQG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE;IACtC,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,0EAA0E;IAC1E,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,GAAG,MAAM,CA+DT"}
|
package/dist/directory.js
CHANGED
|
@@ -1,21 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Render a directory listing as a body fragment for auto-index pages.
|
|
3
|
+
* The surrounding document (head, navigation, styles) comes from the page
|
|
4
|
+
* template — this returns only `<h1>` + the listing table.
|
|
5
|
+
*
|
|
6
|
+
* File links use the canonical clean-URL form: `.md`/`.mdx` entries point to
|
|
7
|
+
* the trailing-slash doc route; index files (README/index) are hidden because
|
|
8
|
+
* they are the page itself.
|
|
9
|
+
*/
|
|
1
10
|
export function renderDirectory(params) {
|
|
2
11
|
const { urlPath, entries } = params;
|
|
12
|
+
const lastSegment = urlPath.replace(/\/+$/, "").split("/").pop() || "";
|
|
13
|
+
const title = params.title ??
|
|
14
|
+
(lastSegment
|
|
15
|
+
? decodeURIComponent(lastSegment).replace(/[-_]/g, " ")
|
|
16
|
+
: "Index");
|
|
3
17
|
// Sort: folders first, then files (alphabetically)
|
|
4
|
-
const sorted = [...entries]
|
|
18
|
+
const sorted = [...entries]
|
|
19
|
+
.filter((entry) => !isIndexEntry(entry.name))
|
|
20
|
+
.sort((a, b) => {
|
|
5
21
|
if (a.isDirectory() && !b.isDirectory())
|
|
6
22
|
return -1;
|
|
7
23
|
if (!a.isDirectory() && b.isDirectory())
|
|
8
24
|
return 1;
|
|
9
25
|
return a.name.localeCompare(b.name);
|
|
10
26
|
});
|
|
27
|
+
const base = urlPath.replace(/\/+$/, "") + "/";
|
|
11
28
|
const rows = sorted
|
|
12
29
|
.map((entry) => {
|
|
13
30
|
const name = entry.name;
|
|
14
31
|
const isDir = entry.isDirectory();
|
|
15
|
-
const
|
|
16
|
-
const
|
|
17
|
-
|
|
18
|
-
|
|
32
|
+
const isDoc = /\.(md|mdx)$/i.test(name);
|
|
33
|
+
const icon = isDir ? "📁" : isDoc ? "📄" : "📃";
|
|
34
|
+
const href = isDir || isDoc
|
|
35
|
+
? `${base}${encodeURIComponent(name.replace(/\.(md|mdx)$/i, ""))}/`
|
|
36
|
+
: `${base}${encodeURIComponent(name)}`;
|
|
19
37
|
const size = !isDir && entry.isFile()
|
|
20
38
|
? formatSize(entry.size || 0)
|
|
21
39
|
: "-";
|
|
@@ -25,104 +43,15 @@ export function renderDirectory(params) {
|
|
|
25
43
|
</tr>`;
|
|
26
44
|
})
|
|
27
45
|
.join("\n");
|
|
28
|
-
const
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
<script>
|
|
32
|
-
(function() {
|
|
33
|
-
var theme = localStorage.getItem('theme') || 'system';
|
|
34
|
-
if (theme === 'system') {
|
|
35
|
-
theme = window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light';
|
|
36
|
-
}
|
|
37
|
-
document.documentElement.setAttribute('data-theme', theme);
|
|
38
|
-
})();
|
|
39
|
-
</script>`;
|
|
40
|
-
return `<!DOCTYPE html>
|
|
41
|
-
<html lang="en" data-theme="light">
|
|
42
|
-
<head>
|
|
43
|
-
<meta charset="UTF-8">
|
|
44
|
-
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
45
|
-
<title>Index of ${escapeHtml(urlPath)}</title>
|
|
46
|
-
${themeScript}
|
|
47
|
-
<style>
|
|
48
|
-
:root {
|
|
49
|
-
--bg: #f6f8fa;
|
|
50
|
-
--bg-secondary: #ffffff;
|
|
51
|
-
--text: #24292f;
|
|
52
|
-
--text-muted: #656d76;
|
|
53
|
-
--border: #d0d7de;
|
|
54
|
-
--accent: #0969da;
|
|
55
|
-
--header-bg: #0d1117;
|
|
56
|
-
--header-text: #f0f6fc;
|
|
57
|
-
--header-border: #30363d;
|
|
58
|
-
}
|
|
59
|
-
:root[data-theme="dark"] {
|
|
60
|
-
--bg: #0d1117;
|
|
61
|
-
--bg-secondary: #161b22;
|
|
62
|
-
--text: #e6edf3;
|
|
63
|
-
--text-muted: #8d96a0;
|
|
64
|
-
--border: #30363d;
|
|
65
|
-
--accent: #58a6ff;
|
|
66
|
-
--header-bg: #161b22;
|
|
67
|
-
--header-text: #e6edf3;
|
|
68
|
-
--header-border: #30363d;
|
|
69
|
-
}
|
|
70
|
-
* { box-sizing: border-box; }
|
|
71
|
-
body {
|
|
72
|
-
margin: 0;
|
|
73
|
-
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Noto Sans', Helvetica, Arial, sans-serif;
|
|
74
|
-
font-size: 16px;
|
|
75
|
-
line-height: 1.6;
|
|
76
|
-
color: var(--text);
|
|
77
|
-
background: var(--bg);
|
|
78
|
-
}
|
|
79
|
-
.header {
|
|
80
|
-
background: var(--header-bg);
|
|
81
|
-
padding: 16px 24px;
|
|
82
|
-
border-bottom: 1px solid var(--header-border);
|
|
83
|
-
}
|
|
84
|
-
.header-logo {
|
|
85
|
-
color: var(--header-text);
|
|
86
|
-
font-weight: 600;
|
|
87
|
-
font-size: 14px;
|
|
88
|
-
text-decoration: none;
|
|
89
|
-
}
|
|
90
|
-
.container {
|
|
91
|
-
max-width: 860px;
|
|
92
|
-
margin: 32px auto;
|
|
93
|
-
padding: 32px;
|
|
94
|
-
background: var(--bg-secondary);
|
|
95
|
-
border: 1px solid var(--border);
|
|
96
|
-
border-radius: 6px;
|
|
97
|
-
}
|
|
98
|
-
h1 { font-size: 20px; font-weight: 600; margin: 0 0 16px; color: var(--text); }
|
|
99
|
-
.breadcrumb { font-size: 14px; color: var(--text-muted); margin-bottom: 20px; }
|
|
100
|
-
.breadcrumb a { color: var(--accent); text-decoration: none; }
|
|
101
|
-
.breadcrumb a:hover { text-decoration: underline; }
|
|
102
|
-
table { width: 100%; border-collapse: collapse; }
|
|
103
|
-
th, td { padding: 8px 12px; text-align: left; border-bottom: 1px solid var(--border); }
|
|
104
|
-
th { font-weight: 600; color: var(--text-muted); font-size: 14px; }
|
|
105
|
-
td { font-size: 14px; }
|
|
106
|
-
td a { color: var(--accent); text-decoration: none; }
|
|
107
|
-
td a:hover { text-decoration: underline; }
|
|
108
|
-
.size { color: var(--text-muted); text-align: right; width: 100px; }
|
|
109
|
-
.empty { color: var(--text-muted); font-style: italic; padding: 24px 0; }
|
|
110
|
-
@media (max-width: 900px) {
|
|
111
|
-
.container { margin: 16px; padding: 20px; }
|
|
112
|
-
.header { padding: 12px 16px; }
|
|
113
|
-
}
|
|
114
|
-
@media (max-width: 480px) {
|
|
115
|
-
.container { margin: 8px; padding: 16px; }
|
|
116
|
-
}
|
|
117
|
-
</style>
|
|
118
|
-
</head>
|
|
119
|
-
<body>
|
|
46
|
+
const hasParent = urlPath !== "" && urlPath !== "/";
|
|
47
|
+
return `<h1>${escapeHtml(title)}</h1>
|
|
48
|
+
<nav class="dir-listing" aria-label="Directory listing">
|
|
120
49
|
<table>
|
|
121
50
|
<thead>
|
|
122
51
|
<tr><th>Name</th><th class="size">Size</th></tr>
|
|
123
52
|
</thead>
|
|
124
53
|
<tbody>
|
|
125
|
-
${
|
|
54
|
+
${hasParent
|
|
126
55
|
? ` <tr>
|
|
127
56
|
<td>📁 <a href="../">../</a></td>
|
|
128
57
|
<td class="size">-</td>
|
|
@@ -131,24 +60,11 @@ ${urlPath
|
|
|
131
60
|
${rows || ' <tr><td colspan="2" class="empty">Empty directory</td></tr>'}
|
|
132
61
|
</tbody>
|
|
133
62
|
</table>
|
|
134
|
-
</
|
|
135
|
-
</html>`;
|
|
63
|
+
</nav>`;
|
|
136
64
|
}
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
}
|
|
141
|
-
const parts = urlPath.split("/").filter(Boolean);
|
|
142
|
-
let accum = "";
|
|
143
|
-
const links = parts.map((part, i) => {
|
|
144
|
-
accum += "/" + part;
|
|
145
|
-
const isLast = i === parts.length - 1;
|
|
146
|
-
if (isLast) {
|
|
147
|
-
return `<strong>${escapeHtml(part)}</strong>`;
|
|
148
|
-
}
|
|
149
|
-
return `<a href="${accum}/">${escapeHtml(part)}</a>`;
|
|
150
|
-
});
|
|
151
|
-
return '<a href="/">home</a> / ' + links.join(" / ");
|
|
65
|
+
/** Index files render as the directory page itself — hide them in listings. */
|
|
66
|
+
function isIndexEntry(name) {
|
|
67
|
+
return /^(readme|index)\.(md|mdx|html?)$/i.test(name);
|
|
152
68
|
}
|
|
153
69
|
function formatSize(bytes) {
|
|
154
70
|
if (bytes === 0)
|
package/dist/directory.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"directory.js","sourceRoot":"","sources":["../src/directory.ts"],"names":[],"mappings":"AAEA,MAAM,UAAU,eAAe,CAAC,
|
|
1
|
+
{"version":3,"file":"directory.js","sourceRoot":"","sources":["../src/directory.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"feed.d.ts","sourceRoot":"","sources":["../../src/generators/feed.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;
|
|
1
|
+
{"version":3,"file":"feed.d.ts","sourceRoot":"","sources":["../../src/generators/feed.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAuGrD,wBAAsB,YAAY,CAChC,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,QAAQ,GACjB,OAAO,CAAC,MAAM,CAAC,CA+CjB"}
|
package/dist/generators/feed.js
CHANGED
|
@@ -9,7 +9,7 @@ function isHidden(filePath, settings) {
|
|
|
9
9
|
if (pattern.startsWith("*") && basename.endsWith(pattern.slice(1)))
|
|
10
10
|
return true;
|
|
11
11
|
}
|
|
12
|
-
if (basename.startsWith("_"))
|
|
12
|
+
if (basename.startsWith("_") || basename.startsWith("."))
|
|
13
13
|
return true;
|
|
14
14
|
return false;
|
|
15
15
|
}
|
|
@@ -46,7 +46,14 @@ async function readDirRecursive(dirPath, rootDir, baseUrl, settings) {
|
|
|
46
46
|
if (isNaN(date.getTime()))
|
|
47
47
|
continue;
|
|
48
48
|
const relativePath = "/" + path.relative(rootDir, fullPath).replace(/\\/g, "/");
|
|
49
|
-
|
|
49
|
+
let urlPath = relativePath.replace(/\.(md|mdx)$/, "");
|
|
50
|
+
// Index files render at the directory URL; other docs are
|
|
51
|
+
// trailing-slash routes — both canonical clean-URL forms.
|
|
52
|
+
if (/^(readme|index)$/i.test(path.basename(urlPath))) {
|
|
53
|
+
urlPath = path.dirname(urlPath);
|
|
54
|
+
}
|
|
55
|
+
if (!urlPath.endsWith("/"))
|
|
56
|
+
urlPath += "/";
|
|
50
57
|
const fullUrl = `${baseUrl.replace(/\/$/, "")}${urlPath}`;
|
|
51
58
|
const title = parsed.data.title ||
|
|
52
59
|
parsed.content.match(/^#\s+(.+)$/m)?.[1] ||
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"feed.js","sourceRoot":"","sources":["../../src/generators/feed.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,QAAQ,IAAI,EAAE,EAAE,MAAM,SAAS,CAAC;AACzC,OAAO,MAAM,MAAM,aAAa,CAAC;AAWjC,SAAS,QAAQ,CAAC,QAAgB,EAAE,QAAkB;IACpD,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;IAEzC,KAAK,MAAM,OAAO,IAAI,QAAQ,CAAC,KAAK,CAAC,UAAU,CAAC,MAAM,EAAE,CAAC;QACvD,IAAI,QAAQ,KAAK,OAAO;YAAE,OAAO,IAAI,CAAC;QACtC,IAAI,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,QAAQ,CAAC,QAAQ,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;YAChE,OAAO,IAAI,CAAC;IAChB,CAAC;IAED,IAAI,QAAQ,CAAC,UAAU,CAAC,GAAG,CAAC;QAAE,OAAO,IAAI,CAAC;
|
|
1
|
+
{"version":3,"file":"feed.js","sourceRoot":"","sources":["../../src/generators/feed.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { Settings } from "../settings/index.js";
|
|
2
|
+
/**
|
|
3
|
+
* Generate robots.txt content.
|
|
4
|
+
*
|
|
5
|
+
* A non-empty `robots.txt` in the docs root always wins. Otherwise emit a
|
|
6
|
+
* permissive file; the `Sitemap:` line is only included when an absolute
|
|
7
|
+
* sitemap URL can be derived (`site.baseUrl`, or the request `origin`
|
|
8
|
+
* in serve mode) — relative Sitemap URLs are invalid per spec.
|
|
9
|
+
*/
|
|
10
|
+
export declare function generateRobotsTxt(rootDir: string, settings: Settings, origin?: string): Promise<string>;
|
|
11
|
+
//# sourceMappingURL=robots.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"robots.d.ts","sourceRoot":"","sources":["../../src/generators/robots.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAGrD;;;;;;;GAOG;AACH,wBAAsB,iBAAiB,CACrC,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,QAAQ,EAClB,MAAM,CAAC,EAAE,MAAM,GACd,OAAO,CAAC,MAAM,CAAC,CAmBjB"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import path from "node:path";
|
|
2
|
+
import { promises as fs } from "node:fs";
|
|
3
|
+
import { buildSiteUrl } from "../seo/url.js";
|
|
4
|
+
/**
|
|
5
|
+
* Generate robots.txt content.
|
|
6
|
+
*
|
|
7
|
+
* A non-empty `robots.txt` in the docs root always wins. Otherwise emit a
|
|
8
|
+
* permissive file; the `Sitemap:` line is only included when an absolute
|
|
9
|
+
* sitemap URL can be derived (`site.baseUrl`, or the request `origin`
|
|
10
|
+
* in serve mode) — relative Sitemap URLs are invalid per spec.
|
|
11
|
+
*/
|
|
12
|
+
export async function generateRobotsTxt(rootDir, settings, origin) {
|
|
13
|
+
const customRobotsPath = path.join(rootDir, "robots.txt");
|
|
14
|
+
try {
|
|
15
|
+
const customRobots = await fs.readFile(customRobotsPath, "utf-8");
|
|
16
|
+
if (customRobots.trim().length > 0) {
|
|
17
|
+
return customRobots;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
catch {
|
|
21
|
+
// No custom robots.txt
|
|
22
|
+
}
|
|
23
|
+
const lines = ["User-agent: *", "Allow: /"];
|
|
24
|
+
if (settings.seo.generateSitemap) {
|
|
25
|
+
const siteUrl = buildSiteUrl(settings, origin);
|
|
26
|
+
if (siteUrl) {
|
|
27
|
+
lines.push(`Sitemap: ${siteUrl}sitemap.xml`);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
return `${lines.join("\n")}\n`;
|
|
31
|
+
}
|
|
32
|
+
//# sourceMappingURL=robots.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"robots.js","sourceRoot":"","sources":["../../src/generators/robots.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,QAAQ,IAAI,EAAE,EAAE,MAAM,SAAS,CAAC;AAEzC,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAE7C;;;;;;;GAOG;AACH,MAAM,CAAC,KAAK,UAAU,iBAAiB,CACrC,OAAe,EACf,QAAkB,EAClB,MAAe;IAEf,MAAM,gBAAgB,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,YAAY,CAAC,CAAC;IAC1D,IAAI,CAAC;QACH,MAAM,YAAY,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,gBAAgB,EAAE,OAAO,CAAC,CAAC;QAClE,IAAI,YAAY,CAAC,IAAI,EAAE,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACnC,OAAO,YAAY,CAAC;QACtB,CAAC;IACH,CAAC;IAAC,MAAM,CAAC;QACP,uBAAuB;IACzB,CAAC;IAED,MAAM,KAAK,GAAG,CAAC,eAAe,EAAE,UAAU,CAAC,CAAC;IAC5C,IAAI,QAAQ,CAAC,GAAG,CAAC,eAAe,EAAE,CAAC;QACjC,MAAM,OAAO,GAAG,YAAY,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;QAC/C,IAAI,OAAO,EAAE,CAAC;YACZ,KAAK,CAAC,IAAI,CAAC,YAAY,OAAO,aAAa,CAAC,CAAC;QAC/C,CAAC;IACH,CAAC;IACD,OAAO,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC;AACjC,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"search-index.d.ts","sourceRoot":"","sources":["../../src/generators/search-index.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAErD,MAAM,WAAW,WAAW;IAC1B,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC;CACjB;
|
|
1
|
+
{"version":3,"file":"search-index.d.ts","sourceRoot":"","sources":["../../src/generators/search-index.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAErD,MAAM,WAAW,WAAW;IAC1B,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC;CACjB;AAuGD,wBAAsB,gBAAgB,CACpC,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,QAAQ,GACjB,OAAO,CAAC,WAAW,EAAE,CAAC,CAMxB"}
|
|
@@ -9,7 +9,7 @@ function isHidden(filePath, settings) {
|
|
|
9
9
|
if (pattern.startsWith("*") && basename.endsWith(pattern.slice(1)))
|
|
10
10
|
return true;
|
|
11
11
|
}
|
|
12
|
-
if (basename.startsWith("_"))
|
|
12
|
+
if (basename.startsWith("_") || basename.startsWith("."))
|
|
13
13
|
return true;
|
|
14
14
|
return false;
|
|
15
15
|
}
|
|
@@ -59,12 +59,13 @@ async function readDirRecursive(dirPath, rootDir, settings) {
|
|
|
59
59
|
const parsed = matter(content);
|
|
60
60
|
const relativePath = "/" + path.relative(rootDir, fullPath).replace(/\\/g, "/");
|
|
61
61
|
let href = relativePath.replace(/\.(md|mdx)$/, "");
|
|
62
|
-
//
|
|
63
|
-
|
|
62
|
+
// Index files render at the directory URL; everything else is a
|
|
63
|
+
// trailing-slash doc route — both canonical clean-URL forms.
|
|
64
|
+
if (/^(readme|index)$/i.test(path.basename(href))) {
|
|
64
65
|
href = path.dirname(href);
|
|
65
|
-
if (!href.endsWith("/"))
|
|
66
|
-
href += "/";
|
|
67
66
|
}
|
|
67
|
+
if (!href.endsWith("/"))
|
|
68
|
+
href += "/";
|
|
68
69
|
const title = parsed.data.title ||
|
|
69
70
|
parsed.content.match(/^#\s+(.+)$/m)?.[1] ||
|
|
70
71
|
item.name.replace(/\.\w+$/, "");
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"search-index.js","sourceRoot":"","sources":["../../src/generators/search-index.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,QAAQ,IAAI,EAAE,EAAE,MAAM,SAAS,CAAC;AACzC,OAAO,MAAM,MAAM,aAAa,CAAC;AAWjC,SAAS,QAAQ,CAAC,QAAgB,EAAE,QAAkB;IACpD,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;IAEzC,KAAK,MAAM,OAAO,IAAI,QAAQ,CAAC,KAAK,CAAC,UAAU,CAAC,MAAM,EAAE,CAAC;QACvD,IAAI,QAAQ,KAAK,OAAO;YAAE,OAAO,IAAI,CAAC;QACtC,IAAI,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,QAAQ,CAAC,QAAQ,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;YAChE,OAAO,IAAI,CAAC;IAChB,CAAC;IAED,IAAI,QAAQ,CAAC,UAAU,CAAC,GAAG,CAAC;QAAE,OAAO,IAAI,CAAC;
|
|
1
|
+
{"version":3,"file":"search-index.js","sourceRoot":"","sources":["../../src/generators/search-index.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,3 +1,19 @@
|
|
|
1
1
|
import type { Settings } from "../settings/index.js";
|
|
2
|
-
export
|
|
2
|
+
export interface SitemapPage {
|
|
3
|
+
urlPath: string;
|
|
4
|
+
lastmod?: string;
|
|
5
|
+
noIndex?: boolean;
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* Sitemap for the static-export path: consumes the same page list the
|
|
9
|
+
* exporter wrote, so output and sitemap always agree (including
|
|
10
|
+
* auto-index directory pages). Returns `null` without `site.baseUrl`.
|
|
11
|
+
*/
|
|
12
|
+
export declare function generateSitemapFromPages(pages: SitemapPage[], settings: Settings, origin?: string): string | null;
|
|
13
|
+
/**
|
|
14
|
+
* Scan-based sitemap used by the dev server. `origin` is the request
|
|
15
|
+
* origin (`http://host:port`); `site.baseUrl` wins when configured.
|
|
16
|
+
* Returns `null` when no absolute base is available.
|
|
17
|
+
*/
|
|
18
|
+
export declare function generateSitemap(rootDir: string, settings: Settings, origin?: string): Promise<string | null>;
|
|
3
19
|
//# sourceMappingURL=sitemap.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sitemap.d.ts","sourceRoot":"","sources":["../../src/generators/sitemap.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;
|
|
1
|
+
{"version":3,"file":"sitemap.d.ts","sourceRoot":"","sources":["../../src/generators/sitemap.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAGrD,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAyED;;;;GAIG;AACH,wBAAgB,wBAAwB,CACtC,KAAK,EAAE,WAAW,EAAE,EACpB,QAAQ,EAAE,QAAQ,EAClB,MAAM,CAAC,EAAE,MAAM,GACd,MAAM,GAAG,IAAI,CAGf;AAED;;;;GAIG;AACH,wBAAsB,eAAe,CACnC,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,QAAQ,EAClB,MAAM,CAAC,EAAE,MAAM,GACd,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAKxB"}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import path from "node:path";
|
|
2
2
|
import { promises as fs } from "node:fs";
|
|
3
3
|
import matter from "gray-matter";
|
|
4
|
+
import { buildPageUrl } from "../seo/url.js";
|
|
4
5
|
function isHidden(filePath, settings) {
|
|
5
6
|
const basename = path.basename(filePath);
|
|
6
7
|
for (const pattern of settings.files.extensions.hidden) {
|
|
@@ -9,75 +10,44 @@ function isHidden(filePath, settings) {
|
|
|
9
10
|
if (pattern.startsWith("*") && basename.endsWith(pattern.slice(1)))
|
|
10
11
|
return true;
|
|
11
12
|
}
|
|
12
|
-
if (basename.startsWith("_"))
|
|
13
|
+
if (basename.startsWith("_") || basename.startsWith("."))
|
|
13
14
|
return true;
|
|
14
15
|
return false;
|
|
15
16
|
}
|
|
16
|
-
|
|
17
|
+
function toIsoDate(value) {
|
|
18
|
+
if (value == null || value === "")
|
|
19
|
+
return undefined;
|
|
20
|
+
const d = value instanceof Date ? value : new Date(String(value));
|
|
21
|
+
return Number.isNaN(d.getTime()) ? undefined : d.toISOString().split("T")[0];
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Build sorted, deduped sitemap entries from page records. `noindex` pages
|
|
25
|
+
* are excluded and URLs are normalized + absolute. Returns `null` when no
|
|
26
|
+
* absolute base (`site.baseUrl` or `origin`) is available — a sitemap
|
|
27
|
+
* requires absolute URLs.
|
|
28
|
+
*/
|
|
29
|
+
function buildEntries(pages, settings, origin) {
|
|
30
|
+
if (!settings.site.baseUrl && !origin)
|
|
31
|
+
return null;
|
|
32
|
+
const seen = new Set();
|
|
17
33
|
const entries = [];
|
|
18
|
-
const
|
|
19
|
-
|
|
20
|
-
const fullPath = path.join(dirPath, item.name);
|
|
21
|
-
if (isHidden(fullPath, settings))
|
|
34
|
+
for (const page of pages) {
|
|
35
|
+
if (page.noIndex || settings.seo.noIndex)
|
|
22
36
|
continue;
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
(item.name.endsWith(".mdx") && settings.mdx.enabled)) {
|
|
29
|
-
try {
|
|
30
|
-
const relativePath = "/" + path.relative(rootDir, fullPath).replace(/\\/g, "/");
|
|
31
|
-
let urlPath = relativePath.replace(/\.(md|mdx)$/, "");
|
|
32
|
-
// README files render at the directory index URL
|
|
33
|
-
if (path.basename(urlPath).toLowerCase() === "readme") {
|
|
34
|
-
const dirPath = path.dirname(urlPath);
|
|
35
|
-
urlPath = dirPath === "/" ? "/" : `${dirPath}/`;
|
|
36
|
-
}
|
|
37
|
-
const fullUrl = `${baseUrl.replace(/\/$/, "")}${urlPath}`;
|
|
38
|
-
// Try to get lastmod from frontmatter or file stat
|
|
39
|
-
let lastmod;
|
|
40
|
-
try {
|
|
41
|
-
const content = await fs.readFile(fullPath, "utf-8");
|
|
42
|
-
const parsed = matter(content);
|
|
43
|
-
if (parsed.data.date) {
|
|
44
|
-
const date = new Date(parsed.data.date);
|
|
45
|
-
if (!isNaN(date.getTime())) {
|
|
46
|
-
lastmod = date.toISOString().split("T")[0];
|
|
47
|
-
}
|
|
48
|
-
}
|
|
49
|
-
}
|
|
50
|
-
catch {
|
|
51
|
-
// Fall through to file stat
|
|
52
|
-
}
|
|
53
|
-
if (!lastmod) {
|
|
54
|
-
const stat = await fs.stat(fullPath);
|
|
55
|
-
lastmod = stat.mtime.toISOString().split("T")[0];
|
|
56
|
-
}
|
|
57
|
-
entries.push({
|
|
58
|
-
url: fullUrl,
|
|
59
|
-
lastmod,
|
|
60
|
-
changefreq: "weekly",
|
|
61
|
-
});
|
|
62
|
-
}
|
|
63
|
-
catch {
|
|
64
|
-
// Skip files that can't be read
|
|
65
|
-
}
|
|
66
|
-
}
|
|
37
|
+
const loc = buildPageUrl(page.urlPath, settings, origin);
|
|
38
|
+
if (!loc || seen.has(loc))
|
|
39
|
+
continue;
|
|
40
|
+
seen.add(loc);
|
|
41
|
+
entries.push({ loc, lastmod: page.lastmod, changefreq: "weekly" });
|
|
67
42
|
}
|
|
43
|
+
entries.sort((a, b) => a.loc.localeCompare(b.loc));
|
|
68
44
|
return entries;
|
|
69
45
|
}
|
|
70
|
-
|
|
71
|
-
const baseUrl = settings.site.baseUrl || "http://localhost:1800";
|
|
72
|
-
const basePath = settings.generate.basePath || "";
|
|
73
|
-
const fullBaseUrl = baseUrl.replace(/\/$/, "") + basePath;
|
|
74
|
-
const entries = await readDirRecursive(rootDir, rootDir, fullBaseUrl, settings);
|
|
75
|
-
// Sort by URL for consistent output
|
|
76
|
-
entries.sort((a, b) => a.url.localeCompare(b.url));
|
|
46
|
+
function renderXml(entries) {
|
|
77
47
|
const urlElements = entries
|
|
78
48
|
.map((entry) => ` <url>
|
|
79
|
-
<loc>${escapeXml(entry.
|
|
80
|
-
|
|
49
|
+
<loc>${escapeXml(entry.loc)}</loc>
|
|
50
|
+
${entry.lastmod ? `<lastmod>${entry.lastmod}</lastmod>` : ""}
|
|
81
51
|
<changefreq>${entry.changefreq}</changefreq>
|
|
82
52
|
</url>`)
|
|
83
53
|
.join("\n");
|
|
@@ -86,6 +56,96 @@ export async function generateSitemap(rootDir, settings) {
|
|
|
86
56
|
${urlElements}
|
|
87
57
|
</urlset>`;
|
|
88
58
|
}
|
|
59
|
+
/**
|
|
60
|
+
* Sitemap for the static-export path: consumes the same page list the
|
|
61
|
+
* exporter wrote, so output and sitemap always agree (including
|
|
62
|
+
* auto-index directory pages). Returns `null` without `site.baseUrl`.
|
|
63
|
+
*/
|
|
64
|
+
export function generateSitemapFromPages(pages, settings, origin) {
|
|
65
|
+
const entries = buildEntries(pages, settings, origin);
|
|
66
|
+
return entries ? renderXml(entries) : null;
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Scan-based sitemap used by the dev server. `origin` is the request
|
|
70
|
+
* origin (`http://host:port`); `site.baseUrl` wins when configured.
|
|
71
|
+
* Returns `null` when no absolute base is available.
|
|
72
|
+
*/
|
|
73
|
+
export async function generateSitemap(rootDir, settings, origin) {
|
|
74
|
+
const pages = [];
|
|
75
|
+
await scanDirectory(rootDir, rootDir, settings, pages);
|
|
76
|
+
const entries = buildEntries(pages, settings, origin);
|
|
77
|
+
return entries ? renderXml(entries) : null;
|
|
78
|
+
}
|
|
79
|
+
async function scanDirectory(dirPath, rootDir, settings, pages) {
|
|
80
|
+
const items = await fs.readdir(dirPath, { withFileTypes: true });
|
|
81
|
+
const subDirs = [];
|
|
82
|
+
let hasIndexFile = false;
|
|
83
|
+
const indexBaseNames = settings.files.indexFiles.map((name) => name.replace(/\.\w+$/, "").toLowerCase());
|
|
84
|
+
for (const item of items) {
|
|
85
|
+
const fullPath = path.join(dirPath, item.name);
|
|
86
|
+
if (isHidden(fullPath, settings))
|
|
87
|
+
continue;
|
|
88
|
+
if (item.isDirectory()) {
|
|
89
|
+
subDirs.push(fullPath);
|
|
90
|
+
continue;
|
|
91
|
+
}
|
|
92
|
+
if (!item.name.endsWith(".md") &&
|
|
93
|
+
!(item.name.endsWith(".mdx") && settings.mdx.enabled)) {
|
|
94
|
+
continue;
|
|
95
|
+
}
|
|
96
|
+
try {
|
|
97
|
+
const baseName = item.name.replace(/\.(md|mdx)$/i, "").toLowerCase();
|
|
98
|
+
const relDir = path.relative(rootDir, dirPath).replace(/\\/g, "/");
|
|
99
|
+
const dirUrl = relDir ? `/${relDir}/` : "/";
|
|
100
|
+
const urlPath = indexBaseNames.includes(baseName)
|
|
101
|
+
? dirUrl
|
|
102
|
+
: `${dirUrl}${item.name.replace(/\.(md|mdx)$/i, "")}`;
|
|
103
|
+
if (indexBaseNames.includes(baseName))
|
|
104
|
+
hasIndexFile = true;
|
|
105
|
+
let lastmod;
|
|
106
|
+
let noIndex = false;
|
|
107
|
+
try {
|
|
108
|
+
const content = await fs.readFile(fullPath, "utf-8");
|
|
109
|
+
const parsed = matter(content);
|
|
110
|
+
lastmod = toIsoDate(parsed.data.dateModified ??
|
|
111
|
+
parsed.data.lastmod ??
|
|
112
|
+
parsed.data.updated ??
|
|
113
|
+
parsed.data.date);
|
|
114
|
+
noIndex = (parsed.data.noindex ?? parsed.data.noIndex) === true;
|
|
115
|
+
}
|
|
116
|
+
catch {
|
|
117
|
+
// Fall through to file stat
|
|
118
|
+
}
|
|
119
|
+
if (!lastmod) {
|
|
120
|
+
const stat = await fs.stat(fullPath);
|
|
121
|
+
lastmod = stat.mtime.toISOString().split("T")[0];
|
|
122
|
+
}
|
|
123
|
+
pages.push({ urlPath, lastmod, noIndex });
|
|
124
|
+
}
|
|
125
|
+
catch {
|
|
126
|
+
// Skip files that can't be read
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
// Auto-index directory page (directory without an index file)
|
|
130
|
+
if (!hasIndexFile) {
|
|
131
|
+
try {
|
|
132
|
+
const relDir = path.relative(rootDir, dirPath).replace(/\\/g, "/");
|
|
133
|
+
const urlPath = relDir ? `/${relDir}/` : "/";
|
|
134
|
+
const stat = await fs.stat(dirPath);
|
|
135
|
+
pages.push({
|
|
136
|
+
urlPath,
|
|
137
|
+
lastmod: stat.mtime.toISOString().split("T")[0],
|
|
138
|
+
noIndex: settings.seo.noIndexDirectoryPages,
|
|
139
|
+
});
|
|
140
|
+
}
|
|
141
|
+
catch {
|
|
142
|
+
// Skip directories that can't be stat'ed
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
for (const subDir of subDirs) {
|
|
146
|
+
await scanDirectory(subDir, rootDir, settings, pages);
|
|
147
|
+
}
|
|
148
|
+
}
|
|
89
149
|
function escapeXml(text) {
|
|
90
150
|
return text
|
|
91
151
|
.replace(/&/g, "&")
|