fumadocs-core 15.2.8 → 16.0.3
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 +1 -1
- package/dist/algolia-IZEDLPHE.js +58 -0
- package/dist/breadcrumb.d.ts +7 -5
- package/dist/breadcrumb.js +46 -52
- package/dist/builder-feW_xVjc.d.ts +296 -0
- package/dist/{chunk-FVY6EZ3N.js → chunk-BBP7MIO4.js} +12 -14
- package/dist/{chunk-ORHEEQVY.js → chunk-EMWGTXSW.js} +0 -7
- package/dist/chunk-FAEPKD7U.js +20 -0
- package/dist/{chunk-NNKVN7WA.js → chunk-H2GMUTQG.js} +4 -2
- package/dist/chunk-IZPLHEX4.js +113 -0
- package/dist/chunk-OTD7MV33.js +53 -0
- package/dist/chunk-PFNP6PEB.js +11 -0
- package/dist/{chunk-Y2774T3B.js → chunk-QMATWJ5F.js} +6 -7
- package/dist/chunk-U67V476Y.js +35 -0
- package/dist/{chunk-BUCUQ3WX.js → chunk-XN2LKXFZ.js} +39 -34
- package/dist/{chunk-WFUH5VBX.js → chunk-XOFXGHS4.js} +26 -10
- package/dist/chunk-XZSI7AHE.js +67 -0
- package/dist/chunk-YVVDKJ2H.js +34 -0
- package/dist/chunk-ZMWYLUDP.js +21 -0
- package/dist/content/github.d.ts +34 -0
- package/dist/content/github.js +43 -0
- package/dist/content/index.d.ts +16 -0
- package/dist/content/index.js +30 -0
- package/dist/{get-toc-Cr2URuiP.d.ts → content/toc.d.ts} +6 -10
- package/dist/content/toc.js +21 -0
- package/dist/{page-tree-BG3wP0gU.d.ts → definitions-BRsJlZ6m.d.ts} +10 -15
- package/dist/dynamic-link.js +3 -3
- package/dist/fetch-2XFMBLBA.js +22 -0
- package/dist/framework/index.d.ts +1 -1
- package/dist/framework/index.js +2 -2
- package/dist/framework/next.js +2 -2
- package/dist/framework/react-router.js +2 -2
- package/dist/framework/tanstack.js +2 -2
- package/dist/framework/waku.d.ts +8 -0
- package/dist/framework/waku.js +51 -0
- package/dist/hide-if-empty.d.ts +18 -0
- package/dist/hide-if-empty.js +83 -0
- package/dist/highlight/client.d.ts +8 -5
- package/dist/highlight/client.js +9 -93
- package/dist/highlight/index.d.ts +20 -5
- package/dist/highlight/index.js +10 -6
- package/dist/i18n/index.d.ts +35 -8
- package/dist/i18n/index.js +5 -69
- package/dist/i18n/middleware.d.ts +12 -0
- package/dist/i18n/middleware.js +63 -0
- package/dist/link.js +3 -3
- package/dist/mdx-plugins/index.d.ts +124 -18
- package/dist/mdx-plugins/index.js +605 -203
- package/dist/mixedbread-RAHDVXGJ.js +118 -0
- package/dist/negotiation/index.d.ts +19 -0
- package/dist/negotiation/index.js +11 -0
- package/dist/{orama-cloud-USLSOSXS.js → orama-cloud-WEGQE5A6.js} +37 -27
- package/dist/page-tree/index.d.ts +32 -0
- package/dist/page-tree/index.js +15 -0
- package/dist/remark-code-tab-DmyIyi6m.d.ts +57 -0
- package/dist/{remark-structure-FIjTA11P.d.ts → remark-structure-DkCXCzpD.d.ts} +13 -2
- package/dist/search/algolia.d.ts +9 -7
- package/dist/search/algolia.js +31 -17
- package/dist/search/client.d.ts +88 -17
- package/dist/search/client.js +71 -50
- package/dist/search/index.d.ts +26 -0
- package/dist/search/index.js +7 -0
- package/dist/search/orama-cloud.d.ts +7 -5
- package/dist/search/orama-cloud.js +18 -10
- package/dist/search/server.d.ts +33 -25
- package/dist/search/server.js +109 -47
- package/dist/source/index.d.ts +33 -254
- package/dist/source/index.js +532 -353
- package/dist/source/plugins/lucide-icons.d.ts +14 -0
- package/dist/source/plugins/lucide-icons.js +23 -0
- package/dist/static-A2YJ5TXV.js +62 -0
- package/dist/toc.d.ts +11 -7
- package/dist/toc.js +6 -5
- package/dist/utils/use-effect-event.d.ts +4 -3
- package/dist/utils/use-effect-event.js +9 -6
- package/dist/utils/use-media-query.d.ts +3 -0
- package/dist/utils/use-media-query.js +23 -0
- package/dist/utils/use-on-change.js +2 -2
- package/package.json +92 -40
- package/dist/algolia-NTWLS6J3.js +0 -49
- package/dist/chunk-KAOEMCTI.js +0 -17
- package/dist/chunk-MLKGABMK.js +0 -9
- package/dist/chunk-XMCPKVJQ.js +0 -34
- package/dist/config-inq6kP6y.d.ts +0 -26
- package/dist/fetch-W5EHIBOE.js +0 -21
- package/dist/remark-heading-BPCoYwjn.d.ts +0 -31
- package/dist/server/index.d.ts +0 -117
- package/dist/server/index.js +0 -202
- package/dist/sidebar.d.ts +0 -33
- package/dist/sidebar.js +0 -89
- package/dist/static-VESU2S64.js +0 -61
- package/dist/types-Ch8gnVgO.d.ts +0 -8
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
// src/page-tree/utils.ts
|
|
2
|
+
function flattenTree(nodes) {
|
|
3
|
+
const out = [];
|
|
4
|
+
for (const node of nodes) {
|
|
5
|
+
if (node.type === "folder") {
|
|
6
|
+
if (node.index) out.push(node.index);
|
|
7
|
+
out.push(...flattenTree(node.children));
|
|
8
|
+
} else if (node.type === "page") {
|
|
9
|
+
out.push(node);
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
return out;
|
|
13
|
+
}
|
|
14
|
+
function findNeighbour(tree, url, options) {
|
|
15
|
+
const { separateRoot = true } = options ?? {};
|
|
16
|
+
const roots = separateRoot ? getPageTreeRoots(tree) : [tree];
|
|
17
|
+
if (tree.fallback) roots.push(tree.fallback);
|
|
18
|
+
for (const root of roots) {
|
|
19
|
+
const list = flattenTree(root.children);
|
|
20
|
+
const idx = list.findIndex((item) => item.url === url);
|
|
21
|
+
if (idx === -1) continue;
|
|
22
|
+
return {
|
|
23
|
+
previous: list[idx - 1],
|
|
24
|
+
next: list[idx + 1]
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
return {};
|
|
28
|
+
}
|
|
29
|
+
function getPageTreeRoots(pageTree) {
|
|
30
|
+
const result = pageTree.children.flatMap((child) => {
|
|
31
|
+
if (child.type !== "folder") return [];
|
|
32
|
+
const roots = getPageTreeRoots(child);
|
|
33
|
+
if (child.root) roots.push(child);
|
|
34
|
+
return roots;
|
|
35
|
+
});
|
|
36
|
+
if (!("type" in pageTree)) result.push(pageTree);
|
|
37
|
+
return result;
|
|
38
|
+
}
|
|
39
|
+
function getPageTreePeers(treeOrTrees, url) {
|
|
40
|
+
if ("children" in treeOrTrees) {
|
|
41
|
+
const tree = treeOrTrees;
|
|
42
|
+
const parent = findParentFromTree(tree, url);
|
|
43
|
+
if (!parent) return [];
|
|
44
|
+
return parent.children.filter(
|
|
45
|
+
(item) => item.type === "page" && item.url !== url
|
|
46
|
+
);
|
|
47
|
+
}
|
|
48
|
+
const trees = treeOrTrees;
|
|
49
|
+
for (const lang in trees) {
|
|
50
|
+
const rootTree = trees[lang];
|
|
51
|
+
if (rootTree) {
|
|
52
|
+
const parent = findParentFromTree(rootTree, url);
|
|
53
|
+
if (parent) {
|
|
54
|
+
return parent.children.filter(
|
|
55
|
+
(item) => item.type === "page" && item.url !== url
|
|
56
|
+
);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
return [];
|
|
61
|
+
}
|
|
62
|
+
function findParentFromTree(node, url) {
|
|
63
|
+
if ("index" in node && node.index?.url === url) {
|
|
64
|
+
return node;
|
|
65
|
+
}
|
|
66
|
+
for (const child of node.children) {
|
|
67
|
+
if (child.type === "folder") {
|
|
68
|
+
const parent = findParentFromTree(child, url);
|
|
69
|
+
if (parent) return parent;
|
|
70
|
+
}
|
|
71
|
+
if (child.type === "page" && child.url === url) {
|
|
72
|
+
return node;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
if ("fallback" in node && node.fallback) {
|
|
76
|
+
return findParentFromTree(node.fallback, url);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
function findPath(nodes, matcher, options = {}) {
|
|
80
|
+
const { includeSeparator = true } = options;
|
|
81
|
+
function run(nodes2) {
|
|
82
|
+
let separator;
|
|
83
|
+
for (const node of nodes2) {
|
|
84
|
+
if (matcher(node)) {
|
|
85
|
+
const items = [];
|
|
86
|
+
if (separator) items.push(separator);
|
|
87
|
+
items.push(node);
|
|
88
|
+
return items;
|
|
89
|
+
}
|
|
90
|
+
if (node.type === "separator" && includeSeparator) {
|
|
91
|
+
separator = node;
|
|
92
|
+
continue;
|
|
93
|
+
}
|
|
94
|
+
if (node.type === "folder") {
|
|
95
|
+
const items = node.index && matcher(node.index) ? [node.index] : run(node.children);
|
|
96
|
+
if (items) {
|
|
97
|
+
items.unshift(node);
|
|
98
|
+
if (separator) items.unshift(separator);
|
|
99
|
+
return items;
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
return run(nodes) ?? null;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
export {
|
|
108
|
+
flattenTree,
|
|
109
|
+
findNeighbour,
|
|
110
|
+
getPageTreeRoots,
|
|
111
|
+
getPageTreePeers,
|
|
112
|
+
findPath
|
|
113
|
+
};
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
// src/search/index.ts
|
|
2
|
+
function escapeRegExp(input) {
|
|
3
|
+
return input.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
4
|
+
}
|
|
5
|
+
function buildRegexFromQuery(q) {
|
|
6
|
+
const trimmed = q.trim();
|
|
7
|
+
if (trimmed.length === 0) return null;
|
|
8
|
+
const terms = Array.from(
|
|
9
|
+
new Set(
|
|
10
|
+
trimmed.split(/\s+/).map((t) => t.trim()).filter(Boolean)
|
|
11
|
+
)
|
|
12
|
+
);
|
|
13
|
+
if (terms.length === 0) return null;
|
|
14
|
+
const escaped = terms.map(escapeRegExp).join("|");
|
|
15
|
+
return new RegExp(`(${escaped})`, "gi");
|
|
16
|
+
}
|
|
17
|
+
function createContentHighlighter(query) {
|
|
18
|
+
const regex = typeof query === "string" ? buildRegexFromQuery(query) : query;
|
|
19
|
+
return {
|
|
20
|
+
highlight(content) {
|
|
21
|
+
if (!regex) return [{ type: "text", content }];
|
|
22
|
+
const out = [];
|
|
23
|
+
let i = 0;
|
|
24
|
+
for (const match of content.matchAll(regex)) {
|
|
25
|
+
if (i < match.index) {
|
|
26
|
+
out.push({
|
|
27
|
+
type: "text",
|
|
28
|
+
content: content.substring(i, match.index)
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
out.push({
|
|
32
|
+
type: "text",
|
|
33
|
+
content: match[0],
|
|
34
|
+
styles: {
|
|
35
|
+
highlight: true
|
|
36
|
+
}
|
|
37
|
+
});
|
|
38
|
+
i = match.index + match[0].length;
|
|
39
|
+
}
|
|
40
|
+
if (i < content.length) {
|
|
41
|
+
out.push({
|
|
42
|
+
type: "text",
|
|
43
|
+
content: content.substring(i)
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
return out;
|
|
47
|
+
}
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
export {
|
|
52
|
+
createContentHighlighter
|
|
53
|
+
};
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
// src/utils/normalize-url.tsx
|
|
2
|
+
function normalizeUrl(url) {
|
|
3
|
+
if (url.startsWith("http://") || url.startsWith("https://")) return url;
|
|
4
|
+
if (!url.startsWith("/")) url = "/" + url;
|
|
5
|
+
if (url.length > 1 && url.endsWith("/")) url = url.slice(0, -1);
|
|
6
|
+
return url;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export {
|
|
10
|
+
normalizeUrl
|
|
11
|
+
};
|
|
@@ -24,25 +24,24 @@ function remarkHeading({
|
|
|
24
24
|
visit(root, "heading", (heading) => {
|
|
25
25
|
heading.data ||= {};
|
|
26
26
|
heading.data.hProperties ||= {};
|
|
27
|
-
|
|
27
|
+
const props = heading.data.hProperties;
|
|
28
28
|
const lastNode = heading.children.at(-1);
|
|
29
|
-
if (
|
|
29
|
+
if (lastNode?.type === "text" && customId) {
|
|
30
30
|
const match = regex.exec(lastNode.value);
|
|
31
31
|
if (match?.[1]) {
|
|
32
|
-
id = match[1];
|
|
32
|
+
props.id = match[1];
|
|
33
33
|
lastNode.value = lastNode.value.slice(0, match.index);
|
|
34
34
|
}
|
|
35
35
|
}
|
|
36
36
|
let flattened = null;
|
|
37
|
-
if (!id) {
|
|
37
|
+
if (!props.id) {
|
|
38
38
|
flattened ??= flattenNode(heading);
|
|
39
|
-
id = defaultSlug ? defaultSlug(root, heading, flattened) : slugger.slug(flattened);
|
|
39
|
+
props.id = defaultSlug ? defaultSlug(root, heading, flattened) : slugger.slug(flattened);
|
|
40
40
|
}
|
|
41
|
-
heading.data.hProperties.id = id;
|
|
42
41
|
if (generateToc) {
|
|
43
42
|
toc.push({
|
|
44
43
|
title: flattened ?? flattenNode(heading),
|
|
45
|
-
url: `#${id}`,
|
|
44
|
+
url: `#${props.id}`,
|
|
46
45
|
depth: heading.depth
|
|
47
46
|
});
|
|
48
47
|
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
var __create = Object.create;
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
6
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
7
|
+
var __commonJS = (cb, mod) => function __require() {
|
|
8
|
+
return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
|
|
9
|
+
};
|
|
10
|
+
var __export = (target, all) => {
|
|
11
|
+
for (var name in all)
|
|
12
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
13
|
+
};
|
|
14
|
+
var __copyProps = (to, from, except, desc) => {
|
|
15
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
16
|
+
for (let key of __getOwnPropNames(from))
|
|
17
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
18
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
19
|
+
}
|
|
20
|
+
return to;
|
|
21
|
+
};
|
|
22
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
23
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
24
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
25
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
26
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
27
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
28
|
+
mod
|
|
29
|
+
));
|
|
30
|
+
|
|
31
|
+
export {
|
|
32
|
+
__commonJS,
|
|
33
|
+
__export,
|
|
34
|
+
__toESM
|
|
35
|
+
};
|
|
@@ -1,66 +1,70 @@
|
|
|
1
1
|
// src/highlight/shiki.ts
|
|
2
|
-
import {
|
|
2
|
+
import {
|
|
3
|
+
toJsxRuntime
|
|
4
|
+
} from "hast-util-to-jsx-runtime";
|
|
3
5
|
import { Fragment } from "react";
|
|
4
6
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
5
|
-
function createStyleTransformer() {
|
|
6
|
-
return {
|
|
7
|
-
name: "rehype-code:styles",
|
|
8
|
-
line(hast) {
|
|
9
|
-
if (hast.children.length === 0) {
|
|
10
|
-
hast.children.push({
|
|
11
|
-
type: "text",
|
|
12
|
-
value: " "
|
|
13
|
-
});
|
|
14
|
-
}
|
|
15
|
-
}
|
|
16
|
-
};
|
|
17
|
-
}
|
|
18
7
|
var defaultThemes = {
|
|
19
8
|
light: "github-light",
|
|
20
9
|
dark: "github-dark"
|
|
21
10
|
};
|
|
22
11
|
var highlighters = /* @__PURE__ */ new Map();
|
|
23
|
-
async function
|
|
24
|
-
const {
|
|
25
|
-
|
|
12
|
+
async function highlightHast(code, options) {
|
|
13
|
+
const {
|
|
14
|
+
lang: initialLang,
|
|
15
|
+
fallbackLanguage,
|
|
16
|
+
components: _,
|
|
17
|
+
engine = "js",
|
|
18
|
+
...rest
|
|
19
|
+
} = options;
|
|
20
|
+
let lang = initialLang;
|
|
21
|
+
let themes;
|
|
22
|
+
let themesToLoad;
|
|
26
23
|
if ("theme" in options && options.theme) {
|
|
27
24
|
themes = { theme: options.theme };
|
|
28
|
-
|
|
29
|
-
|
|
25
|
+
themesToLoad = [themes.theme];
|
|
26
|
+
} else {
|
|
27
|
+
themes = {
|
|
28
|
+
themes: "themes" in options && options.themes ? options.themes : defaultThemes
|
|
29
|
+
};
|
|
30
|
+
themesToLoad = Object.values(themes.themes).filter((v) => v !== void 0);
|
|
30
31
|
}
|
|
31
|
-
const highlighter = await getHighlighter(
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
themes: "theme" in themes ? [themes.theme] : Object.values(themes.themes).filter((v) => v !== void 0)
|
|
32
|
+
const highlighter = await getHighlighter(engine, {
|
|
33
|
+
langs: [],
|
|
34
|
+
themes: themesToLoad
|
|
35
35
|
});
|
|
36
|
+
try {
|
|
37
|
+
await highlighter.loadLanguage(lang);
|
|
38
|
+
} catch {
|
|
39
|
+
lang = fallbackLanguage ?? "text";
|
|
40
|
+
await highlighter.loadLanguage(lang);
|
|
41
|
+
}
|
|
36
42
|
return highlighter.codeToHast(code, {
|
|
37
43
|
lang,
|
|
38
44
|
...rest,
|
|
39
45
|
...themes,
|
|
40
|
-
transformers: [createStyleTransformer(), ...rest.transformers ?? []],
|
|
41
46
|
defaultColor: "themes" in themes ? false : void 0
|
|
42
47
|
});
|
|
43
48
|
}
|
|
44
|
-
function
|
|
49
|
+
function hastToJsx(hast, options) {
|
|
45
50
|
return toJsxRuntime(hast, {
|
|
46
51
|
jsx,
|
|
47
52
|
jsxs,
|
|
48
53
|
development: false,
|
|
49
|
-
|
|
50
|
-
|
|
54
|
+
Fragment,
|
|
55
|
+
...options
|
|
51
56
|
});
|
|
52
57
|
}
|
|
53
58
|
async function getHighlighter(engineType, options) {
|
|
54
59
|
const { createHighlighter } = await import("shiki");
|
|
55
60
|
let highlighter = highlighters.get(engineType);
|
|
56
61
|
if (!highlighter) {
|
|
57
|
-
let engine
|
|
62
|
+
let engine;
|
|
58
63
|
if (engineType === "js") {
|
|
59
64
|
engine = import("shiki/engine/javascript").then(
|
|
60
65
|
(res) => res.createJavaScriptRegexEngine()
|
|
61
66
|
);
|
|
62
|
-
}
|
|
63
|
-
if (engineType === "oniguruma" || !engine) {
|
|
67
|
+
} else {
|
|
64
68
|
engine = import("shiki/engine/oniguruma").then(
|
|
65
69
|
(res) => res.createOnigurumaEngine(import("shiki/wasm"))
|
|
66
70
|
);
|
|
@@ -83,14 +87,15 @@ async function getHighlighter(engineType, options) {
|
|
|
83
87
|
});
|
|
84
88
|
}
|
|
85
89
|
async function highlight(code, options) {
|
|
86
|
-
return
|
|
90
|
+
return hastToJsx(await highlightHast(code, options), {
|
|
91
|
+
components: options.components
|
|
92
|
+
});
|
|
87
93
|
}
|
|
88
94
|
|
|
89
95
|
export {
|
|
90
|
-
createStyleTransformer,
|
|
91
96
|
defaultThemes,
|
|
92
|
-
|
|
93
|
-
|
|
97
|
+
highlightHast,
|
|
98
|
+
hastToJsx,
|
|
94
99
|
getHighlighter,
|
|
95
100
|
highlight
|
|
96
101
|
};
|
|
@@ -1,10 +1,14 @@
|
|
|
1
1
|
import {
|
|
2
2
|
removeUndefined
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-ZMWYLUDP.js";
|
|
4
|
+
import {
|
|
5
|
+
createContentHighlighter
|
|
6
|
+
} from "./chunk-OTD7MV33.js";
|
|
4
7
|
|
|
5
8
|
// src/search/orama/search/simple.ts
|
|
6
9
|
import { search } from "@orama/orama";
|
|
7
10
|
async function searchSimple(db, query, params = {}) {
|
|
11
|
+
const highlighter = createContentHighlighter(query);
|
|
8
12
|
const result = await search(db, {
|
|
9
13
|
term: query,
|
|
10
14
|
tolerance: 1,
|
|
@@ -17,6 +21,8 @@ async function searchSimple(db, query, params = {}) {
|
|
|
17
21
|
return result.hits.map((hit) => ({
|
|
18
22
|
type: "page",
|
|
19
23
|
content: hit.document.title,
|
|
24
|
+
breadcrumbs: hit.document.breadcrumbs,
|
|
25
|
+
contentWithHighlights: highlighter.highlight(hit.document.title),
|
|
20
26
|
id: hit.document.url,
|
|
21
27
|
url: hit.document.url
|
|
22
28
|
}));
|
|
@@ -24,38 +30,46 @@ async function searchSimple(db, query, params = {}) {
|
|
|
24
30
|
|
|
25
31
|
// src/search/orama/search/advanced.ts
|
|
26
32
|
import { getByID, search as search2 } from "@orama/orama";
|
|
27
|
-
async function searchAdvanced(db, query, tag
|
|
33
|
+
async function searchAdvanced(db, query, tag = [], {
|
|
34
|
+
mode = "fulltext",
|
|
35
|
+
...override
|
|
36
|
+
} = {}) {
|
|
37
|
+
if (typeof tag === "string") tag = [tag];
|
|
28
38
|
let params = {
|
|
39
|
+
...override,
|
|
40
|
+
mode,
|
|
29
41
|
where: removeUndefined({
|
|
30
|
-
tag
|
|
31
|
-
|
|
42
|
+
tags: tag.length > 0 ? {
|
|
43
|
+
containsAll: tag
|
|
44
|
+
} : void 0,
|
|
45
|
+
...override.where
|
|
32
46
|
}),
|
|
33
47
|
groupBy: {
|
|
34
48
|
properties: ["page_id"],
|
|
35
49
|
maxResult: 8,
|
|
36
|
-
...
|
|
50
|
+
...override.groupBy
|
|
37
51
|
}
|
|
38
52
|
};
|
|
39
53
|
if (query.length > 0) {
|
|
40
54
|
params = {
|
|
41
55
|
...params,
|
|
42
56
|
term: query,
|
|
43
|
-
properties: ["content", "
|
|
44
|
-
...extraParams,
|
|
45
|
-
where: params.where,
|
|
46
|
-
groupBy: params.groupBy
|
|
57
|
+
properties: mode === "fulltext" ? ["content"] : ["content", "embeddings"]
|
|
47
58
|
};
|
|
48
59
|
}
|
|
60
|
+
const highlighter = createContentHighlighter(query);
|
|
49
61
|
const result = await search2(db, params);
|
|
50
62
|
const list = [];
|
|
51
63
|
for (const item of result.groups ?? []) {
|
|
52
64
|
const pageId = item.values[0];
|
|
53
|
-
const page =
|
|
65
|
+
const page = getByID(db, pageId);
|
|
54
66
|
if (!page) continue;
|
|
55
67
|
list.push({
|
|
56
68
|
id: pageId,
|
|
57
69
|
type: "page",
|
|
58
70
|
content: page.content,
|
|
71
|
+
breadcrumbs: page.breadcrumbs,
|
|
72
|
+
contentWithHighlights: highlighter.highlight(page.content),
|
|
59
73
|
url: page.url
|
|
60
74
|
});
|
|
61
75
|
for (const hit of item.result) {
|
|
@@ -63,6 +77,8 @@ async function searchAdvanced(db, query, tag, extraParams = {}) {
|
|
|
63
77
|
list.push({
|
|
64
78
|
id: hit.document.id.toString(),
|
|
65
79
|
content: hit.document.content,
|
|
80
|
+
breadcrumbs: hit.document.breadcrumbs,
|
|
81
|
+
contentWithHighlights: highlighter.highlight(hit.document.content),
|
|
66
82
|
type: hit.document.type,
|
|
67
83
|
url: hit.document.url
|
|
68
84
|
});
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import {
|
|
2
|
+
__export
|
|
3
|
+
} from "./chunk-U67V476Y.js";
|
|
4
|
+
|
|
5
|
+
// src/source/path.ts
|
|
6
|
+
var path_exports = {};
|
|
7
|
+
__export(path_exports, {
|
|
8
|
+
basename: () => basename,
|
|
9
|
+
dirname: () => dirname,
|
|
10
|
+
extname: () => extname,
|
|
11
|
+
joinPath: () => joinPath,
|
|
12
|
+
slash: () => slash,
|
|
13
|
+
splitPath: () => splitPath
|
|
14
|
+
});
|
|
15
|
+
function basename(path, ext) {
|
|
16
|
+
const idx = path.lastIndexOf("/");
|
|
17
|
+
return path.substring(
|
|
18
|
+
idx === -1 ? 0 : idx + 1,
|
|
19
|
+
ext ? path.length - ext.length : path.length
|
|
20
|
+
);
|
|
21
|
+
}
|
|
22
|
+
function extname(path) {
|
|
23
|
+
const dotIdx = path.lastIndexOf(".");
|
|
24
|
+
if (dotIdx !== -1) {
|
|
25
|
+
return path.substring(dotIdx);
|
|
26
|
+
}
|
|
27
|
+
return "";
|
|
28
|
+
}
|
|
29
|
+
function dirname(path) {
|
|
30
|
+
return path.split("/").slice(0, -1).join("/");
|
|
31
|
+
}
|
|
32
|
+
function splitPath(path) {
|
|
33
|
+
return path.split("/").filter((p) => p.length > 0);
|
|
34
|
+
}
|
|
35
|
+
function joinPath(...paths) {
|
|
36
|
+
const out = [];
|
|
37
|
+
const parsed = paths.flatMap(splitPath);
|
|
38
|
+
for (const seg of parsed) {
|
|
39
|
+
switch (seg) {
|
|
40
|
+
case "..":
|
|
41
|
+
out.pop();
|
|
42
|
+
break;
|
|
43
|
+
case ".":
|
|
44
|
+
break;
|
|
45
|
+
default:
|
|
46
|
+
out.push(seg);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
return out.join("/");
|
|
50
|
+
}
|
|
51
|
+
function slash(path) {
|
|
52
|
+
const isExtendedLengthPath = path.startsWith("\\\\?\\");
|
|
53
|
+
if (isExtendedLengthPath) {
|
|
54
|
+
return path;
|
|
55
|
+
}
|
|
56
|
+
return path.replaceAll("\\", "/");
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
export {
|
|
60
|
+
basename,
|
|
61
|
+
extname,
|
|
62
|
+
dirname,
|
|
63
|
+
splitPath,
|
|
64
|
+
joinPath,
|
|
65
|
+
slash,
|
|
66
|
+
path_exports
|
|
67
|
+
};
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
// src/negotiation/index.ts
|
|
2
|
+
import Negotiator from "negotiator";
|
|
3
|
+
import { compile, match } from "path-to-regexp";
|
|
4
|
+
function getNegotiator(request) {
|
|
5
|
+
const headers = {};
|
|
6
|
+
request.headers.forEach((value, key) => {
|
|
7
|
+
headers[key] = value;
|
|
8
|
+
});
|
|
9
|
+
return new Negotiator({ headers });
|
|
10
|
+
}
|
|
11
|
+
function rewritePath(source, destination) {
|
|
12
|
+
const matcher = match(source, { decode: false });
|
|
13
|
+
const compiler = compile(destination, { encode: false });
|
|
14
|
+
return {
|
|
15
|
+
rewrite(pathname) {
|
|
16
|
+
const result = matcher(pathname);
|
|
17
|
+
if (!result) return false;
|
|
18
|
+
return compiler(result.params);
|
|
19
|
+
}
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
function isMarkdownPreferred(request, options) {
|
|
23
|
+
const {
|
|
24
|
+
markdownMediaTypes = ["text/plain", "text/markdown", "text/x-markdown"]
|
|
25
|
+
} = options ?? {};
|
|
26
|
+
const mediaTypes = getNegotiator(request).mediaTypes();
|
|
27
|
+
return markdownMediaTypes.some((type) => mediaTypes.includes(type));
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export {
|
|
31
|
+
getNegotiator,
|
|
32
|
+
rewritePath,
|
|
33
|
+
isMarkdownPreferred
|
|
34
|
+
};
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
// src/utils/remove-undefined.ts
|
|
2
|
+
function removeUndefined(value, deep = false) {
|
|
3
|
+
const obj = value;
|
|
4
|
+
for (const key in obj) {
|
|
5
|
+
if (obj[key] === void 0) delete obj[key];
|
|
6
|
+
if (!deep) continue;
|
|
7
|
+
const entry = obj[key];
|
|
8
|
+
if (typeof entry === "object" && entry !== null) {
|
|
9
|
+
removeUndefined(entry, deep);
|
|
10
|
+
continue;
|
|
11
|
+
}
|
|
12
|
+
if (Array.isArray(entry)) {
|
|
13
|
+
for (const item of entry) removeUndefined(item, deep);
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
return value;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export {
|
|
20
|
+
removeUndefined
|
|
21
|
+
};
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
interface GetGithubLastCommitOptions {
|
|
2
|
+
/**
|
|
3
|
+
* Repository name, like "fumadocs"
|
|
4
|
+
*/
|
|
5
|
+
repo: string;
|
|
6
|
+
/** Owner of repository */
|
|
7
|
+
owner: string;
|
|
8
|
+
/**
|
|
9
|
+
* Path to file
|
|
10
|
+
*/
|
|
11
|
+
path: string;
|
|
12
|
+
/**
|
|
13
|
+
* GitHub access token
|
|
14
|
+
*/
|
|
15
|
+
token?: string;
|
|
16
|
+
/**
|
|
17
|
+
* SHA or ref (branch or tag) name.
|
|
18
|
+
*/
|
|
19
|
+
sha?: string;
|
|
20
|
+
/**
|
|
21
|
+
* Custom query parameters
|
|
22
|
+
*/
|
|
23
|
+
params?: Record<string, string>;
|
|
24
|
+
options?: RequestInit;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Get the last edit time of a file using GitHub API
|
|
28
|
+
*
|
|
29
|
+
* By default, this will cache the result forever.
|
|
30
|
+
* Set `options.next.revalidate` to customise this.
|
|
31
|
+
*/
|
|
32
|
+
declare function getGithubLastEdit({ repo, token, owner, path, sha, options, params: customParams, }: GetGithubLastCommitOptions): Promise<Date | null>;
|
|
33
|
+
|
|
34
|
+
export { type GetGithubLastCommitOptions, getGithubLastEdit };
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import "../chunk-U67V476Y.js";
|
|
2
|
+
|
|
3
|
+
// src/content/github.ts
|
|
4
|
+
async function getGithubLastEdit({
|
|
5
|
+
repo,
|
|
6
|
+
token,
|
|
7
|
+
owner,
|
|
8
|
+
path,
|
|
9
|
+
sha,
|
|
10
|
+
options = {},
|
|
11
|
+
params: customParams = {}
|
|
12
|
+
}) {
|
|
13
|
+
const headers = new Headers(options.headers);
|
|
14
|
+
const params = new URLSearchParams();
|
|
15
|
+
params.set("path", path);
|
|
16
|
+
params.set("page", "1");
|
|
17
|
+
params.set("per_page", "1");
|
|
18
|
+
if (sha) params.set("sha", sha);
|
|
19
|
+
for (const [key, value] of Object.entries(customParams)) {
|
|
20
|
+
params.set(key, value);
|
|
21
|
+
}
|
|
22
|
+
if (token) {
|
|
23
|
+
headers.append("authorization", token);
|
|
24
|
+
}
|
|
25
|
+
const res = await fetch(
|
|
26
|
+
`https://api.github.com/repos/${owner}/${repo}/commits?${params.toString()}`,
|
|
27
|
+
{
|
|
28
|
+
cache: "force-cache",
|
|
29
|
+
...options,
|
|
30
|
+
headers
|
|
31
|
+
}
|
|
32
|
+
);
|
|
33
|
+
if (!res.ok)
|
|
34
|
+
throw new Error(
|
|
35
|
+
`Failed to fetch last edit time from Git ${await res.text()}`
|
|
36
|
+
);
|
|
37
|
+
const data = await res.json();
|
|
38
|
+
if (data.length === 0) return null;
|
|
39
|
+
return new Date(data[0].commit.committer.date);
|
|
40
|
+
}
|
|
41
|
+
export {
|
|
42
|
+
getGithubLastEdit
|
|
43
|
+
};
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import * as react from 'react';
|
|
2
|
+
import { ReactNode } from 'react';
|
|
3
|
+
import { Compatible } from 'vfile';
|
|
4
|
+
import { Components } from 'hast-util-to-jsx-runtime';
|
|
5
|
+
import { PluggableList } from 'unified';
|
|
6
|
+
|
|
7
|
+
interface MarkdownProps {
|
|
8
|
+
components?: Components;
|
|
9
|
+
}
|
|
10
|
+
declare function Markdown({ children: content, remarkPlugins, rehypePlugins, ...options }: MarkdownProps & {
|
|
11
|
+
remarkPlugins?: PluggableList;
|
|
12
|
+
rehypePlugins?: PluggableList;
|
|
13
|
+
children: Compatible;
|
|
14
|
+
}): Promise<react.ReactElement<unknown, string | react.JSXElementConstructor<any>> | Iterable<ReactNode> | (string | number | bigint | boolean | react.ReactPortal | react.ReactElement<unknown, string | react.JSXElementConstructor<any>> | Iterable<ReactNode> | null | undefined)>;
|
|
15
|
+
|
|
16
|
+
export { Markdown, type MarkdownProps };
|