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.
Files changed (92) hide show
  1. package/README.md +1 -1
  2. package/dist/algolia-IZEDLPHE.js +58 -0
  3. package/dist/breadcrumb.d.ts +7 -5
  4. package/dist/breadcrumb.js +46 -52
  5. package/dist/builder-feW_xVjc.d.ts +296 -0
  6. package/dist/{chunk-FVY6EZ3N.js → chunk-BBP7MIO4.js} +12 -14
  7. package/dist/{chunk-ORHEEQVY.js → chunk-EMWGTXSW.js} +0 -7
  8. package/dist/chunk-FAEPKD7U.js +20 -0
  9. package/dist/{chunk-NNKVN7WA.js → chunk-H2GMUTQG.js} +4 -2
  10. package/dist/chunk-IZPLHEX4.js +113 -0
  11. package/dist/chunk-OTD7MV33.js +53 -0
  12. package/dist/chunk-PFNP6PEB.js +11 -0
  13. package/dist/{chunk-Y2774T3B.js → chunk-QMATWJ5F.js} +6 -7
  14. package/dist/chunk-U67V476Y.js +35 -0
  15. package/dist/{chunk-BUCUQ3WX.js → chunk-XN2LKXFZ.js} +39 -34
  16. package/dist/{chunk-WFUH5VBX.js → chunk-XOFXGHS4.js} +26 -10
  17. package/dist/chunk-XZSI7AHE.js +67 -0
  18. package/dist/chunk-YVVDKJ2H.js +34 -0
  19. package/dist/chunk-ZMWYLUDP.js +21 -0
  20. package/dist/content/github.d.ts +34 -0
  21. package/dist/content/github.js +43 -0
  22. package/dist/content/index.d.ts +16 -0
  23. package/dist/content/index.js +30 -0
  24. package/dist/{get-toc-Cr2URuiP.d.ts → content/toc.d.ts} +6 -10
  25. package/dist/content/toc.js +21 -0
  26. package/dist/{page-tree-BG3wP0gU.d.ts → definitions-BRsJlZ6m.d.ts} +10 -15
  27. package/dist/dynamic-link.js +3 -3
  28. package/dist/fetch-2XFMBLBA.js +22 -0
  29. package/dist/framework/index.d.ts +1 -1
  30. package/dist/framework/index.js +2 -2
  31. package/dist/framework/next.js +2 -2
  32. package/dist/framework/react-router.js +2 -2
  33. package/dist/framework/tanstack.js +2 -2
  34. package/dist/framework/waku.d.ts +8 -0
  35. package/dist/framework/waku.js +51 -0
  36. package/dist/hide-if-empty.d.ts +18 -0
  37. package/dist/hide-if-empty.js +83 -0
  38. package/dist/highlight/client.d.ts +8 -5
  39. package/dist/highlight/client.js +9 -93
  40. package/dist/highlight/index.d.ts +20 -5
  41. package/dist/highlight/index.js +10 -6
  42. package/dist/i18n/index.d.ts +35 -8
  43. package/dist/i18n/index.js +5 -69
  44. package/dist/i18n/middleware.d.ts +12 -0
  45. package/dist/i18n/middleware.js +63 -0
  46. package/dist/link.js +3 -3
  47. package/dist/mdx-plugins/index.d.ts +124 -18
  48. package/dist/mdx-plugins/index.js +605 -203
  49. package/dist/mixedbread-RAHDVXGJ.js +118 -0
  50. package/dist/negotiation/index.d.ts +19 -0
  51. package/dist/negotiation/index.js +11 -0
  52. package/dist/{orama-cloud-USLSOSXS.js → orama-cloud-WEGQE5A6.js} +37 -27
  53. package/dist/page-tree/index.d.ts +32 -0
  54. package/dist/page-tree/index.js +15 -0
  55. package/dist/remark-code-tab-DmyIyi6m.d.ts +57 -0
  56. package/dist/{remark-structure-FIjTA11P.d.ts → remark-structure-DkCXCzpD.d.ts} +13 -2
  57. package/dist/search/algolia.d.ts +9 -7
  58. package/dist/search/algolia.js +31 -17
  59. package/dist/search/client.d.ts +88 -17
  60. package/dist/search/client.js +71 -50
  61. package/dist/search/index.d.ts +26 -0
  62. package/dist/search/index.js +7 -0
  63. package/dist/search/orama-cloud.d.ts +7 -5
  64. package/dist/search/orama-cloud.js +18 -10
  65. package/dist/search/server.d.ts +33 -25
  66. package/dist/search/server.js +109 -47
  67. package/dist/source/index.d.ts +33 -254
  68. package/dist/source/index.js +532 -353
  69. package/dist/source/plugins/lucide-icons.d.ts +14 -0
  70. package/dist/source/plugins/lucide-icons.js +23 -0
  71. package/dist/static-A2YJ5TXV.js +62 -0
  72. package/dist/toc.d.ts +11 -7
  73. package/dist/toc.js +6 -5
  74. package/dist/utils/use-effect-event.d.ts +4 -3
  75. package/dist/utils/use-effect-event.js +9 -6
  76. package/dist/utils/use-media-query.d.ts +3 -0
  77. package/dist/utils/use-media-query.js +23 -0
  78. package/dist/utils/use-on-change.js +2 -2
  79. package/package.json +92 -40
  80. package/dist/algolia-NTWLS6J3.js +0 -49
  81. package/dist/chunk-KAOEMCTI.js +0 -17
  82. package/dist/chunk-MLKGABMK.js +0 -9
  83. package/dist/chunk-XMCPKVJQ.js +0 -34
  84. package/dist/config-inq6kP6y.d.ts +0 -26
  85. package/dist/fetch-W5EHIBOE.js +0 -21
  86. package/dist/remark-heading-BPCoYwjn.d.ts +0 -31
  87. package/dist/server/index.d.ts +0 -117
  88. package/dist/server/index.js +0 -202
  89. package/dist/sidebar.d.ts +0 -33
  90. package/dist/sidebar.js +0 -89
  91. package/dist/static-VESU2S64.js +0 -61
  92. 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
- let id = heading.data.hProperties.id;
27
+ const props = heading.data.hProperties;
28
28
  const lastNode = heading.children.at(-1);
29
- if (!id && lastNode?.type === "text" && customId) {
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 { toJsxRuntime } from "hast-util-to-jsx-runtime";
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 _highlight(code, options) {
24
- const { lang, components: _, engine, ...rest } = options;
25
- let themes = { themes: defaultThemes };
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
- } else if ("themes" in options && options.themes) {
29
- themes = { themes: options.themes };
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("custom", {
32
- engine,
33
- langs: [lang],
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 _renderHighlight(hast, options) {
49
+ function hastToJsx(hast, options) {
45
50
  return toJsxRuntime(hast, {
46
51
  jsx,
47
52
  jsxs,
48
53
  development: false,
49
- components: options?.components,
50
- Fragment
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 = options.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 _renderHighlight(await _highlight(code, options), options);
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
- _highlight,
93
- _renderHighlight,
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-KAOEMCTI.js";
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, extraParams = {}) {
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
- ...extraParams.where
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
- ...extraParams.groupBy
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", "keywords"],
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 = await getByID(db, pageId);
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 };