@mintlify/link-rot 3.0.590 → 3.0.592

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/dist/graph.d.ts CHANGED
@@ -73,6 +73,8 @@ export declare class Graph {
73
73
  source: string;
74
74
  destination: string;
75
75
  }[]): void;
76
+ matchesWildcardPattern(path: string, pattern: string): boolean;
77
+ applyWildcardRedirect(path: string, sourcePattern: string, destinationPattern: string): string;
76
78
  addAliasNodes(): void;
77
79
  getNode(label: string): Node | undefined;
78
80
  private addEdge;
package/dist/graph.js CHANGED
@@ -231,6 +231,51 @@ export class Graph {
231
231
  this.redirectMap.set(normalizePath(redirect.source), normalizePath(redirect.destination));
232
232
  }
233
233
  }
234
+ matchesWildcardPattern(path, pattern) {
235
+ // Escape special regex characters except : and *
236
+ const escapedPattern = pattern.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
237
+ // Replace :param patterns with named capture groups
238
+ const paramPattern = escapedPattern.replace(/:(\w+)/g, '(?<$1>[^/]+)');
239
+ // Replace * wildcards with greedy capture
240
+ const wildcardPattern = paramPattern.replace(/\\\*/g, '(.*)');
241
+ // Anchor the pattern to match the full path
242
+ const fullPattern = `^${wildcardPattern}$`;
243
+ return new RegExp(fullPattern).test(path);
244
+ }
245
+ applyWildcardRedirect(path, sourcePattern, destinationPattern) {
246
+ // Escape special regex characters except : and *
247
+ const escapedPattern = sourcePattern.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
248
+ // Track the order of capture groups
249
+ const captureGroups = [];
250
+ // Replace :param patterns with named capture groups and track them
251
+ const paramPattern = escapedPattern.replace(/:(\w+)/g, (_, paramName) => {
252
+ captureGroups.push({ type: 'param', name: paramName });
253
+ return `(?<${paramName}>[^/]+)`;
254
+ });
255
+ // Replace * wildcards with capture groups and track them
256
+ const wildcardPattern = paramPattern.replace(/\\\*/g, () => {
257
+ captureGroups.push({ type: 'wildcard' });
258
+ return '(.*)';
259
+ });
260
+ const regex = new RegExp(`^${wildcardPattern}$`);
261
+ const match = path.match(regex);
262
+ if (!match)
263
+ return destinationPattern;
264
+ let result = destinationPattern;
265
+ const namedGroups = match.groups || {};
266
+ // Replace named parameters (e.g., :slug)
267
+ for (const [paramName, value] of Object.entries(namedGroups)) {
268
+ result = result.replace(new RegExp(`:${paramName}`, 'g'), value);
269
+ }
270
+ const allCaptures = match.slice(1);
271
+ let wildcardIndex = 0;
272
+ const wildcardCaptures = allCaptures.filter((_, index) => {
273
+ // Skip captures that are named parameters
274
+ return captureGroups[index] && captureGroups[index].type === 'wildcard';
275
+ });
276
+ result = result.replace(/\*/g, () => wildcardCaptures[wildcardIndex++] || '');
277
+ return result;
278
+ }
234
279
  /*
235
280
  * Aliases are additional paths that are valid due to redirects
236
281
  */
@@ -296,8 +341,20 @@ export class Graph {
296
341
  const pathString = path.toString();
297
342
  const resolvedFiles = this.fileResolutionMap.get(pathString);
298
343
  const hasExistingFile = resolvedFiles && [...resolvedFiles].some((file) => nodeSet.has(file));
299
- const redirectDestination = this.redirectMap.get(pathString);
300
- const hasValidRedirect = redirectDestination && nodeSet.has(`${redirectDestination}.mdx`);
344
+ let redirectDestination = this.redirectMap.get(pathString);
345
+ let hasValidRedirect = redirectDestination &&
346
+ (nodeSet.has(`${redirectDestination}.mdx`) || nodeSet.has(redirectDestination));
347
+ if (!hasValidRedirect) {
348
+ for (const [sourcePattern, destinationPattern] of this.redirectMap.entries()) {
349
+ if (this.matchesWildcardPattern(pathString, sourcePattern)) {
350
+ redirectDestination = this.applyWildcardRedirect(pathString, sourcePattern, destinationPattern);
351
+ hasValidRedirect =
352
+ nodeSet.has(`${redirectDestination}.mdx`) || nodeSet.has(redirectDestination);
353
+ if (hasValidRedirect)
354
+ break;
355
+ }
356
+ }
357
+ }
301
358
  if (!hasExistingFile && !hasValidRedirect) {
302
359
  brokenLinks.push(path);
303
360
  }