mirror of
https://github.com/supabase/supabase.git
synced 2026-09-22 13:37:53 +08:00
028e05205b
Warn that default signOut scope revokes all sessions. Motivation: https://github.com/supabase/ssr/issues/68 <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Documentation** * Clarified that signing out without a specified scope ends all sessions by default. * Added guidance for using a local sign-out scope to preserve sessions on other devices and browsers. * Documented the invalid refresh token errors that may occur when other sessions are revoked. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
78 lines
2.3 KiB
TypeScript
78 lines
2.3 KiB
TypeScript
import type { Page } from '@playwright/test'
|
|
|
|
export const GUIDE_ARTICLE_SELECTOR = '[data-testid="sb-docs-guide-main-article"]'
|
|
export const TROUBLESHOOTING_ARTICLE_SELECTOR =
|
|
'[data-testid="sb-docs-troubleshooting-main-article"]'
|
|
const DOCS_PATH_PREFIX = '/docs'
|
|
const TROUBLESHOOTING_PATH_PREFIX = '/docs/guides/troubleshooting/'
|
|
|
|
export function articleSelectorForPagePath(pagePath: string): string {
|
|
const pathname = pagePath.startsWith('http') ? new URL(pagePath).pathname : pagePath
|
|
|
|
if (
|
|
pathname === TROUBLESHOOTING_PATH_PREFIX.slice(0, -1) ||
|
|
pathname.startsWith(TROUBLESHOOTING_PATH_PREFIX)
|
|
) {
|
|
return TROUBLESHOOTING_ARTICLE_SELECTOR
|
|
}
|
|
|
|
return GUIDE_ARTICLE_SELECTOR
|
|
}
|
|
|
|
export async function collectDocsOwnedLinks(
|
|
page: Page,
|
|
baseURL: string,
|
|
articleSelector: string = GUIDE_ARTICLE_SELECTOR
|
|
): Promise<string[]> {
|
|
const origin = new URL(baseURL).origin
|
|
const hrefs = await page
|
|
.locator(`${articleSelector} a[href]`)
|
|
.evaluateAll((anchors) =>
|
|
anchors.map((anchor) => (anchor as HTMLAnchorElement).getAttribute('href') ?? '')
|
|
)
|
|
const links = new Set<string>()
|
|
|
|
for (const href of hrefs) {
|
|
if (!href || href.startsWith('#')) continue
|
|
|
|
let url: URL
|
|
try {
|
|
url = new URL(href, baseURL)
|
|
} catch {
|
|
continue
|
|
}
|
|
|
|
if (!['http:', 'https:'].includes(url.protocol)) continue
|
|
if (url.origin !== origin) continue
|
|
if (url.pathname !== DOCS_PATH_PREFIX && !url.pathname.startsWith(`${DOCS_PATH_PREFIX}/`)) {
|
|
continue
|
|
}
|
|
|
|
url.hash = ''
|
|
links.add(url.toString())
|
|
}
|
|
|
|
return [...links].sort()
|
|
}
|
|
|
|
export type LinkCheckResult = {
|
|
ok: boolean
|
|
status: number
|
|
error?: string
|
|
}
|
|
|
|
// The docs middleware rewrites /reference/* requests whose user agent looks like a bot
|
|
// (isbot, which matches HeadlessChrome) to /api/crawlers. Fetching from inside the page
|
|
// keeps the browser's own user agent and network stack, so a link resolves the same way
|
|
// page.goto resolves it in this suite.
|
|
export async function checkLinkFromBrowser(page: Page, url: string): Promise<LinkCheckResult> {
|
|
return page.evaluate(async (linkUrl) => {
|
|
try {
|
|
const response = await fetch(linkUrl)
|
|
return { ok: response.ok, status: response.status }
|
|
} catch (error) {
|
|
return { ok: false, status: 0, error: error instanceof Error ? error.message : String(error) }
|
|
}
|
|
}, url)
|
|
}
|