From cfc9e6e750ca78b0d7a1948a86e9b5bb4efde874 Mon Sep 17 00:00:00 2001 From: Schahin Rouhanizadeh Date: Sat, 7 Sep 2024 14:09:24 +0200 Subject: [PATCH] Update `docs` generation Add tailwind css mdx generation and update README.md --- README.md | 43 ++-- docs/astro.config.ts | 6 +- docs/biome.json | 7 +- docs/bun.lockb | Bin 309780 -> 323028 bytes docs/deno.lock | 14 +- docs/package.json | 20 +- docs/src/styles/custom.css | 49 +++++ docs/src/styles/tailwind.css | 24 ++- docs/src/utils/md_to_mdx.ts | 358 ++++++++++++++++++++++++++++---- docs/src/utils/md_to_mdx_aot.ts | 148 ++++++++----- docs/starlight.conf.ts | 16 +- docs/tsconfig.json | 3 +- 12 files changed, 548 insertions(+), 140 deletions(-) diff --git a/README.md b/README.md index 6b1e52e94..6b6877faa 100644 --- a/README.md +++ b/README.md @@ -1,20 +1,31 @@ -# -

+

+ +
+ enter the shipstorm +
+ +
+ + +
+ + [![Homepage](https://img.shields.io/badge/Homepage-8A2BE2)](https://nativelink.com) + [![GitHub stars](https://img.shields.io/github/stars/tracemachina/nativelink?style=social)](https://github.com/TraceMachina/nativelink) + [![OpenSSF Scorecard](https://api.securityscorecards.dev/projects/github.com/TraceMachina/nativelink/badge)](https://securityscorecards.dev/viewer/?uri=github.com/TraceMachina/nativelink) + [![OpenSSF Best Practices](https://www.bestpractices.dev/projects/8050/badge)](https://www.bestpractices.dev/projects/8050) + [![Slack](https://img.shields.io/badge/slack--channel-blue?logo=slack)](https://nativelink.slack.com/join/shared_invite/zt-281qk1ho0-krT7HfTUIYfQMdwflRuq7A#/shared-invite/email) + [![License](https://img.shields.io/badge/License-Apache_2.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) +
## What's NativeLink? @@ -22,9 +33,11 @@ NativeLink is an efficient, high-performance build cache and remote execution sy NativeLink is trusted in production environments to reduce costs and developer iteration times--handling over **one billion requests** per month for its customers, including large corporations such as **Samsung**. - - NativeLink Explained in 90 seconds - +

+ + NativeLink Explained in 90 seconds + +

## 🔑 Key Features diff --git a/docs/astro.config.ts b/docs/astro.config.ts index 9421b984f..c642809b9 100644 --- a/docs/astro.config.ts +++ b/docs/astro.config.ts @@ -4,14 +4,14 @@ import mdx from "@astrojs/mdx"; import sitemap from "@astrojs/sitemap"; import starlight from "@astrojs/starlight"; import deno from "@deno/astro-adapter"; +import tailwindcss from "@tailwindcss/vite"; // import partytown from "@astrojs/partytown"; import { rehypeHeadingIds } from "@astrojs/markdown-remark"; import { rehypeMermaid } from "@beoe/rehype-mermaid"; // "rehype-mermaid"; -import tailwindcss from "@tailwindcss/vite"; import rehypeAutolinkHeadings from "rehype-autolink-headings"; -import { starlightConfig } from "./starlight.conf.ts"; -// import { default as playformCompress } from "@playform/compress"; + +import { starlightConfig } from "./starlight.conf"; // https://astro.build/config export default defineConfig({ diff --git a/docs/biome.json b/docs/biome.json index eb2cdb535..91bc63dc9 100644 --- a/docs/biome.json +++ b/docs/biome.json @@ -14,8 +14,11 @@ "rules": { "all": true, "style": { - "useNamingConvention": "off", - "noDefaultExport": "off" + "useBlockStatements": "error", + "useShorthandArrayType": "error", + "noShoutyConstants": "warn", + "noDefaultExport": "off", + "useNamingConvention": "off" } } }, diff --git a/docs/bun.lockb b/docs/bun.lockb index b37cfb40f38524acf1169f543f0240f269beeee0..7b76508d19c4956e12abc1ae8b1c4fb1d0d2f72b 100755 GIT binary patch delta 59238 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 yze(JsvR26^*?jqM#s1F<1vIv7+Kpw>9?OWA9xN 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 JdfZ`4{s;LgKoI}{ diff --git a/docs/deno.lock b/docs/deno.lock index 885f5082d..028687487 100644 --- a/docs/deno.lock +++ b/docs/deno.lock @@ -58,25 +58,25 @@ "workspace": { "packageJson": { "dependencies": [ - "npm:@astrojs/check@^0.7.0", + "npm:@astrojs/check@0.9.3", "npm:@astrojs/deno@5.0.1", - "npm:@astrojs/markdown-remark@^5.1.0", - "npm:@astrojs/partytown@^2.1.1", + "npm:@astrojs/markdown-remark@5.2.0", + "npm:@astrojs/partytown@2.1.2", "npm:@astrojs/sitemap@^3.1.6", - "npm:@astrojs/starlight@^0.25.5", + "npm:@astrojs/starlight@0.27.0", "npm:@bazel/bazelisk@^1.19.0", "npm:@beoe/pan-zoom@^0.0.3", "npm:@beoe/rehype-mermaid@^0.0.1", "npm:@biomejs/biome@^1.8.1", "npm:@deno/astro-adapter@^0.1.3", "npm:@lorenzo_lewis/starlight-utils@^0.1.1", - "npm:@tailwindcss/vite@^4.0.0-alpha.19", + "npm:@tailwindcss/vite@^4.0.0-alpha.23", "npm:@types/bun@latest", - "npm:astro@^4.5.12", + "npm:astro@4.15.4", "npm:rehype-autolink-headings@^7.1.0", "npm:rehype-mermaid@^2.1.0", "npm:remark@^15.0.1", - "npm:tailwindcss@^4.0.0-alpha.19", + "npm:tailwindcss@^4.0.0-alpha.23", "npm:typescript@^5.4.5" ] } diff --git a/docs/package.json b/docs/package.json index 27492dd68..9cac9ff5f 100644 --- a/docs/package.json +++ b/docs/package.json @@ -6,9 +6,9 @@ "sync": "astro sync", "astro": "astro", "biome": "biome", - "docs": "bun run docs.build && bun run docs.generate", - "docs.build": "cd .. && unset TMPDIR TMP; bazelisk build nativelink-config:docs_json && cd docs && bun run src/utils/metaphase_aot.ts", - "docs.generate": "bun run src/utils/md_to_mdx_aot.ts", + "docs": "bun run build.docs && bun run generate.docs", + "build.docs": "cd .. && unset TMPDIR TMP; bazelisk build nativelink-config:docs_json && cd docs && bun run src/utils/metaphase_aot.ts", + "generate.docs": "bun run src/utils/md_to_mdx_aot.ts", "build": "bun fix && astro build", "check": "biome ci . && astro check", "dev": "astro dev", @@ -24,19 +24,19 @@ "setup": "bun install && bun run deno install -Arf jsr:@deno/deployctl@1.12.0" }, "dependencies": { - "@astrojs/check": "^0.7.0", + "@astrojs/check": "0.9.3", "@astrojs/deno": "5.0.1", - "@astrojs/markdown-remark": "^5.1.0", - "@astrojs/partytown": "^2.1.1", + "@astrojs/markdown-remark": "5.2.0", + "@astrojs/partytown": "2.1.2", "@astrojs/sitemap": "^3.1.6", - "@astrojs/starlight": "^0.25.5", + "@astrojs/starlight": "0.27.0", "@beoe/pan-zoom": "^0.0.3", "@beoe/rehype-mermaid": "^0.0.1", "@deno/astro-adapter": "^0.1.3", - "@tailwindcss/vite": "^4.0.0-alpha.19", - "astro": "^4.5.12", + "@tailwindcss/vite": "^4.0.0-alpha.23", + "astro": "4.15.4", "rehype-mermaid": "^2.1.0", - "tailwindcss": "^4.0.0-alpha.19" + "tailwindcss": "^4.0.0-alpha.23" }, "devDependencies": { "@bazel/bazelisk": "^1.19.0", diff --git a/docs/src/styles/custom.css b/docs/src/styles/custom.css index 18debe3f9..458d4ab9c 100644 --- a/docs/src/styles/custom.css +++ b/docs/src/styles/custom.css @@ -18,3 +18,52 @@ html[data-theme="dark"] .beoe-light { html { scroll-behavior: smooth; } + +.buttons { + display: flex; + justify-content: center; + gap: 10px; + margin-top: 20px; +} + +.buttons button { + background-color: #4A90E2; /* A nice blue color */ + color: white; + font-size: 18px; + font-weight: bold; + border: none; + border-radius: 50%; + width: 50px; + height: 50px; + cursor: pointer; + transition: transform 0.2s ease, background-color 0.2s ease; + box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1); + display: flex; + justify-content: center; + align-items: center; +} + +.buttons button:hover { + background-color: #357ABD; /* Darker blue on hover */ + transform: scale(1.1); +} + +.buttons button:active { + background-color: #2C6BA1; /* Even darker blue on active */ + transform: scale(1.05); +} + +.buttons button:focus { + outline: none; + box-shadow: 0 0 0 3px rgba(74, 144, 226, 0.5); +} + +.buttons button:disabled { + background-color: #B0BEC5; /* Grey color for disabled state */ + cursor: not-allowed; + transform: none; +} + +.buttons button:disabled:hover { + transform: none; +} diff --git a/docs/src/styles/tailwind.css b/docs/src/styles/tailwind.css index b398a123f..ec72093a1 100644 --- a/docs/src/styles/tailwind.css +++ b/docs/src/styles/tailwind.css @@ -1,4 +1,26 @@ -/* @import "tailwindcss"; */ +@import "tailwindcss"; + +a { + @apply underline; +} + + /* Header Links and Sidebar classes generated by astro */ +a.astro-3ii7xxms, +a.astro-vtgkq7vy { + @apply no-underline; +} + +#logo { + @apply flex justify-center items-center; +} + +#description { + @apply text-lg font-semibold; +} + +#badges { + @apply flex-wrap gap-0.5 md:px-20; +} /* @theme { --color-primaryColor: rgb(99, 102, 241); diff --git a/docs/src/utils/md_to_mdx.ts b/docs/src/utils/md_to_mdx.ts index 9d3ec52ed..84ba1bace 100644 --- a/docs/src/utils/md_to_mdx.ts +++ b/docs/src/utils/md_to_mdx.ts @@ -2,19 +2,28 @@ import type { Blockquote, Code, Heading, + Image, InlineCode, Paragraph, + PhrasingContent, Root, RootContent, Text, } from "mdast"; + import { remark } from "remark"; import remarkMdx from "remark-mdx"; import remarkParse from "remark-parse"; import remarkStringify from "remark-stringify"; import { visit } from "unist-util-visit"; -const DEFAULT_TITLE = "Default Title"; +export type MarkdownProps = { + title: string; + description: string; + pagefind?: boolean; + assets?: string[]; +}; + const BLOCK_TYPES = ["caution", "note", "tip"]; export function parseMarkdown(markdown: string): Root { @@ -34,7 +43,7 @@ function extractTitleFromTree(tree: Root): { title: string; index: number; } { - let title = DEFAULT_TITLE; + let title = "Default Title"; let titleIndex = -1; for (let i = 0; i < tree.children.length; i++) { @@ -66,12 +75,12 @@ function extractTextFromNode(node: Heading | Paragraph): string { export function generateFrontMatter( title: string, description: string, - pagefind: boolean, + pagefind = true, ): string { return `--- title: "${title}" description: "${description}" -pagefind: ${pagefind} +pagefind: ${pagefind ? "true" : "false"} --- `; } @@ -183,55 +192,109 @@ function removeValeAndGitCliffComments(markdown: string): string { function processLines(lines: string[]): string[] { const processedLines = []; - let inMermaidBlock = false; - let inCodeBlock = false; + const block = { + code: false, + list: false, + }; for (const line of lines) { - if (isMermaidBlockStart(line)) { - inMermaidBlock = true; - processedLines.push(line); - continue; - } - if (isBlockEnd(line, inMermaidBlock)) { - inMermaidBlock = false; - processedLines.push(line); + if (processCodeBlock(line, block.code, processedLines)) { + block.code = !block.code; continue; } - if (isCodeBlock(line, inMermaidBlock)) { - inCodeBlock = !inCodeBlock; - processedLines.push(line); + block.list = processListBlock(line, block.list, processedLines); + if (block.list) { continue; } - if (inMermaidBlock || inCodeBlock || isSpecialLine(line)) { - processedLines.push(line); + if (processSpecialLine(line, processedLines)) { continue; } processedLines.push(escapeHtml(line)); } + // Ensure any unclosed list is closed + closeList(block.list, processedLines); + return processedLines; } -function isMermaidBlockStart(line: string): boolean { - return line.trim().startsWith("```mermaid"); +// Utility to escape HTML entities +function replaceHtml(unsafe: string): string { + return unsafe + .replace(/&/g, "&") + .replace(//g, ">") + .replace(/"/g, """) + .replace(/'/g, "'"); +} + +function processCodeBlock( + line: string, + codeBlock: boolean, + processedLines: string[], + // languages: string[], +): boolean { + if (isCodeBlock(line)) { + processedLines.push(line); + return true; + } + + if (codeBlock) { + processedLines.push(line); + return true; + } + + return false; } -function isBlockEnd(line: string, inMermaidBlock: boolean): boolean { - return inMermaidBlock && line.trim() === "```"; +function isCodeBlock(line: string): boolean { + const trimmedLine = line.trim(); + return trimmedLine.startsWith("```"); } -function isCodeBlock(line: string, inMermaidBlock: boolean): boolean { - return line.trim().startsWith("```") && !inMermaidBlock; +function processListBlock( + line: string, + listBlock: boolean, + processedLines: string[], +): boolean { + let isListBlock = listBlock; + + if (/^\d+\.\s+\*\*(.+)\*\*:/.test(line)) { + isListBlock = closeList(isListBlock, processedLines); + processedLines.push(line); + processedLines.push('

    '); + return true; + } + + if (isListBlock && /^\s*-\s+(.+)/.test(line)) { + processedLines.push(line.replace(/^\s*-\s+(.+)/, "
  • $1
  • ")); + return true; + } + + return closeList(isListBlock, processedLines); } -function isSpecialLine(line: string): boolean { - return ( +function processSpecialLine(line: string, processedLines: string[]): boolean { + if ( line.trim().startsWith(">") || /^\[!(TIP|NOTE|WARNING|IMPORTANT|CAUTION)\]/.test(line) - ); + ) { + processedLines.push(line); + return true; + } + + return false; +} + +function closeList(inList: boolean, processedLines: string[]): boolean { + if (inList) { + processedLines.push("
"); + return false; + } + return inList; } function escapeHtml(line: string): string { @@ -242,27 +305,246 @@ function escapeHtml(line: string): string { } export async function transformMarkdownToMdx( - markdown: string, - description: string, - pagefind = true, + input: string, + docs: MarkdownProps, + // languages: string[], ): Promise { - const preprocessedMarkdown = preProcessMarkdown(markdown); + const preprocessedMarkdown = preProcessMarkdown(input); const tree = parseMarkdown(preprocessedMarkdown); - const { title, content } = extractTitle(tree); - let transformedContent = transformGitHubMarkdown(content); + // Extract title and content + const { content } = extractTitle(tree); + + // Apply transformations in sequence + // Prepend the import statements to the content + let transformedContent = docs.assets + ? [...generateAssetImports(docs.assets), ...content] + : [...content]; + + // Apply transformations for target IDs + const targetIds = ["logo", "description", "badges"]; + for (const targetId of targetIds) { + transformedContent = processTarget(transformedContent, targetId); + } + + // GitHub Markdown specific transformations + transformedContent = transformGitHubMarkdown(transformedContent); + + // Preserve inline code transformedContent = preserveInlineCode(transformedContent); - const modifiedMarkdown = remark() - .use(remarkStringify) - .stringify({ type: "root", children: transformedContent }); + // Reassemble the tree with the transformed content + tree.children = transformedContent; + // Convert the transformed tree back to Markdown + const modifiedMarkdown = remark().use(remarkStringify).stringify(tree); + + // Convert Markdown to MDX const processedMdx = await remark() .use(remarkParse) .use(remarkMdx) .use(remarkStringify) .process(modifiedMarkdown); - const frontMatter = generateFrontMatter(title, description, pagefind); + // Generate front matter + const frontMatter = generateFrontMatter( + docs.title, + docs.description, + docs.pagefind, + ); + + // Return the final MDX content return frontMatter + String(processedMdx); } + +// Function to generate asset import statements +export function generateAssetImports(assets: string[]): RootContent[] { + return assets.map((asset) => { + const assetName = transformToPascalCase(asset); + return { + type: "html", + value: `import ${assetName} from '${asset}';\n`, + }; + }); +} + +// Helper function to convert file paths to PascalCase +function transformToPascalCase(filePath: string): string { + const fileName = filePath.split("/").pop()?.split(".")[0]; + if (!fileName) { + throw new Error("Invalid file path"); + } + + return fileName + .split(/[^a-zA-Z0-9]/) + .map((part) => part.charAt(0).toUpperCase() + part.slice(1).toLowerCase()) + .join(""); +} + +export function processTarget( + tree: RootContent[], + targetId: string, +): RootContent[] { + const alignRegex = /align=["'](center|left|right)["']/i; + + const content = tree.map((node, index, children) => { + if (isMatchingTargetNode(node, targetId)) { + replaceAlignAttributeInNode(node, alignRegex); + if (targetId === "logo") { + transformImgSrc(node); + } + if (targetId === "badges") { + ensureBadgeClasses(node); + processAndWrapNextBlock(children, index); + } + } + return node; + }); + + return content; +} + +function ensureBadgeClasses(node: RootContent): void { + if (isHtmlNode(node)) { + // Replace the class="" attribute directly in node.value + node.value = node.value.replace(/class="([^"]*)"/g, (_, classes) => { + // Ensure the required classes are present + const requiredClasses = [ + "flex", + "justify-center", + "items-center", + "flex-wrap", + "gap-0.5", + ]; + + // Split the existing classes into an array + const existingClasses = classes.trim().split(/\s+/); + + // Add any missing required classes + for (const requiredClass of requiredClasses) { + if (!existingClasses.includes(requiredClass)) { + existingClasses.push(requiredClass); + } + } + + // Return the updated class attribute + return `class="${existingClasses.join(" ")}"`; + }); + } +} + +// Helper function to check if a node matches the target ID +function isMatchingTargetNode(node: RootContent, targetId: string): boolean { + if (node.type === "html" && typeof node.value === "string") { + const idRegex = new RegExp(`id=["']${targetId}["']`, "i"); + return idRegex.test(node.value); + } + return false; +} + +// Function to replace the align attribute with a CSS class +function replaceAlignAttributeInNode( + node: RootContent, + alignRegex: RegExp, +): void { + if (node.type === "html" && typeof node.value === "string") { + const newValue = node.value.replace(alignRegex, (_, p1) => { + const alignment = p1.toLowerCase() as keyof typeof alignToClassMap; + return `class="${alignToClassMap[alignment]}"`; + }); + node.value = newValue; + } +} + +function transformImgSrc(node: RootContent): void { + if (isHtmlNode(node)) { + node.value = node.value + // Remove the entire tag and replace it with the two tags + .replace( + /[\s\S]*?]*>\s*]*>\s*]*src="[^"]*"[^>]*>\s*<\/picture>/g, + ` + NativeLink Logo + NativeLink Logo + `, + ); + } +} + +// Type guard to check if a node is an HTML node with a value property +function isHtmlNode( + node: RootContent, +): node is RootContent & { value: string } { + return node.type === "html" && typeof node.value === "string"; +} + +function wrapLinksInBlocks(blockNode: RootContent): RootContent[] { + if (blockNode.type !== "paragraph") { + return [blockNode]; + } + + const block = blockNode as Paragraph; + let modified = false; + + const newChildren = block.children.map((child) => { + if ( + child.type === "link" && + child.children.some((c) => c.type === "image") + ) { + const image = child.children.find((c) => c.type === "image") as Image; + if (image) { + modified = true; + const altText = replaceHtml(image.alt || ""); + const imageUrl = replaceHtml(image.url || ""); + const linkUrl = replaceHtml(child.url || ""); + + return { + type: "html", + value: `

\n[![${altText}](${imageUrl})](${linkUrl})\n

`, + } as RootContent; + } + } + return child; + }); + + if (modified) { + return [ + { + type: "paragraph", + children: newChildren.filter((node): node is PhrasingContent => !!node), + }, + ]; + } + return [blockNode]; +} + +// Function to process and wrap the next block in the children array +function processAndWrapNextBlock( + children: RootContent[], + index: number, +): Paragraph | null { + const nextNode = children[index + 1]; + + // Ensure the next node exists and is a paragraph + if (nextNode && nextNode.type === "paragraph") { + // console.log(nextNode) + // Wrap links in blocks if applicable + const wrappedParagraphs = wrapLinksInBlocks(nextNode); + + // If the paragraph has been modified, replace it in the children array + if (wrappedParagraphs.length > 0) { + children.splice(index + 1, 1, ...wrappedParagraphs); + return wrappedParagraphs[0] as Paragraph; + } + } + + // If no wrapping was done, return null to signal no changes + return null; +} + +// Alignments to CSS class mapping +type Alignments = "center" | "left" | "right"; +const alignToClassMap: Record = { + center: "flex justify-center items-center", + left: "flex justify-start items-center", + right: "flex justify-end items-center", +}; diff --git a/docs/src/utils/md_to_mdx_aot.ts b/docs/src/utils/md_to_mdx_aot.ts index a59fc69cf..89df7c049 100644 --- a/docs/src/utils/md_to_mdx_aot.ts +++ b/docs/src/utils/md_to_mdx_aot.ts @@ -22,65 +22,103 @@ async function writeMdxFile( } } -async function convertMarkdownToMdx( - filePath: string, - outputFilePath: string, - description: string, - pagefind = true, -): Promise { +async function convertMarkdownToMdx(file: ConvertFileType): Promise { try { - const markdown = await readMarkdownFile(filePath); - const mdxContent = await transformMarkdownToMdx( - markdown, - description, - pagefind, - ); - await writeMdxFile(outputFilePath, mdxContent); + const markdown = await readMarkdownFile(file.input); + const mdxContent = await transformMarkdownToMdx(markdown, file.docs); + await writeMdxFile(file.output, mdxContent); } catch (err) { console.error(`Error during conversion: ${err}`); throw err; } } -// Convert the actual files. -convertMarkdownToMdx( - "../local-remote-execution/README.md", - "src/content/docs/explanations/lre.mdx", - "Local Remote Execution architecture", -); -convertMarkdownToMdx( - "../CONTRIBUTING.md", - "src/content/docs/contribute/guidelines.mdx", - "NativeLink contribution guidelines", -); -convertMarkdownToMdx( - "README.md", - "src/content/docs/contribute/docs.mdx", - "Working on documentation", -); -convertMarkdownToMdx( - "../nativelink-config/README.md", - "src/content/docs/config/configuration-intro.mdx", - "NativeLink configuration guide", -); -convertMarkdownToMdx( - "../deployment-examples/chromium/README.md", - "src/content/docs/deployment-examples/chromium.mdx", - "NativeLink deployment example for Chromium", -); -convertMarkdownToMdx( - "../deployment-examples/kubernetes/README.md", - "src/content/docs/deployment-examples/kubernetes.mdx", - "NativeLink deployment example for Kubernetes", -); -convertMarkdownToMdx( - "../CHANGELOG.md", - "src/content/docs/reference/changelog.mdx", - "NativeLink's Changelog", - false, // Set pagefind to false for changelog -); -convertMarkdownToMdx( - "../README.md", - "src/content/docs/introduction/setup.mdx", - "Get started with NativeLink", -); +export type ConvertFileType = { + input: string; + output: string; + docs: { + title: string; + description: string; + pagefind?: boolean; + assets?: string[]; + }; +}; + +// Directories +const rootDir = "../"; +const docsDir = "src/content/docs"; +const assetsDir = "@assets"; + +const filesToConvert: ConvertFileType[] = [ + { + input: `${rootDir}/local-remote-execution/README.md`, + output: `${docsDir}/explanations/lre.mdx`, + docs: { + title: "Local Remote Execution", + description: "Local Remote Execution architecture", + }, + }, + { + input: `${rootDir}/CONTRIBUTING.md`, + output: `${docsDir}/contribute/guidelines.mdx`, + docs: { + title: "NativeLink contribution guidelines", + description: "Contribution Guidelines", + }, + }, + { + input: "README.md", + output: `${docsDir}/contribute/docs.mdx`, + docs: { + title: "The NativeLink documentation", + description: "Working on documentation", + }, + }, + { + input: `${rootDir}/nativelink-config/README.md`, + output: `${docsDir}/config/configuration-intro.mdx`, + docs: { + title: "NativeLink configuration guide", + description: "NativeLink configuration guide", + }, + }, + { + input: `${rootDir}/deployment-examples/chromium/README.md`, + output: `${docsDir}/deployment-examples/chromium.mdx`, + docs: { + title: "NativeLink deployment example for Chromium", + description: "NativeLink deployment example for Chromium", + }, + }, + { + input: `${rootDir}/deployment-examples/kubernetes/README.md`, + output: `${docsDir}/deployment-examples/kubernetes.mdx`, + docs: { + title: "Local Remote Execution architecture", + description: "Local Remote Execution architecture", + }, + }, + { + input: `${rootDir}/CHANGELOG.md`, + output: `${docsDir}/reference/changelog.mdx`, + docs: { + title: "Changelog", + description: "NativeLink's Changelog", + pagefind: false, // Set pagefind to false for changelog + }, + }, + { + input: `${rootDir}/README.md`, + output: `${docsDir}/introduction/setup.mdx`, + docs: { + title: "Introduction", + description: "Get started with NativeLink", + pagefind: true, + assets: [`${assetsDir}/logo-dark.svg`, `${assetsDir}/logo-light.svg`], + }, + }, +]; + +filesToConvert.map((file) => { + convertMarkdownToMdx(file); +}); diff --git a/docs/starlight.conf.ts b/docs/starlight.conf.ts index dcda3f7a1..0bc84bc04 100644 --- a/docs/starlight.conf.ts +++ b/docs/starlight.conf.ts @@ -34,7 +34,7 @@ export const starlightConfig = { // See https://diataxis.fr/ for details. { label: "Getting Started", - collapsed: false, + collapsed: true, items: [ { label: "Introduction", @@ -55,7 +55,7 @@ export const starlightConfig = { // content without elaborate explanations. Tutorials should have a // clear goal and a straightforward "follow-these-commands" structure. label: "NativeLink Cloud", - collapsed: false, + collapsed: true, items: [ { label: "Bazel", @@ -84,7 +84,7 @@ export const starlightConfig = { // need to be "complete". They should provide practical guidance for // real-world use-cases. label: "Configuring NativeLink", - collapsed: false, + collapsed: true, items: [ { label: "Configuration Introduction", @@ -105,7 +105,7 @@ export const starlightConfig = { // need to be "complete". They should provide practical guidance for // real-world use-cases. label: "On-Prem Examples", - collapsed: false, + collapsed: true, items: [ { label: "On-Prem Overview", @@ -126,7 +126,7 @@ export const starlightConfig = { // internal functionality and design concepts. Explanations should // explain design decisions, constraints, etc. label: "Understanding NativeLink", - collapsed: false, + collapsed: true, items: [ { label: "Architecture", @@ -147,7 +147,7 @@ export const starlightConfig = { // common questions and confusions about esoteric tooling and // concepts. It aims to help new users feel more at ease and label: "FAQ", - collapsed: false, + collapsed: true, items: [ { label: "Is NativeLink Free?", @@ -188,7 +188,7 @@ export const starlightConfig = { // contributors. They should provide practical guidance for // real-world use-cases. label: "For Contributors", - collapsed: false, + collapsed: true, items: [ { label: "Contribution Guidelines", @@ -217,7 +217,7 @@ export const starlightConfig = { // descriptions with the intent to be used as consulting material. // Mostly autogenerated to stay in sync with the codebase. label: "Reference", - collapsed: false, + collapsed: true, items: [ { label: "Glossary", diff --git a/docs/tsconfig.json b/docs/tsconfig.json index 1057e7cab..4da5cd7af 100644 --- a/docs/tsconfig.json +++ b/docs/tsconfig.json @@ -3,7 +3,8 @@ "compilerOptions": { "baseUrl": ".", "paths": { - "@components/*": ["./src/components/*"] + "@components/*": ["./src/components/*"], + "@assets/*": ["./src/assets/*"] } } }