@mintlify/cli 4.0.976 → 4.0.978
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/__test__/brokenLinks.test.ts +83 -9
- package/bin/cli.js +44 -12
- package/bin/tsconfig.build.tsbuildinfo +1 -1
- package/package.json +8 -8
- package/src/cli.tsx +57 -17
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mintlify/cli",
|
|
3
|
-
"version": "4.0.
|
|
3
|
+
"version": "4.0.978",
|
|
4
4
|
"description": "The Mintlify CLI",
|
|
5
5
|
"engines": {
|
|
6
6
|
"node": ">=18.0.0"
|
|
@@ -45,13 +45,13 @@
|
|
|
45
45
|
},
|
|
46
46
|
"dependencies": {
|
|
47
47
|
"@inquirer/prompts": "7.9.0",
|
|
48
|
-
"@mintlify/common": "1.0.
|
|
49
|
-
"@mintlify/link-rot": "3.0.
|
|
48
|
+
"@mintlify/common": "1.0.749",
|
|
49
|
+
"@mintlify/link-rot": "3.0.913",
|
|
50
50
|
"@mintlify/models": "0.0.274",
|
|
51
|
-
"@mintlify/prebuild": "1.0.
|
|
52
|
-
"@mintlify/previewing": "4.0.
|
|
53
|
-
"@mintlify/scraping": "4.0.
|
|
54
|
-
"@mintlify/validation": "0.1.
|
|
51
|
+
"@mintlify/prebuild": "1.0.886",
|
|
52
|
+
"@mintlify/previewing": "4.0.943",
|
|
53
|
+
"@mintlify/scraping": "4.0.611",
|
|
54
|
+
"@mintlify/validation": "0.1.605",
|
|
55
55
|
"adm-zip": "0.5.16",
|
|
56
56
|
"chalk": "5.2.0",
|
|
57
57
|
"color": "4.2.3",
|
|
@@ -87,5 +87,5 @@
|
|
|
87
87
|
"vitest": "2.0.4",
|
|
88
88
|
"vitest-mock-process": "1.0.4"
|
|
89
89
|
},
|
|
90
|
-
"gitHead": "
|
|
90
|
+
"gitHead": "df62f7b5da4b6c247166f8bc114037a8d76fc4b3"
|
|
91
91
|
}
|
package/src/cli.tsx
CHANGED
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
import { validate, getOpenApiDocumentFromUrl, isAllowedLocalSchemaUrl } from '@mintlify/common';
|
|
2
|
-
import {
|
|
2
|
+
import {
|
|
3
|
+
buildGraph,
|
|
4
|
+
getBrokenExternalLinks,
|
|
5
|
+
renameFilesAndUpdateLinksInContent,
|
|
6
|
+
} from '@mintlify/link-rot';
|
|
3
7
|
import {
|
|
4
8
|
addLog,
|
|
5
9
|
dev,
|
|
@@ -216,13 +220,24 @@ export const cli = ({ packageName = 'mint' }: { packageName?: string }) => {
|
|
|
216
220
|
)
|
|
217
221
|
.command(
|
|
218
222
|
'broken-links',
|
|
219
|
-
'check for
|
|
223
|
+
'check for broken links',
|
|
220
224
|
(yargs) =>
|
|
221
|
-
yargs
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
225
|
+
yargs
|
|
226
|
+
.option('check-anchors', {
|
|
227
|
+
type: 'boolean',
|
|
228
|
+
default: false,
|
|
229
|
+
description: 'also validate anchor links (e.g. #section) against heading slugs',
|
|
230
|
+
})
|
|
231
|
+
.option('check-external', {
|
|
232
|
+
type: 'boolean',
|
|
233
|
+
default: false,
|
|
234
|
+
description: 'also check external links for broken URLs',
|
|
235
|
+
})
|
|
236
|
+
.option('check-snippets', {
|
|
237
|
+
type: 'boolean',
|
|
238
|
+
default: false,
|
|
239
|
+
description: 'also check links inside <Snippet> components',
|
|
240
|
+
}),
|
|
226
241
|
async (argv) => {
|
|
227
242
|
const hasMintJson = await checkForMintJson();
|
|
228
243
|
if (!hasMintJson) {
|
|
@@ -231,25 +246,50 @@ export const cli = ({ packageName = 'mint' }: { packageName?: string }) => {
|
|
|
231
246
|
|
|
232
247
|
addLog(<SpinnerLog message="checking for broken links..." />);
|
|
233
248
|
try {
|
|
234
|
-
const
|
|
249
|
+
const graph = await buildGraph(undefined, {
|
|
250
|
+
checkSnippets: argv['check-snippets'],
|
|
251
|
+
});
|
|
252
|
+
graph.precomputeFileResolutions();
|
|
253
|
+
|
|
254
|
+
const brokenInternalLinks = graph.getBrokenInternalLinks({
|
|
235
255
|
checkAnchors: argv['check-anchors'],
|
|
236
256
|
});
|
|
237
|
-
if (brokenLinks.length === 0) {
|
|
238
|
-
clearLogs();
|
|
239
|
-
addLog(<SuccessLog message="no broken links found" />);
|
|
240
|
-
await terminate(0);
|
|
241
|
-
}
|
|
242
257
|
|
|
243
258
|
const brokenLinksByFile: Record<string, string[]> = {};
|
|
244
|
-
|
|
259
|
+
|
|
260
|
+
brokenInternalLinks.forEach((mdxPath) => {
|
|
245
261
|
const filename = path.join(mdxPath.relativeDir, mdxPath.filename);
|
|
246
|
-
const
|
|
247
|
-
if (
|
|
248
|
-
|
|
262
|
+
const existing = brokenLinksByFile[filename];
|
|
263
|
+
if (existing) {
|
|
264
|
+
existing.push(mdxPath.originalPath);
|
|
249
265
|
} else {
|
|
250
266
|
brokenLinksByFile[filename] = [mdxPath.originalPath];
|
|
251
267
|
}
|
|
252
268
|
});
|
|
269
|
+
|
|
270
|
+
if (argv['check-external']) {
|
|
271
|
+
const brokenExternalLinks = await getBrokenExternalLinks(graph);
|
|
272
|
+
for (const result of brokenExternalLinks) {
|
|
273
|
+
for (const source of result.sources) {
|
|
274
|
+
const label = result.status
|
|
275
|
+
? `${result.url} (${result.status})`
|
|
276
|
+
: `${result.url} (${result.error})`;
|
|
277
|
+
const existing = brokenLinksByFile[source.file];
|
|
278
|
+
if (existing) {
|
|
279
|
+
existing.push(label);
|
|
280
|
+
} else {
|
|
281
|
+
brokenLinksByFile[source.file] = [label];
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
if (Object.keys(brokenLinksByFile).length === 0) {
|
|
288
|
+
clearLogs();
|
|
289
|
+
addLog(<SuccessLog message="no broken links found" />);
|
|
290
|
+
await terminate(0);
|
|
291
|
+
}
|
|
292
|
+
|
|
253
293
|
clearLogs();
|
|
254
294
|
addLog(<BrokenLinksLog brokenLinksByFile={brokenLinksByFile} />);
|
|
255
295
|
} catch (err) {
|