@mintlify/cli 4.0.976 → 4.0.977

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mintlify/cli",
3
- "version": "4.0.976",
3
+ "version": "4.0.977",
4
4
  "description": "The Mintlify CLI",
5
5
  "engines": {
6
6
  "node": ">=18.0.0"
@@ -46,7 +46,7 @@
46
46
  "dependencies": {
47
47
  "@inquirer/prompts": "7.9.0",
48
48
  "@mintlify/common": "1.0.748",
49
- "@mintlify/link-rot": "3.0.911",
49
+ "@mintlify/link-rot": "3.0.912",
50
50
  "@mintlify/models": "0.0.274",
51
51
  "@mintlify/prebuild": "1.0.885",
52
52
  "@mintlify/previewing": "4.0.942",
@@ -87,5 +87,5 @@
87
87
  "vitest": "2.0.4",
88
88
  "vitest-mock-process": "1.0.4"
89
89
  },
90
- "gitHead": "92cd443cb6af79021bfaa814b3e5e96c10846baa"
90
+ "gitHead": "8f066a43dd9d3552038aa9b421a4e83142206abb"
91
91
  }
package/src/cli.tsx CHANGED
@@ -1,5 +1,9 @@
1
1
  import { validate, getOpenApiDocumentFromUrl, isAllowedLocalSchemaUrl } from '@mintlify/common';
2
- import { getBrokenInternalLinks, renameFilesAndUpdateLinksInContent } from '@mintlify/link-rot';
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 invalid internal links',
223
+ 'check for broken links',
220
224
  (yargs) =>
221
- yargs.option('check-anchors', {
222
- type: 'boolean',
223
- default: false,
224
- description: 'also validate anchor links (e.g. #section) against heading slugs',
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 brokenLinks = await getBrokenInternalLinks(undefined, {
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
- brokenLinks.forEach((mdxPath) => {
259
+
260
+ brokenInternalLinks.forEach((mdxPath) => {
245
261
  const filename = path.join(mdxPath.relativeDir, mdxPath.filename);
246
- const brokenLinksForFile = brokenLinksByFile[filename];
247
- if (brokenLinksForFile) {
248
- brokenLinksForFile.push(mdxPath.originalPath);
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) {