New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

nuxt-link-checker

Package Overview
Dependencies
Maintainers
1
Versions
67
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

nuxt-link-checker - npm Package Compare versions

Comparing version 3.0.2 to 3.1.0

dist/client/_nuxt/-0RnDExV.js

2

dist/client/_nuxt/builds/latest.json

@@ -1,1 +0,1 @@

{"id":"7bcc0ccc-7abc-4c7a-a38f-10c82bc8da01","timestamp":1721143475429}
{"id":"3af16b43-4f9f-439e-a21d-22a114ed006f","timestamp":1721923131671}
import * as _nuxt_schema from '@nuxt/schema';
import { DefaultInspections } from '../dist/runtime/pure/inspect.js';
import { CreateStorageOptions } from 'unstorage';

@@ -12,3 +12,3 @@ interface ModuleOptions {

*/
skipInspections: (Partial<keyof typeof DefaultInspections>)[];
skipInspections: string[];
/**

@@ -36,2 +36,14 @@ * The timeout for fetching a URL.

markdown?: boolean;
/**
* Whether to output a JSON report.
*/
json?: boolean;
/**
* Where to store the files.
*
* Either provide a path relative to the nuxt root or an object with options for `unstorage`.
*
* By default, they'll be in your .output directory.
*/
storage?: string | CreateStorageOptions;
};

@@ -38,0 +50,0 @@ /**

@@ -8,3 +8,3 @@ {

"configKey": "linkChecker",
"version": "3.0.1",
"version": "3.0.2",
"builder": {

@@ -11,0 +11,0 @@ "@nuxt/module-builder": "0.8.1",

export declare function serverQueryContent(): {
findOne(): Promise<boolean>;
find(): Promise<never[]>;
};

@@ -5,4 +5,7 @@ export function serverQueryContent() {

return false;
},
async find() {
return [];
}
};
}

@@ -1,2 +0,2 @@

declare const _default: import("h3").EventHandler<import("h3").EventHandlerRequest, Promise<Partial<import("../../../types").LinkInspectionResult>[]>>;
declare const _default: import("h3").EventHandler<import("h3").EventHandlerRequest, Promise<any>>;
export default _default;

@@ -5,12 +5,13 @@ import { defineEventHandler, getHeader, readBody } from "h3";

import { resolve } from "pathe";
import { inspect } from "../../../pure/inspect.js";
import { generateFileLinkDiff, generateFileLinkPreviews, lruFsCache } from "../../../pure/diff.js";
import { getLinkResponse } from "../../../pure/crawl.js";
import { isNonFetchableLink } from "../../../pure/inspections/util.js";
import { isInternalRoute } from "../../util.js";
import { useNitroApp, useNitroOrigin, useRuntimeConfig, useSiteConfig } from "#imports";
import Fuse from "fuse.js";
import { generateFileLinkDiff, generateFileLinkPreviews, getLinkResponse, inspect, isNonFetchableLink, lruFsCache } from "#link-checker/pure";
import { useNitroOrigin, useRuntimeConfig, useSiteConfig } from "#imports";
import { serverQueryContent } from "#content/server";
function isInternalRoute(path) {
const lastSegment = path.split("/").pop() || path;
return lastSegment.includes(".") || path.startsWith("/__") || path.startsWith("@");
}
export default defineEventHandler(async (e) => {
const { tasks, ids } = await readBody(e);
const runtimeConfig = useRuntimeConfig().public["nuxt-link-checker"];
const runtimeConfig = useRuntimeConfig().public["nuxt-link-checker"] || {};
const partialCtx = {

@@ -28,3 +29,3 @@ ids,

lruFsCache.clear();
const pageSearch = useNitroApp()._linkCheckerPageSearch;
const links = await $fetch("/__link-checker__/links");
return Promise.all(

@@ -47,3 +48,6 @@ tasks.map(async ({ link, paths, textContent }) => {

textContent,
pageSearch,
pageSearch: new Fuse(links, {
keys: ["path", "title"],
threshold: 0.5
}),
response,

@@ -50,0 +54,0 @@ skipInspections: runtimeConfig.skipInspections

@@ -1,2 +0,2 @@

declare const _default: import("h3").EventHandler<import("h3").EventHandlerRequest, Promise<any[]>>;
declare const _default: any;
export default _default;

@@ -1,6 +0,20 @@

import { defineEventHandler } from "h3";
import { useRuntimeConfig } from "#imports";
import { createDefu } from "defu";
import { defineCachedEventHandler, useRuntimeConfig } from "#imports";
import pagePaths from "#nuxt-link-checker-sitemap/pages.mjs";
export default defineEventHandler(async () => {
const runtimeConfig = useRuntimeConfig().public["nuxt-link-checker"];
import { serverQueryContent } from "#content/server";
const merger = createDefu((obj, key, value) => {
if (Array.isArray(obj[key]) && Array.isArray(value))
obj[key] = Array.from(/* @__PURE__ */ new Set([...obj[key], ...value]));
return obj[key];
});
function mergeOnKey(arr, key) {
const res = {};
arr.forEach((item) => {
const k = item[key];
res[k] = merger(item, res[k] || {});
});
return Object.values(res);
}
export default defineCachedEventHandler(async (e) => {
const runtimeConfig = useRuntimeConfig().public["nuxt-link-checker"] || {};
const linkDb = [

@@ -12,5 +26,17 @@ ...pagePaths

const entries = sitemapDebug.globalSources.map((source) => source.urls).flat();
linkDb.push(...entries.map((s) => s.loc));
linkDb.push(...entries.map((s) => ({ path: s.loc, title: "" })));
}
return [.../* @__PURE__ */ new Set([...linkDb])];
if (serverQueryContent) {
const contentDocuments = await serverQueryContent(e).find();
if (contentDocuments) {
linkDb.push(...contentDocuments.map((doc) => ({
path: doc._path,
title: doc.title
})));
}
}
return mergeOnKey(linkDb, "link");
}, {
maxAge: 10
// avoid thrashing
});

@@ -1,2 +0,2 @@

import { defineNuxtPlugin } from "#imports";
import { defineNuxtPlugin, useRoute } from "#imports";
export default defineNuxtPlugin((nuxt) => {

@@ -16,4 +16,6 @@ if (typeof document === "undefined" || typeof window === "undefined")

}
const route = useRoute();
import("./view/client.js").then(({ setupLinkCheckerClient }) => {
setupLinkCheckerClient({
route,
nuxt

@@ -20,0 +22,0 @@ });

import type { NuxtApp } from 'nuxt/app';
export declare function setupLinkCheckerClient({ nuxt }: {
import type { useRoute } from '#imports';
export declare function setupLinkCheckerClient({ nuxt, route }: {
nuxt: NuxtApp;
route: ReturnType<typeof useRoute>;
}): Promise<void>;

@@ -6,5 +6,8 @@ import { computed, createApp, h, ref, shallowReactive, unref } from "vue";

import { linkDb } from "./state.js";
import { useRoute, useRuntimeConfig } from "#imports";
import { useRuntimeConfig } from "#imports";
function resolveDevtoolsIframe() {
return document.querySelector("#nuxt-devtools-iframe")?.contentWindow?.__NUXT_DEVTOOLS__;
const iframe = document.querySelector("#nuxt-devtools-iframe");
if (!iframe)
return;
return iframe?.contentWindow?.__NUXT_DEVTOOLS__;
}

@@ -24,3 +27,3 @@ function resolvePathsForEl(el) {

}
export async function setupLinkCheckerClient({ nuxt }) {
export async function setupLinkCheckerClient({ nuxt, route }) {
let queue = [];

@@ -35,7 +38,6 @@ let queueWorkerTimer;

let isOpeningDevtools = false;
const route = useRoute();
let startQueueIdleId;
let startQueueTimeoutId;
const showInspections = useLocalStorage("nuxt-link-checker:show-inspections", true);
const runtimeConfig = useRuntimeConfig().public["nuxt-link-checker"];
const runtimeConfig = useRuntimeConfig().public["nuxt-link-checker"] || {};
const filter = createFilter({

@@ -156,6 +158,3 @@ exclude: runtimeConfig.excludeLinks

} else {
if (typeof devtoolsClient.host.open === "function")
devtoolsClient.host.open();
else
devtoolsClient.host.devtools.open();
devtoolsClient.host.devtools.open();
const srcPath = new URL(devtoolsClient.host.getIframe().src).pathname;

@@ -182,3 +181,3 @@ if (!srcPath.startsWith("/__nuxt_devtools__/client/modules/custom-nuxt-link-checker")) {

if (!startQueueTimeoutId) {
startQueueTimeoutId = setTimeout(() => {
startQueueTimeoutId = window.setTimeout(() => {
client.scanLinks();

@@ -185,0 +184,0 @@ client.startQueueWorker();

import type { LinkInspectionResult, Rule, RuleTestContext } from '../types.js';
export declare const DefaultInspections: {
readonly 'missing-hash': Rule;
readonly 'no-error-response': Rule;
readonly 'no-baseless': Rule;
readonly 'no-javascript': Rule;
readonly 'trailing-slash': Rule;
readonly 'absolute-site-urls': Rule;
readonly redirects: Rule;
readonly 'link-text': Rule;
};
export declare function inspect(ctx: RuleTestContext, rules?: {
readonly 'missing-hash': Rule;
readonly 'no-error-response': Rule;
readonly 'no-baseless': Rule;
readonly 'no-javascript': Rule;
readonly 'trailing-slash': Rule;
readonly 'absolute-site-urls': Rule;
readonly redirects: Rule;
readonly 'link-text': Rule;
}): Partial<LinkInspectionResult>;
export declare const AllInspections: Rule[];
export declare function inspect(ctx: Pick<Required<RuleTestContext>, 'link'> & Omit<Partial<RuleTestContext>, 'link'>, rules?: Rule[]): Partial<LinkInspectionResult>;

@@ -11,13 +11,14 @@ import { parseURL } from "ufo";

import { isNonFetchableLink } from "./inspections/util.js";
export const DefaultInspections = {
"missing-hash": RuleMissingHash(),
"no-error-response": RuleNoErrorResponse(),
"no-baseless": RuleNoBaseLess(),
"no-javascript": RuleNoJavascript(),
"trailing-slash": RuleTrailingSlash(),
"absolute-site-urls": RuleAbsoluteSiteUrls(),
"redirects": RuleRedirects(),
"link-text": RuleDescriptiveLinkText()
};
export function inspect(ctx, rules = DefaultInspections) {
export const AllInspections = [
RuleMissingHash(),
RuleNoErrorResponse(),
RuleNoBaseLess(),
RuleNoJavascript(),
RuleTrailingSlash(),
RuleAbsoluteSiteUrls(),
RuleRedirects(),
RuleDescriptiveLinkText()
];
export function inspect(ctx, rules) {
rules = rules || AllInspections;
const res = { error: [], warning: [], fix: ctx.link, link: ctx.link };

@@ -24,0 +25,0 @@ let link = ctx.link;

@@ -1,9 +0,8 @@

import { parseURL } from "ufo";
import { defineRule } from "./util.js";
export default function RuleAbsoluteSiteUrls() {
return defineRule({
test({ report, link, siteConfig }) {
id: "absolute-site-urls",
test({ report, link, url, siteConfig }) {
if (!link.startsWith(siteConfig.url))
return;
const $url = parseURL(link);
report({

@@ -14,3 +13,3 @@ name: "absolute-site-urls",

tip: "Using internal links that start with / is recommended to avoid issues when deploying your site to different domain names",
fix: $url.pathname,
fix: url.pathname,
fixDescription: `Remove ${siteConfig.url}.`

@@ -17,0 +16,0 @@ });

import { defineRule } from "./util.js";
export default function RuleDescriptiveLinkText() {
return defineRule({
id: "link-text",
test({ textContent, report }) {

@@ -5,0 +6,0 @@ if (typeof textContent === "undefined")

@@ -6,2 +6,3 @@ import Fuse from "fuse.js";

return defineRule({
id: "missing-hash",
test({ link, report, ids, fromPath }) {

@@ -8,0 +9,0 @@ const [path, hash] = link.split("#");

@@ -5,2 +5,3 @@ import { joinURL } from "ufo";

return defineRule({
id: "no-baseless",
test({ link, fromPath, report }) {

@@ -7,0 +8,0 @@ if (link.startsWith("/") || link.startsWith("http") || isNonFetchableLink(link))

import { defineRule, isNonFetchableLink } from "./util.js";
export default function RuleNoErrorResponse() {
return defineRule({
id: "no-error-response",
test({ link, response, report, pageSearch }) {

@@ -13,6 +14,6 @@ if (!response.status || response.status.toString().startsWith("2") || response.status.toString().startsWith("3") || isNonFetchableLink(link))

if (link.startsWith("/") && pageSearch) {
const fix = pageSearch.search(link)?.[0]?.item;
if (fix && fix !== link) {
payload.fix = fix;
payload.fixDescription = `Did you mean ${fix}?`;
const related = pageSearch.search(link)?.[0]?.item;
if (related?.path && related.path !== link) {
payload.fix = related.path;
payload.fixDescription = `Did you mean ${related.path}?`;
}

@@ -19,0 +20,0 @@ } else {

import { defineRule } from "./util.js";
export default function RuleNoJavascript() {
return defineRule({
id: "no-javascript",
test({ link, report }) {

@@ -5,0 +6,0 @@ if (link.startsWith("javascript:")) {

@@ -6,2 +6,3 @@ import { fixSlashes } from "site-config-stack/urls";

return defineRule({
id: "trailing-slash",
test({ report, link, siteConfig }) {

@@ -8,0 +9,0 @@ if (!link.startsWith("/") && !link.startsWith(siteConfig.url))

import { defineRule } from "./inspections/util.js";
export default function RuleRedirects() {
return defineRule({
id: "redirects",
test({ report, response }) {

@@ -5,0 +6,0 @@ if (response.status !== 301 && response.status !== 302)

@@ -1,2 +0,1 @@

import type { FetchResponse } from 'ofetch';
import type { SiteConfigResolved } from 'site-config-stack';

@@ -7,2 +6,3 @@ import type Fuse from 'fuse.js';

export interface Rule {
id: string;
test: (ctx: RuleTestContext) => void;

@@ -16,5 +16,8 @@ }

fromPath: string;
response: FetchResponse<any>;
response: any;
siteConfig: SiteConfigResolved;
pageSearch?: Fuse<string>;
pageSearch?: Fuse<{
path: string;
title: string;
}>;
report: (report: RuleReport) => void;

@@ -21,0 +24,0 @@ skipInspections?: string[];

{
"name": "nuxt-link-checker",
"type": "module",
"version": "3.0.2",
"version": "3.1.0",
"description": "Find and magically fix links that may be negatively effecting your Nuxt sites SEO.",

@@ -31,3 +31,5 @@ "author": {

"ofetch",
"std-env"
"std-env",
"unstorage",
"unstorage/drivers/fs"
]

@@ -42,4 +44,4 @@ },

"@nuxt/devtools-kit": "^1.3.9",
"@nuxt/kit": "^3.12.3",
"@vueuse/core": "^11.0.0-beta.1",
"@nuxt/kit": "^3.12.4",
"@vueuse/core": "^11.0.0-beta.2",
"chalk": "^5.3.0",

@@ -57,13 +59,13 @@ "cheerio": "1.0.0-rc.12",

"site-config-stack": "^2.2.15",
"ufo": "^1.5.3"
"ufo": "^1.5.4"
},
"devDependencies": {
"@antfu/eslint-config": "2.22.4",
"@nuxt/content": "^2.13.1",
"@antfu/eslint-config": "^2.23.2",
"@nuxt/content": "^2.13.2",
"@nuxt/devtools": "^1.3.9",
"@nuxt/module-builder": "0.8.1",
"@nuxt/test-utils": "^3.13.1",
"@nuxt/ui": "^2.17.0",
"@nuxt/ui": "^2.18.1",
"@nuxtjs/eslint-config-typescript": "^12.1.0",
"@nuxtjs/sitemap": "^5.3.4",
"@nuxtjs/sitemap": "^5.3.5",
"@types/diff": "^5.2.1",

@@ -73,11 +75,14 @@ "bumpp": "^9.4.1",

"execa": "^9.3.0",
"nuxt": "^3.12.3",
"vitest": "^2.0.3"
"nuxt": "^3.12.4",
"vitest": "^2.0.4"
},
"resolutions": {
"nuxt-link-checker": "workspace:*"
},
"scripts": {
"build": "nuxt-module-build build --stub && nuxt-module-build prepare && nuxt-module-build build && npm run client:build",
"client:build": "nuxi generate client",
"client:dev": "nuxi dev client --port 3300",
"client:dev": "nuxi dev client --port 3030",
"dev": "npm run play:dev",
"dev:prepare": "nuxt-module-build build --stub && nuxi prepare client",
"dev:prepare": "nuxt-module-build build --stub && nuxt-module-build prepare && nuxi prepare client && nuxi prepare playground",
"play:dev": "nuxi dev playground",

@@ -88,4 +93,5 @@ "play:prod": "npm run build && nuxi dev playground",

"test": "vitest run",
"test:types": "npx nuxi typecheck",
"test:watch": "vitest watch"
}
}

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc