diff --git a/apps/docs/app/guides/database/extensions/wrappers/[[...slug]]/page.tsx b/apps/docs/app/guides/database/extensions/wrappers/[[...slug]]/page.tsx index d7cb4b25678..ebafbd690b7 100644 --- a/apps/docs/app/guides/database/extensions/wrappers/[[...slug]]/page.tsx +++ b/apps/docs/app/guides/database/extensions/wrappers/[[...slug]]/page.tsx @@ -15,7 +15,7 @@ import { linkTransform, type UrlTransformFunction } from '~/lib/mdx/plugins/rehy import remarkMkDocsAdmonition from '~/lib/mdx/plugins/remarkAdmonition' import { removeTitle } from '~/lib/mdx/plugins/remarkRemoveTitle' import remarkPyMdownTabs from '~/lib/mdx/plugins/remarkTabs' -import { getGitHubFileContents } from '~/lib/octokit' +import { getGitHubFileContents, octokit } from '~/lib/octokit' import type { SerializeOptions } from '~/types/next-mdx-remote-serialize' import { isFeatureEnabled } from 'common' import matter from 'gray-matter' @@ -29,10 +29,62 @@ import { Admonition } from 'ui-patterns' // We fetch these docs at build time from an external repo const org = 'supabase' const repo = 'wrappers' -const branch = 'main' const docsDir = 'docs/catalog' const externalSite = 'https://supabase.github.io/wrappers' +type DocsTagsQueryResponse = { + repository: { + refs: { + nodes: { name: string }[] | null + pageInfo: { hasNextPage: boolean; endCursor: string | null } + } + } +} + +const docsTagsQuery = ` + query DocsTagsQuery($owner: String!, $name: String!, $after: String) { + repository(owner: $owner, name: $name) { + refs( + refPrefix: "refs/tags/", + orderBy: { field: TAG_COMMIT_DATE, direction: DESC }, + first: 5, + after: $after + ) { + nodes { name } + pageInfo { hasNextPage endCursor } + } + } + } +` + +async function getLatestDocsTag(after: string | null = null): Promise { + try { + /** + * We use GraphQL as it's the only way to use `orderBy` on Github API. + */ + const { + repository: { + refs: { + nodes, + pageInfo: { hasNextPage, endCursor }, + }, + }, + } = await octokit().graphql(docsTagsQuery, { + owner: org, + name: repo, + after, + }) + + return ( + nodes?.find(({ name }) => /^docs_v\d+\.\d+\.\d+/.test(name))?.name ?? + (hasNextPage && endCursor ? await getLatestDocsTag(endCursor) : null) + ) + } catch (error) { + console.error(`Error fetching docs tags for wrappers federated pages: ${error}`) + return null + } +} + // Each external docs page is mapped to a local page const pageMap = [ { @@ -378,16 +430,22 @@ const getContent = async (params: Params) => { let remoteFile: string ;({ remoteFile, meta } = federatedPage) - editLink = `${org}/${repo}/blob/${branch}/${docsDir}/${remoteFile}` + const tag = await getLatestDocsTag() + + if (!tag) { + throw new Error('No latest docs tag found for federated wrappers pages') + } + + editLink = `${org}/${repo}/blob/${tag}/${docsDir}/${remoteFile}` let rawContent = await getGitHubFileContents({ org, repo, path: `${docsDir}/${remoteFile}`, - branch, + branch: tag, }) - assetsBaseUrl = `https://raw.githubusercontent.com/${org}/${repo}/${branch}/docs/assets/` + assetsBaseUrl = `https://raw.githubusercontent.com/${org}/${repo}/${tag}/docs/assets/` const { content: contentWithoutFrontmatter } = matter(rawContent) content = removeRedundantH1(contentWithoutFrontmatter)