import fs from 'fs/promises' import path from 'path' async function handlePath(dirName, siteMap) { // Get all directories in the 'dirName' const dirs = await fs.readdir(dirName) // For each file in the directory: check if it is a // file or a folder, if a folder recursively run this // function in that folder. for (const dirIndex in dirs) { const file = dirs[dirIndex] const fullPath = path.join(dirName, file) const fileStats = await fs.stat(fullPath) if (fileStats.isDirectory()) siteMap[fullPath.replace(/^[\s\S]+\/pages/, "")] = { path: fullPath.replace(/^[\s\S]+\/pages/, "").replace(/\/.+\//, "/"), address: fullPath.replace(/^[\s\S]+\/pages/, ""), type: "directory", children: await handlePath(fullPath, {}) } else // Check if it already exists siteMap[fullPath.replace(/^[\s\S]+\/pages/, "").replace(/\.[a-z]+$/, "")] ? siteMap[fullPath.replace(/^[\s\S]+\/pages/, "").replace(/\.[a-z]+$/, "")] : siteMap[fullPath.replace(/^[\s\S]+\/pages/, "").replace(/\.[a-z]+$/, "")] = { path: fullPath.replace(/^[\s\S]+\/pages/, "").replace(/\.[a-z]+$/, "").replace(/\/.+\//, "/"), address: fullPath.replace(/^[\s\S]+\/pages/, "").replace(/\.[a-z]+$/, ""), type: "file" } } return siteMap } function renderSiteMap(siteMap, entrypoint) { // Make a template for the sitemap and recursively run // for all directories with children. return `
${(() => { let result = [] for (const dirIndex in siteMap) { const dir = siteMap[dirIndex] if (!dir.address.startsWith(entrypoint)) continue if (dir.type === "directory") { result.push(`${dir.path}`) result.push(renderSiteMap(dir.children, entrypoint)) result.push(``) } else { result.push(`${dir.path}`) } } return result.join("") })()}
` } export async function generateSiteMap(Config) { // Generate a site map and return it and a render-function. const siteMap = await handlePath(`${Config.contentDir}/pages`, {}) return { siteMap, render: entrypoint => renderSiteMap(siteMap, entrypoint) } }