Skip to content

Commit 9c1c749

Browse files
committed
Running autofix
1 parent 68d66bb commit 9c1c749

File tree

2 files changed

+122
-80
lines changed

2 files changed

+122
-80
lines changed

app/api/llms-txt/[...path]/route.ts

Lines changed: 114 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,24 @@
1-
import { NextRequest, NextResponse } from 'next/server';
2-
import { nodeForPath, getDocsRootNode } from 'sentry-docs/docTree';
3-
import { getFileBySlugWithCache } from 'sentry-docs/mdx';
4-
import { isDeveloperDocs } from 'sentry-docs/isDeveloperDocs';
5-
import matter from 'gray-matter';
61
import fs from 'fs';
72
import path from 'path';
83

4+
import matter from 'gray-matter';
5+
import {NextRequest, NextResponse} from 'next/server';
6+
7+
import {getDocsRootNode,nodeForPath} from 'sentry-docs/docTree';
8+
import {isDeveloperDocs} from 'sentry-docs/isDeveloperDocs';
9+
import {getFileBySlugWithCache} from 'sentry-docs/mdx';
10+
911
export async function GET(
1012
request: NextRequest,
11-
{ params }: { params: Promise<{ path: string[] }> }
13+
{params}: {params: Promise<{path: string[]}>}
1214
) {
1315
try {
1416
const resolvedParams = await params;
1517
const pathSegments = resolvedParams.path || [];
16-
18+
1719
// Get the document tree
1820
const rootNode = await getDocsRootNode();
19-
21+
2022
if (pathSegments.length === 0 && !isDeveloperDocs) {
2123
// Handle home page - try to get the actual index content
2224
try {
@@ -25,7 +27,11 @@ export async function GET(
2527
const rawContent = fs.readFileSync(indexPath, 'utf8');
2628
const parsed = matter(rawContent);
2729
const cleanContent = await cleanupMarkdown(parsed.content, pathSegments);
28-
return createResponse(parsed.data.title || 'Welcome to Sentry Documentation', cleanContent, '/');
30+
return createResponse(
31+
parsed.data.title || 'Welcome to Sentry Documentation',
32+
cleanContent,
33+
'/'
34+
);
2935
}
3036
} catch (e) {
3137
// Fallback for home page
@@ -54,12 +60,20 @@ Sentry helps developers monitor and fix crashes in real time. The platform suppo
5460
if (isDeveloperDocs) {
5561
// Handle developer docs
5662
try {
57-
const doc = await getFileBySlugWithCache(`develop-docs/${pathSegments.join('/') || ''}`);
58-
63+
const doc = await getFileBySlugWithCache(
64+
`develop-docs/${pathSegments.join('/') || ''}`
65+
);
66+
5967
// Try to get raw content from file system
6068
const possiblePaths = [
61-
path.join(process.cwd(), `develop-docs/${pathSegments.join('/') || 'index'}.mdx`),
62-
path.join(process.cwd(), `develop-docs/${pathSegments.join('/') || 'index'}.md`),
69+
path.join(
70+
process.cwd(),
71+
`develop-docs/${pathSegments.join('/') || 'index'}.mdx`
72+
),
73+
path.join(
74+
process.cwd(),
75+
`develop-docs/${pathSegments.join('/') || 'index'}.md`
76+
),
6377
path.join(process.cwd(), `develop-docs/${pathSegments.join('/')}/index.mdx`),
6478
path.join(process.cwd(), `develop-docs/${pathSegments.join('/')}/index.md`),
6579
];
@@ -74,9 +88,12 @@ Sentry helps developers monitor and fix crashes in real time. The platform suppo
7488
}
7589
}
7690

77-
pageTitle = frontMatter.title || doc.frontMatter.title || `Developer Documentation: ${pathSegments.join(' / ')}`;
91+
pageTitle =
92+
frontMatter.title ||
93+
doc.frontMatter.title ||
94+
`Developer Documentation: ${pathSegments.join(' / ')}`;
7895
} catch (e) {
79-
return new NextResponse('Page not found', { status: 404 });
96+
return new NextResponse('Page not found', {status: 404});
8097
}
8198
} else if (pathSegments[0] === 'api' && pathSegments.length > 1) {
8299
// Handle API docs - these are generated from OpenAPI specs
@@ -92,9 +109,9 @@ For complete API reference with examples and detailed parameters, please visit t
92109
} else {
93110
// Handle regular docs
94111
const pageNode = nodeForPath(rootNode, pathSegments);
95-
112+
96113
if (!pageNode) {
97-
return new NextResponse('Page not found', { status: 404 });
114+
return new NextResponse('Page not found', {status: 404});
98115
}
99116

100117
try {
@@ -110,29 +127,29 @@ For complete API reference with examples and detailed parameters, please visit t
110127
// Check if it's a platform guide that might use common files
111128
if (pageNode.path.includes('platforms/')) {
112129
const pathParts = pageNode.path.split('/');
113-
130+
114131
// For paths like platforms/javascript/guides/react/tracing
115132
// Check platforms/javascript/common/tracing
116133
if (pathParts.length >= 5 && pathParts[2] === 'guides') {
117134
const platform = pathParts[1]; // e.g., 'javascript'
118135
const commonPath = `platforms/${platform}/common`;
119136
const remainingPath = pathParts.slice(4).join('/'); // e.g., 'tracing'
120-
137+
121138
possiblePaths.push(
122139
path.join(process.cwd(), 'docs', commonPath, remainingPath + '.mdx'),
123140
path.join(process.cwd(), 'docs', commonPath, remainingPath + '.md'),
124141
path.join(process.cwd(), 'docs', commonPath, remainingPath, 'index.mdx'),
125142
path.join(process.cwd(), 'docs', commonPath, remainingPath, 'index.md')
126143
);
127144
}
128-
145+
129146
// For paths like platforms/javascript/tracing (direct platform paths)
130147
// Check platforms/javascript/common/tracing
131148
else if (pathParts.length >= 3) {
132149
const platform = pathParts[1]; // e.g., 'javascript'
133150
const commonPath = `platforms/${platform}/common`;
134151
const remainingPath = pathParts.slice(2).join('/'); // e.g., 'tracing'
135-
152+
136153
possiblePaths.push(
137154
path.join(process.cwd(), 'docs', commonPath, remainingPath + '.mdx'),
138155
path.join(process.cwd(), 'docs', commonPath, remainingPath + '.md'),
@@ -153,11 +170,15 @@ For complete API reference with examples and detailed parameters, please visit t
153170
const parsed = matter(rawContent);
154171
pageContent = parsed.content;
155172
frontMatter = parsed.data;
156-
pageTitle = frontMatter.title || pageNode.frontmatter.title || `Documentation: ${pathSegments.join(' / ')}`;
173+
pageTitle =
174+
frontMatter.title ||
175+
pageNode.frontmatter.title ||
176+
`Documentation: ${pathSegments.join(' / ')}`;
157177
} else {
158178
// Fallback - try to get processed content
159179
const doc = await getFileBySlugWithCache(`docs/${pageNode.path}`);
160-
pageTitle = doc.frontMatter.title || `Documentation: ${pathSegments.join(' / ')}`;
180+
pageTitle =
181+
doc.frontMatter.title || `Documentation: ${pathSegments.join(' / ')}`;
161182
pageContent = `# ${pageTitle}
162183
163184
This page exists in the documentation tree but the source markdown content could not be accessed directly.
@@ -168,22 +189,25 @@ The content may be dynamically generated or processed through the MDX pipeline.
168189
For the complete content with full formatting, code examples, and interactive elements, please visit the original page.`;
169190
}
170191
} catch (e) {
171-
return new NextResponse('Error processing page', { status: 500 });
192+
return new NextResponse('Error processing page', {status: 500});
172193
}
173194
}
174195

175196
// Clean up the markdown content
176197
const cleanContent = await cleanupMarkdown(pageContent, pathSegments);
177-
178-
return createResponse(pageTitle, cleanContent, `/${pathSegments.join('/')}`);
179198

199+
return createResponse(pageTitle, cleanContent, `/${pathSegments.join('/')}`);
180200
} catch (error) {
181201
console.error('Error generating llms.txt:', error);
182-
return new NextResponse('Internal server error', { status: 500 });
202+
return new NextResponse('Internal server error', {status: 500});
183203
}
184204
}
185205

186-
function createResponse(title: string, content: string, originalPath: string): NextResponse {
206+
function createResponse(
207+
title: string,
208+
content: string,
209+
originalPath: string
210+
): NextResponse {
187211
const markdownOutput = `# ${title}
188212
189213
${content}
@@ -203,108 +227,119 @@ ${content}
203227
});
204228
}
205229

206-
async function cleanupMarkdown(content: string, pathSegments: string[] = []): Promise<string> {
230+
async function cleanupMarkdown(
231+
content: string,
232+
pathSegments: string[] = []
233+
): Promise<string> {
207234
let cleaned = content;
208-
235+
209236
// First, try to resolve PlatformContent includes with actual content
210237
cleaned = await resolvePlatformIncludes(cleaned, pathSegments);
211-
238+
212239
// Preserve existing code blocks by temporarily replacing them
213240
const codeBlocks: string[] = [];
214241
const codeBlockPlaceholder = '___CODE_BLOCK_PLACEHOLDER___';
215-
242+
216243
// Extract code blocks to preserve them
217-
cleaned = cleaned.replace(/```[\s\S]*?```/g, (match) => {
244+
cleaned = cleaned.replace(/```[\s\S]*?```/g, match => {
218245
codeBlocks.push(match);
219246
return `${codeBlockPlaceholder}${codeBlocks.length - 1}`;
220247
});
221-
248+
222249
// First pass: Extract content from specific platform components while preserving inner text
223250
cleaned = cleaned
224251
// Extract content from Alert components
225252
.replace(/<Alert[^>]*>([\s\S]*?)<\/Alert>/g, '\n> **Note:** $1\n')
226-
253+
227254
// Extract content from PlatformSection components - preserve inner content
228255
.replace(/<PlatformSection[^>]*>([\s\S]*?)<\/PlatformSection>/g, '$1')
229-
230-
// Extract content from PlatformContent components - preserve inner content
256+
257+
// Extract content from PlatformContent components - preserve inner content
231258
.replace(/<PlatformContent[^>]*>([\s\S]*?)<\/PlatformContent>/g, '$1')
232-
259+
233260
// Extract content from PlatformCategorySection components - preserve inner content
234261
.replace(/<PlatformCategorySection[^>]*>([\s\S]*?)<\/PlatformCategorySection>/g, '$1')
235-
262+
236263
// Handle PlatformIdentifier components - extract name attribute or use placeholder
237264
.replace(/<PlatformIdentifier[^>]*name="([^"]*)"[^>]*\/>/g, '`$1`')
238265
.replace(/<PlatformIdentifier[^>]*\/>/g, '`[PLATFORM_IDENTIFIER]`')
239-
266+
240267
// Handle PlatformLink components - preserve link text and convert to markdown links when possible
241-
.replace(/<PlatformLink[^>]*to="([^"]*)"[^>]*>([\s\S]*?)<\/PlatformLink>/g, '[$2]($1)')
268+
.replace(
269+
/<PlatformLink[^>]*to="([^"]*)"[^>]*>([\s\S]*?)<\/PlatformLink>/g,
270+
'[$2]($1)'
271+
)
242272
.replace(/<PlatformLink[^>]*>([\s\S]*?)<\/PlatformLink>/g, '$1');
243-
273+
244274
// Multiple passes to handle any remaining nested components
245275
for (let i = 0; i < 3; i++) {
246276
cleaned = cleaned
247277
// Remove any remaining JSX components but try to preserve inner content first
248278
.replace(/<([A-Z][a-zA-Z0-9]*)[^>]*>([\s\S]*?)<\/\1>/g, '$2')
249-
279+
250280
// Remove any remaining self-closing JSX components
251281
.replace(/<[A-Z][a-zA-Z0-9]*[^>]*\/>/g, '')
252-
282+
253283
// Remove JSX expressions
254284
.replace(/\{[^}]*\}/g, '')
255-
285+
256286
// Remove any remaining opening/closing JSX tags
257287
.replace(/<\/?[A-Z][a-zA-Z0-9]*[^>]*>/g, '');
258288
}
259-
289+
260290
// Restore code blocks
261291
codeBlocks.forEach((block, index) => {
262292
cleaned = cleaned.replace(`${codeBlockPlaceholder}${index}`, block);
263293
});
264-
265-
return cleaned
266-
// Remove import/export statements
267-
.replace(/^import\s+.*$/gm, '')
268-
.replace(/^export\s+.*$/gm, '')
269-
270-
// Remove HTML comments
271-
.replace(/<!--[\s\S]*?-->/g, '')
272-
273-
// Clean up whitespace and formatting
274-
.replace(/\n{3,}/g, '\n\n')
275-
.replace(/^\s*\n/gm, '\n')
276-
.replace(/\n\s*\n\s*\n/g, '\n\n')
277-
.trim();
294+
295+
return (
296+
cleaned
297+
// Remove import/export statements
298+
.replace(/^import\s+.*$/gm, '')
299+
.replace(/^export\s+.*$/gm, '')
300+
301+
// Remove HTML comments
302+
.replace(/<!--[\s\S]*?-->/g, '')
303+
304+
// Clean up whitespace and formatting
305+
.replace(/\n{3,}/g, '\n\n')
306+
.replace(/^\s*\n/gm, '\n')
307+
.replace(/\n\s*\n\s*\n/g, '\n\n')
308+
.trim()
309+
);
278310
}
279311

280-
async function resolvePlatformIncludes(content: string, pathSegments: string[]): Promise<string> {
312+
async function resolvePlatformIncludes(
313+
content: string,
314+
pathSegments: string[]
315+
): Promise<string> {
281316
// Detect platform and guide from path segments
282317
let platform = '';
283318
let guide = '';
284-
319+
285320
if (pathSegments.length >= 2 && pathSegments[0] === 'platforms') {
286321
platform = pathSegments[1]; // e.g., 'javascript'
287-
322+
288323
if (pathSegments.length >= 4 && pathSegments[2] === 'guides') {
289324
guide = pathSegments[3]; // e.g., 'react'
290325
}
291326
}
292-
327+
293328
// Build platform identifier for include files
294329
let platformId = platform;
295330
if (guide && guide !== platform) {
296331
platformId = `${platform}.${guide}`;
297332
}
298-
333+
299334
// Replace PlatformContent includes with actual content
300335
const includePattern = /<PlatformContent[^>]*includePath="([^"]*)"[^>]*\/>/g;
301336
let result = content;
302337
let match;
303-
338+
304339
while ((match = includePattern.exec(content)) !== null) {
305340
const includePath = match[1];
306341
const fullMatch = match[0];
307-
342+
308343
try {
309344
// Try to load the platform-specific include file
310345
const possiblePaths = [
@@ -313,7 +348,7 @@ async function resolvePlatformIncludes(content: string, pathSegments: string[]):
313348
// Fallback to generic if platform-specific doesn't exist
314349
path.join(process.cwd(), `platform-includes/${includePath}/index.mdx`),
315350
];
316-
351+
317352
let includeContent = '';
318353
for (const filePath of possiblePaths) {
319354
if (fs.existsSync(filePath)) {
@@ -323,20 +358,26 @@ async function resolvePlatformIncludes(content: string, pathSegments: string[]):
323358
break;
324359
}
325360
}
326-
361+
327362
if (includeContent) {
328363
result = result.replace(fullMatch, `\n${includeContent}\n`);
329364
} else {
330365
// Fallback placeholder with more descriptive text
331366
const sectionName = includePath.split('/').pop() || 'content';
332-
result = result.replace(fullMatch, `\n*[${sectionName.charAt(0).toUpperCase() + sectionName.slice(1)} instructions would appear here for ${platformId || platform || 'this platform'}]*\n`);
367+
result = result.replace(
368+
fullMatch,
369+
`\n*[${sectionName.charAt(0).toUpperCase() + sectionName.slice(1)} instructions would appear here for ${platformId || platform || 'this platform'}]*\n`
370+
);
333371
}
334372
} catch (error) {
335373
console.error(`Error loading include ${includePath}:`, error);
336374
const sectionName = includePath.split('/').pop() || 'content';
337-
result = result.replace(fullMatch, `\n*[${sectionName.charAt(0).toUpperCase() + sectionName.slice(1)} instructions would appear here]*\n`);
375+
result = result.replace(
376+
fullMatch,
377+
`\n*[${sectionName.charAt(0).toUpperCase() + sectionName.slice(1)} instructions would appear here]*\n`
378+
);
338379
}
339380
}
340-
381+
341382
return result;
342-
}
383+
}

0 commit comments

Comments
 (0)