nuxt-link-checker 4.3.8 → 5.0.1

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.
Files changed (59) hide show
  1. package/LICENSE.md +1 -1
  2. package/README.md +8 -2
  3. package/dist/eslint.d.mts +5 -0
  4. package/dist/eslint.d.ts +5 -0
  5. package/dist/eslint.mjs +356 -0
  6. package/dist/module.d.mts +31 -1
  7. package/dist/module.d.ts +123 -0
  8. package/dist/module.json +1 -1
  9. package/dist/module.mjs +168 -117
  10. package/dist/runtime/app/plugins/ui.client.d.ts +3 -2
  11. package/dist/runtime/app/plugins/ui.client.js +2 -1
  12. package/dist/runtime/app/plugins/view/Squiggle.d.vue.ts +5 -1
  13. package/dist/runtime/app/plugins/view/Squiggle.vue.d.ts +5 -1
  14. package/dist/runtime/app/plugins/view/client.js +14 -9
  15. package/dist/runtime/server/providers/content-v2.d.ts +4 -1
  16. package/dist/runtime/server/providers/content-v3.d.ts +3 -3
  17. package/dist/runtime/server/routes/__link-checker__/inspect.js +4 -4
  18. package/dist/runtime/shared/crawl.d.ts +2 -7
  19. package/dist/runtime/shared/diff.d.ts +6 -21
  20. package/dist/runtime/shared/diff.js +2 -1
  21. package/dist/runtime/shared/inspections/absolute-site-urls.d.ts +2 -1
  22. package/dist/runtime/shared/inspections/link-text.d.ts +2 -1
  23. package/dist/runtime/shared/inspections/missing-hash.d.ts +2 -1
  24. package/dist/runtime/shared/inspections/no-baseless.d.ts +2 -1
  25. package/dist/runtime/shared/inspections/no-double-slashes.d.ts +2 -1
  26. package/dist/runtime/shared/inspections/no-double-slashes.js +5 -3
  27. package/dist/runtime/shared/inspections/no-duplicate-query-params.d.ts +2 -1
  28. package/dist/runtime/shared/inspections/no-error-response.d.ts +2 -1
  29. package/dist/runtime/shared/inspections/no-javascript.d.ts +2 -1
  30. package/dist/runtime/shared/inspections/no-missing-href.d.ts +2 -1
  31. package/dist/runtime/shared/inspections/no-non-ascii-chars.d.ts +2 -1
  32. package/dist/runtime/shared/inspections/no-non-ascii-chars.js +2 -1
  33. package/dist/runtime/shared/inspections/no-underscores.d.ts +2 -1
  34. package/dist/runtime/shared/inspections/no-uppercase-chars.d.ts +2 -1
  35. package/dist/runtime/shared/inspections/no-uppercase-chars.js +2 -1
  36. package/dist/runtime/shared/inspections/no-whitespace.d.ts +2 -1
  37. package/dist/runtime/shared/inspections/no-whitespace.js +2 -1
  38. package/dist/runtime/shared/inspections/trailing-slash.d.ts +2 -1
  39. package/dist/runtime/shared/redirects.d.ts +2 -1
  40. package/dist/runtime/shared/sharedUtils.d.ts +8 -4
  41. package/dist/runtime/shared/sharedUtils.js +10 -26
  42. package/package.json +44 -33
  43. package/dist/client/200.html +0 -1
  44. package/dist/client/404.html +0 -1
  45. package/dist/client/_nuxt/C8aYPslm.js +0 -1
  46. package/dist/client/_nuxt/CSiVy0Dp.js +0 -160
  47. package/dist/client/_nuxt/CVO1_9PV.js +0 -1
  48. package/dist/client/_nuxt/Cp-IABpG.js +0 -1
  49. package/dist/client/_nuxt/D0r3Knsf.js +0 -1
  50. package/dist/client/_nuxt/DDvKHl5l.js +0 -1
  51. package/dist/client/_nuxt/OpE9gtc9.js +0 -1
  52. package/dist/client/_nuxt/builds/latest.json +0 -1
  53. package/dist/client/_nuxt/builds/meta/6cac7f03-69dd-420f-9de1-94795b196176.json +0 -1
  54. package/dist/client/_nuxt/entry.vDvfjTuE.css +0 -1
  55. package/dist/client/_nuxt/error-404.DO_nRKko.css +0 -1
  56. package/dist/client/_nuxt/error-500.DwrmseFw.css +0 -1
  57. package/dist/client/_nuxt/uApKdN3K.js +0 -1
  58. package/dist/client/_nuxt/wDzz0qaB.js +0 -1
  59. package/dist/client/index.html +0 -1
package/LICENSE.md CHANGED
@@ -1,6 +1,6 @@
1
1
  MIT License
2
2
 
3
- Copyright (c) 2025 Harlan Wilton
3
+ Copyright (c) 2026 Harlan Wilton
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
6
6
 
package/README.md CHANGED
@@ -27,7 +27,7 @@ need this module.
27
27
  - ✅ 13 SEO focused link inspections
28
28
  - ✨ See live inspections right in your Nuxt App
29
29
  - 🧙 Magically fix them in Nuxt Dev Tools
30
- - 🚩 Generate reports on build (html, markdown)
30
+ - 🚩 Generate reports on build (HTML, markdown)
31
31
 
32
32
  ## Installation
33
33
 
@@ -37,6 +37,12 @@ Install `nuxt-link-checker` dependency to your project:
37
37
  npx nuxi@latest module add link-checker
38
38
  ```
39
39
 
40
+ > [!TIP]
41
+ > Generate an Agent Skill for this package using [skilld](https://github.com/harlan-zw/skilld):
42
+ > ```bash
43
+ > npx skilld add nuxt-link-checker
44
+ > ```
45
+
40
46
  ## Documentation
41
47
 
42
48
  [📖 Read the full documentation](https://nuxtseo.com/link-checker/getting-started/installation) for more information.
@@ -49,7 +55,7 @@ npx nuxi@latest module add link-checker
49
55
 
50
56
  <p align="center">
51
57
  <a href="https://raw.githubusercontent.com/harlan-zw/static/main/sponsors.svg">
52
- <img src='https://raw.githubusercontent.com/harlan-zw/static/main/sponsors.svg'/>
58
+ <img src='https://raw.githubusercontent.com/harlan-zw/static/main/sponsors.svg' alt="Sponsors"/>
53
59
  </a>
54
60
  </p>
55
61
 
@@ -0,0 +1,5 @@
1
+ import { ESLint } from 'eslint';
2
+
3
+ declare const plugin: ESLint.Plugin;
4
+
5
+ export { plugin as default };
@@ -0,0 +1,5 @@
1
+ import { ESLint } from 'eslint';
2
+
3
+ declare const plugin: ESLint.Plugin;
4
+
5
+ export { plugin as default };
@@ -0,0 +1,356 @@
1
+ import { statSync, readFileSync } from 'node:fs';
2
+ import Fuse from 'fuse.js';
3
+ import { join } from 'pathe';
4
+ import { createRouter } from 'radix3';
5
+
6
+ const MD_LINK_RE = /\[([^\]]*)\]\(([^)]+)\)/g;
7
+ const BACKSLASH_RE = /\\/g;
8
+ const SINGLE_QUOTE_RE = /'/g;
9
+ function extractMarkdownLinks(text) {
10
+ const links = [];
11
+ const lines = text.split("\n");
12
+ for (let i = 0; i < lines.length; i++) {
13
+ const line = lines[i];
14
+ MD_LINK_RE.lastIndex = 0;
15
+ let match = MD_LINK_RE.exec(line);
16
+ while (match !== null) {
17
+ const linkText = match[1] ?? "";
18
+ const url = match[2] ?? "";
19
+ const urlStart = match.index + linkText.length + 2;
20
+ links.push({
21
+ url,
22
+ line: i + 1,
23
+ column: urlStart + 1
24
+ });
25
+ match = MD_LINK_RE.exec(line);
26
+ }
27
+ }
28
+ return links;
29
+ }
30
+ const lineMapStack = [];
31
+ const markdownProcessor = {
32
+ meta: {
33
+ name: "link-checker/markdown",
34
+ version: "1.0.0"
35
+ },
36
+ preprocess(text) {
37
+ const links = extractMarkdownLinks(text);
38
+ if (!links.length) {
39
+ lineMapStack.push(/* @__PURE__ */ new Map());
40
+ return [{ text, filename: "0.md" }];
41
+ }
42
+ const virtualLines = [];
43
+ const lineMap = /* @__PURE__ */ new Map();
44
+ for (let i = 0; i < links.length; i++) {
45
+ const link = links[i];
46
+ const escaped = link.url.replace(BACKSLASH_RE, "\\\\").replace(SINGLE_QUOTE_RE, "\\'");
47
+ virtualLines.push(`navigateTo('${escaped}')`);
48
+ lineMap.set(i + 1, link);
49
+ }
50
+ lineMapStack.push(lineMap);
51
+ return [
52
+ { text: virtualLines.join("\n"), filename: "0.js" }
53
+ ];
54
+ },
55
+ postprocess(messages) {
56
+ const lineMap = lineMapStack.pop();
57
+ if (!lineMap || !lineMap.size)
58
+ return messages.flat();
59
+ return messages.flat().map((msg) => {
60
+ const link = lineMap.get(msg.line);
61
+ if (link) {
62
+ return {
63
+ ...msg,
64
+ line: link.line,
65
+ column: link.column
66
+ };
67
+ }
68
+ return msg;
69
+ });
70
+ },
71
+ supportsAutofix: false
72
+ };
73
+
74
+ let cachedRoutes;
75
+ let cachedMtime;
76
+ let cachedPath;
77
+ function loadRoutes(options) {
78
+ const routesFile = options?.routesFile ?? join(options?.rootDir ?? process.cwd(), ".nuxt/link-checker/routes.json");
79
+ let mtime;
80
+ try {
81
+ mtime = statSync(routesFile).mtimeMs;
82
+ } catch {
83
+ return { staticRoutes: [], dynamicRoutes: [] };
84
+ }
85
+ if (cachedRoutes && cachedPath === routesFile && cachedMtime === mtime)
86
+ return cachedRoutes;
87
+ try {
88
+ const data = JSON.parse(readFileSync(routesFile, "utf-8"));
89
+ cachedRoutes = data;
90
+ cachedMtime = mtime;
91
+ cachedPath = routesFile;
92
+ return data;
93
+ } catch {
94
+ return { staticRoutes: [], dynamicRoutes: [] };
95
+ }
96
+ }
97
+ function createSuggester(routes) {
98
+ const fuse = new Fuse(routes, { threshold: 0.5 });
99
+ return (link) => {
100
+ const result = fuse.search(link)?.[0]?.item;
101
+ return result !== link ? result : void 0;
102
+ };
103
+ }
104
+ function createRouteMatcher(dynamicRoutes) {
105
+ const router = createRouter();
106
+ for (const route of dynamicRoutes) {
107
+ router.insert(route, { pattern: route });
108
+ }
109
+ return (path) => {
110
+ const match = router.lookup(path);
111
+ return match ? match.pattern : null;
112
+ };
113
+ }
114
+
115
+ const LINK_ELEMENTS = /* @__PURE__ */ new Set(["a", "NuxtLink", "nuxt-link", "RouterLink", "router-link"]);
116
+ const LINK_ATTRS = /* @__PURE__ */ new Set(["to", "href"]);
117
+ const SKIP_PREFIXES = ["http://", "https://", "//", "mailto:", "tel:", "javascript:", "blob:", "data:", "ftp:"];
118
+ const WHITESPACE_RE = /\s+/;
119
+ const STATIC_FILE_EXTENSIONS = /* @__PURE__ */ new Set([
120
+ ".pdf",
121
+ ".png",
122
+ ".jpg",
123
+ ".jpeg",
124
+ ".gif",
125
+ ".svg",
126
+ ".ico",
127
+ ".webp",
128
+ ".avif",
129
+ ".mp3",
130
+ ".mp4",
131
+ ".webm",
132
+ ".ogg",
133
+ ".wav",
134
+ ".zip",
135
+ ".gz",
136
+ ".tar",
137
+ ".rar",
138
+ ".xml",
139
+ ".txt",
140
+ ".json",
141
+ ".csv",
142
+ ".rss",
143
+ ".atom",
144
+ ".woff",
145
+ ".woff2",
146
+ ".ttf",
147
+ ".eot",
148
+ ".js",
149
+ ".css",
150
+ ".map"
151
+ ]);
152
+ function shouldSkipLink(link) {
153
+ if (!link || link === "#" || link.startsWith("#"))
154
+ return true;
155
+ if (SKIP_PREFIXES.some((prefix) => link.startsWith(prefix)))
156
+ return true;
157
+ const pathname = (link.split("?")[0] ?? "").split("#")[0] ?? "";
158
+ const lastDot = pathname.lastIndexOf(".");
159
+ if (lastDot !== -1 && STATIC_FILE_EXTENSIONS.has(pathname.slice(lastDot).toLowerCase()))
160
+ return true;
161
+ return false;
162
+ }
163
+ function stripQueryAndHash(link) {
164
+ const hashIndex = link.indexOf("#");
165
+ const queryIndex = link.indexOf("?");
166
+ const endIndex = Math.min(
167
+ hashIndex === -1 ? link.length : hashIndex,
168
+ queryIndex === -1 ? link.length : queryIndex
169
+ );
170
+ return link.slice(0, endIndex);
171
+ }
172
+ function hasRelNofollow(element) {
173
+ const attrs = element.startTag?.attributes ?? element.attributes ?? [];
174
+ return attrs.some(
175
+ (attr) => !attr.directive && attr.key?.name === "rel" && typeof attr.value?.value === "string" && attr.value.value.split(WHITESPACE_RE).includes("nofollow")
176
+ );
177
+ }
178
+ function createTemplateVisitors(report) {
179
+ return {
180
+ "VAttribute[directive=false]": function(node) {
181
+ if (!LINK_ATTRS.has(node.key?.name))
182
+ return;
183
+ const parent = node.parent?.parent;
184
+ if (!parent || !LINK_ELEMENTS.has(parent.rawName))
185
+ return;
186
+ if (hasRelNofollow(parent))
187
+ return;
188
+ const value = node.value?.value;
189
+ if (typeof value === "string" && !shouldSkipLink(value))
190
+ report(value, node);
191
+ },
192
+ 'VAttribute[directive=true][key.name.name="bind"]': function(node) {
193
+ if (!LINK_ATTRS.has(node.key?.argument?.name))
194
+ return;
195
+ const parent = node.parent?.parent;
196
+ if (!parent || !LINK_ELEMENTS.has(parent.rawName))
197
+ return;
198
+ if (hasRelNofollow(parent))
199
+ return;
200
+ const expr = node.value?.expression;
201
+ if (expr?.type === "Literal" && typeof expr.value === "string" && !shouldSkipLink(expr.value))
202
+ report(expr.value, expr);
203
+ }
204
+ };
205
+ }
206
+ function createScriptVisitors(report) {
207
+ return {
208
+ CallExpression(node) {
209
+ const callee = node.callee;
210
+ if (!callee)
211
+ return;
212
+ let isNavCall = false;
213
+ if (callee.type === "Identifier" && callee.name === "navigateTo")
214
+ isNavCall = true;
215
+ if (callee.type === "MemberExpression" && callee.object?.type === "Identifier" && callee.object.name === "router" && callee.property?.type === "Identifier" && (callee.property.name === "push" || callee.property.name === "replace")) {
216
+ isNavCall = true;
217
+ }
218
+ if (!isNavCall)
219
+ return;
220
+ const arg = node.arguments?.[0];
221
+ if (arg?.type === "Literal" && typeof arg.value === "string" && !shouldSkipLink(arg.value))
222
+ report(arg.value, arg);
223
+ }
224
+ };
225
+ }
226
+ function createCombinedVisitors(context, check) {
227
+ const isVue = context.filename.endsWith(".vue");
228
+ const scriptVisitors = createScriptVisitors(check);
229
+ if (isVue) {
230
+ const parserServices = context.sourceCode.parserServices;
231
+ if (parserServices?.defineTemplateBodyVisitor) {
232
+ return parserServices.defineTemplateBodyVisitor(
233
+ createTemplateVisitors(check),
234
+ scriptVisitors
235
+ );
236
+ }
237
+ }
238
+ return scriptVisitors;
239
+ }
240
+
241
+ const rule$1 = {
242
+ meta: {
243
+ type: "problem",
244
+ docs: {
245
+ description: "Validate that relative URLs match a known vue-router route pattern"
246
+ },
247
+ schema: [{
248
+ type: "object",
249
+ properties: {
250
+ routesFile: { type: "string" },
251
+ rootDir: { type: "string" }
252
+ },
253
+ additionalProperties: false
254
+ }],
255
+ messages: {
256
+ invalidRoute: 'Link "{{link}}" does not match any known route.{{suggestion}}'
257
+ }
258
+ },
259
+ create(context) {
260
+ const options = context.options[0];
261
+ const routes = loadRoutes({ routesFile: options?.routesFile, rootDir: options?.rootDir });
262
+ if (!routes.staticRoutes.length && !routes.dynamicRoutes.length)
263
+ return {};
264
+ const allStaticSet = new Set(routes.staticRoutes);
265
+ const matchDynamic = createRouteMatcher(routes.dynamicRoutes);
266
+ const suggest = createSuggester(routes.staticRoutes);
267
+ const check = (link, node) => {
268
+ if (!link.startsWith("/"))
269
+ return;
270
+ const pathname = stripQueryAndHash(link);
271
+ if (allStaticSet.has(pathname))
272
+ return;
273
+ if (matchDynamic(pathname))
274
+ return;
275
+ const suggested = suggest(pathname);
276
+ const suggestion = suggested ? ` Did you mean "${suggested}"?` : "";
277
+ context.report({
278
+ node,
279
+ messageId: "invalidRoute",
280
+ data: { link: pathname, suggestion }
281
+ });
282
+ };
283
+ return createCombinedVisitors(context, check);
284
+ }
285
+ };
286
+
287
+ const rule = {
288
+ meta: {
289
+ type: "suggestion",
290
+ docs: {
291
+ description: "Validate that relative URLs exist in the sitemap"
292
+ },
293
+ schema: [{
294
+ type: "object",
295
+ properties: {
296
+ routesFile: { type: "string" },
297
+ rootDir: { type: "string" }
298
+ },
299
+ additionalProperties: false
300
+ }],
301
+ messages: {
302
+ notInSitemap: 'Link "{{link}}" is not in the sitemap.{{suggestion}}'
303
+ }
304
+ },
305
+ create(context) {
306
+ const options = context.options[0];
307
+ const routes = loadRoutes({ routesFile: options?.routesFile, rootDir: options?.rootDir });
308
+ if (!routes.staticRoutes.length)
309
+ return {};
310
+ const staticSet = new Set(routes.staticRoutes);
311
+ const matchDynamic = createRouteMatcher(routes.dynamicRoutes);
312
+ const suggest = createSuggester(routes.staticRoutes);
313
+ const patternsWithSitemapEntries = /* @__PURE__ */ new Set();
314
+ for (const url of routes.staticRoutes) {
315
+ const pattern = matchDynamic(url);
316
+ if (pattern)
317
+ patternsWithSitemapEntries.add(pattern);
318
+ }
319
+ const check = (link, node) => {
320
+ if (!link.startsWith("/"))
321
+ return;
322
+ const pathname = stripQueryAndHash(link);
323
+ if (staticSet.has(pathname))
324
+ return;
325
+ const matchedPattern = matchDynamic(pathname);
326
+ if (matchedPattern) {
327
+ if (!patternsWithSitemapEntries.has(matchedPattern))
328
+ return;
329
+ }
330
+ const suggested = suggest(pathname);
331
+ const suggestion = suggested ? ` Did you mean "${suggested}"?` : "";
332
+ context.report({
333
+ node,
334
+ messageId: "notInSitemap",
335
+ data: { link: pathname, suggestion }
336
+ });
337
+ };
338
+ return createCombinedVisitors(context, check);
339
+ }
340
+ };
341
+
342
+ const plugin = {
343
+ meta: {
344
+ name: "nuxt-link-checker",
345
+ version: "1.0.0"
346
+ },
347
+ rules: {
348
+ "valid-route": rule$1,
349
+ "valid-sitemap-link": rule
350
+ },
351
+ processors: {
352
+ markdown: markdownProcessor
353
+ }
354
+ };
355
+
356
+ export { plugin as default };
package/dist/module.d.mts CHANGED
@@ -18,8 +18,25 @@ interface ModuleOptions {
18
18
  fetchTimeout: number;
19
19
  /**
20
20
  * Links to ignore when running inspections.
21
+ *
22
+ * Supports:
23
+ * - Exact matches: `/about`
24
+ * - Wildcards: `/admin/**`, `/api/*`
25
+ * - RegExp patterns: `/^\\/blog\\/\\d+$/`
26
+ *
27
+ * Uses radix3 route matching for string patterns.
28
+ *
29
+ * @example
30
+ * ```ts
31
+ * excludeLinks: [
32
+ * '/admin/**', // Exclude all admin routes
33
+ * '/api/*', // Exclude direct /api children
34
+ * /^\/blog\/\d+$/, // Exclude blog posts using regex
35
+ * 'https://example.com/**' // Exclude external domain
36
+ * ]
37
+ * ```
21
38
  */
22
- excludeLinks: string[];
39
+ excludeLinks: (string | RegExp)[];
23
40
  /**
24
41
  * Generate a report when using nuxt build` or `nuxt generate`.
25
42
  */
@@ -78,6 +95,19 @@ interface ModuleOptions {
78
95
  * @default true
79
96
  */
80
97
  enabled: boolean;
98
+ /**
99
+ * Pages to exclude from link checking entirely.
100
+ *
101
+ * When a page matches, none of its links will be inspected.
102
+ *
103
+ * Supports the same pattern types as `excludeLinks`:
104
+ * - Exact matches: `/about`
105
+ * - Wildcards: `/admin/**`
106
+ * - RegExp patterns: `/^\/blog\/\d+$/`
107
+ *
108
+ * @default []
109
+ */
110
+ excludePages: (string | RegExp)[];
81
111
  /**
82
112
  * Display debug information.
83
113
  *
@@ -0,0 +1,123 @@
1
+ import * as _nuxt_schema from '@nuxt/schema';
2
+ import { CreateStorageOptions } from 'unstorage';
3
+
4
+ interface ModuleOptions {
5
+ /**
6
+ * Whether the build should fail when a 404 is encountered.
7
+ */
8
+ failOnError: boolean;
9
+ /**
10
+ * Skip specific inspections from running.
11
+ */
12
+ skipInspections: string[];
13
+ /**
14
+ * The timeout for fetching a URL.
15
+ *
16
+ * @default 5000
17
+ */
18
+ fetchTimeout: number;
19
+ /**
20
+ * Links to ignore when running inspections.
21
+ *
22
+ * Supports:
23
+ * - Exact matches: `/about`
24
+ * - Wildcards: `/admin/**`, `/api/*`
25
+ * - RegExp patterns: `/^\\/blog\\/\\d+$/`
26
+ *
27
+ * Uses radix3 route matching for string patterns.
28
+ *
29
+ * @example
30
+ * ```ts
31
+ * excludeLinks: [
32
+ * '/admin/**', // Exclude all admin routes
33
+ * '/api/*', // Exclude direct /api children
34
+ * /^\/blog\/\d+$/, // Exclude blog posts using regex
35
+ * 'https://example.com/**' // Exclude external domain
36
+ * ]
37
+ * ```
38
+ */
39
+ excludeLinks: (string | RegExp)[];
40
+ /**
41
+ * Generate a report when using nuxt build` or `nuxt generate`.
42
+ */
43
+ report?: {
44
+ /**
45
+ * Whether to output a HTML report.
46
+ */
47
+ html?: boolean;
48
+ /**
49
+ * Whether to output a JSON report.
50
+ */
51
+ markdown?: boolean;
52
+ /**
53
+ * Whether to output a JSON report.
54
+ */
55
+ json?: boolean;
56
+ /**
57
+ * Where to store the files.
58
+ *
59
+ * Either provide a path relative to the nuxt root or an object with options for `unstorage`.
60
+ *
61
+ * By default, they'll be in your .output directory.
62
+ */
63
+ storage?: string | CreateStorageOptions;
64
+ /**
65
+ * Whether to publish the reports with the build.
66
+ *
67
+ * By default, will output files at `.output/public/__link-checker__/link-checker-report.<format>`.
68
+ */
69
+ publish?: boolean;
70
+ };
71
+ /**
72
+ * Whether to show live inspections in your Nuxt app.
73
+ */
74
+ showLiveInspections: boolean;
75
+ /**
76
+ * Whether to run the module on `nuxt build` or `nuxt generate`.
77
+ */
78
+ runOnBuild: boolean;
79
+ /**
80
+ * Should remote URLs be fetched.
81
+ *
82
+ * @default false
83
+ */
84
+ fetchRemoteUrls: boolean;
85
+ /**
86
+ * Enable when your nuxt/content files match your pages. This will automatically detect link sources
87
+ * for the current page.
88
+ *
89
+ * This is the same behavior to using `nuxt/content` with `documentDriven: true`.
90
+ */
91
+ strictNuxtContentPaths: boolean;
92
+ /**
93
+ * Whether the module is enabled.
94
+ *
95
+ * @default true
96
+ */
97
+ enabled: boolean;
98
+ /**
99
+ * Pages to exclude from link checking entirely.
100
+ *
101
+ * When a page matches, none of its links will be inspected.
102
+ *
103
+ * Supports the same pattern types as `excludeLinks`:
104
+ * - Exact matches: `/about`
105
+ * - Wildcards: `/admin/**`
106
+ * - RegExp patterns: `/^\/blog\/\d+$/`
107
+ *
108
+ * @default []
109
+ */
110
+ excludePages: (string | RegExp)[];
111
+ /**
112
+ * Display debug information.
113
+ *
114
+ * @default false
115
+ */
116
+ debug: boolean;
117
+ }
118
+ interface ModuleHooks {
119
+ }
120
+ declare const _default: _nuxt_schema.NuxtModule<ModuleOptions, ModuleOptions, false>;
121
+
122
+ export { _default as default };
123
+ export type { ModuleHooks, ModuleOptions };
package/dist/module.json CHANGED
@@ -4,7 +4,7 @@
4
4
  "nuxt": ">=3.9.0"
5
5
  },
6
6
  "configKey": "linkChecker",
7
- "version": "4.3.8",
7
+ "version": "5.0.1",
8
8
  "builder": {
9
9
  "@nuxt/module-builder": "1.0.2",
10
10
  "unbuild": "3.6.1"