| 
 | 1 | +import { NextResponse } from 'next/server'  | 
 | 2 | +import type { NextRequest } from 'next/server'  | 
 | 3 | +import docsConfig from '../docs.config.js'  | 
 | 4 | + | 
 | 5 | +const { updatedRedirectsData } = require('./data/redirects.ts');  | 
 | 6 | + | 
 | 7 | +function createRedirectUrl(request: NextRequest, destination: string, path: string): string {  | 
 | 8 | +  // Handle absolute URLs  | 
 | 9 | +  if (destination.startsWith('http')) {  | 
 | 10 | +    // Handle dynamic slug replacements  | 
 | 11 | +    if (destination.includes(':slug')) {  | 
 | 12 | +      const slugMatch = path.match(/[^/]+$/)  | 
 | 13 | +      const slug = slugMatch ? slugMatch[0] : ''  | 
 | 14 | +      destination = destination.replace(':slug*', slug)  | 
 | 15 | +    }  | 
 | 16 | +    // Handle version replacements  | 
 | 17 | +    if (destination.includes(':version')) {  | 
 | 18 | +      const versionMatch = path.match(/\d+\.\d+/)  | 
 | 19 | +      const version = versionMatch ? versionMatch[0] : ''  | 
 | 20 | +      destination = destination.replace(':version', version)  | 
 | 21 | +    }  | 
 | 22 | + | 
 | 23 | +    return destination  | 
 | 24 | +  }  | 
 | 25 | + | 
 | 26 | +  // Handle relative paths  | 
 | 27 | +  const basePath = '/docs'  | 
 | 28 | +  return destination.startsWith('/') ?   | 
 | 29 | +    `${request.nextUrl.origin}${basePath}${destination}` :   | 
 | 30 | +    `${request.nextUrl.origin}${basePath}/${destination}`  | 
 | 31 | +}  | 
 | 32 | + | 
 | 33 | +export function middleware(request: NextRequest) {  | 
 | 34 | +  const path = request.nextUrl.pathname  | 
 | 35 | +  const pathWithoutBase = path.replace('/docs', '')  | 
 | 36 | + | 
 | 37 | +  // Handle base redirects from redirects.ts  | 
 | 38 | +  const redirect = updatedRedirectsData.find((r: any) => r.source === pathWithoutBase)  | 
 | 39 | +  if (redirect) {  | 
 | 40 | +    return NextResponse.redirect(createRedirectUrl(request, redirect.destination, path))  | 
 | 41 | +  }  | 
 | 42 | +  // Handle version without slug  | 
 | 43 | +  const versionOnlyMatch = pathWithoutBase.match(/^\/v\/(\d+\.\d+)$/)  | 
 | 44 | +  if (versionOnlyMatch) {  | 
 | 45 | +    return NextResponse.redirect(`https://${versionOnlyMatch[1]}.sourcegraph.com/`)  | 
 | 46 | +  }  | 
 | 47 | +  // Handle version-specific redirects  | 
 | 48 | +  if (pathWithoutBase.startsWith(`/v/${docsConfig.DOCS_LATEST_VERSION}/`)) {  | 
 | 49 | +    return NextResponse.redirect(createRedirectUrl(  | 
 | 50 | +      request,  | 
 | 51 | +      `https://sourcegraph.com/docs/:slug*`,  | 
 | 52 | +      pathWithoutBase  | 
 | 53 | +    ))  | 
 | 54 | +  }  | 
 | 55 | +  if (pathWithoutBase.startsWith(`/@${docsConfig.DOCS_LATEST_VERSION}/`)) {  | 
 | 56 | +    return NextResponse.redirect(createRedirectUrl(  | 
 | 57 | +      request,  | 
 | 58 | +      `https://sourcegraph.com/docs/:slug*`,  | 
 | 59 | +      pathWithoutBase  | 
 | 60 | +    ))  | 
 | 61 | +  }  | 
 | 62 | +  const versionMatch = pathWithoutBase.match(/^\/v\/(\d+\.\d+)\/(.*)/)  | 
 | 63 | +  if (versionMatch) {  | 
 | 64 | +    return NextResponse.redirect(createRedirectUrl(  | 
 | 65 | +      request,  | 
 | 66 | +      'https://:version.sourcegraph.com/:slug*',  | 
 | 67 | +      pathWithoutBase  | 
 | 68 | +    ))  | 
 | 69 | +  }  | 
 | 70 | +  const atVersionMatch = pathWithoutBase.match(/^\/@(\d+\.\d+)\/(.*)/)  | 
 | 71 | +  if (atVersionMatch) {  | 
 | 72 | +    return NextResponse.redirect(createRedirectUrl(  | 
 | 73 | +      request,  | 
 | 74 | +      'https://:version.sourcegraph.com/:slug*',  | 
 | 75 | +      pathWithoutBase  | 
 | 76 | +    ))  | 
 | 77 | +  }  | 
 | 78 | +  if (pathWithoutBase === '/changelog.rss')   | 
 | 79 | +    return NextResponse.redirect(createRedirectUrl(request, '/technical-changelog.rss', path))  | 
 | 80 | + | 
 | 81 | +  return NextResponse.next()  | 
 | 82 | +}  | 
 | 83 | + | 
 | 84 | +export const config = {  | 
 | 85 | +  matcher: [  | 
 | 86 | +    '/((?!api|_next/static|_next/image|assets|favicon.ico|sw.js).*)',  | 
 | 87 | +  ],  | 
 | 88 | +}  | 
0 commit comments