Skip to content

Commit 3651b6e

Browse files
authored
fix script generating llms.txt (facebook#4799)
1 parent 41b9f28 commit 3651b6e

File tree

1 file changed

+39
-48
lines changed

1 file changed

+39
-48
lines changed

scripts/generate-llms-txt.js

Lines changed: 39 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,29 @@ const DESCRIPTION =
1010
'React Native is a framework for building native apps using React. It lets you create mobile apps using only JavaScript and React.';
1111
const URL_PREFIX = 'https://reactnative.dev';
1212

13+
const INPUT_FILE_PATHS = [
14+
{
15+
name: 'sidebars.ts',
16+
docPath: '../docs/',
17+
prefix: '/docs',
18+
},
19+
{
20+
name: 'sidebarsArchitecture.ts',
21+
docPath: './architecture/',
22+
prefix: '/architecture',
23+
},
24+
{
25+
name: 'sidebarsCommunity.ts',
26+
docPath: './community/',
27+
prefix: '/community',
28+
},
29+
{
30+
name: 'sidebarsContributing.ts',
31+
docPath: './contributing/',
32+
prefix: '/contributing',
33+
},
34+
];
35+
1336
const SLUG_TO_URL = {
1437
'architecture-overview': 'overview',
1538
'architecture-glossary': 'glossary',
@@ -108,15 +131,13 @@ function checkUrl(urlString) {
108131
resolve({
109132
url: urlString,
110133
status: res.statusCode,
111-
is404: res.statusCode === 404,
112134
});
113135
});
114136

115137
req.on('error', error => {
116138
resolve({
117139
url: urlString,
118140
status: 'Error',
119-
is404: false,
120141
error: error.message,
121142
});
122143
});
@@ -126,7 +147,6 @@ function checkUrl(urlString) {
126147
resolve({
127148
url: urlString,
128149
status: 'Timeout',
129-
is404: false,
130150
});
131151
});
132152

@@ -140,11 +160,7 @@ async function processUrls(urls) {
140160

141161
for (const urlToCheck of urls) {
142162
const result = await checkUrl(urlToCheck);
143-
if (
144-
result.is404 ||
145-
result.status === 'Error' ||
146-
result.status === 'Timeout'
147-
) {
163+
if (result.status !== 200) {
148164
unavailableUrls.push({
149165
url: urlToCheck,
150166
status: result.status,
@@ -176,18 +192,14 @@ function extractMetadataFromMarkdown(filePath) {
176192
slug: slugMatch ? slugMatch[1].trim().replace(/^\//, '') : null,
177193
};
178194
}
179-
// If no frontmatter found, use the filename
180-
return {
181-
title: filePath.split('/').pop().replace('.md', ''),
182-
slug: null,
183-
};
184195
} catch (error) {
185196
console.error(`Error reading file ${filePath}:`, error);
186-
return {
187-
title: filePath.split('/').pop().replace('.md', ''),
188-
slug: null,
189-
};
190197
}
198+
// If no frontmatter found, on an error occurred use the filename
199+
return {
200+
title: filePath.split('/').pop().replace('.md', ''),
201+
slug: null,
202+
};
191203
}
192204

193205
// Function to map special cases for file names that don't match the sidebar
@@ -283,38 +295,15 @@ function generateMarkdown(sidebarConfig, docPath, prefix, unavailableUrls) {
283295
return markdown.replace(/(#+ .*)\n/g, '\n$1\n').replace(/\n(\n)+/g, '\n\n');
284296
}
285297

286-
const inputFilePaths = [
287-
{
288-
name: 'sidebars.ts',
289-
docPath: '../docs/',
290-
prefix: '/docs',
291-
},
292-
{
293-
name: 'sidebarsArchitecture.ts',
294-
docPath: './architecture/',
295-
prefix: '/architecture',
296-
},
297-
{
298-
name: 'sidebarsCommunity.ts',
299-
docPath: './community/',
300-
prefix: '/community',
301-
},
302-
{
303-
name: 'sidebarsContributing.ts',
304-
docPath: './contributing/',
305-
prefix: '/contributing',
306-
},
307-
];
308-
309-
let output = `# ${TITLE}\n\n`;
310-
output += `> ${DESCRIPTION}\n\n`;
311-
output += `This documentation covers all aspects of using React Native, from installation to advanced usage.\n\n`;
312-
313298
async function generateOutput() {
314299
const results = [];
315300
const promises = [];
316301

317-
for (const {name, docPath, prefix} of inputFilePaths) {
302+
let output = `# ${TITLE}\n\n`;
303+
output += `> ${DESCRIPTION}\n\n`;
304+
output += `This documentation covers all aspects of using React Native, from installation to advanced usage.\n\n`;
305+
306+
for (const {name, docPath, prefix} of INPUT_FILE_PATHS) {
318307
const sidebarConfig = await convertSidebarConfigToJson(name);
319308

320309
if (sidebarConfig) {
@@ -324,8 +313,10 @@ async function generateOutput() {
324313
.then(result => {
325314
if (result.unavailableUrls.length > 0) {
326315
console.error(
327-
'Skipping new pages not existing in production deployment yet:',
328-
result.unavailableUrls.map(entry => entry.url)
316+
'Skipping new pages not existing in the latest version docs yet:',
317+
result.unavailableUrls.map(entry =>
318+
entry.url.replace('/docs', '/docs/next')
319+
)
329320
);
330321
}
331322
const markdown = generateMarkdown(
@@ -375,7 +366,7 @@ async function generateOutput() {
375366
}
376367

377368
function isEntryUnavailable(unavailableUrls, docPath) {
378-
return !unavailableUrls.find(entry =>
369+
return !!unavailableUrls.find(entry =>
379370
entry.url.endsWith(docPath.substring(1))
380371
);
381372
}

0 commit comments

Comments
 (0)