-
Notifications
You must be signed in to change notification settings - Fork 979
feat(docs): serve the Prisma Next error reference, with anchors matching emitted docsUrls #8125
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Some comments aren't visible on the classic Files Changed page.
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,52 @@ | ||
| name: Error Reference Check | ||
|
|
||
| # The published error-reference page must list every structured error code the | ||
| # product (prisma/prisma main) can emit — each emitted error links to | ||
| # /docs/orm/next/reference/error-reference#<CODE>. This check fails if any | ||
| # known code is missing from the page, even if the sync workflow breaks. | ||
| # | ||
| # Runs on pushes to main, on PRs that touch the page or its tooling, and on a | ||
| # daily schedule so drift introduced upstream is flagged without blocking | ||
| # unrelated PRs. | ||
|
|
||
| on: | ||
| push: | ||
| branches: [main] | ||
| pull_request: | ||
| paths: | ||
| - apps/docs/content/docs/orm/next/reference/error-reference.mdx | ||
| - apps/docs/scripts/generate-error-reference.mjs | ||
| - .github/workflows/error-reference-check.yml | ||
| - .github/workflows/sync-error-reference-docs.yml | ||
| schedule: | ||
| - cron: "30 6 * * *" | ||
| workflow_dispatch: | ||
|
|
||
| permissions: | ||
| contents: read | ||
|
|
||
| jobs: | ||
| verify: | ||
| name: Verify error-reference completeness | ||
| runs-on: ubuntu-latest | ||
| steps: | ||
| - name: Checkout repository | ||
| uses: actions/checkout@v4 | ||
| with: | ||
| persist-credentials: false | ||
|
|
||
| - name: Checkout prisma/prisma (main) | ||
| uses: actions/checkout@v4 | ||
| with: | ||
| repository: prisma/prisma | ||
| ref: main | ||
| path: prisma-src | ||
| persist-credentials: false | ||
|
|
||
| - name: Setup Node.js | ||
| uses: actions/setup-node@v4 | ||
| with: | ||
| node-version: "20" | ||
|
|
||
| - name: Verify page lists every known error code | ||
| run: node prisma-src/scripts/list-error-codes.mjs --root prisma-src --verify apps/docs/content/docs/orm/next/reference/error-reference.mdx | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,74 @@ | ||
| name: Sync Error Reference Docs | ||
|
|
||
| on: | ||
| repository_dispatch: | ||
| types: [error-reference-updated] | ||
| schedule: | ||
| - cron: "0 6 * * *" | ||
| workflow_dispatch: | ||
|
|
||
| concurrency: | ||
| group: sync-error-reference-docs | ||
| cancel-in-progress: false | ||
|
|
||
| permissions: | ||
| contents: read | ||
|
|
||
| jobs: | ||
| sync: | ||
| name: Sync Error Reference Documentation | ||
| runs-on: ubuntu-latest | ||
| steps: | ||
|
coderabbitai[bot] marked this conversation as resolved.
|
||
| - name: Checkout repository | ||
| uses: actions/checkout@v4 | ||
| with: | ||
| persist-credentials: false | ||
|
|
||
| - name: Checkout prisma/prisma (main) | ||
| uses: actions/checkout@v4 | ||
| with: | ||
| repository: prisma/prisma | ||
| ref: main | ||
| path: prisma-src | ||
|
coderabbitai[bot] marked this conversation as resolved.
|
||
| persist-credentials: false | ||
|
|
||
| - name: Setup Node.js | ||
| uses: actions/setup-node@v4 | ||
| with: | ||
| node-version: "20" | ||
|
|
||
| - name: Generate error reference page | ||
| working-directory: apps/docs | ||
| run: node ./scripts/generate-error-reference.mjs --source ../../prisma-src/docs/reference/error-reference.md | ||
|
|
||
| - name: Verify page lists every known error code | ||
| run: node prisma-src/scripts/list-error-codes.mjs --root prisma-src --verify apps/docs/content/docs/orm/next/reference/error-reference.mdx | ||
|
|
||
| - name: Check for changes | ||
| id: changes | ||
| run: | | ||
| if [[ -z "$(git status --porcelain --untracked-files=all -- apps/docs/content/docs/orm/next/reference/error-reference.mdx)" ]]; then | ||
| echo "changed=false" >> $GITHUB_OUTPUT | ||
| echo "No changes detected" | ||
| else | ||
| echo "changed=true" >> $GITHUB_OUTPUT | ||
| echo "Changes detected:" | ||
| git status --short -- apps/docs/content/docs/orm/next/reference/error-reference.mdx | ||
| fi | ||
|
|
||
| - name: Commit and push | ||
| if: steps.changes.outputs.changed == 'true' | ||
| env: | ||
| BOT_TOKEN: ${{ secrets.BOT_TOKEN_DOCS_COMMIT }} | ||
| TARGET_REPO: ${{ github.repository }} | ||
| TARGET_REF: ${{ github.ref_name }} | ||
| run: | | ||
| git config user.email "prismabots@gmail.com" | ||
| git config user.name "Prismo" | ||
| git add apps/docs/content/docs/orm/next/reference/error-reference.mdx | ||
| git commit -m "chore(docs): sync Prisma Next error reference" | ||
| git push "https://x-access-token:${BOT_TOKEN}@github.com/${TARGET_REPO}.git" "HEAD:${TARGET_REF}" | ||
|
|
||
| - name: Trigger Vercel deploy | ||
| if: steps.changes.outputs.changed == 'true' | ||
| run: curl --fail -X POST "${{ secrets.VERCEL_DEPLOY_HOOK_URL }}" | ||
1,043 changes: 1,043 additions & 0 deletions
1,043
apps/docs/content/docs/orm/next/reference/error-reference.mdx
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,117 @@ | ||
| // Generates content/docs/orm/next/reference/error-reference.mdx from the | ||
| // canonical docs/reference/error-reference.md in prisma/prisma (main branch). | ||
| // | ||
| // Usage: | ||
| // node scripts/generate-error-reference.mjs [--source <path-to-error-reference.md>] | ||
| // | ||
| // Without --source, the file is fetched from raw.githubusercontent.com. | ||
| // | ||
| // Every Prisma Next error carries a docsUrl of the form | ||
| // https://docs.prisma.io/docs/orm/next/reference/error-reference#<CODE> | ||
| // so each `### NAMESPACE.SUBCODE` heading gets an explicit anchor equal to the | ||
| // raw code text (uppercase, with the dot) via Fumadocs' `[#custom-id]` syntax. | ||
|
|
||
| import { readFileSync, writeFileSync } from "node:fs"; | ||
| import { dirname, join } from "node:path"; | ||
| import { fileURLToPath } from "node:url"; | ||
|
|
||
| const SOURCE_URL = | ||
| "https://raw.githubusercontent.com/prisma/prisma/main/docs/reference/error-reference.md"; | ||
| const GITHUB_BLOB_BASE = "https://github.com/prisma/prisma/blob/main/docs/reference/"; | ||
| const OUTPUT = join( | ||
| dirname(fileURLToPath(import.meta.url)), | ||
| "../content/docs/orm/next/reference/error-reference.mdx", | ||
| ); | ||
| const CODE_HEADING = /^### ([A-Z0-9_]+\.[A-Z0-9_.]+)$/; | ||
|
|
||
| async function loadSource() { | ||
| const flagIndex = process.argv.indexOf("--source"); | ||
| if (flagIndex !== -1) { | ||
| const path = process.argv[flagIndex + 1]; | ||
| if (!path) throw new Error("--source requires a path"); | ||
| return readFileSync(path, "utf8"); | ||
| } | ||
| const response = await fetch(SOURCE_URL); | ||
| if (!response.ok) { | ||
| throw new Error(`Failed to fetch ${SOURCE_URL}: ${response.status}`); | ||
| } | ||
| return response.text(); | ||
| } | ||
|
|
||
| function assertMdxSafe(markdown) { | ||
| // The page is plain markdown compiled as MDX. Braces and JSX-like tags | ||
| // outside code spans/fences would change meaning or break the build, so | ||
| // refuse them here where the failure is attributable to the source file. | ||
| const withoutCode = markdown.replace(/```[\s\S]*?```/g, "").replace(/`[^`\n]*`/g, ""); | ||
| const hostile = withoutCode.match(/[{}]|<[A-Za-z/]/); | ||
| if (hostile) { | ||
| throw new Error( | ||
| `Source contains MDX-unsafe text outside code spans (found ${JSON.stringify(hostile[0])}). ` + | ||
| "Escape it in prisma/prisma docs/reference/error-reference.md or teach this generator to handle it.", | ||
| ); | ||
| } | ||
| } | ||
|
|
||
| function transform(markdown) { | ||
| assertMdxSafe(markdown); | ||
|
|
||
| let body = markdown.replace(/^# Error reference\s*\n/, ""); | ||
|
|
||
| // The source intro describes itself from the prisma/prisma repo's point of | ||
| // view ("canonical source", its own CI check). Reworded for readers of the | ||
| // hosted page; if upstream rewrites the sentence the original is kept. | ||
| body = body.replace( | ||
| /It is the canonical source for the hosted reference at[\s\S]*?missing from this page\./, | ||
| "Each code anchors as `#<CODE>` — the exact fragment every emitted error carries in its " + | ||
| "`docsUrl`. This page is generated from the canonical reference in the `prisma/prisma` " + | ||
| "repository, whose CI requires every code in production source to be documented before it ships.", | ||
| ); | ||
|
coderabbitai[bot] marked this conversation as resolved.
|
||
|
|
||
| // Repo-relative links point at files that only exist in prisma/prisma. | ||
| body = body.replace(/\]\((\.\.?\/[^)]+)\)/g, (_, target) => { | ||
| const url = new URL(target, `${GITHUB_BLOB_BASE}error-reference.md`); | ||
| return `](${url.href})`; | ||
| }); | ||
|
|
||
| const codes = []; | ||
| body = body.replace(/^### .+$/gm, (heading) => { | ||
| const match = heading.match(CODE_HEADING); | ||
| if (!match) { | ||
| throw new Error( | ||
| `Unexpected heading shape: ${JSON.stringify(heading)}. ` + | ||
| "Anchors are only generated for `### NAMESPACE.SUBCODE` headings.", | ||
| ); | ||
| } | ||
| codes.push(match[1]); | ||
| return `${heading} [#${match[1]}]`; | ||
| }); | ||
|
|
||
| if (codes.length === 0) { | ||
| throw new Error("No error-code headings found — refusing to write an empty page."); | ||
| } | ||
| const duplicates = codes.filter((code, i) => codes.indexOf(code) !== i); | ||
| if (duplicates.length > 0) { | ||
| throw new Error(`Duplicate error codes in source: ${duplicates.join(", ")}`); | ||
| } | ||
|
|
||
| const frontmatter = `--- | ||
| title: Error reference | ||
| description: Every structured error code Prisma Next can emit, by namespace, with the condition that raises it. | ||
| url: /orm/next/reference/error-reference | ||
| metaTitle: Prisma Next error reference | ||
| metaDescription: Every structured error code Prisma Next can emit, by namespace, with the condition that raises it. | ||
| badge: early-access | ||
| --- | ||
|
|
||
| {/* Generated by scripts/generate-error-reference.mjs from | ||
| https://github.com/prisma/prisma/blob/main/docs/reference/error-reference.md | ||
| Do not edit by hand — changes are overwritten by the sync workflow. */} | ||
|
|
||
| `; | ||
|
|
||
| return { mdx: frontmatter + body, codeCount: codes.length }; | ||
| } | ||
|
|
||
| const { mdx, codeCount } = transform(await loadSource()); | ||
| writeFileSync(OUTPUT, mdx); | ||
| console.log(`Wrote ${OUTPUT} with ${codeCount} error codes.`); | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,15 @@ | ||
| import { expect, test } from "@playwright/test"; | ||
|
|
||
| // Every Prisma Next error carries a docsUrl like | ||
| // https://docs.prisma.io/docs/orm/next/reference/error-reference#CONTRACT.IDENTIFIER_INVALID | ||
| // The fragment is the raw code — uppercase, with the dot — so the heading ids | ||
| // must be the raw code text, not a slugified form. | ||
| test("error-reference anchors use raw error codes", async ({ page }) => { | ||
| await page.goto("/docs/orm/next/reference/error-reference#CONTRACT.IDENTIFIER_INVALID"); | ||
|
|
||
| const heading = page.locator('h3[id="CONTRACT.IDENTIFIER_INVALID"]'); | ||
| await expect(heading).toHaveText("CONTRACT.IDENTIFIER_INVALID"); | ||
| await expect(heading).toBeInViewport(); | ||
|
|
||
| expect(await page.locator('h3[id*="."]').count()).toBeGreaterThan(200); | ||
| }); |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.