nuxt-link-checker 2.1.1 → 2.1.2
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/client/200.html +2 -2
- package/dist/client/404.html +2 -2
- package/dist/client/_nuxt/{entry.5fe95c60.css → entry.5606e9a3.css} +1 -1
- package/dist/client/_nuxt/{entry.48231557.js → entry.5e22743d.js} +12 -12
- package/dist/client/_nuxt/{error-404.821eb1e0.js → error-404.609b100b.js} +1 -1
- package/dist/client/_nuxt/{error-500.eb30c601.js → error-500.5402d037.js} +1 -1
- package/dist/client/index.html +2 -2
- package/dist/module.d.ts +6 -0
- package/dist/module.json +1 -1
- package/dist/module.mjs +35 -19
- package/dist/runtime/plugin/view/client.mjs +8 -3
- package/dist/runtime/server/api/inspect.d.ts +1 -1
- package/dist/runtime/server/api/inspect.mjs +1 -1
- package/dist/runtime/server/api/links.d.ts +1 -1
- package/dist/runtime/sharedUtils.d.ts +1 -5
- package/dist/runtime/sharedUtils.mjs +8 -3
- package/package.json +12 -11
|
@@ -1 +1 @@
|
|
|
1
|
-
import{_ as a,u as n,o as r,c as l,a as e,t as s,b as c,w as d,d as p,e as f,p as x,f as h}from"./entry.
|
|
1
|
+
import{_ as a,u as n,o as r,c as l,a as e,t as s,b as c,w as d,d as p,e as f,p as x,f as h}from"./entry.5e22743d.js";const m=t=>(x("data-v-ac41e552"),t=t(),h(),t),u={class:"font-sans antialiased bg-white dark:bg-black text-black dark:text-white grid min-h-screen place-content-center overflow-hidden"},g=m(()=>e("div",{class:"fixed left-0 right-0 spotlight z-10"},null,-1)),_={class:"max-w-520px text-center z-20"},b=["textContent"],w=["textContent"],y={class:"w-full flex items-center justify-center"},S={__name:"error-404",props:{appName:{type:String,default:"Nuxt"},version:{type:String,default:""},statusCode:{type:Number,default:404},statusMessage:{type:String,default:"Not Found"},description:{type:String,default:"Sorry, the page you are looking for could not be found."},backHome:{type:String,default:"Go back home"}},setup(t){const o=t;return n({title:`${o.statusCode} - ${o.statusMessage} | ${o.appName}`,script:[],style:[{children:'*,:before,:after{-webkit-box-sizing:border-box;box-sizing:border-box;border-width:0;border-style:solid;border-color:#e0e0e0}*{--tw-ring-inset:var(--tw-empty, );--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-color:rgba(14, 165, 233, .5);--tw-ring-offset-shadow:0 0 #0000;--tw-ring-shadow:0 0 #0000;--tw-shadow:0 0 #0000}:root{-moz-tab-size:4;-o-tab-size:4;tab-size:4}a{color:inherit;text-decoration:inherit}body{margin:0;font-family:inherit;line-height:inherit}html{-webkit-text-size-adjust:100%;font-family:ui-sans-serif,system-ui,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Arial,Noto Sans,sans-serif,"Apple Color Emoji","Segoe UI Emoji",Segoe UI Symbol,"Noto Color Emoji";line-height:1.5}h1,p{margin:0}h1{font-size:inherit;font-weight:inherit}'}]}),(k,v)=>{const i=f;return r(),l("div",u,[g,e("div",_,[e("h1",{class:"text-8xl sm:text-10xl font-medium mb-8",textContent:s(t.statusCode)},null,8,b),e("p",{class:"text-xl px-8 sm:px-0 sm:text-4xl font-light mb-16 leading-tight",textContent:s(t.description)},null,8,w),e("div",y,[c(i,{to:"/",class:"gradient-border text-md sm:text-xl py-2 px-4 sm:py-3 sm:px-6 cursor-pointer"},{default:d(()=>[p(s(t.backHome),1)]),_:1})])])])}}},z=a(S,[["__scopeId","data-v-ac41e552"]]);export{z as default};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{_ as i,u as a,o as r,c as n,a as e,t as s,p as l,f as d}from"./entry.
|
|
1
|
+
import{_ as i,u as a,o as r,c as n,a as e,t as s,p as l,f as d}from"./entry.5e22743d.js";const c=t=>(l("data-v-35000bea"),t=t(),d(),t),p={class:"font-sans antialiased bg-white dark:bg-black text-black dark:text-white grid min-h-screen place-content-center overflow-hidden"},h=c(()=>e("div",{class:"fixed -bottom-1/2 left-0 right-0 h-1/2 spotlight"},null,-1)),f={class:"max-w-520px text-center"},g=["textContent"],m=["textContent"],b={__name:"error-500",props:{appName:{type:String,default:"Nuxt"},version:{type:String,default:""},statusCode:{type:Number,default:500},statusMessage:{type:String,default:"Server error"},description:{type:String,default:"This page is temporarily unavailable."}},setup(t){const o=t;return a({title:`${o.statusCode} - ${o.statusMessage} | ${o.appName}`,script:[],style:[{children:'*,:before,:after{-webkit-box-sizing:border-box;box-sizing:border-box;border-width:0;border-style:solid;border-color:#e0e0e0}*{--tw-ring-inset:var(--tw-empty, );--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-color:rgba(14, 165, 233, .5);--tw-ring-offset-shadow:0 0 #0000;--tw-ring-shadow:0 0 #0000;--tw-shadow:0 0 #0000}:root{-moz-tab-size:4;-o-tab-size:4;tab-size:4}body{margin:0;font-family:inherit;line-height:inherit}html{-webkit-text-size-adjust:100%;font-family:ui-sans-serif,system-ui,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Arial,Noto Sans,sans-serif,"Apple Color Emoji","Segoe UI Emoji",Segoe UI Symbol,"Noto Color Emoji";line-height:1.5}h1,p{margin:0}h1{font-size:inherit;font-weight:inherit}'}]}),(x,u)=>(r(),n("div",p,[h,e("div",f,[e("h1",{class:"text-8xl sm:text-10xl font-medium mb-8",textContent:s(t.statusCode)},null,8,g),e("p",{class:"text-xl px-8 sm:px-0 sm:text-4xl font-light mb-16 leading-tight",textContent:s(t.description)},null,8,m)])]))}},w=i(b,[["__scopeId","data-v-35000bea"]]);export{w as default};
|
package/dist/client/index.html
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
<!DOCTYPE html>
|
|
2
2
|
<html >
|
|
3
3
|
<head><meta charset="utf-8">
|
|
4
|
-
<meta name="viewport" content="width=device-width, initial-scale=1"><link rel="modulepreload" as="script" crossorigin href="/__nuxt-link-checker/_nuxt/entry.
|
|
4
|
+
<meta name="viewport" content="width=device-width, initial-scale=1"><link rel="modulepreload" as="script" crossorigin href="/__nuxt-link-checker/_nuxt/entry.5e22743d.js"><link rel="preload" as="style" href="/__nuxt-link-checker/_nuxt/entry.5606e9a3.css"><link rel="prefetch" as="style" href="/__nuxt-link-checker/_nuxt/error-404.d7252154.css"><link rel="prefetch" as="script" crossorigin href="/__nuxt-link-checker/_nuxt/error-404.609b100b.js"><link rel="prefetch" as="style" href="/__nuxt-link-checker/_nuxt/error-500.06915589.css"><link rel="prefetch" as="script" crossorigin href="/__nuxt-link-checker/_nuxt/error-500.5402d037.js"><link rel="stylesheet" href="/__nuxt-link-checker/_nuxt/entry.5606e9a3.css"><script>"use strict";(()=>{const a=window,e=document.documentElement,m=["dark","light"],c=window.localStorage.getItem("nuxt-color-mode")||"system";let n=c==="system"?f():c;const l=e.getAttribute("data-color-mode-forced");l&&(n=l),i(n),a["__NUXT_COLOR_MODE__"]={preference:c,value:n,getColorScheme:f,addColorScheme:i,removeColorScheme:d};function i(o){const t=""+o+"",s="";e.classList?e.classList.add(t):e.className+=" "+t,s&&e.setAttribute("data-"+s,o)}function d(o){const t=""+o+"",s="";e.classList?e.classList.remove(t):e.className=e.className.replace(new RegExp(t,"g"),""),s&&e.removeAttribute("data-"+s)}function r(o){return a.matchMedia("(prefers-color-scheme"+o+")")}function f(){if(a.matchMedia&&r("").media!=="not all"){for(const o of m)if(r(":"+o).matches)return o}return"light"}})();
|
|
5
5
|
</script></head>
|
|
6
|
-
<body ><div id="__nuxt"><svg class="nuxt-spa-loading" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 37 25" fill="none" width="80"><path d="M24.236 22.006h10.742L25.563 5.822l-8.979 14.31a4 4 0 0 1-3.388 1.874H2.978l11.631-20 5.897 10.567"></path></svg><style>.nuxt-spa-loading{position:fixed;top:50%;left:50%;transform:translate(-50%, -50%)}.nuxt-spa-loading>path{fill:none;stroke:#00DC82;stroke-width:4px;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:128;stroke-dashoffset:128;animation:nuxt-spa-loading-move 3s linear infinite}@keyframes nuxt-spa-loading-move{100%{stroke-dashoffset:-128}}</style></div><script type="application/json" id="__NUXT_DATA__" data-ssr="false">[{"_errors":1,"serverRendered":2,"data":3,"state":4},{},false,{},{}]</script><script>window.__NUXT__={};window.__NUXT__.config={public:{},app:{baseURL:"/__nuxt-link-checker",buildAssetsDir:"/_nuxt/",cdnURL:""}}</script><script type="module" src="/__nuxt-link-checker/_nuxt/entry.
|
|
6
|
+
<body ><div id="__nuxt"><svg class="nuxt-spa-loading" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 37 25" fill="none" width="80"><path d="M24.236 22.006h10.742L25.563 5.822l-8.979 14.31a4 4 0 0 1-3.388 1.874H2.978l11.631-20 5.897 10.567"></path></svg><style>.nuxt-spa-loading{position:fixed;top:50%;left:50%;transform:translate(-50%, -50%)}.nuxt-spa-loading>path{fill:none;stroke:#00DC82;stroke-width:4px;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:128;stroke-dashoffset:128;animation:nuxt-spa-loading-move 3s linear infinite}@keyframes nuxt-spa-loading-move{100%{stroke-dashoffset:-128}}</style></div><script type="application/json" id="__NUXT_DATA__" data-ssr="false">[{"_errors":1,"serverRendered":2,"data":3,"state":4},{},false,{},{}]</script><script>window.__NUXT__={};window.__NUXT__.config={public:{},app:{baseURL:"/__nuxt-link-checker",buildAssetsDir:"/_nuxt/",cdnURL:""}}</script><script type="module" src="/__nuxt-link-checker/_nuxt/entry.5e22743d.js" crossorigin></script></body>
|
|
7
7
|
</html>
|
package/dist/module.d.ts
CHANGED
|
@@ -78,6 +78,12 @@ interface ModuleOptions {
|
|
|
78
78
|
* Whether to run the module on `nuxt build` or `nuxt generate`.
|
|
79
79
|
*/
|
|
80
80
|
runOnBuild: boolean;
|
|
81
|
+
/**
|
|
82
|
+
* Should remote URLs be fetched.
|
|
83
|
+
*
|
|
84
|
+
* @default true (disabled in stackblitz)
|
|
85
|
+
*/
|
|
86
|
+
fetchRemoteUrls: boolean;
|
|
81
87
|
/**
|
|
82
88
|
* Whether the module is enabled.
|
|
83
89
|
*
|
package/dist/module.json
CHANGED
package/dist/module.mjs
CHANGED
|
@@ -1,13 +1,15 @@
|
|
|
1
1
|
import { useNuxt, extendPages, defineNuxtModule, useLogger, createResolver, addPlugin, addServerHandler, addServerPlugin, hasNuxtModule } from '@nuxt/kit';
|
|
2
2
|
import { useSiteConfig, installNuxtSiteConfig, updateSiteConfig } from 'nuxt-site-config-kit';
|
|
3
|
+
import { provider } from 'std-env';
|
|
3
4
|
import fs, { readFile, writeFile } from 'node:fs/promises';
|
|
4
5
|
import chalk from 'chalk';
|
|
5
6
|
import Fuse from 'fuse.js';
|
|
6
|
-
import { resolve } from 'pathe';
|
|
7
|
+
import { resolve, relative } from 'pathe';
|
|
7
8
|
import { load } from 'cheerio';
|
|
8
9
|
import { parseURL, joinURL } from 'ufo';
|
|
9
10
|
import { fixSlashes } from 'site-config-stack';
|
|
10
11
|
import { toRouteMatcher, createRouter } from 'radix3';
|
|
12
|
+
import { $fetch } from 'ofetch';
|
|
11
13
|
import { existsSync } from 'node:fs';
|
|
12
14
|
import { onDevToolsInitialized, extendServerRpc } from '@nuxt/devtools-kit';
|
|
13
15
|
import { diffLines, diffArrays } from 'diff';
|
|
@@ -238,17 +240,21 @@ function createFilter(options = {}) {
|
|
|
238
240
|
};
|
|
239
241
|
}
|
|
240
242
|
async function crawlFetch(link, options = {}) {
|
|
241
|
-
const
|
|
243
|
+
const $ = options.fetch || $fetch;
|
|
242
244
|
const timeout = options.timeout || 5e3;
|
|
243
245
|
const timeoutController = new AbortController();
|
|
244
246
|
const abortRequestTimeout = setTimeout(() => timeoutController.abort(), timeout);
|
|
245
|
-
return await
|
|
247
|
+
return await $(link, {
|
|
246
248
|
method: "HEAD",
|
|
247
249
|
signal: timeoutController.signal,
|
|
248
250
|
headers: {
|
|
249
251
|
"user-agent": "Nuxt Link Checker"
|
|
250
252
|
}
|
|
251
|
-
}).catch(() =>
|
|
253
|
+
}).catch((error) => {
|
|
254
|
+
if (error.name === "AbortError")
|
|
255
|
+
return { status: 408, statusText: "Request Timeout", headers: {} };
|
|
256
|
+
return { status: 404, statusText: "Not Found", headers: {} };
|
|
257
|
+
}).finally(() => clearTimeout(abortRequestTimeout));
|
|
252
258
|
}
|
|
253
259
|
|
|
254
260
|
const responses = {};
|
|
@@ -259,10 +265,14 @@ function extractPayload(html) {
|
|
|
259
265
|
const links = $("#__nuxt a[href]").map((i, el) => $(el).attr("href")).get();
|
|
260
266
|
return { ids, links };
|
|
261
267
|
}
|
|
262
|
-
async function getLinkResponse(link, timeout) {
|
|
268
|
+
async function getLinkResponse(link, timeout, fetchRemoteUrls) {
|
|
263
269
|
const response = responses[link];
|
|
264
270
|
if (!response) {
|
|
265
|
-
|
|
271
|
+
if (isInvalidLinkProtocol(link) || link.startsWith("#") || link.startsWith("http") && fetchRemoteUrls) {
|
|
272
|
+
responses[link] = Promise.resolve({ status: 200, statusText: "OK", headers: {} });
|
|
273
|
+
} else {
|
|
274
|
+
responses[link] = crawlFetch(link, { timeout });
|
|
275
|
+
}
|
|
266
276
|
}
|
|
267
277
|
return responses[link];
|
|
268
278
|
}
|
|
@@ -276,7 +286,7 @@ function prerender(config, nuxt = useNuxt()) {
|
|
|
276
286
|
if (ctx.contents && !ctx.error && ctx.fileName?.endsWith(".html") && !ctx.route.endsWith(".html") && urlFilter(ctx.route)) {
|
|
277
287
|
linkMap[ctx.route] = extractPayload(ctx.contents);
|
|
278
288
|
linkMap[ctx.route].links.forEach((link) => {
|
|
279
|
-
getLinkResponse(link, config.fetchTimeout);
|
|
289
|
+
getLinkResponse(link, config.fetchTimeout, config.fetchRemoteUrls);
|
|
280
290
|
});
|
|
281
291
|
}
|
|
282
292
|
responses[ctx.route] = Promise.resolve({ status: Number(ctx.error?.statusCode) || 200, statusText: ctx.error?.statusMessage || "" });
|
|
@@ -294,7 +304,7 @@ function prerender(config, nuxt = useNuxt()) {
|
|
|
294
304
|
let errorCount = 0;
|
|
295
305
|
await Promise.all(payloads.map(async ([route, payload]) => {
|
|
296
306
|
const reports = await Promise.all(payload.links.map(async (link) => {
|
|
297
|
-
const response = await getLinkResponse(link);
|
|
307
|
+
const response = await getLinkResponse(link, config.fetchTimeout, config.fetchRemoteUrls);
|
|
298
308
|
return inspect({
|
|
299
309
|
ids: linkMap[route].ids,
|
|
300
310
|
fromPath: route,
|
|
@@ -368,7 +378,7 @@ function prerender(config, nuxt = useNuxt()) {
|
|
|
368
378
|
</html>
|
|
369
379
|
`;
|
|
370
380
|
await fs.writeFile(resolve(nitro.options.output.dir, "link-checker-report.html"), html);
|
|
371
|
-
nitro.logger.info(`Nuxt Link Checker
|
|
381
|
+
nitro.logger.info(`Nuxt Link Checker HTML report written to ${relative(nuxt.options.rootDir, resolve(nitro.options.output.dir, "link-checker-report.html"))}`);
|
|
372
382
|
}
|
|
373
383
|
}
|
|
374
384
|
if (config.report?.markdown) {
|
|
@@ -376,27 +386,26 @@ function prerender(config, nuxt = useNuxt()) {
|
|
|
376
386
|
const reportMarkdown = reports.map((r) => {
|
|
377
387
|
const errors2 = r.error?.map((error) => {
|
|
378
388
|
return `| ${r.link} | ${error.message} (${error.name}) |`;
|
|
379
|
-
})
|
|
389
|
+
});
|
|
380
390
|
const warnings2 = r.warning?.map((warning) => {
|
|
381
391
|
return `| ${r.link} | ${warning.message} (${warning.name}) |`;
|
|
382
|
-
})
|
|
383
|
-
return
|
|
384
|
-
}).join("");
|
|
392
|
+
});
|
|
393
|
+
return [errors2, warnings2];
|
|
394
|
+
}).flat().filter(Boolean).join("\n");
|
|
385
395
|
const markdown = [
|
|
386
396
|
"# Link Checker Report",
|
|
387
397
|
"",
|
|
388
398
|
"| Link | Message |",
|
|
389
|
-
"| --- | --- |"
|
|
390
|
-
|
|
391
|
-
].join("\n");
|
|
399
|
+
"| --- | --- |"
|
|
400
|
+
].join("\n") + reportMarkdown;
|
|
392
401
|
await fs.writeFile(resolve(nitro.options.output.dir, "link-checker-report.md"), markdown);
|
|
393
|
-
nitro.logger.info(`Nuxt Link Checker
|
|
402
|
+
nitro.logger.info(`Nuxt Link Checker Markdown report written to ${relative(nuxt.options.rootDir, resolve(nitro.options.output.dir, "link-checker-report.md"))}`);
|
|
394
403
|
}
|
|
395
404
|
}
|
|
396
405
|
}));
|
|
397
406
|
if (errorCount > 0 && config.failOnError) {
|
|
398
407
|
nitro.logger.error(`Nuxt Link Checker found ${errorCount} errors, failing build.`);
|
|
399
|
-
nitro.logger.log(chalk.gray('You can disable this by setting "linkChecker: {
|
|
408
|
+
nitro.logger.log(chalk.gray('You can disable this by setting "linkChecker: { failOnError: false }" in your nuxt.config.'));
|
|
400
409
|
process.exit(1);
|
|
401
410
|
}
|
|
402
411
|
});
|
|
@@ -568,6 +577,7 @@ const module = defineNuxtModule({
|
|
|
568
577
|
configKey: "linkChecker"
|
|
569
578
|
},
|
|
570
579
|
defaults: {
|
|
580
|
+
fetchRemoteUrls: provider !== "stackblitz",
|
|
571
581
|
runOnBuild: true,
|
|
572
582
|
debug: false,
|
|
573
583
|
showLiveInspections: true,
|
|
@@ -593,6 +603,11 @@ const module = defineNuxtModule({
|
|
|
593
603
|
host: config.host
|
|
594
604
|
});
|
|
595
605
|
}
|
|
606
|
+
if (config.fetchRemoteUrls) {
|
|
607
|
+
config.fetchRemoteUrls = (await crawlFetch("https://google.com")).status === 200;
|
|
608
|
+
if (!config.fetchRemoteUrls)
|
|
609
|
+
logger.warn("Remote URL fetching is disabled because https://google.com could not be fetched.");
|
|
610
|
+
}
|
|
596
611
|
const isDevToolsEnabled = typeof nuxt.options.devtools === "boolean" ? nuxt.options.devtools : nuxt.options.devtools.enabled;
|
|
597
612
|
if (nuxt.options.dev && isDevToolsEnabled) {
|
|
598
613
|
addPlugin({
|
|
@@ -624,7 +639,8 @@ const module = defineNuxtModule({
|
|
|
624
639
|
excludeLinks: config.excludeLinks,
|
|
625
640
|
skipInspections: config.skipInspections,
|
|
626
641
|
fetchTimeout: config.fetchTimeout,
|
|
627
|
-
showLiveInspections: config.showLiveInspections
|
|
642
|
+
showLiveInspections: config.showLiveInspections,
|
|
643
|
+
fetchRemoteUrls: config.fetchRemoteUrls
|
|
628
644
|
};
|
|
629
645
|
setupDevToolsUI(config, resolve);
|
|
630
646
|
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { computed, createApp, h, ref, shallowReactive, unref } from "vue";
|
|
2
|
+
import { useLocalStorage } from "@vueuse/core";
|
|
2
3
|
import { createFilter } from "../../sharedUtils.mjs";
|
|
3
4
|
import Main from "./Main.vue";
|
|
4
5
|
import { linkDb } from "./state.mjs";
|
|
@@ -28,7 +29,7 @@ export async function setupLinkCheckerClient({ nuxt }) {
|
|
|
28
29
|
const route = useRoute();
|
|
29
30
|
let startQueueIdleId;
|
|
30
31
|
let startQueueTimeoutId;
|
|
31
|
-
const showInspections =
|
|
32
|
+
const showInspections = useLocalStorage("nuxt-link-checker:show-inspections", true);
|
|
32
33
|
const runtimeConfig = useRuntimeConfig().public["nuxt-link-checker"];
|
|
33
34
|
const filter = createFilter({
|
|
34
35
|
exclude: runtimeConfig.excludeLinks
|
|
@@ -130,7 +131,7 @@ export async function setupLinkCheckerClient({ nuxt }) {
|
|
|
130
131
|
devtoolsButton.dispatchEvent(new MouseEvent("click", { bubbles: true }));
|
|
131
132
|
const interval = setInterval(() => {
|
|
132
133
|
devtoolsClient = resolveDevtoolsIframe();
|
|
133
|
-
if (devtoolsClient && devtoolsClient.host
|
|
134
|
+
if (devtoolsClient && devtoolsClient.host?.getIframe()) {
|
|
134
135
|
devtoolsClient.host.getIframe().src = `/__nuxt_devtools__/client/modules/custom-nuxt-link-checker?link=${encodeURIComponent(link)}`;
|
|
135
136
|
isOpeningDevtools = false;
|
|
136
137
|
clearInterval(interval);
|
|
@@ -138,7 +139,11 @@ export async function setupLinkCheckerClient({ nuxt }) {
|
|
|
138
139
|
}, 250);
|
|
139
140
|
}
|
|
140
141
|
} else {
|
|
141
|
-
devtoolsClient.host.open
|
|
142
|
+
if (typeof devtoolsClient.host.open === "function") {
|
|
143
|
+
devtoolsClient.host.open();
|
|
144
|
+
} else {
|
|
145
|
+
devtoolsClient.host.devtools.open();
|
|
146
|
+
}
|
|
142
147
|
const srcPath = new URL(devtoolsClient.host.getIframe().src).pathname;
|
|
143
148
|
if (!srcPath.startsWith("/__nuxt_devtools__/client/modules/custom-nuxt-link-checker")) {
|
|
144
149
|
devtoolsClient.host.getIframe().src = `/__nuxt_devtools__/client/modules/custom-nuxt-link-checker?link=${encodeURIComponent(link)}`;
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
declare const _default: import("h3").EventHandler<Partial<import("../../types").LinkInspectionResult
|
|
1
|
+
declare const _default: import("h3").EventHandler<import("h3").EventHandlerRequest, Promise<Partial<import("../../types").LinkInspectionResult>>>;
|
|
2
2
|
export default _default;
|
|
@@ -19,7 +19,7 @@ export default defineEventHandler(async (e) => {
|
|
|
19
19
|
};
|
|
20
20
|
const runtimeConfig = useRuntimeConfig().public["nuxt-link-checker"];
|
|
21
21
|
let response;
|
|
22
|
-
if (isInvalidLinkProtocol(link) || link.startsWith("#")) {
|
|
22
|
+
if (isInvalidLinkProtocol(link) || link.startsWith("#") || link.startsWith("http") && runtimeConfig.fetchRemoteUrls) {
|
|
23
23
|
response = { status: 200, statusText: "OK", headers: {} };
|
|
24
24
|
} else {
|
|
25
25
|
response = await crawlFetch(link, {
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
declare const _default: import("h3").EventHandler<any[]
|
|
1
|
+
declare const _default: import("h3").EventHandler<import("h3").EventHandlerRequest, Promise<any[]>>;
|
|
2
2
|
export default _default;
|
|
@@ -6,8 +6,4 @@ export declare function createFilter(options?: CreateFilterOptions): (path: stri
|
|
|
6
6
|
export declare function crawlFetch(link: string, options?: {
|
|
7
7
|
fetch?: typeof globalThis.fetch;
|
|
8
8
|
timeout?: number;
|
|
9
|
-
}): Promise<
|
|
10
|
-
status: number;
|
|
11
|
-
statusText: string;
|
|
12
|
-
headers: {};
|
|
13
|
-
}>;
|
|
9
|
+
}): Promise<any>;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { createRouter, toRouteMatcher } from "radix3";
|
|
2
|
+
import { $fetch } from "ofetch";
|
|
2
3
|
export function createFilter(options = {}) {
|
|
3
4
|
const include = options.include || [];
|
|
4
5
|
const exclude = options.exclude || [];
|
|
@@ -26,15 +27,19 @@ export function createFilter(options = {}) {
|
|
|
26
27
|
};
|
|
27
28
|
}
|
|
28
29
|
export async function crawlFetch(link, options = {}) {
|
|
29
|
-
const
|
|
30
|
+
const $ = options.fetch || $fetch;
|
|
30
31
|
const timeout = options.timeout || 5e3;
|
|
31
32
|
const timeoutController = new AbortController();
|
|
32
33
|
const abortRequestTimeout = setTimeout(() => timeoutController.abort(), timeout);
|
|
33
|
-
return await
|
|
34
|
+
return await $(link, {
|
|
34
35
|
method: "HEAD",
|
|
35
36
|
signal: timeoutController.signal,
|
|
36
37
|
headers: {
|
|
37
38
|
"user-agent": "Nuxt Link Checker"
|
|
38
39
|
}
|
|
39
|
-
}).catch(() =>
|
|
40
|
+
}).catch((error) => {
|
|
41
|
+
if (error.name === "AbortError")
|
|
42
|
+
return { status: 408, statusText: "Request Timeout", headers: {} };
|
|
43
|
+
return { status: 404, statusText: "Not Found", headers: {} };
|
|
44
|
+
}).finally(() => clearTimeout(abortRequestTimeout));
|
|
40
45
|
}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "nuxt-link-checker",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "2.1.
|
|
4
|
+
"version": "2.1.2",
|
|
5
5
|
"packageManager": "pnpm@8.6.12",
|
|
6
6
|
"license": "MIT",
|
|
7
7
|
"funding": "https://github.com/sponsors/harlan-zw",
|
|
@@ -22,7 +22,8 @@
|
|
|
22
22
|
},
|
|
23
23
|
"build": {
|
|
24
24
|
"externals": [
|
|
25
|
-
"ofetch"
|
|
25
|
+
"ofetch",
|
|
26
|
+
"std-env"
|
|
26
27
|
]
|
|
27
28
|
},
|
|
28
29
|
"main": "./dist/module.cjs",
|
|
@@ -31,35 +32,35 @@
|
|
|
31
32
|
"dist"
|
|
32
33
|
],
|
|
33
34
|
"dependencies": {
|
|
34
|
-
"@nuxt/devtools-kit": "^0.
|
|
35
|
-
"@nuxt/devtools-ui-kit": "^0.
|
|
35
|
+
"@nuxt/devtools-kit": "^0.8.0",
|
|
36
|
+
"@nuxt/devtools-ui-kit": "^0.8.0",
|
|
36
37
|
"@nuxt/kit": "^3.6.5",
|
|
37
38
|
"@vueuse/core": "^10.3.0",
|
|
38
39
|
"chalk": "^5.3.0",
|
|
39
40
|
"cheerio": "1.0.0-rc.12",
|
|
40
41
|
"diff": "^5.1.0",
|
|
41
42
|
"fuse.js": "^6.6.2",
|
|
42
|
-
"magic-string": "^0.30.
|
|
43
|
+
"magic-string": "^0.30.3",
|
|
43
44
|
"nuxt-site-config": "1.0.10",
|
|
44
45
|
"nuxt-site-config-kit": "1.0.10",
|
|
45
46
|
"pathe": "^1.1.1",
|
|
46
|
-
"radix3": "^1.0
|
|
47
|
+
"radix3": "^1.1.0",
|
|
47
48
|
"shiki-es": "^0.14.0",
|
|
48
49
|
"sirv": "^2.0.3",
|
|
49
50
|
"site-config-stack": "^1.0.10",
|
|
50
51
|
"ufo": "^1.2.0"
|
|
51
52
|
},
|
|
52
53
|
"devDependencies": {
|
|
53
|
-
"@antfu/eslint-config": "^0.
|
|
54
|
+
"@antfu/eslint-config": "^0.41.0",
|
|
54
55
|
"@nuxt/module-builder": "^0.4.0",
|
|
55
56
|
"@nuxt/test-utils": "^3.6.5",
|
|
56
57
|
"@nuxtjs/eslint-config-typescript": "^12.0.0",
|
|
57
58
|
"@types/diff": "^5.0.3",
|
|
58
|
-
"bumpp": "^9.
|
|
59
|
-
"eslint": "8.
|
|
60
|
-
"execa": "^
|
|
59
|
+
"bumpp": "^9.2.0",
|
|
60
|
+
"eslint": "8.47.0",
|
|
61
|
+
"execa": "^8.0.1",
|
|
61
62
|
"nuxt": "^3.6.5",
|
|
62
|
-
"vitest": "^0.34.
|
|
63
|
+
"vitest": "^0.34.2"
|
|
63
64
|
},
|
|
64
65
|
"scripts": {
|
|
65
66
|
"build": "npm run prepack",
|