diff --git a/.github/workflows/docs-markdown-manifest-sync.yml b/.github/workflows/docs-markdown-manifest-sync.yml new file mode 100644 index 00000000000..815d3edc57b --- /dev/null +++ b/.github/workflows/docs-markdown-manifest-sync.yml @@ -0,0 +1,55 @@ +name: Docs Markdown Manifest Sync + +on: + pull_request: + branches: ['master'] + paths: + - 'apps/docs/content/guides/**/*.mdx' + - 'apps/docs/content/troubleshooting/**/*.mdx' + - 'apps/docs/internals/generate-markdown-manifest.ts' + - 'apps/docs/internals/markdown-sources.ts' + - 'apps/docs/lib/markdown-manifest.ts' + +# Cancel old builds on new commit for same workflow + branch/PR +concurrency: + group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} + cancel-in-progress: true + +permissions: + contents: read + +env: + CI: true + +jobs: + check: + name: Check apps/docs/lib/markdown-manifest.ts is in sync + runs-on: blacksmith-4vcpu-ubuntu-2404 + + steps: + - uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4.3.0 + with: + persist-credentials: false + sparse-checkout: | + apps/docs + examples + packages + supabase + patches + + - uses: pnpm/action-setup@41ff72655975bd51cab0327fa583b6e92b6d3061 # v4.2.0 + name: Install pnpm + with: + run_install: false + + - name: Use Node.js + uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0 + with: + node-version-file: '.nvmrc' + cache: 'pnpm' + + - name: Install deps + run: pnpm install --frozen-lockfile + + - name: Verify markdown manifest is up to date + run: pnpm --filter docs check:markdown-manifest diff --git a/.prettierignore b/.prettierignore index 66e4d58fa92..1f07211dd8f 100644 --- a/.prettierignore +++ b/.prettierignore @@ -21,6 +21,8 @@ apps/studio/public apps/**/.turbo apps/docs/CONTRIBUTING.md apps/docs/__generated__ +# Generated by apps/docs/internals/generate-markdown-manifest.ts +apps/docs/lib/markdown-manifest.ts apps/design-system/__registry__ # TanStack Router auto-generated route tree; the file header explicitly # says to exclude it from formatters. diff --git a/apps/docs/internals/generate-guides-markdown.ts b/apps/docs/internals/generate-guides-markdown.ts index 39abdcba099..f2a378915b0 100644 --- a/apps/docs/internals/generate-guides-markdown.ts +++ b/apps/docs/internals/generate-guides-markdown.ts @@ -1,6 +1,5 @@ import fs from 'node:fs/promises' import path from 'node:path' -import { globby } from 'globby' import matter from 'gray-matter' import type { Content, Parent, Root } from 'mdast' import { fromMarkdown } from 'mdast-util-from-markdown' @@ -10,6 +9,7 @@ import type { MdxJsxFlowElement, MdxJsxTextElement } from 'mdast-util-mdx-jsx' import { toMarkdown } from 'mdast-util-to-markdown' import { gfm } from 'micromark-extension-gfm' import { mdxjs } from 'micromark-extension-mdxjs' +import { parse as parseToml } from 'smol-toml' import { addBaseUrlPrefix } from './internal-links' import { Admonition } from './markdown-schema/Admonition' @@ -26,6 +26,7 @@ import { RegionsList, SmartRegionsList } from './markdown-schema/RegionsList' import { SharedData } from './markdown-schema/SharedData' import { StepHike } from './markdown-schema/StepHike' import { TabPanel } from './markdown-schema/TabPanel' +import { collectMarkdownSources, type FrontmatterFormat } from './markdown-sources' const PARTIALS_DIR = path.join(process.cwd(), 'content', '_partials') @@ -155,10 +156,14 @@ const SCHEMA: ComponentSchema = { SharedData, } -async function generateOne(filePath: string): Promise { - const raw = await fs.readFile(filePath, 'utf8') - const { content, data } = matter(raw) +function parseFrontmatter(raw: string, frontmatter: FrontmatterFormat) { + if (frontmatter === 'toml') { + return matter(raw, { language: 'toml', engines: { toml: parseToml } }) + } + return matter(raw) +} +async function transformBody(content: string, data: Record): Promise { const tree = parseMdx(content) await inlinePartials(tree) addBaseUrlPrefix(tree) @@ -166,9 +171,8 @@ async function generateOne(filePath: string): Promise { const body = serializeMdx(tree) const headerParts: string[] = [] - if (data.title) headerParts.push(`# ${data.title}`) + if (data.title) headerParts.push(`# ${String(data.title)}`) if (data.subtitle) headerParts.push(String(data.subtitle)) - // Add description only when differs from subtitle. if (data.description && String(data.description) !== String(data.subtitle)) headerParts.push(String(data.description)) @@ -177,31 +181,30 @@ async function generateOne(filePath: string): Promise { return header ? `${header}\n\n${body}` : body } +async function generateOne(sourceFile: string, frontmatter: FrontmatterFormat): Promise { + const raw = await fs.readFile(sourceFile, 'utf8') + const { content, data } = parseFrontmatter(raw, frontmatter) + return transformBody(content, data) +} + async function generate() { - const files = await globby(['content/guides/**/!(_)*.mdx']) + const sources = await collectMarkdownSources() let warnings = 0 await Promise.all( - files.map(async (filePath) => { - // content/guides/ai/vector-columns.mdx → public/markdown/guides/ai/vector-columns.md - // Placing under public/markdown/ ensures the file is served at /docs/guides/... - // matching the URL of the rendered page. - const outPath = filePath - .replace(/^content\/guides\//, 'public/markdown/guides/') - .replace(/\.mdx$/, '.md') - + sources.map(async ({ sourceFile, outPath, frontmatter }) => { let output: string try { - output = await generateOne(filePath) + output = await generateOne(sourceFile, frontmatter) } catch (err) { warnings++ console.warn( - `[warn] Failed to process ${filePath}: ${err instanceof Error ? err.message : err}` + `[warn] Failed to process ${sourceFile}: ${err instanceof Error ? err.message : err}` ) try { - output = await fs.readFile(filePath, 'utf8') + output = await fs.readFile(sourceFile, 'utf8') } catch { - output = `` + output = `` } } @@ -211,7 +214,7 @@ async function generate() { ) const summary = warnings ? ` (${warnings} with warnings)` : '' - console.log(`Generated ${files.length} markdown files under public/markdown/guides/${summary}`) + console.log(`Generated ${sources.length} markdown files under public/markdown/guides/${summary}`) } generate() diff --git a/apps/docs/internals/generate-markdown-manifest.ts b/apps/docs/internals/generate-markdown-manifest.ts new file mode 100644 index 00000000000..40362d8245b --- /dev/null +++ b/apps/docs/internals/generate-markdown-manifest.ts @@ -0,0 +1,59 @@ +import fs from 'node:fs/promises' +import path from 'node:path' + +import { collectMarkdownSources } from './markdown-sources' + +const MANIFEST_PATH = path.join(process.cwd(), 'lib', 'markdown-manifest.ts') +const RELATIVE_PATH = 'apps/docs/lib/markdown-manifest.ts' + +const HEADER = `// GENERATED FILE — DO NOT EDIT. +// +// The guide slugs that have a generated markdown (.md) variant. middleware.ts +// imports this to decide whether a bot request for /guides/ can be served +// markdown. It is committed (not left under __generated__) so the import resolves +// in every build context — turbo does not run the npm \`prebuild\` hook that +// regenerates it, so a gitignored file would be missing during typecheck/lint. +// +// Regenerate with: pnpm --filter docs build:markdown-manifest +// CI fails if this drifts from the content sources (docs-markdown-manifest-sync workflow). +` + +async function collectSlugs(): Promise { + const sources = await collectMarkdownSources() + return [...new Set(sources.map((source) => source.slug))].sort() +} + +function renderManifest(slugs: string[]): string { + return `${HEADER}\nexport const MARKDOWN_SLUGS: readonly string[] = ${JSON.stringify(slugs, null, 2)}\n` +} + +async function main() { + const slugs = await collectSlugs() + const expected = renderManifest(slugs) + + if (process.argv.includes('--check')) { + let actual: string | null = null + try { + actual = await fs.readFile(MANIFEST_PATH, 'utf8') + } catch { + actual = null + } + + if (actual !== expected) { + console.error( + `${RELATIVE_PATH} is out of sync with the markdown content sources.\n` + + 'Run `pnpm --filter docs build:markdown-manifest` and commit the result.' + ) + process.exit(1) + } + + console.log(`${RELATIVE_PATH} is up to date (${slugs.length} slugs).`) + return + } + + await fs.mkdir(path.dirname(MANIFEST_PATH), { recursive: true }) + await fs.writeFile(MANIFEST_PATH, expected) + console.log(`Wrote ${slugs.length} slugs to ${RELATIVE_PATH}`) +} + +main() diff --git a/apps/docs/internals/markdown-sources.test.ts b/apps/docs/internals/markdown-sources.test.ts new file mode 100644 index 00000000000..0db0b32dc11 --- /dev/null +++ b/apps/docs/internals/markdown-sources.test.ts @@ -0,0 +1,21 @@ +import { describe, expect, it } from 'vitest' + +import { guideSlug, troubleshootingSlug } from './markdown-sources' + +describe('guideSlug', () => { + it('strips the content/guides prefix and .mdx extension, keeping nested path', () => { + expect(guideSlug('content/guides/ai/vector-columns.mdx')).toBe('ai/vector-columns') + }) + + it('handles a top-level guide', () => { + expect(guideSlug('content/guides/getting-started.mdx')).toBe('getting-started') + }) +}) + +describe('troubleshootingSlug', () => { + it('flattens to a troubleshooting/ slug', () => { + expect(troubleshootingSlug('content/troubleshooting/all-about-egress-a_Sg_e.mdx')).toBe( + 'troubleshooting/all-about-egress-a_Sg_e' + ) + }) +}) diff --git a/apps/docs/internals/markdown-sources.ts b/apps/docs/internals/markdown-sources.ts new file mode 100644 index 00000000000..808d29d7210 --- /dev/null +++ b/apps/docs/internals/markdown-sources.ts @@ -0,0 +1,42 @@ +import path from 'node:path' +import { globby } from 'globby' + +export type FrontmatterFormat = 'yaml' | 'toml' + +export interface MarkdownSource { + sourceFile: string + slug: string + outPath: string + frontmatter: FrontmatterFormat +} + +const OUTPUT_ROOT = 'public/markdown/guides' +const GUIDES_GLOB = 'content/guides/**/!(_)*.mdx' +const TROUBLESHOOTING_GLOB = 'content/troubleshooting/!(_)*.mdx' + +export function guideSlug(sourceFile: string): string { + return sourceFile.replace(/^content\/guides\//, '').replace(/\.mdx$/, '') +} + +export function troubleshootingSlug(sourceFile: string): string { + return `troubleshooting/${path.basename(sourceFile, '.mdx')}` +} + +export async function collectMarkdownSources(): Promise { + const [guideFiles, troubleshootingFiles] = await Promise.all([ + globby([GUIDES_GLOB]), + globby([TROUBLESHOOTING_GLOB]), + ]) + + const guides: MarkdownSource[] = guideFiles.map((sourceFile) => { + const slug = guideSlug(sourceFile) + return { sourceFile, slug, outPath: `${OUTPUT_ROOT}/${slug}.md`, frontmatter: 'yaml' } + }) + + const troubleshooting: MarkdownSource[] = troubleshootingFiles.map((sourceFile) => { + const slug = troubleshootingSlug(sourceFile) + return { sourceFile, slug, outPath: `${OUTPUT_ROOT}/${slug}.md`, frontmatter: 'toml' } + }) + + return [...guides, ...troubleshooting] +} diff --git a/apps/docs/lib/markdown-manifest.ts b/apps/docs/lib/markdown-manifest.ts new file mode 100644 index 00000000000..05bf99b1093 --- /dev/null +++ b/apps/docs/lib/markdown-manifest.ts @@ -0,0 +1,757 @@ +// GENERATED FILE — DO NOT EDIT. +// +// The guide slugs that have a generated markdown (.md) variant. middleware.ts +// imports this to decide whether a bot request for /guides/ can be served +// markdown. It is committed (not left under __generated__) so the import resolves +// in every build context — turbo does not run the npm `prebuild` hook that +// regenerates it, so a gitignored file would be missing during typecheck/lint. +// +// Regenerate with: pnpm --filter docs build:markdown-manifest +// CI fails if this drifts from the content sources (docs-markdown-manifest-sync workflow). + +export const MARKDOWN_SLUGS: readonly string[] = [ + "ai", + "ai-tools", + "ai-tools/ai-prompts", + "ai-tools/ai-skills", + "ai-tools/byo-mcp", + "ai-tools/mcp", + "ai-tools/plugins", + "ai/automatic-embeddings", + "ai/choosing-compute-addon", + "ai/concepts", + "ai/engineering-for-scale", + "ai/examples/building-chatgpt-plugins", + "ai/examples/headless-vector-search", + "ai/examples/huggingface-image-captioning", + "ai/examples/image-search-openai-clip", + "ai/examples/mixpeek-video-search", + "ai/examples/nextjs-vector-search", + "ai/examples/openai", + "ai/examples/semantic-image-search-amazon-titan", + "ai/going-to-prod", + "ai/google-colab", + "ai/hugging-face", + "ai/hybrid-search", + "ai/integrations/amazon-bedrock", + "ai/integrations/llamaindex", + "ai/integrations/roboflow", + "ai/keyword-search", + "ai/langchain", + "ai/python-clients", + "ai/quickstarts/face-similarity", + "ai/quickstarts/generate-text-embeddings", + "ai/quickstarts/hello-world", + "ai/quickstarts/text-deduplication", + "ai/rag-with-permissions", + "ai/semantic-search", + "ai/structured-unstructured", + "ai/vecs-python-client", + "ai/vector-columns", + "ai/vector-indexes", + "ai/vector-indexes/hnsw-indexes", + "ai/vector-indexes/ivf-indexes", + "api", + "api/automatic-retries-in-supabase-js", + "api/creating-routes", + "api/custom-claims-and-role-based-access-control-rbac", + "api/handling-errors-in-supabase-js", + "api/quickstart", + "api/rest/auto-generated-docs", + "api/rest/client-libs", + "api/rest/generating-python-types", + "api/rest/generating-types", + "api/rest/postgrest-error-codes", + "api/securing-your-api", + "api/sql-to-api", + "api/sql-to-rest", + "api/using-custom-schemas", + "auth", + "auth/architecture", + "auth/audit-logs", + "auth/auth-anonymous", + "auth/auth-captcha", + "auth/auth-email-passwordless", + "auth/auth-email-templates", + "auth/auth-hooks", + "auth/auth-hooks/before-user-created-hook", + "auth/auth-hooks/custom-access-token-hook", + "auth/auth-hooks/mfa-verification-hook", + "auth/auth-hooks/password-verification-hook", + "auth/auth-hooks/send-email-hook", + "auth/auth-hooks/send-sms-hook", + "auth/auth-identity-linking", + "auth/auth-mfa", + "auth/auth-mfa/phone", + "auth/auth-mfa/totp", + "auth/auth-smtp", + "auth/auth-web3", + "auth/custom-oauth-providers", + "auth/debugging/error-codes", + "auth/enterprise-sso", + "auth/enterprise-sso/auth-sso-saml", + "auth/general-configuration", + "auth/identities", + "auth/jwt-fields", + "auth/jwts", + "auth/managing-user-data", + "auth/native-mobile-deep-linking", + "auth/oauth-server", + "auth/oauth-server/getting-started", + "auth/oauth-server/mcp-authentication", + "auth/oauth-server/oauth-flows", + "auth/oauth-server/token-security", + "auth/passkeys", + "auth/password-security", + "auth/passwords", + "auth/phone-login", + "auth/quickstarts/astrojs", + "auth/quickstarts/nextjs", + "auth/quickstarts/react", + "auth/quickstarts/react-native", + "auth/quickstarts/with-expo-react-native-social-auth", + "auth/rate-limits", + "auth/redirect-urls", + "auth/server-side", + "auth/server-side/advanced-guide", + "auth/server-side/creating-a-client", + "auth/server-side/migrating-to-ssr-from-auth-helpers", + "auth/sessions", + "auth/sessions/implicit-flow", + "auth/sessions/pkce-flow", + "auth/signing-keys", + "auth/signout", + "auth/social-login", + "auth/social-login/auth-apple", + "auth/social-login/auth-azure", + "auth/social-login/auth-bitbucket", + "auth/social-login/auth-discord", + "auth/social-login/auth-facebook", + "auth/social-login/auth-figma", + "auth/social-login/auth-github", + "auth/social-login/auth-gitlab", + "auth/social-login/auth-google", + "auth/social-login/auth-kakao", + "auth/social-login/auth-keycloak", + "auth/social-login/auth-linkedin", + "auth/social-login/auth-notion", + "auth/social-login/auth-slack", + "auth/social-login/auth-spotify", + "auth/social-login/auth-twitch", + "auth/social-login/auth-twitter", + "auth/social-login/auth-workos", + "auth/social-login/auth-zoom", + "auth/third-party/auth0", + "auth/third-party/aws-cognito", + "auth/third-party/clerk", + "auth/third-party/firebase-auth", + "auth/third-party/overview", + "auth/third-party/workos", + "auth/users", + "cli", + "cron", + "cron/install", + "cron/quickstart", + "database/arrays", + "database/beekeeper-studio", + "database/connecting-to-postgres", + "database/connecting-to-postgres/serverless-drivers", + "database/connection-management", + "database/custom-postgres-config", + "database/dbeaver", + "database/debugging-performance", + "database/drizzle", + "database/extensions", + "database/extensions/http", + "database/extensions/hypopg", + "database/extensions/index_advisor", + "database/extensions/pg_cron", + "database/extensions/pg_graphql", + "database/extensions/pg_hashids", + "database/extensions/pg_jsonschema", + "database/extensions/pg_net", + "database/extensions/pg_partman", + "database/extensions/pg_plan_filter", + "database/extensions/pg_repack", + "database/extensions/pg_stat_statements", + "database/extensions/pgaudit", + "database/extensions/pgjwt", + "database/extensions/pgmq", + "database/extensions/pgroonga", + "database/extensions/pgrouting", + "database/extensions/pgsodium", + "database/extensions/pgtap", + "database/extensions/pgvector", + "database/extensions/plpgsql_check", + "database/extensions/plv8", + "database/extensions/postgis", + "database/extensions/postgres_fdw", + "database/extensions/rum", + "database/extensions/timescaledb", + "database/extensions/uuid-ossp", + "database/extensions/wrappers/overview", + "database/full-text-search", + "database/functions", + "database/import-data", + "database/inspect", + "database/joins-and-nesting", + "database/json", + "database/metabase", + "database/migrating-to-pg-partman", + "database/orioledb", + "database/overview", + "database/partitions", + "database/pgadmin", + "database/postgres-js", + "database/postgres/cascade-deletes", + "database/postgres/column-level-security", + "database/postgres/configuration", + "database/postgres/data-deletion", + "database/postgres/dropping-all-tables-in-schema", + "database/postgres/enums", + "database/postgres/event-triggers", + "database/postgres/first-row-in-group", + "database/postgres/indexes", + "database/postgres/roles", + "database/postgres/roles-superuser", + "database/postgres/row-level-security", + "database/postgres/setup-replication-external", + "database/postgres/timeouts", + "database/postgres/triggers", + "database/postgres/which-version-of-postgres", + "database/prisma", + "database/prisma/prisma-troubleshooting", + "database/psql", + "database/query-optimization", + "database/replication", + "database/replication/bigquery", + "database/replication/manual-replication-faq", + "database/replication/manual-replication-monitoring", + "database/replication/manual-replication-setup", + "database/replication/pipelines", + "database/replication/pipelines-faq", + "database/replication/pipelines-monitoring", + "database/secure-data", + "database/supavisor", + "database/tables", + "database/testing", + "database/vault", + "database/webhooks", + "deployment", + "deployment/branching", + "deployment/branching/configuration", + "deployment/branching/dashboard", + "deployment/branching/github-integration", + "deployment/branching/integrations", + "deployment/branching/troubleshooting", + "deployment/branching/working-with-branches", + "deployment/database-migrations", + "deployment/going-into-prod", + "deployment/managing-environments", + "deployment/maturity-model", + "deployment/shared-responsibility-model", + "functions", + "functions/ai-models", + "functions/architecture", + "functions/auth", + "functions/auth-headers", + "functions/auth-legacy-jwt", + "functions/background-tasks", + "functions/compression", + "functions/connect-to-postgres", + "functions/cors", + "functions/dart-edge", + "functions/debugging-tools", + "functions/dependencies", + "functions/deploy", + "functions/development-environment", + "functions/development-tips", + "functions/ephemeral-storage", + "functions/error-codes", + "functions/error-handling", + "functions/examples/amazon-bedrock-image-generator", + "functions/examples/auth-send-email-hook-react-email-resend", + "functions/examples/cloudflare-turnstile", + "functions/examples/discord-bot", + "functions/examples/elevenlabs-generate-speech-stream", + "functions/examples/elevenlabs-transcribe-speech", + "functions/examples/github-actions", + "functions/examples/image-manipulation", + "functions/examples/mcp-server-mcp-lite", + "functions/examples/og-image", + "functions/examples/push-notifications", + "functions/examples/rate-limiting", + "functions/examples/resumable-websockets", + "functions/examples/screenshots", + "functions/examples/semantic-search", + "functions/examples/send-emails", + "functions/examples/sentry-monitoring", + "functions/examples/slack-bot-mention", + "functions/examples/stripe-webhooks", + "functions/examples/telegram-bot", + "functions/examples/upstash-redis", + "functions/function-configuration", + "functions/http-methods", + "functions/kysely-postgres", + "functions/limits", + "functions/logging", + "functions/pricing", + "functions/quickstart", + "functions/quickstart-dashboard", + "functions/recursive-functions", + "functions/regional-invocation", + "functions/routing", + "functions/schedule-functions", + "functions/secrets", + "functions/status-codes", + "functions/storage-caching", + "functions/unit-test", + "functions/wasm", + "functions/websockets", + "getting-started", + "getting-started/api-keys", + "getting-started/architecture", + "getting-started/features", + "getting-started/migrating-to-new-api-keys", + "getting-started/quickstarts/astrojs", + "getting-started/quickstarts/expo-react-native", + "getting-started/quickstarts/flask", + "getting-started/quickstarts/flutter", + "getting-started/quickstarts/hono", + "getting-started/quickstarts/ios-swiftui", + "getting-started/quickstarts/kotlin", + "getting-started/quickstarts/laravel", + "getting-started/quickstarts/nextjs", + "getting-started/quickstarts/nuxtjs", + "getting-started/quickstarts/reactjs", + "getting-started/quickstarts/redwoodjs", + "getting-started/quickstarts/refine", + "getting-started/quickstarts/ruby-on-rails", + "getting-started/quickstarts/solidjs", + "getting-started/quickstarts/sveltekit", + "getting-started/quickstarts/tanstack", + "getting-started/quickstarts/vue", + "getting-started/tutorials/with-angular", + "getting-started/tutorials/with-expo-react-native", + "getting-started/tutorials/with-flutter", + "getting-started/tutorials/with-ionic-angular", + "getting-started/tutorials/with-ionic-react", + "getting-started/tutorials/with-ionic-vue", + "getting-started/tutorials/with-kotlin", + "getting-started/tutorials/with-nextjs", + "getting-started/tutorials/with-nuxt-3", + "getting-started/tutorials/with-react", + "getting-started/tutorials/with-redwoodjs", + "getting-started/tutorials/with-refine", + "getting-started/tutorials/with-solidjs", + "getting-started/tutorials/with-svelte", + "getting-started/tutorials/with-sveltekit", + "getting-started/tutorials/with-swift", + "getting-started/tutorials/with-vue-3", + "integrations", + "integrations/build-a-supabase-oauth-integration", + "integrations/build-a-supabase-oauth-integration/oauth-scopes", + "integrations/partner-integration-guide", + "integrations/supabase-for-platforms", + "integrations/supabase-marketplace", + "integrations/vercel-marketplace", + "local-development", + "local-development/cli/getting-started", + "local-development/cli/testing-and-linting", + "local-development/customizing-email-templates", + "local-development/declarative-database-schemas", + "local-development/managing-config", + "local-development/overview", + "local-development/restoring-downloaded-backup", + "local-development/seeding-your-database", + "local-development/testing/overview", + "local-development/testing/pgtap-extended", + "platform", + "platform/access-control", + "platform/aws-marketplace", + "platform/aws-marketplace/account-setup", + "platform/aws-marketplace/faq", + "platform/aws-marketplace/getting-started", + "platform/aws-marketplace/invoices", + "platform/aws-marketplace/manage-your-subscription", + "platform/backups", + "platform/billing-faq", + "platform/billing-on-supabase", + "platform/clone-project", + "platform/compute-and-disk", + "platform/cost-control", + "platform/credits", + "platform/custom-domains", + "platform/database-size", + "platform/free-project-pausing", + "platform/get-set-up-for-billing", + "platform/hipaa-projects", + "platform/ipv4-address", + "platform/manage-your-subscription", + "platform/manage-your-usage", + "platform/manage-your-usage/advanced-mfa-phone", + "platform/manage-your-usage/branching", + "platform/manage-your-usage/compute", + "platform/manage-your-usage/custom-domains", + "platform/manage-your-usage/disk-iops", + "platform/manage-your-usage/disk-size", + "platform/manage-your-usage/disk-throughput", + "platform/manage-your-usage/edge-function-invocations", + "platform/manage-your-usage/egress", + "platform/manage-your-usage/ipv4", + "platform/manage-your-usage/log-drains", + "platform/manage-your-usage/logs", + "platform/manage-your-usage/logs-ingest", + "platform/manage-your-usage/logs-query", + "platform/manage-your-usage/monthly-active-users", + "platform/manage-your-usage/monthly-active-users-sso", + "platform/manage-your-usage/monthly-active-users-third-party", + "platform/manage-your-usage/point-in-time-recovery", + "platform/manage-your-usage/read-replicas", + "platform/manage-your-usage/realtime-messages", + "platform/manage-your-usage/realtime-peak-connections", + "platform/manage-your-usage/storage-image-transformations", + "platform/manage-your-usage/storage-size", + "platform/mfa/org-mfa-enforcement", + "platform/migrating-to-supabase", + "platform/migrating-to-supabase/amazon-rds", + "platform/migrating-to-supabase/auth0", + "platform/migrating-to-supabase/firebase-auth", + "platform/migrating-to-supabase/firebase-storage", + "platform/migrating-to-supabase/firestore-data", + "platform/migrating-to-supabase/heroku", + "platform/migrating-to-supabase/mssql", + "platform/migrating-to-supabase/mysql", + "platform/migrating-to-supabase/neon", + "platform/migrating-to-supabase/postgres", + "platform/migrating-to-supabase/render", + "platform/migrating-to-supabase/vercel-postgres", + "platform/migrating-within-supabase", + "platform/migrating-within-supabase/backup-restore", + "platform/migrating-within-supabase/dashboard-restore", + "platform/multi-factor-authentication", + "platform/network-restrictions", + "platform/performance", + "platform/permissions", + "platform/postgres-connection-logging", + "platform/privatelink", + "platform/project-transfer", + "platform/read-replicas", + "platform/read-replicas/getting-started", + "platform/regions", + "platform/ssl-enforcement", + "platform/sso", + "platform/sso/azure", + "platform/sso/choosing-login-flow", + "platform/sso/gsuite", + "platform/sso/login-flows", + "platform/sso/multiple-providers", + "platform/sso/okta", + "platform/sso/testing-best-practices", + "platform/temporary-access", + "platform/upgrading", + "platform/your-monthly-invoice", + "queues", + "queues/api", + "queues/consuming-messages-with-edge-functions", + "queues/expose-self-hosted-queues", + "queues/pgmq", + "queues/quickstart", + "realtime", + "realtime/architecture", + "realtime/authorization", + "realtime/benchmarks", + "realtime/broadcast", + "realtime/concepts", + "realtime/error_codes", + "realtime/getting_started", + "realtime/limits", + "realtime/postgres-changes", + "realtime/presence", + "realtime/pricing", + "realtime/protocol", + "realtime/realtime-listening-flutter", + "realtime/realtime-user-presence", + "realtime/realtime-with-nextjs", + "realtime/reports", + "realtime/settings", + "realtime/subscribing-to-database-changes", + "resources", + "resources/glossary", + "security", + "security/hipaa-compliance", + "security/npm-security", + "security/platform-audit-logs", + "security/platform-security", + "security/product-security", + "security/security-testing", + "security/soc-2-compliance", + "self-hosting", + "self-hosting/copy-from-platform-s3", + "self-hosting/custom-email-templates", + "self-hosting/docker", + "self-hosting/enable-mcp", + "self-hosting/postgres-upgrade-17", + "self-hosting/remove-superuser-access", + "self-hosting/restore-from-platform", + "self-hosting/self-hosted-auth-keys", + "self-hosting/self-hosted-envoy", + "self-hosting/self-hosted-functions", + "self-hosting/self-hosted-oauth", + "self-hosting/self-hosted-phone-mfa", + "self-hosting/self-hosted-proxy-https", + "self-hosting/self-hosted-s3", + "self-hosting/self-hosted-saml-sso", + "storage", + "storage/analytics/connecting-to-analytics-bucket", + "storage/analytics/creating-analytics-buckets", + "storage/analytics/examples/apache-spark", + "storage/analytics/examples/duckdb", + "storage/analytics/examples/pyiceberg", + "storage/analytics/introduction", + "storage/analytics/limits", + "storage/analytics/pricing", + "storage/analytics/query-with-postgres", + "storage/buckets/creating-buckets", + "storage/buckets/fundamentals", + "storage/cdn/fundamentals", + "storage/cdn/metrics", + "storage/cdn/smart-cdn", + "storage/debugging/error-codes", + "storage/debugging/logs", + "storage/management/copy-move-objects", + "storage/management/delete-objects", + "storage/management/download-objects", + "storage/pricing", + "storage/production/scaling", + "storage/quickstart", + "storage/s3/authentication", + "storage/s3/compatibility", + "storage/schema/custom-roles", + "storage/schema/design", + "storage/schema/helper-functions", + "storage/security/access-control", + "storage/security/ownership", + "storage/serving/bandwidth", + "storage/serving/downloads", + "storage/serving/image-transformations", + "storage/uploads/file-limits", + "storage/uploads/resumable-uploads", + "storage/uploads/s3-uploads", + "storage/uploads/standard-uploads", + "storage/vector/creating-vector-buckets", + "storage/vector/introduction", + "storage/vector/limits", + "storage/vector/local-development", + "storage/vector/querying-vectors", + "storage/vector/storing-vectors", + "storage/vector/working-with-indexes", + "telemetry", + "telemetry/advanced-log-filtering", + "telemetry/client-side-tracing", + "telemetry/log-drains", + "telemetry/log-field-reference", + "telemetry/logs", + "telemetry/metrics", + "telemetry/metrics/grafana-cloud", + "telemetry/metrics/grafana-self-hosted", + "telemetry/metrics/vendor-agnostic", + "telemetry/reports", + "telemetry/sentry-monitoring", + "troubleshooting/42501--permission-denied-for-table-httprequestqueue-KnozmQ", + "troubleshooting/FWD-wrappers-error-component-verification-failed-94a76b", + "troubleshooting/all-about-supabase-egress-a_Sg_e", + "troubleshooting/an-invalid-response-was-received-from-the-upstream-server-error-when-querying-auth-RI4Vl-", + "troubleshooting/app-store-rejection-tls-error-in-ipv6-only-environments-4e9c62", + "troubleshooting/are-all-features-available-in-self-hosted-supabase-THPcqw", + "troubleshooting/auth-error-401-invalid-claim-missing-sub--AFwMR", + "troubleshooting/auth-error-503-authretryablefetcherror-51b88c", + "troubleshooting/auth-hooks-invalid-payload-when-anonymous-users-attempt-phone-changes-022c47", + "troubleshooting/autovacuum-stalled-due-to-inactive-replication-slot-d55aa2", + "troubleshooting/avoiding-timeouts-in-long-running-queries-6nmbdN", + "troubleshooting/canceling-statement-due-to-statement-timeout-581wFv", + "troubleshooting/cant-access-supabase-project-lovable-cloud", + "troubleshooting/certain-operations-are-too-complex-to-perform-directly-using-the-client-libraries-8JaphH", + "troubleshooting/change-email-associated-with-supabase-account-T5eHNT", + "troubleshooting/change-project-region-eWJo5Z", + "troubleshooting/check-usage-for-monthly-active-users-mau-MwZaBs", + "troubleshooting/cloudflare-origin-error-1016-on-custom-domain-a57af4", + "troubleshooting/converted-github-account-to-organisation---lost-supabase-account-access-5wsE_1", + "troubleshooting/customizing-emails-by-language-KZ_38Q", + "troubleshooting/dashboard-errors-when-managing-users-N1ls4A", + "troubleshooting/database-api-42501-errors", + "troubleshooting/database-error-remaining-connection-slots-are-reserved-for-non-replication-superuser-connections-3V3nIb", + "troubleshooting/database-error-saving-new-user-RU_EwB", + "troubleshooting/deprecated-rls-features-Pm77Zs", + "troubleshooting/disabling-prepared-statements-qL8lEL", + "troubleshooting/discovering-and-interpreting-api-errors-in-the-logs-7xREI9", + "troubleshooting/disk-size-not-shrinking-after-deleting-data-135390", + "troubleshooting/do-i-need-to-expose-security-definer-functions-in-row-level-security-policies-iI0uOw", + "troubleshooting/download-logical-backups", + "troubleshooting/edge-function-401-error-response", + "troubleshooting/edge-function-404-error-response", + "troubleshooting/edge-function-500-error-response", + "troubleshooting/edge-function-503-response", + "troubleshooting/edge-function-504-error-response", + "troubleshooting/edge-function-546-error-response", + "troubleshooting/edge-function-bundle-size-issues", + "troubleshooting/edge-function-cpu-limits", + "troubleshooting/edge-function-dependency-analysis", + "troubleshooting/edge-function-error-rate-limit-exceeded-for-trace-1094d3", + "troubleshooting/edge-function-fails-deploy", + "troubleshooting/edge-function-monitoring-resource-usage", + "troubleshooting/edge-function-shutdown-reasons-explained", + "troubleshooting/edge-function-takes-too-long-to-respond", + "troubleshooting/edge-function-wall-clock-time-limit-reached-Nk38bW", + "troubleshooting/edge-functions-worker-timeouts-and-websocket-drops", + "troubleshooting/email-password-login-disabled-supabase-vercel-marketplace-a7dd36", + "troubleshooting/email-template-not-updating", + "troubleshooting/enabling-ipv4-addon", + "troubleshooting/error-connection-refused-when-trying-to-connect-to-supabase-database-hwG0Dr", + "troubleshooting/error-index-row-size-exceeds-btree-version-4-maximum-for-index-LMmoeU", + "troubleshooting/error-invalid-byte-sequence-for-encoding-utf8-0x00-when-accessing-triggers-or-webhooks-e78cf8", + "troubleshooting/error-invalid-totp-code-entered-CukLCj", + "troubleshooting/error-no-pghbaconf-entry-for-host-xxxxxxxxxxx-user-postgres-database-postgres-ssl-off-GOt5Ja", + "troubleshooting/error-prepared-statement-xxx-already-exists-3laqeM", + "troubleshooting/error-target-organization-is-not-managed-by-vercel-marketplace-during-project-transfer-5262c3", + "troubleshooting/exhaust-disk-io", + "troubleshooting/exhaust-ram", + "troubleshooting/exhaust-swap", + "troubleshooting/failed-to-fetch-in-dashboard-and-other-areas----browser-extension-dyDTRU", + "troubleshooting/failed-to-restore-from-backup-all-subscriptions-and-replication-slots-must-be-dropped-before-a-backup-can-be-restored-L-rCvt", + "troubleshooting/failed-to-retrieve-tables", + "troubleshooting/failed-to-run-sql-query-connection-terminated-due-to-connection-timeout", + "troubleshooting/fetch-requests-to-api-endpoints-arent-showing-the-session-UbUwRs", + "troubleshooting/fixing-520-errors-in-the-database-rest-api-Ur5-B2", + "troubleshooting/forbidden-resource-error-from-the-cli-L6rm6l", + "troubleshooting/get-detailed-storage-metrics-with-the-aws-cli-587a7d", + "troubleshooting/google-auth-fails-for-some-users-XcFXEu", + "troubleshooting/grafana-not-displaying-data-sXJrMj", + "troubleshooting/high-cpu-and-slow-queries-with-error-must-be-a-superuser-to-terminate-superuser-process", + "troubleshooting/high-cpu-usage", + "troubleshooting/high-latency-with-supabase-client-z0pZzR", + "troubleshooting/how-can-i-revoke-execution-of-a-postgresql-function-2GYb0A", + "troubleshooting/how-do-i-check-gotrueapi-version-of-a-supabase-project-lQAnOR", + "troubleshooting/how-do-i-make-the-cookies-httponly-vwweFx", + "troubleshooting/how-do-i-reset-my-supabase-database-password-oTs5sB", + "troubleshooting/how-do-i-update-connection-pool-settings-in-my-dashboard-wAxTJ_", + "troubleshooting/how-do-you-troubleshoot-nextjs---supabase-auth-issues-riMCZV", + "troubleshooting/how-long-does-it-take-to-restore-a-database-from-a-point-in-time-backup-pitr-qO8gOG", + "troubleshooting/how-postgres-chooses-which-index-to-use-_JHrf4", + "troubleshooting/how-to-bypass-cooldown-period", + "troubleshooting/how-to-change-max-database-connections-_BQ8P5", + "troubleshooting/how-to-check-if-my-queries-are-being-blocked-by-other-queries-NSKtR1", + "troubleshooting/how-to-delete-a-role-in-postgres-8-AvxY", + "troubleshooting/how-to-delete-vercel-linked-projects-9d08aa", + "troubleshooting/how-to-interpret-and-explore-the-postgres-logs-OuCIOj", + "troubleshooting/how-to-migrate-from-supabase-auth-helpers-to-ssr-package-5NRunM", + "troubleshooting/how-to-view-database-metrics-uqf2z_", + "troubleshooting/http-api-issues", + "troubleshooting/http-status-codes", + "troubleshooting/i-am-not-receiving-password-reset-emails-for-supabase-dashboard--cO5yf", + "troubleshooting/identify-lovable-cloud-or-supabase-backend", + "troubleshooting/importing-stripe-or-other-modules-from-esmsh-on-deno-edge-functions-throws-an-error-TmbB5p", + "troubleshooting/increase-vector-lookup-speeds-by-applying-an-hsnw-index-ohLHUM", + "troubleshooting/inserting-into-sequenceserial-table-causes-duplicate-key-violates-unique-constraint-error-pi6DnC", + "troubleshooting/inspecting-edge-function-environment-variables-wg5qOQ", + "troubleshooting/insufficient-privilege-when-accessing-pgstatstatements-e5M_EQ", + "troubleshooting/interpreting-supabase-grafana-cpu-charts-9JSlkC", + "troubleshooting/interpreting-supabase-grafana-io-charts-MUynDR", + "troubleshooting/issues-serving-edge-functions-locally", + "troubleshooting/jwt-expired-error-in-supabase-dashboard-F06k3x", + "troubleshooting/keeping-free-projects-after-pro-upgrade-Kf9Xm2", + "troubleshooting/kong-stops-responding-under-heavy-load-locally", + "troubleshooting/lost-accessforgot-the-mfa-device-nAPT-7", + "troubleshooting/managing-or-disconnecting-github-oauth-connections-e3dc3b", + "troubleshooting/manually-created-databases-are-not-visible-in-the-supabase-dashboard-4415aa", + "troubleshooting/memory-and-swap-usage-explained-aPNgm0", + "troubleshooting/migrating-auth-users-between-projects", + "troubleshooting/monitor-supavisor-postgres-connections", + "troubleshooting/new-branch-doesnt-copy-database", + "troubleshooting/new-variable-is-null-in-a-trigger-function--l9AOZ", + "troubleshooting/nextjs-1314-stale-data-when-changing-rls-or-table-data-85b8oQ", + "troubleshooting/no-toast-messages-on-the-dashboard-BrvP8h", + "troubleshooting/not-receiving-auth-emails-from-the-supabase-project-OFSNzw", + "troubleshooting/oauth-sign-in-isnt-redirecting-on-the-server-side-ShGMtr", + "troubleshooting/otp-verification-failures-token-has-expired-or-otp_expired-errors-5ee4d0", + "troubleshooting/partitioning-an-existing-table-with-same-name-VEnbzK", + "troubleshooting/pausing-pro-projects-vNL-2a", + "troubleshooting/performing-administration-tasks-on-the-server-side-with-the-servicerole-secret-BYM4Fa", + "troubleshooting/pg_cron-launcher-crashes-with-duplicate-key-value-violates-unique-constraint-cc6472", + "troubleshooting/pgcron-debugging-guide-n1KTaz", + "troubleshooting/pgrst106-the-schema-must-be-one-of-the-following-error-when-querying-an-exposed-schema", + "troubleshooting/pkce-flow-errors-cannot-parse-response-or-zgotmplz-in-magic-link-emails-433665", + "troubleshooting/postgrest-error-400-column-example_tableexample_column-does-not-exist-when-using-or-operators-46ff23", + "troubleshooting/postgrest-error-pgrst002-could-not-query-the-database-for-the-schema-cache-c396e9", + "troubleshooting/postgrest-not-recognizing-new-columns-or-functions-bd75f5", + "troubleshooting/postgrest-not-recognizing-objects-in-schema", + "troubleshooting/powerbi-service-error-the-remote-certificate-is-invalid-according-to-the-validation-procedure-640a98", + "troubleshooting/prisma-error-management-Cm5P_o", + "troubleshooting/project-status-reports-unhealthy-services", + "troubleshooting/rclone-error-s3-protocol-error-received-listing-v1-with-istruncated-set-no-nextmarker-and-no-contents-e64d34", + "troubleshooting/realtime-concurrent-peak-connections-quota-jdDqcp", + "troubleshooting/realtime-connections-timed_out-status", + "troubleshooting/realtime-debugging-with-logger", + "troubleshooting/realtime-handling-silent-disconnections-in-backgrounded-applications-592794", + "troubleshooting/realtime-heartbeat-messages", + "troubleshooting/realtime-project-suspended-for-exceeding-quotas", + "troubleshooting/realtime-too-many-channels-error", + "troubleshooting/realtime-warn-sending-broadcast-message", + "troubleshooting/refresh-postgrest-schema", + "troubleshooting/relation-objects-does-not-exist-error-during-storage-uploads-8f21f0", + "troubleshooting/resolving-42p01-relation-does-not-exist-error-W4_9-V", + "troubleshooting/resolving-500-status-authentication-errors-7bU5U8", + "troubleshooting/resolving-cannot-execute-update-in-a-read-only-transaction-on-transaction-pooler-connections-ef582c", + "troubleshooting/resolving-database-hostname-and-managing-your-ip-address-pVlwE0", + "troubleshooting/restore-project-after-90-days-pause", + "troubleshooting/rls-performance-and-best-practices-Z5Jjwv", + "troubleshooting/rls-simplified-BJTcS8", + "troubleshooting/rotating-anon-service-and-jwt-secrets-1Jq6yd", + "troubleshooting/running-explain-analyze-on-functions", + "troubleshooting/scan-error-on-column-confirmation_token-converting-null-to-string-is-unsupported-during-auth-login-a0c686", + "troubleshooting/schema-pg_pgrst_no_exposed_schemas-does-not-exist", + "troubleshooting/security-of-anonymous-sign-ins-iOrGCL", + "troubleshooting/seeing-no-pghbaconf-entry-for-host-errors-in-postgres-and-they-come-from-an-ip-address-that-i-dont-recognize-4gds9f", + "troubleshooting/should-i-set-a-shorter-max-age-parameter-on-the-cookies-8sbF4V", + "troubleshooting/slow-execution-of-alter-table-on-large-table-when-changing-column-type-qmZRpZ", + "troubleshooting/soft-deletes-with-supabase-js", + "troubleshooting/sso-error-you-do-not-have-permissions-to-join-this-organization-or-prompts-to-create-new-organization", + "troubleshooting/steps-to-improve-query-performance-with-indexes-q8PoC9", + "troubleshooting/storage-error-403-forbidden-new-row-violates-row-level-security-policy-on-upload-a94384", + "troubleshooting/supabase--your-network-ipv4-and-ipv6-compatibility-cHe3BP", + "troubleshooting/supabase-cli-failed-sasl-auth-or-invalid-scram-server-final-message", + "troubleshooting/supabase-dashboard-not-loading-project-not-loading-on-dashboard-LfMq9F", + "troubleshooting/supabase-grafana-memory-charts", + "troubleshooting/supabase-project-provisioned-via-bolt-not-visible-in-dashboard-7188fc", + "troubleshooting/supabase-storage-inefficient-folder-operations-and-hierarchical-rls-challenges-b05a4d", + "troubleshooting/supavisor-and-connection-terminology-explained-9pr_ZO", + "troubleshooting/supavisor-error-circuit-breaker-open-after-password-rotation-0fdb72", + "troubleshooting/supavisor-faq-YyP5tI", + "troubleshooting/too-many-connections-for-database-postgres", + "troubleshooting/tracking-postgres-role-activity-to-specific-dashboard-users-8d3715", + "troubleshooting/transfer-edge-function-from-one-project-to-another", + "troubleshooting/transferring-from-cloud-to-self-host-in-supabase-2oWNvW", + "troubleshooting/troubleshooting-connect_timeout-or-hanging-queries-in-vercel-serverless-functions-775f92", + "troubleshooting/unable-to-call-edge-function", + "troubleshooting/unable-to-deploy-edge-function", + "troubleshooting/understanding-postgresql-explain-output-Un9dqX", + "troubleshooting/understanding-postgresql-logging-levels-and-how-they-impact-your-project-KXiJRm", + "troubleshooting/understanding-the-usage-summary-on-the-dashboard-D7Gnle", + "troubleshooting/unexpected-behavior-with-authupdateuser-phone-phone-linked-to-incorrect-user-id-45368f", + "troubleshooting/unused-external-import-warning-vite-rollup", + "troubleshooting/upload-file-size-restrictions-Y4wQLT", + "troubleshooting/using-google-smtp-with-supabase-custom-smtp-ZZzU4Y", + "troubleshooting/using-sqlalchemy-with-supabase-FUqebT", + "troubleshooting/vercel-integration-environment-variables-not-syncing-for-persistent-git-branches-b9191e", + "troubleshooting/webhook-debugging-guide-M8sk47", + "troubleshooting/why-am-i-being-redirected-to-the-wrong-url-when-using-auth-redirectto-option-_vqIeO", + "troubleshooting/why-are-there-gaps-in-my-postgres-id-sequence-Frifus", + "troubleshooting/why-cant-i-uploadlistetc-my-public-bucket-Z6CmGt", + "troubleshooting/why-do-i-see-auth--api-requests-in-the-dashboard-my-app-has-no-users-CyadiO", + "troubleshooting/why-is-my-camelcase-name-not-working-in-postgres-functions-or-rls-policies-EJMzVd", + "troubleshooting/why-is-my-select-returning-an-empty-data-array-and-i-have-data-in-the-table-xvOPgx", + "troubleshooting/why-is-my-service-role-key-client-getting-rls-errors-or-not-returning-data-7_1K9z", + "troubleshooting/why-is-my-supabase-api-call-not-returning-PGzXw0", + "troubleshooting/why-supabase-edge-functions-cannot-provide-static-egress-ips-for-whitelisting-3d78b0", + "troubleshooting/will-backups-be-accessible-from-the-dashboard-immediately-after-upgrading-to-a-paid-plan-hXY4rs" +] diff --git a/apps/docs/middleware.ts b/apps/docs/middleware.ts index 42817c237c7..8c534018604 100644 --- a/apps/docs/middleware.ts +++ b/apps/docs/middleware.ts @@ -1,11 +1,13 @@ import { clientSdkIds } from '~/content/navigation.references' import { BASE_PATH } from '~/lib/constants' +import { MARKDOWN_SLUGS } from '~/lib/markdown-manifest' import { negotiateMarkdown } from 'common/markdown-negotiation' import { isbot } from 'isbot' import { NextResponse, type NextRequest } from 'next/server' const REFERENCE_PATH = `${BASE_PATH ?? ''}/reference` const GUIDES_PATH = `${BASE_PATH ?? ''}/guides` +const GUIDES_MARKDOWN_SLUGS = new Set(MARKDOWN_SLUGS) export function middleware(request: NextRequest) { const url = new URL(request.url) @@ -19,7 +21,7 @@ export function middleware(request: NextRequest) { acceptHeader: request.headers.get('accept') ?? '', userAgent: request.headers.get('user-agent') ?? '', }, - { hasMarkdownVariant: true, isMarkdownSuffix: isMdSuffix } + { hasMarkdownVariant: GUIDES_MARKDOWN_SLUGS.has(slug), isMarkdownSuffix: isMdSuffix } ) if (decision === 'not-acceptable') { diff --git a/apps/docs/package.json b/apps/docs/package.json index 1a16180205f..089a1114267 100644 --- a/apps/docs/package.json +++ b/apps/docs/package.json @@ -10,6 +10,8 @@ "prebuild:reference-markdown": "pnpm run codegen:references", "build:reference-markdown": "tsx ./internals/generate-reference-markdown.ts", "build:markdown": "pnpm build:guides-markdown && pnpm build:reference-markdown", + "build:markdown-manifest": "tsx ./internals/generate-markdown-manifest.ts", + "check:markdown-manifest": "tsx ./internals/generate-markdown-manifest.ts --check", "build:gz-archive": "tsx ./internals/generate-gz-archive.ts", "build:sitemap": "tsx ./internals/generate-sitemap.ts", "clean": "rimraf .next .turbo node_modules features/docs/generated examples __generated__", @@ -32,13 +34,13 @@ "lint": "eslint .", "lint:mdx": "supa-mdx-lint content --config ../../supa-mdx-lint.config.toml", "postbuild": "pnpm run build:sitemap && ./../../scripts/upload-static-assets.sh", - "prebuild": "pnpm run codegen:graphql && pnpm run codegen:references && pnpm run codegen:examples && pnpm run build:markdown && pnpm run build:gz-archive", - "predev": "pnpm run codegen:graphql && pnpm run codegen:references && pnpm run codegen:examples", + "prebuild": "pnpm run codegen:graphql && pnpm run codegen:references && pnpm run codegen:examples && pnpm run build:markdown && pnpm run build:markdown-manifest && pnpm run build:gz-archive", + "predev": "pnpm run codegen:graphql && pnpm run codegen:references && pnpm run codegen:examples && pnpm run build:markdown-manifest", "preembeddings": "pnpm run codegen:references", "preinstall": "npx only-allow pnpm", "presync": "pnpm run codegen:graphql", "pretest": "pnpm run codegen:examples", - "pretypecheck": "pnpm run codegen:graphql && next typegen", + "pretypecheck": "pnpm run codegen:graphql && pnpm run build:markdown-manifest && next typegen", "start": "next start", "sync": "tsx --conditions=react-server ./resources/rootSync.ts", "test": "pnpm supabase start && pnpm run test:local && pnpm supabase stop",