const fs = require("node:fs/promises"); const path = require("node:path"); const fetch = (...args) => import('node-fetch').then(({default: fetch}) => fetch(...args)); const { html: beautifyHtml } = require('js-beautify'); const data = { outputDirectory: "./out", navigationLinks: [ {link: "index.html", text: "home", name: "home"}, {link: "projects.html", text: "projects", name: "projects"}, {link: "https://git.hippoz.xyz", text: "git", name: "__ext_git"}, ], postProcessing: { beautifyOutput: true, beautifyOutputOptions: { indent_size: 2, preserve_newlines: false }, minifyOutputOptions: { indent_size: 0, preserve_newlines: false, end_with_newline: false, eol: "" } }, repositoryList: { gitTargetUsername: "hippoz", repositoryFetchUrl: `https://git.hippoz.xyz/api/v1/users/hippoz/repos?page=1&limit=100`, _cache: null, fetchProjects: async function() { if (this._cache) return this._cache; const response = await fetch(this.repositoryFetchUrl); const json = await response.json(); this._cache = json; return json; } }, navigationBrandingText: "hippoz." }; const linkButton = ({ link, text, selected=false }) => ` ${text} `; const navigation = ({currentName}) => `
${data.navigationBrandingText}
${data.navigationLinks.map(e => linkButton({ ...e, selected: currentName === e.name })).join("")}
`; const makePage = ({ name, description, title }) => content => [` ${title} ${navigation({currentName: name})}
${content}
`, content]; const indexPage = () => makePage({ title: "hippoz", description: "hippoz website homepage", name: "home", })(`

hippoz's website

i think

`); const projectsPage = async () => makePage({ title: "hippoz", description: "hippoz projects", name: "projects", })(` ${ (await data.repositoryList.fetchProjects()) .sort((a, b) => b.size - a.size) // biggest projects first .filter(a => !a.archived) .map( repo =>`
${repo.fork ? "🍴" : "📘"} ${repo.name} view >>
${repo.description ? `

${repo.description}

` : `

Mysterious! This project has no description.

`}
` ) .join("\n") } `); const pages = { "projects.html": projectsPage, "index.html": indexPage }; let renderedPageCache = null; const renderPages = async () => { if (renderedPageCache) return renderedPageCache; renderedPageCache = {}; for (const [pageName, builder] of Object.entries(pages)) { renderedPageCache[pageName] = await builder(); } return renderedPageCache; }; const deployNavScript = async () => { let script = await fs.readFile("./src/assets/fastnav.js"); if (script) script = script.toString(); const renderedPages = await renderPages(); let navMap = {}; for (let [pageName, content] of Object.entries(renderedPages)) { if (data.postProcessing.beautifyOutput) { content = beautifyHtml(content[1], data.postProcessing.minifyOutputOptions); } navMap[pageName] = content; } const content = script.replace(`"{{NAV_DATA}}"`, JSON.stringify(navMap)); await fs.writeFile("./out/res/fastnav.js", content); }; const deployPages = async () => { const renderedPages = await renderPages(); for (let [pageName, content] of Object.entries(renderedPages)) { if (data.postProcessing.beautifyOutput) { content = beautifyHtml(content[0], data.postProcessing.beautifyOutputOptions); } await fs.writeFile(path.join(data.outputDirectory, pageName), content); } }; const deployAll = async () => { await deployNavScript(); await deployPages(); }; deployAll();