Files
supabase/apps/docs/app/guides/database/database-advisors/page.tsx
T
Ivan Vasilov 56de26fe22 chore: Migrate the monorepo to use Tailwind v4 (#45318)
This PR migrates the whole monorepo to use Tailwind v4:
- Removed `@tailwindcss/container-queries` plugin since it's included by
default in v4,
- Bump all instances of Tailwind to v4. Made minimal changes to the
shared config to remove non-supported features (`alpha` mentions),
- Migrate all apps to be compatible with v4 configs,
- Fix the `typography.css` import in 3 apps,
- Add missing rules which were included by default in v3,
- Run `pnpm dlx @tailwindcss/upgrade` on all apps, which renames a lot
of classes
- Rename all misnamed classes according to
https://tailwindcss.com/docs/upgrade-guide#renamed-utilities in all
apps.

---------

Co-authored-by: Jordi Enric <jordi.err@gmail.com>
2026-04-30 10:53:24 +00:00

187 lines
6.2 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { capitalize } from 'lodash-es'
import rehypeSlug from 'rehype-slug'
import { Heading } from 'ui'
import { Admonition } from 'ui-patterns'
import { GuideTemplate, newEditLink } from '~/features/docs/GuidesMdx.template'
import { genGuideMeta } from '~/features/docs/GuidesMdx.utils'
import { MDXRemoteBase } from '~/features/docs/MdxBase'
import { OCTOKIT_RETRY_OPTIONS, getGitHubFileContents, octokit } from '~/lib/octokit'
import { TabPanel, Tabs } from '~/features/ui/Tabs'
import { UrlTransformFunction, linkTransform } from '~/lib/mdx/plugins/rehypeLinkTransform'
import remarkMkDocsAdmonition from '~/lib/mdx/plugins/remarkAdmonition'
import { removeTitle } from '~/lib/mdx/plugins/remarkRemoveTitle'
import remarkPyMdownTabs from '~/lib/mdx/plugins/remarkTabs'
import { SerializeOptions } from '~/types/next-mdx-remote-serialize'
// We fetch these docs at build time from an external repo
const org = 'supabase'
const repo = 'splinter'
const branch = 'main'
const docsDir = 'docs'
const meta = {
title: 'Performance and Security Advisors',
subtitle: 'Check your database for performance and security issues',
}
const generateMetadata = genGuideMeta(() => ({
pathname: '/guides/database/database-linter',
meta,
}))
const editLink = newEditLink('supabase/splinter/tree/main/docs')
const markdownIntro = `
You can use the Database Performance and Security Advisors to check your database for issues such as missing indexes and improperly set-up RLS policies.
## Using the Advisors
In the dashboard, navigate to [Security Advisor](https://supabase.com/dashboard/project/_/database/security-advisor) and [Performance Advisor](https://supabase.com/dashboard/project/_/database/performance-advisor) under Database. The advisors run automatically. You can also manually rerun them after you've resolved issues.
`.trim()
const getBasename = (path: string) => path.split('/').at(-1)!.replace(/\.md$/, '')
const DatabaseAdvisorDocs = async () => {
let lints: Awaited<ReturnType<typeof getLints>>['lints'] = []
let lintsList: Awaited<ReturnType<typeof getLints>>['lintsList'] = []
let fetchError: Error | null = null
try {
const data = await getLints()
lints = data.lints
lintsList = data.lintsList
} catch (error) {
fetchError = error instanceof Error ? error : new Error('Unknown error fetching advisor docs')
console.error('[database-advisors] Failed to fetch advisor docs from GitHub', fetchError)
}
const options = {
mdxOptions: {
remarkPlugins: [remarkMkDocsAdmonition, remarkPyMdownTabs, [removeTitle, meta.title]],
rehypePlugins: [[linkTransform, urlTransform(lintsList)], rehypeSlug],
},
} as SerializeOptions
return (
<GuideTemplate meta={meta} editLink={editLink}>
<MDXRemoteBase source={markdownIntro} />
<Heading tag="h2">Available checks</Heading>
{fetchError ? (
<Admonition type="note" title="Couldnt load the full Advisor library">
We fetch remediation guides straight from the <code>supabase/splinter</code> repository
during the build. GitHub timed out just now, so were showing the overview only.
<br />
<br />
You can check back in a few minutes or browse the
{` `}
<a
className="underline decoration-dashed underline-offset-2"
href="https://github.com/supabase/splinter/tree/main/docs"
target="_blank"
rel="noreferrer"
>
latest Markdown on GitHub (opens in a new tab)
</a>
.
</Admonition>
) : (
<Tabs listClassNames="flex flex-wrap gap-2 [&>button]:m-0!" queryGroup="lint">
{lints.map((lint) => (
<TabPanel
key={lint.path}
id={lint.path}
label={capitalize(getBasename(lint.path).replace(/_/g, ' '))}
>
<section id={getBasename(lint.path)}>
<MDXRemoteBase source={lint.content} options={options} />
</section>
</TabPanel>
))}
</Tabs>
)}
</GuideTemplate>
)
}
/**
* The GitHub repo uses relative links, which don't lead to the right locations
* in docs.
*
* @param url The original link, as written in the Markdown file
* @returns The rewritten link
*/
const urlTransform: (lints: Array<{ path: string }>) => UrlTransformFunction = (lints) => (url) => {
try {
const placeholderHostname = 'placeholder'
const { hostname, pathname, hash } = new URL(url, `http://${placeholderHostname}`)
// Don't modify a url with a FQDN or a url that's only a hash
if (hostname !== placeholderHostname || pathname === '/') {
return url
}
const relativePath = getBasename(pathname)
const section = lints.find(({ path }) => path === relativePath)
if (section) {
const url = new URL(window.location.href)
url.searchParams.set('lint', relativePath)
return url.toString()
}
// If we don't have this page in our docs, link to GitHub repo
return `https://github.com/${org}/${repo}/blob/${branch}${pathname}${hash}`
} catch (err) {
console.error('Error transforming markdown URL', err)
return url
}
}
/**
* Fetch lint remediation Markdown from external repo
*/
const getLints = async () => {
const response = await octokit().request('GET /repos/{owner}/{repo}/contents/{path}', {
owner: org,
repo: repo,
path: docsDir,
ref: branch,
headers: {
'X-GitHub-Api-Version': '2022-11-28',
},
request: OCTOKIT_RETRY_OPTIONS,
})
if (response.status >= 400) {
throw new Error(
`Failed to fetch ${org}/${repo}/contents/${docsDir} docs from GitHub: ${response.status}`
)
}
if (!Array.isArray(response.data)) {
throw Error(
'Reading a directory, not a file. Should not reach this, solely to appease Typescript.'
)
}
const lintsList = response.data.filter(({ path }) => /docs\/\d+.+\.md$/.test(path))
const lints = await Promise.all(
lintsList.map(async ({ path }) => {
const content = await getGitHubFileContents({ org, repo, path, branch })
return {
path: getBasename(path),
content,
}
})
)
return { lints, lintsList }
}
export default DatabaseAdvisorDocs
export { generateMetadata }