Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 2 additions & 3 deletions .github/workflows/pr.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,8 @@ jobs:
typescript:
uses: ./.github/workflows/typescript-typecheck.yml

# todo: add tests
# tests:
# uses: ./.github/workflows/tests.yml
test:
uses: ./.github/workflows/test.yml

website-preview:
uses: ./.github/workflows/website.yml
Expand Down
20 changes: 20 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
on:
workflow_call:

jobs:
unit:
runs-on: ubuntu-24.04
steps:
- name: checkout
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
with:
fetch-depth: 2

- name: setup bun
uses: oven-sh/setup-bun@v2

- name: install dependencies
run: bun install --frozen-lockfile

- name: run tests
run: bun run test
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ coverage
out/
build
dist
*.tsbuildinfo

# Debug
npm-debug.log*
Expand Down
109 changes: 104 additions & 5 deletions bun.lock

Large diffs are not rendered by default.

13 changes: 13 additions & 0 deletions cli.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"$schema": "node_modules/@fumadocs/cli/dist/schema/default.json",
"aliases": {
"uiDir": "./components/ui",
"componentsDir": "./components",
"blockDir": "./components",
"cssDir": "./styles",
"libDir": "./lib"
},
"baseDir": "",
"uiLibrary": "radix-ui",
"commands": {}
}
8 changes: 5 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"name": "@scriptorium/monorepo",
"name": "@graphql-hive/docs",
"private": true,
"engines": {
"node": ">=24"
Expand All @@ -18,10 +18,12 @@
"format": "prettier --write \"**/*.{ts,tsx,md}\"",
"format:check": "prettier --check \"**/*.{ts,tsx,md}\"",
"typecheck": "turbo run typecheck",
"postinstall": "node scripts/fix-nitro-nightly.mjs"
"postinstall": "node scripts/fix-nitro-nightly.mjs",
"test": "turbo run test"
},
"devDependencies": {
"@hasparus/eslint-config": "2.0.12",
"@fumadocs/cli": "^1.2.2",
"@hasparus/eslint-config": "2.0.17",
"@tsconfig/strictest": "2.0.8",
"@types/bun": "latest",
"docs": "workspace:*",
Expand Down
26 changes: 25 additions & 1 deletion packages/design-system/eslint.config.ts
Original file line number Diff line number Diff line change
@@ -1 +1,25 @@
export { default } from "@hasparus/eslint-config/the-guild";
import type { Linter } from "eslint";

import baseConfig from "@hasparus/eslint-config/the-guild";

const config: Linter.Config[] = [
...baseConfig,
{
files: ["src/routes/**/*.tsx"],
rules: {
"unicorn/filename-case": "off",
},
},
{
languageOptions: {
parserOptions: {
project: "./tsconfig.json",
projectService: {
allowDefaultProject: ["*.config.ts"],
},
},
},
},
];

export default config;
7 changes: 4 additions & 3 deletions packages/design-system/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,10 @@
"extends": "../../tsconfig.json",
"compilerOptions": {
"jsx": "react-jsx",
"outDir": "dist",
"noEmit": true
"composite": true,
"noEmit": false,
"outDir": "dist"
},
"include": ["src", "eslint.config.ts"],
"include": ["src"],
"exclude": ["node_modules", "dist"]
}
23 changes: 22 additions & 1 deletion packages/documentation/eslint.config.ts
Original file line number Diff line number Diff line change
@@ -1 +1,22 @@
export { default } from "@hasparus/eslint-config/the-guild";
import type { Linter } from "eslint";

import baseConfig from "@hasparus/eslint-config/the-guild";

const config: Linter.Config[] = [
...baseConfig,
{
files: ["./src/routes/**/*.ts", "./src/routes/**/*.tsx"],
rules: {
"unicorn/filename-case": "off",
},
},
{
languageOptions: {
parserOptions: {
project: "./tsconfig.json",
},
},
},
];

export default config;
7 changes: 5 additions & 2 deletions packages/documentation/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,16 @@
"typecheck": "bun --bun fumadocs-mdx && bun --bun tsc --noEmit",
"postinstall": "bun --bun fumadocs-mdx && bun playwright install chromium",
"lint": "eslint .",
"lint:fix": "eslint . --fix"
"lint:fix": "eslint . --fix",
"test": "bun test"
},
"dependencies": {
"@sparticuz/chromium": "^143.0.4",
"@tanstack/devtools-vite": "^0.4.1",
"@tanstack/react-router": "1.147.1",
"@tanstack/react-router-devtools": "1.147.1",
"@tanstack/react-start": "1.147.1",
"class-variance-authority": "^0.7.1",
"fumadocs-core": "16.4.7",
"fumadocs-mdx": "14.2.5",
"fumadocs-twoslash": "^3.1.12",
Expand All @@ -30,7 +32,8 @@
"rehype-mermaid": "^3.0.0",
"tailwind-merge": "^3.4.0",
"twoslash": "^0.3.6",
"vite": "^7.3.1"
"vite": "^7.3.1",
"zod": "^4.3.5"
},
"devDependencies": {
"@tailwindcss/vite": "^4.1.18",
Expand Down
14 changes: 12 additions & 2 deletions packages/documentation/source.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,15 @@ import rehypeMermaid, { type RehypeMermaidOptions } from "rehype-mermaid";

export const docs = defineDocs({
dir: "content/docs",
docs: {
postprocess: {
includeProcessedMarkdown: true,
},
},
});

export default defineConfig({
mdxOptions: {
// mermaid must run before shiki (rehypeCode) to find raw code blocks
rehypeCodeOptions: {
langs: ["js", "jsx", "ts", "tsx"],
themes: {
Expand All @@ -21,7 +25,13 @@ export default defineConfig({
transformerTwoslash(),
],
},
rehypePlugins: (plugins) => [mermaidConfig(), ...plugins],
rehypePlugins: (plugins) => [
/**
* Mermaid must run before Shiki to find unprocessed code blocks.
*/
mermaidConfig(),
...plugins,
],
},
});

Expand Down
73 changes: 73 additions & 0 deletions packages/documentation/src/components/page-actions.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
"use client";

import { useCopyButton } from "fumadocs-ui/utils/use-copy-button";
import { Check, Copy, Github } from "lucide-react";
import { useState } from "react";

const cache = new Map<string, string>();
const actionClass =
"inline-flex items-center gap-2 text-sm text-fd-muted-foreground transition-colors hover:text-fd-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-fd-ring disabled:pointer-events-none disabled:opacity-50";

export function LLMCopyButton({ markdownUrl }: { markdownUrl: string }) {
const [loading, setLoading] = useState(false);
const [checked, onClick] = useCopyButton(async () => {
const cached = cache.get(markdownUrl);
if (cached) return navigator.clipboard.writeText(cached);

setLoading(true);

try {
await navigator.clipboard.write([
new ClipboardItem({
"text/plain": fetch(markdownUrl).then(async (res) => {
const content = await res.text();

if (!res.ok) {
// If we're rendering this page, we should definitely have Markdown for it.
// eslint-disable-next-line no-console
console.error(`Failed to fetch ${markdownUrl}`, res);
throw new Error(
`${markdownUrl} is unexpectedly missing, try again later`,
);
}

cache.set(markdownUrl, content);
return content;
}),
}),
]);
} finally {
setLoading(false);
}
});

return (
<button className={actionClass} disabled={loading} onClick={onClick}>
{checked ? <Check className="size-3.5" /> : <Copy className="size-3.5" />}
Copy Markdown
</button>
);
}

export function PageActions({
githubUrl,
markdownUrl,
}: {
githubUrl: string;
markdownUrl: string;
}) {
return (
<div className="flex flex-col items-start gap-2">
<LLMCopyButton markdownUrl={markdownUrl} />
<a
className={actionClass}
href={githubUrl}
rel="noreferrer noopener"
target="_blank"
>
<Github className="size-3.5" />
View on GitHub
</a>
</div>
);
}
28 changes: 28 additions & 0 deletions packages/documentation/src/components/ui/button.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import { cva, type VariantProps } from "class-variance-authority";

const variants = {
ghost: "hover:bg-fd-accent hover:text-fd-accent-foreground",
outline: "border hover:bg-fd-accent hover:text-fd-accent-foreground",
primary: "bg-fd-primary text-fd-primary-foreground hover:bg-fd-primary/80",
secondary:
"border bg-fd-secondary text-fd-secondary-foreground hover:bg-fd-accent hover:text-fd-accent-foreground",
} as const;

export const buttonVariants = cva(
"inline-flex items-center justify-center rounded-md p-2 text-sm font-medium transition-colors duration-100 disabled:pointer-events-none disabled:opacity-50 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-fd-ring",
{
variants: {
variant: variants,
// fumadocs use `color` instead of `variant`
color: variants,
size: {
icon: "p-1.5 [&_svg]:size-5",
"icon-sm": "p-1.5 [&_svg]:size-4.5",
"icon-xs": "p-1 [&_svg]:size-4",
sm: "gap-1 px-2 py-1.5 text-xs",
},
},
},
);

export type ButtonProps = VariantProps<typeof buttonVariants>;
1 change: 1 addition & 0 deletions packages/documentation/src/lib/cn.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { twMerge as cn } from "tailwind-merge";
11 changes: 11 additions & 0 deletions packages/documentation/src/lib/get-llm-text.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import type { InferPageType } from "fumadocs-core/source";

import { source } from "@/lib/source";

export async function getLLMText(page: InferPageType<typeof source>) {
const processed = await page.data.getText("processed");

return `# ${page.data.title} (${page.url})

${processed}`;
}
19 changes: 17 additions & 2 deletions packages/documentation/src/lib/source.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,24 @@
import { loader } from "fumadocs-core/source";
import type {
DocCollectionEntry,
MetaCollectionEntry,
} from "fumadocs-mdx/runtime/server";

import {
loader,
type MetaData,
type PageData,
type Source,
} from "fumadocs-core/source";
import { lucideIconsPlugin } from "fumadocs-core/source/lucide-icons";
import { docs } from "fumadocs-mdx:collections/server";

const docsSource = docs.toFumadocsSource() as Source<{
metaData: MetaCollectionEntry<MetaData>;
pageData: DocCollectionEntry<"docs", PageData>;
}>;

export const source = loader({
baseUrl: "/docs",
plugins: [lucideIconsPlugin()],
source: docs.toFumadocsSource(),
source: docsSource,
});
Loading