You're Invited:Meet the Socket Team at RSAC and BSidesSF 2026, March 23–26.RSVP
Socket
Book a DemoSign in
Socket

mentoss

Package Overview
Dependencies
Maintainers
1
Versions
19
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

mentoss - npm Package Compare versions

Comparing version
0.11.0
to
0.12.0
+2
-29
dist/fetch-mocker.js

@@ -9,3 +9,3 @@ /**

//-----------------------------------------------------------------------------
import { stringifyRequest } from "./util.js";
import { NoRouteMatchedError } from "./util.js";
import { isCorsSimpleRequest, CorsPreflightData, assertCorsResponse, processCorsResponse, validateCorsRequest, CORS_REQUEST_METHOD, CORS_REQUEST_HEADERS, CORS_ORIGIN, createCorsPreflightError, getUnsafeHeaders, createCorsError, } from "./cors.js";

@@ -25,29 +25,2 @@ import { createCustomRequest } from "./custom-request.js";

/**
* Formats a message for when no route is matched.
* @param {Request} request The request that wasn't matched.
* @param {string|any|FormData|null} body The body of the request.
* @param {Trace[]} traces The traces from the servers.
* @returns {string} The formatted message.
*/
function formatNoRouteMatchedMessage(request, body, traces) {
return `No route matched for ${request.method} ${request.url}.
Full Request:
${stringifyRequest(request, body)}
${traces.length === 0
? "No partial matches found."
: "Partial matches:\n\n" +
traces
.map(trace => {
let traceMessage = `${trace.title}:`;
trace.messages.forEach(message => {
traceMessage += `\n ${message}`;
});
return traceMessage;
})
.join("\n\n")}`;
}
/**
* Creates a base URL from a URL or string. This is also validates

@@ -349,3 +322,3 @@ * the URL to ensure it's valid. Empty strings are invalid.

// throw an error saying the route wasn't matched
throw new Error(formatNoRouteMatchedMessage(request, body, possibleTraces));
throw new NoRouteMatchedError(request, body, possibleTraces);
}

@@ -352,0 +325,0 @@ /**

+10
-0

@@ -131,5 +131,15 @@ /**

/**
* Traces the details of a request pattern to see if it matches any routes.
* @param {RequestPattern|string} request The request pattern to check.
* @returns {{traces:Array<Trace>, matched:boolean}} The trace result with match status.
*/
traceCalled(request: RequestPattern | string): {
traces: Array<Trace>;
matched: boolean;
};
/**
* Determines if a route has been called.
* @param {RequestPattern|string} request The request pattern to check.
* @returns {boolean} `true` if the route was called, `false` if not.
* @throws {Error} If the request pattern doesn't match any registered routes.
*/

@@ -136,0 +146,0 @@ called(request: RequestPattern | string): boolean;

@@ -5,3 +5,3 @@ /**

*/
/* global Response, FormData, setTimeout */
/* global Request, Response, Headers, FormData, setTimeout */
//-----------------------------------------------------------------------------

@@ -12,3 +12,3 @@ // Imports

import { statusTexts } from "./http.js";
import { getBody } from "./util.js";
import { getBody, NoRouteMatchedError } from "./util.js";
//-----------------------------------------------------------------------------

@@ -476,7 +476,61 @@ // Type Definitions

/**
* Traces the details of a request pattern to see if it matches any routes.
* @param {RequestPattern|string} request The request pattern to check.
* @returns {{traces:Array<Trace>, matched:boolean}} The trace result with match status.
*/
traceCalled(request) {
const requestPattern = typeof request === "string"
? { method: "GET", url: request }
: request;
assertValidRequestPattern(requestPattern);
// if the URL doesn't begin with the baseUrl then add it
if (!requestPattern.url.startsWith(this.baseUrl)) {
requestPattern.url = new URL(requestPattern.url, this.baseUrl).href;
}
const allTraces = [];
// Check matched routes and collect traces in a single pass
const matchedRoutes = this.#matchedRoutes;
for (let i = 0; i < matchedRoutes.length; i++) {
const route = matchedRoutes[i];
const trace = route.traceMatches(requestPattern);
// If we found a match, return immediately without building traces
if (trace.matches) {
return { traces: [], matched: true };
}
// Otherwise, store the trace for later use
allTraces.push({ ...trace, title: route.toString() });
}
// Collect traces from unmatched routes
const unmatchedRoutes = this.#unmatchedRoutes;
for (let i = 0; i < unmatchedRoutes.length; i++) {
const route = unmatchedRoutes[i];
const trace = route.traceMatches(requestPattern);
// Only store traces that don't match because this is likely an error
allTraces.push({ ...trace, title: route.toString() });
}
// Filter out traces that only have basic URL mismatch (single message)
// to focus on meaningful partial matches
const meaningfulTraces = allTraces.filter(trace => trace.messages.length > 1);
return { traces: meaningfulTraces, matched: false };
}
/**
* Determines if a route has been called.
* @param {RequestPattern|string} request The request pattern to check.
* @returns {boolean} `true` if the route was called, `false` if not.
* @throws {Error} If the request pattern doesn't match any registered routes.
*/
called(request) {
if (this.#routes.length === 0) {
throw new Error("No routes registered to match against.");
}
const { traces, matched } = this.traceCalled(request);
if (matched) {
return true;
}
// if one of the traces matches then the route hasn't been called yet
if (traces.some(trace => trace.matches)) {
return false;
}
// No routes match this pattern at all, so throw an error
// We need to create a minimal Request-like object for the error
const requestPattern = typeof request === "string"

@@ -486,7 +540,12 @@ ? { method: "GET", url: request }

assertValidRequestPattern(requestPattern);
// if the URL doesn't being with the baseUrl then add it
// if the URL doesn't begin with the baseUrl then add it
if (!requestPattern.url.startsWith(this.baseUrl)) {
requestPattern.url = new URL(requestPattern.url, this.baseUrl).href;
}
return this.#matchedRoutes.some(route => route.matches(requestPattern));
// Create a minimal Request-like object for the error
const mockRequest = new Request(requestPattern.url, {
method: requestPattern.method,
headers: new Headers(requestPattern.headers || {}),
});
throw new NoRouteMatchedError(mockRequest, null, traces);
}

@@ -493,0 +552,0 @@ /**

@@ -34,1 +34,23 @@ /**

}
/**
* Represents an error that occurs when no route matched a request.
* @extends {Error}
*/
export class NoRouteMatchedError extends Error {
/**
* Creates a new NoRouteMatchedError instance.
* @param {Request} request The request that wasn't matched.
* @param {string|any|FormData|null} body The body of the request.
* @param {Array<{title: string, messages: Array<string>}>} traces The traces from the servers.
*/
constructor(request: Request, body: string | any | FormData | null, traces: Array<{
title: string;
messages: Array<string>;
}>);
request: Request;
body: any;
traces: {
title: string;
messages: Array<string>;
}[];
}

@@ -61,2 +61,39 @@ /**

/**
* Represents an error that occurs when no route matched a request.
* @extends {Error}
*/
export class NoRouteMatchedError extends Error {
/**
* Creates a new NoRouteMatchedError instance.
* @param {Request} request The request that wasn't matched.
* @param {string|any|FormData|null} body The body of the request.
* @param {Array<{title: string, messages: Array<string>}>} traces The traces from the servers.
*/
constructor(request, body, traces) {
const message = `No route matched for ${request.method} ${request.url}.
Full Request:
${stringifyRequest(request, body)}
${traces.length === 0
? "No partial matches found."
: "Partial matches:\n\n" +
traces
.map(trace => {
let traceMessage = `${trace.title}:`;
trace.messages.forEach(message => {
traceMessage += `\n ${message}`;
});
return traceMessage;
})
.join("\n\n")}`;
super(message);
this.name = "NoRouteMatchedError";
this.request = request;
this.body = body;
this.traces = traces;
}
}
/**
* Parses a URL and returns a URL object. This is used instead

@@ -63,0 +100,0 @@ * of the URL constructor to provide a standard error message,

{
"name": "mentoss",
"version": "0.11.0",
"version": "0.12.0",
"description": "A utility to mock fetch requests and responses.",

@@ -45,3 +45,3 @@ "type": "module",

"pretest": "npm run build",
"test:unit": "mocha --exit tests/**/*.*",
"test:unit": "mocha --exit --forbid-only tests/**/*.*",
"test:jsr": "npx jsr@latest publish --dry-run",

@@ -48,0 +48,0 @@ "test": "npm run test:unit"