Repository navigation
Expand file tree
/
Copy pathproxy.ts
More file actions
138 lines (122 loc) · 3.84 KB
/
Copy pathproxy.ts
File metadata and controls
138 lines (122 loc) · 3.84 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
import type {NextRequest} from 'next/server';
import {NextResponse} from 'next/server';
import docsConfig from '../docs.config.js';
import {TECHNICAL_CHANGELOG_RSS_URL} from './data/constants';
import {updatedRedirectsData} from './data/redirects';
function createRedirectUrl(
request: NextRequest,
destination: string,
path: string
): string {
// Handle absolute URLs
if (destination.startsWith('http')) {
// Extract version and full path after version
const versionMatch = path.match(/(?:\/v\/|@)(\d+\.\d+)\/(.*)/);
if (versionMatch) {
// Pass the path through unchanged: each versioned site carries the
// redirects that were current for its version, and applying this
// branch's redirects.ts here sends old versions to pages that did not
// exist yet.
return destination
.replace(':version', versionMatch[1])
.replace(':slug*', versionMatch[2]);
}
// Handle other cases as before
if (destination.includes(':slug')) {
const slugMatch = path.match(/[^/]+$/);
const slug = slugMatch ? slugMatch[0] : '';
destination = destination.replace(':slug*', slug);
}
return destination;
}
// Handle relative paths. basePath is '/docs' on sourcegraph.com/docs and
// '' on the X.Y.sourcegraph.com deployments (see next.config.js).
const {origin, basePath} = request.nextUrl;
return destination.startsWith('/')
? `${origin}${basePath}${destination}`
: `${origin}${basePath}/${destination}`;
}
export function proxy(request: NextRequest) {
const path = request.nextUrl.pathname;
const pathWithoutBase = path.replace('/docs', '');
// Handle .md suffix - return raw markdown
if (pathWithoutBase.endsWith('.md')) {
const docPath = pathWithoutBase.replace(/\.md$/, '');
const url = request.nextUrl.clone();
url.pathname = `/api/md${docPath}`;
return NextResponse.rewrite(url);
}
// Handle base redirects from redirects.ts
const redirect = updatedRedirectsData.find(
(r: any) => r.source === pathWithoutBase
);
if (redirect) {
return NextResponse.redirect(
createRedirectUrl(request, redirect.destination, path)
);
}
// Handle latest version without path - redirect to main docs
const latestVersionOnlyMatch = pathWithoutBase.match(
`^\/(?:v\/|@)${docsConfig.DOCS_LATEST_VERSION}\/?$`
);
if (latestVersionOnlyMatch) {
return NextResponse.redirect(`https://sourcegraph.com/docs`);
}
// Handle version without slug - both /v/X.Y and @X.Y formats (for non-latest versions)
const versionOnlyMatch = pathWithoutBase.match(
/^\/(?:v\/|@)(\d+\.\d+)\/?$/
);
if (
versionOnlyMatch &&
versionOnlyMatch[1] !== docsConfig.DOCS_LATEST_VERSION
) {
return NextResponse.redirect(
`https://${versionOnlyMatch[1]}.sourcegraph.com/`
);
}
// Handle version-specific redirects
if (pathWithoutBase.startsWith(`/v/${docsConfig.DOCS_LATEST_VERSION}/`)) {
return NextResponse.redirect(
createRedirectUrl(
request,
`https://sourcegraph.com/docs/:slug*`,
pathWithoutBase
)
);
}
if (pathWithoutBase.startsWith(`/@${docsConfig.DOCS_LATEST_VERSION}/`)) {
return NextResponse.redirect(
createRedirectUrl(
request,
`https://sourcegraph.com/docs/:slug*`,
pathWithoutBase
)
);
}
const versionMatch = pathWithoutBase.match(/^\/v\/(\d+\.\d+)\/(.*)/);
if (versionMatch) {
return NextResponse.redirect(
createRedirectUrl(
request,
'https://:version.sourcegraph.com/:slug*',
pathWithoutBase
)
);
}
const atVersionMatch = pathWithoutBase.match(/^\/@(\d+\.\d+)\/(.*)/);
if (atVersionMatch) {
return NextResponse.redirect(
createRedirectUrl(
request,
'https://:version.sourcegraph.com/:slug*',
pathWithoutBase
)
);
}
if (pathWithoutBase === '/changelog.rss')
return NextResponse.redirect(TECHNICAL_CHANGELOG_RSS_URL);
return NextResponse.next();
}
export const config = {
matcher: ['/((?!api/md|_next/static|_next/image|assets|favicon.ico|sw.js).*)']
};