const { themes } = require("prism-react-renderer"); const lightCodeTheme = themes.github; const darkCodeTheme = themes.dracula; const semver = require("semver"); import fs from "fs/promises"; const path = require("path"); const { loadPages } = require("./src/lib/ecosystem/loadPages"); const baseUrl = "/"; // With JSDoc @type annotations, IDEs can provide config autocompletion /** @type {import("@docusaurus/types").DocusaurusConfig} */ ( module.exports = { title: "Open Policy Agent", tagline: "Policy-based control for cloud native environments", url: "https://openpolicyagent.org", baseUrl: baseUrl, // Build-time options onBrokenLinks: "throw", onBrokenMarkdownLinks: "throw", trailingSlash: false, presets: [ [ "@docusaurus/preset-classic", /** @type {import("@docusaurus/preset-classic").Options} */ { docs: { path: "docs", routeBasePath: "/docs/", breadcrumbs: false, sidebarPath: require.resolve("./src/lib/sidebars.js"), }, blog: false, theme: { customCss: require.resolve("./src/css/custom.css"), }, gtag: { trackingID: "G-JNBNV64PDX", anonymizeIP: true, }, }, ], ], customFields: { buildVersion: process.env.BUILD_VERSION, }, markdown: { mermaid: true, }, themes: ["@docusaurus/theme-mermaid"], themeConfig: { colorMode: { defaultMode: "light", disableSwitch: false, respectPrefersColorScheme: true, }, metadata: [ { name: "msapplication-TileColor", content: "#2b5797" }, { name: "theme-color", content: "#ffffff" }, ], headTags: [ { tagName: "link", attributes: { rel: "icon", type: "image/png", href: "/favicon-96x96.png", sizes: "96x96", }, }, { tagName: "link", attributes: { rel: "icon", type: "image/svg+xml", href: "/favicon.svg", }, }, { tagName: "link", attributes: { rel: "shortcut icon", href: "/favicon.ico", }, }, { tagName: "link", attributes: { rel: "apple-touch-icon", sizes: "180x180", href: "/apple-touch-icon.png", }, }, { tagName: "meta", attributes: { name: "apple-mobile-web-app-title", content: "OPA", }, }, { tagName: "link", attributes: { rel: "manifest", href: "/site.webmanifest", }, }, ], navbar: { title: "Open Policy Agent", logo: { alt: "OPA Logo", src: "img/nav/logo.png", }, items: [ { // Based on implementation outlined here: // https://github.com/facebook/docusaurus/issues/7227#issue-1212117180 type: "custom-currentVersionNavbarItem", position: "left", }, { to: "/docs/", label: "Docs", position: "right" }, { type: "dropdown", label: "Resources", position: "right", items: [ { to: "/security", label: "Security" }, { to: "/support", label: "Support" }, { to: "/community", label: "Community" }, { href: "https://blog.openpolicyagent.org/", label: "Blog" }, ], }, { to: "/ecosystem/", label: "Ecosystem", position: "right" }, { href: "https://play.openpolicyagent.org/", label: "Play", position: "right" }, { type: "html", position: "right", value: ` GitHub GitHub `, }, { type: "html", position: "right", value: ` Slack Slack `, }, ], }, footer: { style: "light", links: [], copyright: `Open Policy Agent is a Cloud Native Computing Foundation Graduated project. CNCF Logo CNCF Logo
© ${new Date().getFullYear()} Open Policy Agent contributors. Licensed under the Apache License, Version 2.0. See the contributing documentation for information about contributing. The Linux Foundation has registered trademarks and uses trademarks. For a list of trademarks of The Linux Foundation, please see our Trademark Usage page.`, }, prism: { theme: lightCodeTheme, darkTheme: darkCodeTheme, additionalLanguages: [ "rego", "hcl", "json", "java", "scala", "gradle", "javadoc", "sql", "http", "diff", "typescript", "ini", "cypher", "csharp", "shell-session", "go-module", "docker", "javastacktrace", "properties", "log", ], magicComments: [ { className: "code-block-terminal-command", line: "terminal-command", }, { className: "code-block-terminal-command", line: "cmd", }, { className: "code-block-diff-add-line", line: "diff-add", block: { start: "diff-add-start", end: "diff-add-end" }, }, { className: "code-block-diff-remove-line", line: "diff-remove", block: { start: "diff-remove-start", end: "diff-remove-end" }, }, { className: "theme-code-block-highlighted-line", line: "highlight-next-line", block: { start: "highlight-start", end: "highlight-end" }, }, { className: "code-block-error-line", line: "error-next-line", block: { start: "error-start", end: "error-end" }, }, ], }, mermaid: { theme: { light: "base", dark: "dark" }, options: { themeVariables: { // https://mermaid.js.org/config/theming.html#theme-variables fontFamily: "sans-serif", primaryColor: "#76d3ed", secondaryColor: "#fff", tertiaryColor: "#fff", }, }, }, }, plugins: [ [ require.resolve("@easyops-cn/docusaurus-search-local"), { indexPages: true, }, ], () => ({ name: "raw-loader", configureWebpack() { return { module: { rules: [ { test: /\.rego$/, use: "raw-loader" }, { test: /\.mermaid$/, use: "raw-loader" }, { test: /\.txt$/, use: "raw-loader" }, ], }, }; }, }), async function ecosystemLanguagePageGen(context, options) { return { name: "ecosystem-language-gen", async loadContent() { const languages = await loadPages(path.join(context.siteDir, "src/data/ecosystem/languages/*.md")); return { languages }; }, async contentLoaded({ content, actions }) { const { pagesByLanguage, languages } = content; await Promise.all( Object.keys(languages).map(async (language) => { const routePath = path.join(baseUrl, `/ecosystem/by-language/${language}`); return actions.addRoute({ path: routePath, component: require.resolve("./src/EcosystemLanguage.js"), exact: true, modules: {}, customData: { language }, }); }), ); }, }; }, async function ecosystemFeaturePageGen(context, options) { return { name: "ecosystem-feature-gen", async loadContent() { const features = await loadPages(path.join(context.siteDir, "src/data/ecosystem/features/*.md")); return { features }; }, async contentLoaded({ content, actions }) { const { features } = content; await Promise.all( Object.keys(features).map(async (feature) => { const routePath = path.join(baseUrl, `/ecosystem/by-feature/${feature}`); return actions.addRoute({ path: routePath, component: require.resolve("./src/EcosystemFeature.js"), exact: true, modules: {}, customData: { feature }, }); }), ); }, }; }, async function ecosystemData(context, options) { return { name: "ecosystem-data", async loadContent() { const entries = await loadPages(path.join(context.siteDir, "src/data/ecosystem/entries/*.md")); const languages = await loadPages(path.join(context.siteDir, "src/data/ecosystem/languages/*.md")); const features = await loadPages(path.join(context.siteDir, "src/data/ecosystem/features/*.md")); const featureCategories = await loadPages( path.join(context.siteDir, "src/data/ecosystem/feature-categories/*.md"), ); return { entries, languages, features, featureCategories, }; }, async contentLoaded({ content, actions }) { const { createData } = actions; const { entries, languages, features, featureCategories } = content; await createData("entries.json", JSON.stringify(entries, null, 2)); await createData("languages.json", JSON.stringify(languages, null, 2)); await createData("features.json", JSON.stringify(features, null, 2)); await createData("feature-categories.json", JSON.stringify(featureCategories, null, 2)); }, }; }, async function builtinData(context, options) { return { name: "builtin-data", async loadContent() { const filePath = "../builtin_metadata.json"; const fileContent = await fs.readFile(filePath, "utf-8"); const builtins = JSON.parse(fileContent); return { builtins }; }, async contentLoaded({ content, actions }) { const { createData } = actions; const { builtins } = content; await createData("builtins.json", JSON.stringify(builtins, null, 2)); }, }; }, async function ecosystemPagesGen(context, options) { return { name: "ecosystem-entries-pages-gen", async loadContent() { const entries = await loadPages(path.join(context.siteDir, "src/data/ecosystem/entries/*.md")); return { entries }; }, async contentLoaded({ content, actions }) { const { entries } = content; await Promise.all( Object.values(entries).map(async (entry) => { const routePath = path.join(baseUrl, `/ecosystem/entry/${entry.id}`); return actions.addRoute({ path: routePath, component: require.resolve("./src/EcosystemEntry.js"), exact: true, modules: {}, customData: { id: entry.id }, }); }), ); }, }; }, async function versionsData(context, options) { return { name: "versions-data", async loadContent() { const capabilitiesDir = path.resolve(__dirname, "../capabilities"); let sortedVersions = []; const dirents = await fs.readdir(capabilitiesDir, { withFileTypes: true }); const versionStrings = dirents .filter(dirent => dirent.isFile() && dirent.name.endsWith(".json")) .map(dirent => dirent.name.replace(".json", "")); const validVersions = versionStrings.filter(v => semver.valid(v)); sortedVersions = semver.sort(validVersions); return { versions: sortedVersions }; }, async contentLoaded({ content, actions }) { const { createData } = actions; const { versions } = content; await createData("versions.json", JSON.stringify(versions, null, 2)); }, }; }, async function cliData(context, options) { return { name: "cli-data", async loadContent() { const filePath = path.join(context.siteDir, "src/data/cli.json"); const cliJson = await fs.readFile(filePath, "utf-8"); const parsedData = JSON.parse(cliJson); return parsedData; }, async contentLoaded({ content, actions }) { const { createData } = actions; await createData("cli.json", JSON.stringify(content, null, 2)); }, }; }, async function versionsPageGen(context, options) { return { name: "version-page-gen", async contentLoaded({ content, actions }) { return actions.addRoute({ path: path.join(baseUrl, `/docs/archive`), component: require.resolve("./src/Archive.js"), exact: true, modules: {}, }); }, }; }, ], clientModules: [ require.resolve("./src/lib/playground.js"), ], stylesheets: [ { href: "https://unpkg.com/@antonz/codapi@0.19.8/dist/snippet.css", }, ], scripts: [ { src: "https://unpkg.com/@antonz/codapi@0.19.8/dist/snippet.js", defer: true, }, ], } );