@mdxdb/fumadocs
Version:
Fumadocs content source adapter for mdxdb
138 lines • 3.61 kB
JavaScript
// src/index.ts
function pathToSlugs(path, basePath = "") {
const normalizedBasePath = basePath.replace(/^\/+|\/+$/g, "");
let cleanPath = path.replace(/^\/+/, "");
if (normalizedBasePath && cleanPath.startsWith(normalizedBasePath)) {
cleanPath = cleanPath.slice(normalizedBasePath.length);
}
cleanPath = cleanPath.replace(/^\/+|\/+$/g, "").replace(/\.(mdx?|md)$/i, "");
if (cleanPath.endsWith("/index") || cleanPath === "index") {
cleanPath = cleanPath.replace(/\/?index$/, "");
}
return cleanPath ? cleanPath.split("/") : [];
}
function extractTitle(doc) {
if (doc.data.title && typeof doc.data.title === "string") {
return doc.data.title;
}
const headingMatch = doc.content.match(/^#\s+(.+)$/m);
if (headingMatch?.[1]) {
return headingMatch[1].trim();
}
return "Untitled";
}
function defaultTransform(doc, path) {
return {
title: extractTitle(doc),
description: doc.data.description,
icon: doc.data.icon,
content: doc.content,
doc,
...doc.data
};
}
function createSource(documents, options = {}) {
const {
basePath = "",
transform = defaultTransform,
filter,
slugs: customSlugs,
meta = {}
} = options;
const files = [];
const folderPaths = /* @__PURE__ */ new Set();
for (const [path, doc] of documents) {
if (filter && !filter(doc, path)) {
continue;
}
const slugs = customSlugs ? customSlugs(path) : pathToSlugs(path, basePath);
if (slugs.length > 1) {
for (let i = 1; i < slugs.length; i++) {
folderPaths.add(slugs.slice(0, i).join("/"));
}
}
const pageData = transform(doc, path);
const page = {
path,
type: "page",
data: pageData,
slugs
};
files.push(page);
}
for (const folderPath of folderPaths) {
const metaPath = `${basePath ? "/" + basePath : ""}/${folderPath}/meta.json`;
const metaData = meta[folderPath] || {};
const metaFile = {
path: metaPath,
type: "meta",
data: {
title: metaData.title,
icon: metaData.icon,
root: metaData.root,
pages: metaData.pages,
defaultOpen: metaData.defaultOpen,
description: metaData.description
}
};
files.push(metaFile);
}
return { files };
}
function createDynamicSource(options) {
const { fetchDocuments, cacheTTL = 6e4, ...sourceOptions } = options;
let cachedSource = null;
let cacheTime = 0;
return {
/**
* Get the source, using cache if valid
*/
async getSource() {
const now = Date.now();
if (cachedSource && now - cacheTime < cacheTTL) {
return cachedSource;
}
const documents = await fetchDocuments();
cachedSource = createSource(documents, sourceOptions);
cacheTime = now;
return cachedSource;
},
/**
* Force refresh the cache
*/
async refresh() {
const documents = await fetchDocuments();
cachedSource = createSource(documents, sourceOptions);
cacheTime = Date.now();
return cachedSource;
},
/**
* Clear the cache
*/
clearCache() {
cachedSource = null;
cacheTime = 0;
}
};
}
function queryToSource(documents, options = {}) {
const docTuples = documents.map((doc) => [
doc.id || doc.data.slug || "",
doc
]);
return createSource(docTuples, options);
}
function isPage(file) {
return file.type === "page";
}
function isMeta(file) {
return file.type === "meta";
}
export {
createDynamicSource,
createSource,
isMeta,
isPage,
queryToSource
};
//# sourceMappingURL=index.js.map