Skip to content

Commit 6a3d953

Browse files
authored
Add redirects debugging tools (#2634)
1 parent c05df8b commit 6a3d953

File tree

6 files changed

+820
-20
lines changed

6 files changed

+820
-20
lines changed

package-lock.json

Lines changed: 8 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,9 @@
88
"lint:formatting": "prettier . --check",
99
"lint:check-quickstarts": "node ./scripts/check-quickstarts.mjs",
1010
"lint:check-frontmatter": "node ./scripts/check-frontmatter.mjs",
11+
"lint:check-redirects": "bun ./scripts/check-redirects.ts",
12+
"lint:check-duplicate-redirects": "bun ./scripts/check-duplicate-redirects.ts",
13+
"trace-redirect": "bun ./scripts/trace-redirect.ts",
1114
"build": "bun ./scripts/build-docs.ts",
1215
"build:tsx": "tsx ./scripts/build-docs.ts",
1316
"dev": "bun --watch ./scripts/build-docs.ts --watch",
@@ -33,6 +36,7 @@
3336
"dotenv": "^17.2.0",
3437
"glob": "^11.0.1",
3538
"jsonc-parser": "^3.3.1",
39+
"path-to-regexp": "^6.3.0",
3640
"prettier": "^3.2.5",
3741
"prettier-plugin-astro": "^0.14.0",
3842
"prettier-plugin-nginx": "^1.0.3",

redirects/static/docs.json

Lines changed: 20 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -524,6 +524,11 @@
524524
"destination": "/docs/reference/nextjs/app-router/auth",
525525
"permanent": true
526526
},
527+
{
528+
"source": "/docs/reference/nextjs/auth",
529+
"destination": "/docs/reference/nextjs/app-router/auth",
530+
"permanent": true
531+
},
527532
{
528533
"source": "/docs/nextjs/authentication-props",
529534
"destination": "/docs/reference/backend/types/auth-object",
@@ -1559,11 +1564,6 @@
15591564
"destination": "/docs/guides/development/custom-flows/authentication/multi-session-applications",
15601565
"permanent": true
15611566
},
1562-
{
1563-
"source": "/docs/how-to/organizations",
1564-
"destination": "/docs/guides/organizations/overview",
1565-
"permanent": true
1566-
},
15671567
{
15681568
"source": "/docs/authentication/progressive-sign-up-beta",
15691569
"destination": "/docs/guides/development/upgrading/upgrade-guides/progressive-sign-up",
@@ -1614,11 +1614,6 @@
16141614
"destination": "/docs/reference/backend/organization/get-organization-invitation-list",
16151615
"permanent": true
16161616
},
1617-
{
1618-
"source": "/docs/reference/javascript/types/paginated-response",
1619-
"destination": "/docs/reference/javascript/types/clerk-paginated-response",
1620-
"permanent": true
1621-
},
16221617
{
16231618
"source": "/docs/reference/nextjs/with-clerk-middleware",
16241619
"destination": "/docs/reference/nextjs/clerk-middleware",
@@ -2274,11 +2269,6 @@
22742269
"destination": "/docs/guides/development/errors/overview",
22752270
"permanent": true
22762271
},
2277-
{
2278-
"source": "/docs/errors/",
2279-
"destination": "/docs/guides/development/errors/overview",
2280-
"permanent": true
2281-
},
22822272
{
22832273
"source": "/docs/errors/blocklist-identifiers",
22842274
"destination": "/docs/guides/development/errors/overview",
@@ -2461,17 +2451,17 @@
24612451
},
24622452
{
24632453
"source": "/docs/ai-prompts/nextjs",
2464-
"destination": "/docs/guides/ai-prompts",
2454+
"destination": "/docs/guides/development/ai-prompts",
24652455
"permanent": true
24662456
},
24672457
{
24682458
"source": "/docs/ai-prompts/overview",
2469-
"destination": "/docs/guides/ai-prompts",
2459+
"destination": "/docs/guides/development/ai-prompts",
24702460
"permanent": true
24712461
},
24722462
{
24732463
"source": "/docs/ai-prompts/react",
2474-
"destination": "/docs/guides/ai-prompts",
2464+
"destination": "/docs/guides/development/ai-prompts",
24752465
"permanent": true
24762466
},
24772467
{
@@ -3160,12 +3150,12 @@
31603150
"permanent": true
31613151
},
31623152
{
3163-
"source": "/docs/integrations/vercel-marketplace",
3153+
"source": "/docs/guides/development/integrations/vercel-marketplace",
31643154
"destination": "/docs/guides/development/integrations/platforms/vercel-marketplace",
31653155
"permanent": true
31663156
},
31673157
{
3168-
"source": "/docs/integrations/shopify",
3158+
"source": "/docs/guides/development/integrations/shopify",
31693159
"destination": "/docs/guides/development/integrations/platforms/shopify",
31703160
"permanent": true
31713161
},
@@ -3529,6 +3519,11 @@
35293519
"destination": "/docs/guides/development/machine-auth/m2m-tokens",
35303520
"permanent": true
35313521
},
3522+
{
3523+
"source": "/docs/quickstarts/overview",
3524+
"destination": "/docs/getting-started/quickstart/overview",
3525+
"permanent": true
3526+
},
35323527
{
35333528
"source": "/docs/quickstarts/nextjs",
35343529
"destination": "/docs/nextjs/getting-started/quickstart",
@@ -3913,5 +3908,10 @@
39133908
"source": "/docs/reference/nextjs/current-user",
39143909
"destination": "/docs/reference/nextjs/app-router/current-user",
39153910
"permanent": true
3911+
},
3912+
{
3913+
"source": "/docs/guides/configure/auth-strategies/overview",
3914+
"destination": "/docs/guides/configure/auth-strategies/sign-up-sign-in-options",
3915+
"permanent": true
39163916
}
39173917
]
Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
#!/usr/bin/env tsx
2+
3+
/**
4+
* Check Duplicate Redirects Script
5+
*
6+
* This script checks for duplicate redirect sources in the static redirects file.
7+
* It provides friendly feedback about any duplicates found and suggests how to fix them.
8+
*
9+
* Usage:
10+
* npx tsx scripts/check-duplicate-redirects.ts
11+
* npm run lint:check-duplicate-redirects
12+
*/
13+
14+
import fs from 'node:fs/promises'
15+
import path from 'node:path'
16+
17+
interface Redirect {
18+
source: string
19+
destination: string
20+
permanent: boolean
21+
}
22+
23+
function validateNoDuplicateSources(redirects: Redirect[]): boolean {
24+
const sourceMap = new Map<string, Redirect[]>()
25+
26+
// Group redirects by source
27+
for (const redirect of redirects) {
28+
if (!sourceMap.has(redirect.source)) {
29+
sourceMap.set(redirect.source, [])
30+
}
31+
sourceMap.get(redirect.source)!.push(redirect)
32+
}
33+
34+
// Find duplicates
35+
const duplicates: Array<{ source: string; redirects: Redirect[] }> = []
36+
for (const [source, redirectsForSource] of sourceMap.entries()) {
37+
if (redirectsForSource.length > 1) {
38+
duplicates.push({ source, redirects: redirectsForSource })
39+
}
40+
}
41+
42+
if (duplicates.length > 0) {
43+
duplicates.forEach(({ source, redirects }) => {
44+
const destinations = redirects.map((r) => r.destination)
45+
const uniqueDestinations = [...new Set(destinations)]
46+
47+
if (uniqueDestinations.length === 1) {
48+
console.log(`📝 "${source}" appears ${redirects.length} times`)
49+
console.log(` All pointing to: ${uniqueDestinations[0]}`)
50+
console.log(' 💡 This is just redundant - you can safely remove the duplicates')
51+
} else {
52+
console.log(`⚠️ "${source}" has ${redirects.length} conflicting destinations:`)
53+
destinations.forEach((dest, i) => {
54+
console.log(` ${i + 1}. ${dest}`)
55+
})
56+
console.log(' 💡 Please decide which destination is correct and remove the others')
57+
}
58+
console.log('')
59+
})
60+
61+
console.log('🔧 To fix this, please:')
62+
console.log(' 1. Edit redirects/static/docs.json')
63+
console.log(' 2. Remove the duplicate entries listed above')
64+
console.log(' 3. Run this check again to verify')
65+
console.log('')
66+
console.log('✨ Once cleaned up, your redirects will be ready to go!')
67+
68+
return false
69+
}
70+
71+
return true
72+
}
73+
74+
async function checkDuplicateRedirects(): Promise<void> {
75+
console.log('🔎 Checking for duplicate redirect sources...')
76+
77+
try {
78+
const redirectsPath = path.join(process.cwd(), 'redirects', 'static', 'docs.json')
79+
const content = await fs.readFile(redirectsPath, 'utf-8')
80+
const redirects: Redirect[] = JSON.parse(content)
81+
82+
console.log(`📊 Found ${redirects.length} total redirects`)
83+
84+
const isValid = validateNoDuplicateSources(redirects)
85+
86+
if (isValid) {
87+
console.log('✅ No duplicate redirect sources found! Your redirects look great.')
88+
} else {
89+
process.exitCode = 1
90+
}
91+
} catch (error) {
92+
console.error('💥 Error reading redirects file:', error)
93+
process.exitCode = 1
94+
}
95+
}
96+
97+
async function main() {
98+
try {
99+
await checkDuplicateRedirects()
100+
} catch (error) {
101+
console.error('💥 Error checking duplicate redirects:', error)
102+
process.exitCode = 1
103+
}
104+
}
105+
106+
// Run the script if called directly
107+
if (require.main === module) {
108+
main()
109+
}

0 commit comments

Comments
 (0)