From 120136735c7fcf23e2df65b90da01b3f218cbad7 Mon Sep 17 00:00:00 2001 From: dslovinsky Date: Thu, 11 Jun 2026 18:02:56 -0400 Subject: [PATCH 1/4] DX-2231: Add JSON schema for validating docs.yml Replace the Fern schema reference in docs.yml with a local schema (content/docs-yml.schema.json) covering exactly the options the content indexer supports, including Alchemy extensions (skip-slug, noindex, flattened, paginated). Add a validate:docs-yml script (ajv) wired into PR checks, and align docsYaml.ts types with actual usage (collapsed, tab changelog, instances, optional layout). Part of DX-2231 Co-Authored-By: Claude --- .github/workflows/pr-checks.yml | 13 ++ content/docs-yml.schema.json | 227 ++++++++++++++++++++++++++ content/docs.yml | 2 +- package.json | 2 + pnpm-lock.yaml | 32 +++- scripts/validate-docs-yml.ts | 27 +++ src/content-indexer/types/docsYaml.ts | 5 +- 7 files changed, 299 insertions(+), 9 deletions(-) create mode 100644 content/docs-yml.schema.json create mode 100644 scripts/validate-docs-yml.ts diff --git a/.github/workflows/pr-checks.yml b/.github/workflows/pr-checks.yml index ad9896723..4f2dd0426 100644 --- a/.github/workflows/pr-checks.yml +++ b/.github/workflows/pr-checks.yml @@ -30,6 +30,19 @@ jobs: - name: Validate RPC specs run: pnpm run generate:rpc + docs-yml: + name: docs.yml Schema + runs-on: ubuntu-latest + permissions: + contents: read + steps: + - name: Checkout repository + uses: actions/checkout@v4 + - name: Setup pnpm + uses: ./.github/actions/setup-pnpm + - name: Validate docs.yml against schema + run: pnpm run validate:docs-yml + lint: name: Lint Files runs-on: ubuntu-latest diff --git a/content/docs-yml.schema.json b/content/docs-yml.schema.json new file mode 100644 index 000000000..fd986c6d2 --- /dev/null +++ b/content/docs-yml.schema.json @@ -0,0 +1,227 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "Alchemy docs.yml", + "description": "Navigation configuration for the Alchemy docs site. Based on Fern's docs.yml format, restricted to the options supported by the content indexer (src/content-indexer/types/docsYaml.ts) plus Alchemy-specific extensions (skip-slug, noindex, flattened, paginated).", + "type": "object", + "additionalProperties": false, + "required": ["navigation"], + "properties": { + "instances": { + "description": "Deployed instances of the docs site.", + "type": "array", + "items": { + "type": "object", + "additionalProperties": false, + "required": ["url"], + "properties": { + "url": { + "description": "Base URL where the docs are served.", + "type": "string" + } + } + } + }, + "tabs": { + "description": "Top-level tabs shown in the docs header. Keys are tab identifiers referenced by navigation[].tab.", + "type": "object", + "additionalProperties": { + "$ref": "#/definitions/tabConfig" + } + }, + "navigation": { + "description": "Sidebar navigation layout for each tab.", + "type": "array", + "items": { + "type": "object", + "additionalProperties": false, + "required": ["tab"], + "properties": { + "tab": { + "description": "Tab identifier; must match a key under tabs.", + "type": "string" + }, + "layout": { + "description": "Navigation items for this tab. Omit for tabs whose content is generated elsewhere (e.g. the changelog tab).", + "type": "array", + "items": { + "$ref": "#/definitions/navigationItem" + } + } + } + } + } + }, + "definitions": { + "tabConfig": { + "type": "object", + "additionalProperties": false, + "required": ["display-name"], + "properties": { + "display-name": { + "description": "Human-readable tab label shown in the header.", + "type": "string" + }, + "slug": { + "description": "URL segment for the tab. Defaults to the kebab-cased tab key.", + "type": "string" + }, + "skip-slug": { + "description": "Alchemy extension: omit this tab's slug from descendant URL paths.", + "type": "boolean" + }, + "changelog": { + "description": "Path to a changelog directory, relative to the content directory (e.g. ./changelog).", + "type": "string" + } + } + }, + "navigationItem": { + "oneOf": [ + { "$ref": "#/definitions/pageItem" }, + { "$ref": "#/definitions/sectionItem" }, + { "$ref": "#/definitions/linkItem" }, + { "$ref": "#/definitions/apiItem" }, + { "$ref": "#/definitions/changelogItem" } + ] + }, + "mdxPath": { + "type": "string", + "pattern": "\\.mdx$" + }, + "pageItem": { + "description": "A single docs page backed by an MDX file.", + "type": "object", + "additionalProperties": false, + "required": ["page", "path"], + "properties": { + "page": { + "description": "Page title shown in the sidebar.", + "type": "string" + }, + "path": { + "description": "Path to the page's .mdx file, relative to the content directory.", + "$ref": "#/definitions/mdxPath" + }, + "slug": { + "description": "URL segment for the page. Defaults to the kebab-cased page title. May contain slashes to override the full path.", + "type": "string" + }, + "hidden": { + "description": "Hide this page from the sidebar and search indexing.", + "type": "boolean" + }, + "noindex": { + "description": "Alchemy extension: exclude this page from search indexing while keeping it in the sidebar.", + "type": "boolean" + } + } + }, + "sectionItem": { + "description": "A collapsible group of navigation items, optionally with an overview page.", + "type": "object", + "additionalProperties": false, + "required": ["section", "contents"], + "properties": { + "section": { + "description": "Section title shown in the sidebar.", + "type": "string" + }, + "contents": { + "description": "Child navigation items.", + "type": "array", + "items": { + "$ref": "#/definitions/navigationItem" + } + }, + "path": { + "description": "Optional overview page for the section: path to an .mdx file, relative to the content directory.", + "$ref": "#/definitions/mdxPath" + }, + "slug": { + "description": "URL segment for the section. Defaults to the kebab-cased section title.", + "type": "string" + }, + "skip-slug": { + "description": "Alchemy extension: omit this section's slug from descendant URL paths.", + "type": "boolean" + }, + "hidden": { + "description": "Hide this section and its contents from the sidebar and search indexing.", + "type": "boolean" + }, + "collapsed": { + "description": "Render the section initially collapsed in the sidebar.", + "type": "boolean" + } + } + }, + "linkItem": { + "description": "A sidebar entry linking to an internal path or external URL.", + "type": "object", + "additionalProperties": false, + "required": ["link", "href"], + "properties": { + "link": { + "description": "Link text shown in the sidebar.", + "type": "string" + }, + "href": { + "description": "Destination: an internal path (e.g. /docs/...) or an external URL.", + "type": "string" + } + } + }, + "apiItem": { + "description": "An auto-generated API reference section backed by an uploaded API spec.", + "type": "object", + "additionalProperties": false, + "required": ["api", "api-name"], + "properties": { + "api": { + "description": "Title for the API reference section.", + "type": "string" + }, + "api-name": { + "description": "Identifier of the API spec to render (must match an uploaded spec name).", + "type": "string" + }, + "slug": { + "description": "URL segment for the API section. Defaults to the kebab-cased title.", + "type": "string" + }, + "skip-slug": { + "description": "Alchemy extension: omit this section's slug from endpoint URL paths.", + "type": "boolean" + }, + "hidden": { + "description": "Hide the endpoints from the sidebar and search indexing.", + "type": "boolean" + }, + "flattened": { + "description": "Alchemy extension: render endpoints as a flat list instead of grouped by spec hierarchy.", + "type": "boolean" + }, + "paginated": { + "description": "Alchemy extension: paginate large endpoint lists.", + "type": "boolean" + } + } + }, + "changelogItem": { + "description": "A changelog feed generated from a directory of changelog entries.", + "type": "object", + "additionalProperties": false, + "required": ["changelog"], + "properties": { + "changelog": { + "description": "Path to a changelog directory, relative to the content directory.", + "type": "string" + }, + "slug": { + "description": "URL segment for the changelog.", + "type": "string" + } + } + } + } +} diff --git a/content/docs.yml b/content/docs.yml index 6d55de36a..c4e3b53c4 100644 --- a/content/docs.yml +++ b/content/docs.yml @@ -1,4 +1,4 @@ -# yaml-language-server: $schema=https://schema.buildwithfern.dev/docs-yml.json +# yaml-language-server: $schema=./docs-yml.schema.json instances: - url: https://alchemy.com/docs diff --git a/package.json b/package.json index d719e99a0..6e868ddf2 100644 --- a/package.json +++ b/package.json @@ -20,6 +20,7 @@ "clean": "rm -rf content/api-specs", "validate:rest": "./scripts/generate-open-api.sh --validate-only", "validate:rpc": "tsx ./scripts/validate-rpc.ts", + "validate:docs-yml": "tsx ./scripts/validate-docs-yml.ts", "validate": "pnpm run validate:rest & pnpm run validate:rpc", "test:run": "vitest run", "test:coverage": "vitest run --coverage", @@ -64,6 +65,7 @@ "@types/remove-markdown": "^0.3.4", "@typescript-eslint/parser": "^8.31.0", "@vitest/coverage-v8": "^4.0.16", + "ajv": "^8.20.0", "eslint": "^9.25.1", "eslint-config-prettier": "^10.1.2", "eslint-plugin-mdx": "^3.4.1", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index b3151f2de..ecf1280c2 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -47,7 +47,7 @@ importers: version: 1.14.9 '@redocly/cli': specifier: ^1.34.2 - version: 1.34.11(ajv@6.14.0) + version: 1.34.11(ajv@8.20.0) '@trivago/prettier-plugin-sort-imports': specifier: ^5.2.2 version: 5.2.2(prettier@3.4.2) @@ -75,6 +75,9 @@ importers: '@vitest/coverage-v8': specifier: ^4.0.16 version: 4.1.0(vitest@4.1.0(@opentelemetry/api@1.9.0)(@types/node@22.19.15)(vite@7.3.1(@types/node@22.19.15)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.9.0))) + ajv: + specifier: ^8.20.0 + version: 8.20.0 eslint: specifier: ^9.25.1 version: 9.39.4(jiti@2.6.1) @@ -1084,6 +1087,9 @@ packages: ajv@6.14.0: resolution: {integrity: sha512-IWrosm/yrn43eiKqkfkHis7QioDleaXQHdDVPKg0FSwwd/DuvyX79TZnFOnYpB7dcsFAMmtFztZuXPDvSePkFw==} + ajv@8.20.0: + resolution: {integrity: sha512-Thbli+OlOj+iMPYFBVBfJ3OmCAnaSyNn4M1vz9T6Gka5Jt9ba/HIR56joy65tY6kx/FCF5VXNB819Y7/GUrBGA==} + algoliasearch@5.49.2: resolution: {integrity: sha512-1K0wtDaRONwfhL4h8bbJ9qTjmY6rhGgRvvagXkMBsAOMNr+3Q2SffHECh9DIuNVrMA1JwA0zCwhyepgBZVakng==} engines: {node: '>= 14.0.0'} @@ -1558,6 +1564,9 @@ packages: fast-safe-stringify@2.1.1: resolution: {integrity: sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA==} + fast-uri@3.1.2: + resolution: {integrity: sha512-rVjf7ArG3LTk+FS6Yw81V1DLuZl1bRbNrev6Tmd/9RaroeeRRJhAt7jg/6YFxbvAQXUCavSoZhPPj6oOx+5KjQ==} + fast-xml-builder@1.0.0: resolution: {integrity: sha512-fpZuDogrAgnyt9oDDz+5DBz0zgPdPZz6D4IR7iESxRXElrlGTRkHJ9eEt+SACRJwT0FNFrt71DFQIUFBJfX/uQ==} @@ -3898,7 +3907,7 @@ snapshots: require-from-string: 2.0.2 uri-js-replace: 1.0.1 - '@redocly/cli@1.34.11(ajv@6.14.0)': + '@redocly/cli@1.34.11(ajv@8.20.0)': dependencies: '@opentelemetry/api': 1.9.0 '@opentelemetry/exporter-trace-otlp-http': 0.53.0(@opentelemetry/api@1.9.0) @@ -3907,7 +3916,7 @@ snapshots: '@opentelemetry/semantic-conventions': 1.27.0 '@redocly/config': 0.22.0 '@redocly/openapi-core': 1.34.11 - '@redocly/respect-core': 1.34.11(ajv@6.14.0) + '@redocly/respect-core': 1.34.11(ajv@8.20.0) abort-controller: 3.0.0 chokidar: 3.5.3 colorette: 1.4.0 @@ -3950,12 +3959,12 @@ snapshots: transitivePeerDependencies: - supports-color - '@redocly/respect-core@1.34.11(ajv@6.14.0)': + '@redocly/respect-core@1.34.11(ajv@8.20.0)': dependencies: '@faker-js/faker': 7.6.0 '@redocly/ajv': 8.11.2 '@redocly/openapi-core': 1.34.11 - better-ajv-errors: 1.2.0(ajv@6.14.0) + better-ajv-errors: 1.2.0(ajv@8.20.0) colorette: 2.0.20 concat-stream: 2.0.0 cookie: 0.7.2 @@ -4305,6 +4314,13 @@ snapshots: json-schema-traverse: 0.4.1 uri-js: 4.4.1 + ajv@8.20.0: + dependencies: + fast-deep-equal: 3.1.3 + fast-uri: 3.1.2 + json-schema-traverse: 1.0.0 + require-from-string: 2.0.2 + algoliasearch@5.49.2: dependencies: '@algolia/abtesting': 1.15.2 @@ -4367,11 +4383,11 @@ snapshots: balanced-match@4.0.4: {} - better-ajv-errors@1.2.0(ajv@6.14.0): + better-ajv-errors@1.2.0(ajv@8.20.0): dependencies: '@babel/code-frame': 7.29.0 '@humanwhocodes/momoa': 2.0.4 - ajv: 6.14.0 + ajv: 8.20.0 chalk: 4.1.2 jsonpointer: 5.0.1 leven: 3.1.0 @@ -4817,6 +4833,8 @@ snapshots: fast-safe-stringify@2.1.1: {} + fast-uri@3.1.2: {} + fast-xml-builder@1.0.0: {} fast-xml-parser@5.4.1: diff --git a/scripts/validate-docs-yml.ts b/scripts/validate-docs-yml.ts new file mode 100644 index 000000000..7a5101598 --- /dev/null +++ b/scripts/validate-docs-yml.ts @@ -0,0 +1,27 @@ +import { Ajv } from "ajv"; +import { readFileSync } from "fs"; +import yaml from "js-yaml"; + +const DOCS_YML_PATH = "content/docs.yml"; +const SCHEMA_PATH = "content/docs-yml.schema.json"; + +const validateDocsYml = () => { + const schema = JSON.parse(readFileSync(SCHEMA_PATH, "utf8")); + const docsYml = yaml.load(readFileSync(DOCS_YML_PATH, "utf8")); + + const ajv = new Ajv({ allErrors: true }); + const validate = ajv.compile(schema); + + if (!validate(docsYml)) { + const messages = new Set( + (validate.errors ?? []).map( + (error) => `❌ ${DOCS_YML_PATH}${error.instancePath}: ${error.message}`, + ), + ); + throw new Error([...messages].join("\n")); + } + + console.info(`✅ Successfully validated ${DOCS_YML_PATH}`); +}; + +validateDocsYml(); diff --git a/src/content-indexer/types/docsYaml.ts b/src/content-indexer/types/docsYaml.ts index 77d70b09e..3ed8fd81d 100644 --- a/src/content-indexer/types/docsYaml.ts +++ b/src/content-indexer/types/docsYaml.ts @@ -13,6 +13,7 @@ export interface SectionConfig { slug?: string; "skip-slug"?: boolean; hidden?: boolean; + collapsed?: boolean; contents: NavigationItem[]; path?: string; // Optional overview page } @@ -48,13 +49,15 @@ export interface TabConfig { "display-name": string; slug?: string; "skip-slug"?: boolean; + changelog?: string; } export interface DocsYml { + instances?: Array<{ url: string }>; tabs?: Record; navigation: Array<{ tab: string; - layout: NavigationItem[]; + layout?: NavigationItem[]; }>; } From 33b19992f0589001a22c8c742c6d7859898aec4e Mon Sep 17 00:00:00 2001 From: dslovinsky Date: Fri, 12 Jun 2026 11:05:20 -0400 Subject: [PATCH 2/4] DX-2231: Remove dead docs.yml fields instead of typing them Drop fields that nothing in the content indexer or docs-site reads: collapsed (sections), instances, the changelog tab property, noindex (pages; the real noindex is frontmatter-driven), paginated (api items), and changelog navigation items. Removed from docs.yml, the schema, and docsYaml.ts so the schema only allows options that actually do something. Keep optional layout, which the indexer genuinely supports. Part of DX-2231 Co-Authored-By: Claude --- content/docs-yml.schema.json | 52 ++------------------------- content/docs.yml | 18 ---------- src/content-indexer/types/docsYaml.ts | 5 --- 3 files changed, 2 insertions(+), 73 deletions(-) diff --git a/content/docs-yml.schema.json b/content/docs-yml.schema.json index fd986c6d2..d3e5efb52 100644 --- a/content/docs-yml.schema.json +++ b/content/docs-yml.schema.json @@ -1,26 +1,11 @@ { "$schema": "http://json-schema.org/draft-07/schema#", "title": "Alchemy docs.yml", - "description": "Navigation configuration for the Alchemy docs site. Based on Fern's docs.yml format, restricted to the options supported by the content indexer (src/content-indexer/types/docsYaml.ts) plus Alchemy-specific extensions (skip-slug, noindex, flattened, paginated).", + "description": "Navigation configuration for the Alchemy docs site. Based on Fern's docs.yml format, restricted to the options supported by the content indexer (src/content-indexer/types/docsYaml.ts) plus Alchemy-specific extensions (skip-slug, flattened).", "type": "object", "additionalProperties": false, "required": ["navigation"], "properties": { - "instances": { - "description": "Deployed instances of the docs site.", - "type": "array", - "items": { - "type": "object", - "additionalProperties": false, - "required": ["url"], - "properties": { - "url": { - "description": "Base URL where the docs are served.", - "type": "string" - } - } - } - }, "tabs": { "description": "Top-level tabs shown in the docs header. Keys are tab identifiers referenced by navigation[].tab.", "type": "object", @@ -68,10 +53,6 @@ "skip-slug": { "description": "Alchemy extension: omit this tab's slug from descendant URL paths.", "type": "boolean" - }, - "changelog": { - "description": "Path to a changelog directory, relative to the content directory (e.g. ./changelog).", - "type": "string" } } }, @@ -80,8 +61,7 @@ { "$ref": "#/definitions/pageItem" }, { "$ref": "#/definitions/sectionItem" }, { "$ref": "#/definitions/linkItem" }, - { "$ref": "#/definitions/apiItem" }, - { "$ref": "#/definitions/changelogItem" } + { "$ref": "#/definitions/apiItem" } ] }, "mdxPath": { @@ -109,10 +89,6 @@ "hidden": { "description": "Hide this page from the sidebar and search indexing.", "type": "boolean" - }, - "noindex": { - "description": "Alchemy extension: exclude this page from search indexing while keeping it in the sidebar.", - "type": "boolean" } } }, @@ -148,10 +124,6 @@ "hidden": { "description": "Hide this section and its contents from the sidebar and search indexing.", "type": "boolean" - }, - "collapsed": { - "description": "Render the section initially collapsed in the sidebar.", - "type": "boolean" } } }, @@ -200,26 +172,6 @@ "flattened": { "description": "Alchemy extension: render endpoints as a flat list instead of grouped by spec hierarchy.", "type": "boolean" - }, - "paginated": { - "description": "Alchemy extension: paginate large endpoint lists.", - "type": "boolean" - } - } - }, - "changelogItem": { - "description": "A changelog feed generated from a directory of changelog entries.", - "type": "object", - "additionalProperties": false, - "required": ["changelog"], - "properties": { - "changelog": { - "description": "Path to a changelog directory, relative to the content directory.", - "type": "string" - }, - "slug": { - "description": "URL segment for the changelog.", - "type": "string" } } } diff --git a/content/docs.yml b/content/docs.yml index c4e3b53c4..2cb487427 100644 --- a/content/docs.yml +++ b/content/docs.yml @@ -1,8 +1,5 @@ # yaml-language-server: $schema=./docs-yml.schema.json -instances: - - url: https://alchemy.com/docs - tabs: get-started: display-name: Get Started @@ -24,7 +21,6 @@ tabs: slug: rollups changelog: display-name: Changelog - changelog: ./changelog slug: changelog navigation: @@ -879,7 +875,6 @@ navigation: - page: Using API path: wallets/pages/smart-wallets/quickstart/api.mdx - section: Send transactions - collapsed: true contents: - page: Single transactions path: wallets/pages/transactions/send-transactions/index.mdx @@ -889,19 +884,16 @@ navigation: path: wallets/pages/transactions/send-parallel-transactions/index.mdx - section: Debug transactions path: wallets/pages/transactions/debug-transactions/index.mdx - collapsed: true contents: - page: Debug with Tenderly path: wallets/pages/transactions/debug-transactions/debug-with-tenderly.mdx - section: EIP-7702 path: wallets/pages/transactions/using-eip-7702/index.mdx - collapsed: true contents: - page: Undelegate 7702 account path: wallets/pages/transactions/undelegate-account/index.mdx - section: Sponsor gas path: wallets/pages/transactions/sponsor-gas/overview.mdx - collapsed: true contents: - page: Full sponsorship path: wallets/pages/transactions/sponsor-gas/index.mdx @@ -912,14 +904,12 @@ navigation: - page: Solana sponsorship path: wallets/pages/transactions/sponsor-gas/solana/index.mdx - section: Swap tokens - collapsed: true contents: - page: Same-chain swaps path: wallets/pages/transactions/swap-tokens/index.mdx - page: Cross-chain swaps path: wallets/pages/transactions/cross-chain-swap-tokens/index.mdx - section: Grant session keys - collapsed: true contents: - page: Overview path: wallets/pages/smart-wallets/session-keys/index.mdx @@ -932,7 +922,6 @@ navigation: - page: Retry transactions path: wallets/pages/transactions/retry-transactions/index.mdx - section: Sign - collapsed: true contents: - page: Sign messages path: wallets/pages/transactions/signing/sign-messages/index.mdx @@ -947,7 +936,6 @@ navigation: path: wallets/pages/authentication/overview.mdx - section: Privy path: wallets/pages/third-party/signers/privy.mdx - collapsed: true contents: - page: Signer migration overview path: wallets/wallet-integrations/privy/signer-migration-overview.mdx @@ -966,10 +954,8 @@ navigation: - page: Other signers path: wallets/pages/third-party/signers/custom-integration.mdx - section: Account Kit (v4) - collapsed: true contents: - section: Login methods - collapsed: true contents: - page: Email OTP path: wallets/pages/authentication/login-methods/email-otp.mdx @@ -992,7 +978,6 @@ navigation: - page: Adding and removing login methods path: wallets/pages/react/login-methods/adding-and-removing-login-methods.mdx - section: UI components - collapsed: true contents: - page: Using UI components path: wallets/pages/react/ui-components.mdx @@ -1001,21 +986,18 @@ navigation: - page: Tailwind setup path: wallets/pages/react/customization/tailwind-setup.mdx - section: Whitelabel - collapsed: true contents: - page: React hooks path: wallets/pages/react/react-hooks.mdx - page: Other JS initialization path: wallets/pages/signer/quickstart.mdx - section: Connectors - collapsed: true contents: - page: Connect external wallets path: wallets/pages/react/login-methods/eoa-login.mdx - page: Customize path: wallets/pages/react/connectors/customization.mdx - section: MFA - collapsed: true contents: - page: Set up MFA path: wallets/pages/react/mfa/setup-mfa.mdx diff --git a/src/content-indexer/types/docsYaml.ts b/src/content-indexer/types/docsYaml.ts index 3ed8fd81d..82e01f675 100644 --- a/src/content-indexer/types/docsYaml.ts +++ b/src/content-indexer/types/docsYaml.ts @@ -5,7 +5,6 @@ export interface PageConfig { path: string; slug?: string; hidden?: boolean; - noindex?: boolean; } export interface SectionConfig { @@ -13,7 +12,6 @@ export interface SectionConfig { slug?: string; "skip-slug"?: boolean; hidden?: boolean; - collapsed?: boolean; contents: NavigationItem[]; path?: string; // Optional overview page } @@ -30,7 +28,6 @@ export interface ApiConfig { "skip-slug"?: boolean; hidden?: boolean; flattened?: boolean; - paginated?: boolean; } export interface ChangelogConfig { @@ -49,11 +46,9 @@ export interface TabConfig { "display-name": string; slug?: string; "skip-slug"?: boolean; - changelog?: string; } export interface DocsYml { - instances?: Array<{ url: string }>; tabs?: Record; navigation: Array<{ tab: string; From 8b711ec8bb209b856da8bcb002dd61cf710a59fc Mon Sep 17 00:00:00 2001 From: dslovinsky Date: Fri, 12 Jun 2026 11:39:44 -0400 Subject: [PATCH 3/4] DX-2231: Remove docs provider reference from schema description Part of DX-2231 Co-Authored-By: Claude --- content/docs-yml.schema.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/docs-yml.schema.json b/content/docs-yml.schema.json index d3e5efb52..86bfd3e9e 100644 --- a/content/docs-yml.schema.json +++ b/content/docs-yml.schema.json @@ -1,7 +1,7 @@ { "$schema": "http://json-schema.org/draft-07/schema#", "title": "Alchemy docs.yml", - "description": "Navigation configuration for the Alchemy docs site. Based on Fern's docs.yml format, restricted to the options supported by the content indexer (src/content-indexer/types/docsYaml.ts) plus Alchemy-specific extensions (skip-slug, flattened).", + "description": "Navigation configuration for the Alchemy docs site. Allows only the options supported by the content indexer (src/content-indexer/types/docsYaml.ts), including Alchemy-specific extensions (skip-slug, flattened).", "type": "object", "additionalProperties": false, "required": ["navigation"], From 980dfd29317d3f89b7aa164115ada49c9bf7e9c5 Mon Sep 17 00:00:00 2001 From: dslovinsky Date: Fri, 12 Jun 2026 11:42:38 -0400 Subject: [PATCH 4/4] DX-2231: Remove remaining prior-provider references from code comments Part of DX-2231 Co-Authored-By: Claude --- src/content-indexer/core/path-builder.ts | 5 ++--- src/content-indexer/types/page.ts | 1 - 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/src/content-indexer/core/path-builder.ts b/src/content-indexer/core/path-builder.ts index a9fa30de6..7e8d01cea 100644 --- a/src/content-indexer/core/path-builder.ts +++ b/src/content-indexer/core/path-builder.ts @@ -1,8 +1,7 @@ /** - * PathBuilder mimics Fern's slug generation logic to build full URL paths. + * PathBuilder mimics the prior docs provider's slug generation logic to build full URL paths. * Maintains an array of path segments and provides methods to build paths hierarchically. - * @note Fern incorrectly refers to full paths as "slugs" in their terminology - * @see https://buildwithfern.com/learn/docs/seo/configuring-slugs + * @note The prior docs provider incorrectly referred to full paths as "slugs" in its terminology */ export class PathBuilder { private segments: string[]; diff --git a/src/content-indexer/types/page.ts b/src/content-indexer/types/page.ts index b794cbdd9..e46c22fbc 100644 --- a/src/content-indexer/types/page.ts +++ b/src/content-indexer/types/page.ts @@ -1,6 +1,5 @@ /** * Frontmatter for a documentation page - * @see https://buildwithfern.com/learn/docs/configuration/page-level-settings */ export interface DocPageFrontmatter { title?: string;