mirror of
https://github.com/supabase/supabase.git
synced 2026-10-05 09:25:06 +03:00
refactor: move /incident-status to app router (#43881)
## I have read the [CONTRIBUTING.md](https://github.com/supabase/supabase/blob/master/CONTRIBUTING.md) file. YES ## What kind of change does this PR introduce? Refactor ## What is the current behavior? `/incident-status` is handled via Pages Router. ## What is the new behavior? `/incident-status` is handled via App Router, enabling use of Vercel Data Cache to cache the upstream fetch. ## Additional context Adding the first App Router route handler triggered `next typegen` (run as `pretypecheck`) to generate `.next/dev/types/validator.ts`, which imports all route files and expanded the type-checked graph. This surfaced pre-existing `null`-safety errors in: - `components/grid/SupabaseGrid.utils.ts` — `useSearchParams()` result - `components/layouts/ProjectLayout/UpgradingState/index.tsx` — `useSearchParams()` result - `pages/project/[ref]/sql/quickstarts.tsx` — `useParams()` result - `pages/project/[ref]/sql/templates.tsx` — `useParams()` result These are fixed with optional chaining. The `tsconfig.json` change (adding `.next/dev/types/**/*.ts` to `include`) is auto-generated by Next.js and committed as correct behavior.
This commit is contained in:
1 parent
65237597e4
commit
a4641d0b9f
7 files changed
+37
-31
No files matched your search
+28
-22
@@ -1,5 +1,5 @@
|
||||
import { IS_PLATFORM } from 'common'
|
||||
import { NextApiRequest, NextApiResponse } from 'next'
|
||||
import { NextResponse } from 'next/server'
|
||||
|
||||
import { InternalServerError } from '@/lib/api/apiHelpers'
|
||||
import { getActiveIncidents, type IncidentCache } from '@/lib/api/incident-status'
|
||||
@@ -42,22 +42,26 @@ async function fetchIncidentCache(incidentIds: Array<string>): Promise<Map<strin
|
||||
return cacheMap
|
||||
}
|
||||
|
||||
async function handler(req: NextApiRequest, res: NextApiResponse) {
|
||||
if (!IS_PLATFORM) {
|
||||
return res.status(404).end()
|
||||
}
|
||||
export async function OPTIONS() {
|
||||
if (!IS_PLATFORM) return new Response(null, { status: 404 })
|
||||
return new Response(null, {
|
||||
status: 204,
|
||||
headers: {
|
||||
Allow: 'GET, HEAD, OPTIONS',
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
const { method } = req
|
||||
export async function HEAD() {
|
||||
if (!IS_PLATFORM) return new Response(null, { status: 404 })
|
||||
return new Response(null, {
|
||||
status: 200,
|
||||
headers: { 'Cache-Control': CACHE_CONTROL_SETTINGS },
|
||||
})
|
||||
}
|
||||
|
||||
if (method === 'HEAD') {
|
||||
res.setHeader('Cache-Control', CACHE_CONTROL_SETTINGS)
|
||||
return res.status(200).end()
|
||||
}
|
||||
|
||||
if (method !== 'GET') {
|
||||
res.setHeader('Allow', ['GET', 'HEAD'])
|
||||
return res.status(405).json({ error: `Method ${method} Not Allowed` })
|
||||
}
|
||||
export async function GET() {
|
||||
if (!IS_PLATFORM) return new Response(null, { status: 404 })
|
||||
|
||||
try {
|
||||
const allIncidents = await getActiveIncidents()
|
||||
@@ -75,17 +79,18 @@ async function handler(req: NextApiRequest, res: NextApiResponse) {
|
||||
cache: cacheMap.get(incident.id) ?? null,
|
||||
}))
|
||||
|
||||
res.setHeader('Cache-Control', CACHE_CONTROL_SETTINGS)
|
||||
|
||||
return res.status(200).json(enrichedIncidents)
|
||||
return NextResponse.json(enrichedIncidents, {
|
||||
headers: { 'Cache-Control': CACHE_CONTROL_SETTINGS },
|
||||
})
|
||||
} catch (error) {
|
||||
let errorCode = 500
|
||||
const headers = new Headers()
|
||||
|
||||
if (error instanceof InternalServerError) {
|
||||
if (typeof error.details?.status === 'number') errorCode = error.details.status
|
||||
if (errorCode === 420) errorCode = 429
|
||||
if (errorCode === 429 && typeof error.details?.retryAfter === 'string') {
|
||||
res.setHeader('Retry-After', error.details.retryAfter)
|
||||
headers.set('Retry-After', error.details.retryAfter)
|
||||
}
|
||||
console.error('Failed to fetch active StatusPage incidents: %O', {
|
||||
message: error.message,
|
||||
@@ -95,8 +100,9 @@ async function handler(req: NextApiRequest, res: NextApiResponse) {
|
||||
console.error('Unexpected error fetching active StatusPage incidents: %O', error)
|
||||
}
|
||||
|
||||
return res.status(errorCode).json({ error: 'Unable to fetch incidents at this time' })
|
||||
return NextResponse.json(
|
||||
{ error: 'Unable to fetch incidents at this time' },
|
||||
{ status: errorCode, headers }
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
export default handler
|
||||
@@ -242,8 +242,8 @@ export function useSyncTableEditorStateFromLocalStorageWithUrl({
|
||||
// Use nextjs useSearchParams to get the latest URL params
|
||||
const searchParams = useSearchParams()
|
||||
const urlParams = useMemo(() => {
|
||||
const sort = searchParams.getAll('sort')
|
||||
const filter = searchParams.getAll('filter')
|
||||
const sort = searchParams?.getAll('sort') ?? []
|
||||
const filter = searchParams?.getAll('filter') ?? []
|
||||
return { sort, filter }
|
||||
}, [searchParams])
|
||||
|
||||
|
||||
@@ -36,7 +36,7 @@ export const UpgradingState = () => {
|
||||
{
|
||||
projectRef: ref,
|
||||
projectStatus: project?.status,
|
||||
trackingId: queryParams.get('trackingId'),
|
||||
trackingId: queryParams?.get('trackingId'),
|
||||
},
|
||||
{
|
||||
enabled: IS_PLATFORM,
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import z from 'zod'
|
||||
|
||||
import { IS_PLATFORM } from 'common'
|
||||
import { InternalServerError } from 'lib/api/apiHelpers'
|
||||
import z from 'zod'
|
||||
|
||||
export type IncidentCache = {
|
||||
affected_regions: Array<string> | null
|
||||
@@ -81,7 +80,7 @@ export async function getActiveIncidents(): Promise<IncidentInfo[]> {
|
||||
Accept: 'application/json',
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
cache: 'no-store',
|
||||
next: { revalidate: 180 },
|
||||
signal: AbortSignal.timeout(30_000),
|
||||
})
|
||||
const responseText = await response.text()
|
||||
|
||||
@@ -12,7 +12,7 @@ import type { NextPageWithLayout } from 'types'
|
||||
|
||||
const SqlQuickstarts: NextPageWithLayout = () => {
|
||||
const router = useRouter()
|
||||
const { ref } = useParams<{ ref: string }>()
|
||||
const ref = useParams<{ ref: string }>()?.ref
|
||||
const tabs = useTabsStateSnapshot()
|
||||
|
||||
useEffect(() => {
|
||||
|
||||
@@ -12,7 +12,7 @@ import type { NextPageWithLayout } from 'types'
|
||||
|
||||
const SqlTemplates: NextPageWithLayout = () => {
|
||||
const router = useRouter()
|
||||
const { ref } = useParams<{ ref: string }>()
|
||||
const ref = useParams<{ ref: string }>()?.ref
|
||||
const tabs = useTabsStateSnapshot()
|
||||
|
||||
useEffect(() => {
|
||||
|
||||
@@ -36,7 +36,8 @@
|
||||
"**/*.js",
|
||||
"**/*.jsx",
|
||||
".next/types/**/*.ts",
|
||||
"./../../packages/ui/src/**/*.d.ts"
|
||||
"./../../packages/ui/src/**/*.d.ts",
|
||||
".next/dev/types/**/*.ts"
|
||||
],
|
||||
"exclude": ["node_modules", "public/deno/*.ts"]
|
||||
}
|
||||
Reference in new issue
Block a user