Repository: wheresrhys/fetch-mock
Pull request #755 (2024-07-24 22:32:43)

mock and spy methods


Patch:
diff --git a/docs/docs/@fetch-mock/core/mocking-and-spying.md b/docs/docs/@fetch-mock/core/mocking-and-spying.md
new file mode 100644
index 0000000..8c9efa4
--- /dev/null
+++ b/docs/docs/@fetch-mock/core/mocking-and-spying.md
@@ -0,0 +1,33 @@
+---
+sidebar_position: 3
+---
+
+# Mocking and spying
+
+These methods allow mocking or spying on the `fetch` implementation used by your application.
+
+Note that these methods are only implemented in `@fetch-mock/core` and are not avilable when using `@fetch-mock/jest`, `@fetch-mock/vitest` etc.... Those libraries provide ways to mock `fetch` that are more idiomatic to their own ecosystem.
+
+Wrapper around @fetch-mock/core that implements mocking of global fetch, including spying on and falling through to the native fetch implementation.
+
+In addition to the @fetch-mock/core API its methods are:
+
+## When using global fetch in your application
+
+### mockGlobal()
+
+Replaces `globalThis.fetch` with `fm.fetchHandler`
+
+### unmockGlobal()
+
+Restores `globalThis.fetch` to its original state
+
+### spy(matcher, name)
+
+Falls back to the `fetch` implementation set in `fetchMock.config.fetch` for a specific route (which can be named).
+
+When no arguments are provided it will fallback to the native fetch implementation for all requests, similar to `.catch()`
+
+### spyGlobal()
+
+Equivalent to calling `.mockGlobal()` followed by `.spy()`
diff --git a/docs/docs/@fetch-mock/core/resetting.md b/docs/docs/@fetch-mock/core/resetting.md
index 98072f3..06cebfc 100644
--- a/docs/docs/@fetch-mock/core/resetting.md
+++ b/docs/docs/@fetch-mock/core/resetting.md
@@ -26,6 +26,10 @@ A boolean indicating whether or not to remove the fallback route (added using `.
 
 Clears all data recorded for `fetch`'s calls.
 
+## unmockGlobal()
+
+Restores global `fetch` to its original state if `.mockGlobal()` or `.spyGlobal()` have been used .
+
 ## .createInstance()
 
 Can be used to create a standalone instance of fetch mock that is completely independent of other instances.
diff --git a/package.json b/package.json
index fc45003..99b08d6 100644
--- a/package.json
+++ b/package.json
@@ -29,7 +29,7 @@
     "types:check": "tsc --project ./jsconfig.json && echo 'types check done'",
     "types:lint": "dtslint --expectOnly packages/fetch-mock/types",
     "prepare": "husky || echo \"husky not available\"",
-    "build": "npm run build -w=packages/fetch-mock -w=packages/core",
+    "build": "npm run build -w=packages",
     "docs": "npm run start -w docs",
     "test:ci": "vitest .",
     "test:legacy": "vitest ./packages/fetch-mock/test/specs",
diff --git a/packages/core/src/CallHistory.js b/packages/core/src/CallHistory.js
index c5136de..873d415 100644
--- a/packages/core/src/CallHistory.js
+++ b/packages/core/src/CallHistory.js
@@ -11,7 +11,7 @@ import Router from './Router.js';
 
 /**
  * @typedef CallLog
- * @property {any[]} arguments
+ * @property {any[]} args
  * @property {string} url
  * @property {NormalizedRequestOptions} options
  * @property {Request} [request]
diff --git a/packages/core/src/FetchMock.js b/packages/core/src/FetchMock.js
index 9bedfef..3151906 100644
--- a/packages/core/src/FetchMock.js
+++ b/packages/core/src/FetchMock.js
@@ -20,7 +20,7 @@ import * as requestUtils from './RequestUtils.js';
 
 /**
  * @typedef FetchImplementations
- * @property {function(string | Request, RequestInit): Promise<Response>} [fetch]
+ * @property {typeof fetch} [fetch]
  * @property {typeof Headers} [Headers]
  * @property {typeof Request} [Request]
  * @property {typeof Response} [Response]
@@ -96,7 +96,7 @@ const defineGreedyShorthand = (shorthandOptions) => {
 	};
 };
 
-class FetchMock {
+export class FetchMock {
 	/**
 	 *
 	 * @param {FetchMockConfig} config
@@ -119,7 +119,7 @@ class FetchMock {
 	}
 	/**
 	 *
-	 * @param {string | Request} requestInput
+	 * @param {string | URL | Request} requestInput
 	 * @param {RequestInit} [requestInit]
 	 * @this {FetchMock}
 	 * @returns {Promise<Response>}
@@ -162,7 +162,6 @@ class FetchMock {
 	 * @param {RouteResponse} [response]
 	 * @param {UserRouteConfig | string} [options]
 	 * @this {FetchMock}
-	 * @returns {FetchMock}
 	 */
 	route(matcher, response, options) {
 		this.router.addRoute(matcher, response, options);
@@ -172,7 +171,6 @@ class FetchMock {
 	 *
 	 * @param {RouteResponse} [response]
 	 * @this {FetchMock}
-	 * @returns {FetchMock}
 	 */
 	catch(response) {
 		this.router.setFallback(response);
@@ -193,15 +191,13 @@ class FetchMock {
 	 * @param {boolean} [options.includeSticky]
 	 * @param {boolean} [options.includeFallback]
 	 * @this {FetchMock}
-	 * @returns {FetchMock}
 	 */
 	removeRoutes(options) {
 		this.router.removeRoutes(options);
 		return this;
 	}
 	/**
-	 *
-	 * @returns {FetchMock}
+	 * @this {FetchMock}
 	 */
 	clearHistory() {
 		this.callHistory.clear();
@@ -225,6 +221,55 @@ class FetchMock {
 	patchOnce = defineShorthand({ method: 'patch', repeat: 1 });
 }
 
-const fetchMock = new FetchMock({ ...defaultConfig }).createInstance();
+class FetchMockStandalone extends FetchMock {
+	/** @type {typeof fetch} */
+	#originalFetch = null;
+	/**
+	 * @this {FetchMockStandalone}
+	 */
+	mockGlobal() {
+		globalThis.fetch = this.fetchHandler.bind(this);
+		return this;
+	}
+	/**
+	 * @this {FetchMockStandalone}
+	 */
+	unmockGlobal() {
+		globalThis.fetch = this.config.fetch;
+		return this;
+	}
+
+	/**
+	 * @param {RouteMatcher | UserRouteConfig} [matcher]
+	 * @param {RouteName} [name]
+	 * @this {FetchMockStandalone}
+	 */
+	spy(matcher, name) {
+		if (matcher) {
+			// @ts-ignore
+			this.route(matcher, ({ args }) => this.config.fetch(...args), name);
+		} else {
+			// @ts-ignore
+			this.catch(({ args }) => this.config.fetch(...args));
+		}
+
+		return this;
+	}
+	/**
+	 * @this {FetchMockStandalone}
+	 */
+	spyGlobal() {
+		this.mockGlobal();
+		return this.spy();
+	}
+
+	createInstance() {
+		return new FetchMockStandalone({ ...this.config }, this.router);
+	}
+}
+
+const fetchMock = new FetchMockStandalone({
+	...defaultConfig,
+}).createInstance();
 
 export default fetchMock;
diff --git a/packages/core/src/RequestUtils.js b/packages/core/src/RequestUtils.js
index e4a5b94..5fc18eb 100644
--- a/packages/core/src/RequestUtils.js
+++ b/packages/core/src/RequestUtils.js
@@ -45,7 +45,7 @@ export function createCallLogFromUrlAndOptions(url, options) {
 		// @ts-ignore - jsdoc doesn't distinguish between string and String, but typechecker complains
 		url = normalizeUrl(url);
 		return {
-			arguments: [url, options],
+			args: [url, options],
 			url,
 			queryParams: new URLSearchParams(getQuery(url)),
 			options: options || {},
@@ -85,7 +85,7 @@ export async function createCallLogFromRequest(request, options) {
 	}
 	const url = normalizeUrl(request.url);
 	const callLog = {
-		arguments: [request, options],
+		args: [request, options],
 		url,
 		queryParams: new URLSearchParams(getQuery(url)),
 		options: Object.assign(derivedOptions, options || {}),
diff --git a/packages/core/src/Router.js b/packages/core/src/Router.js
index da82d96..1641518 100644
--- a/packages/core/src/Router.js
+++ b/packages/core/src/Router.js
@@ -185,7 +185,6 @@ export default class Router {
 				? [...this.routes, this.fallbackRoute]
 				: this.routes;
 			const route = routesToTry.find((route) => route.matcher(callLog));
-
 			if (route) {
 				try {
 					callLog.route = route;
diff --git a/packages/core/src/index.js b/packages/core/src/index.js
index 75a2590..39686b2 100644
--- a/packages/core/src/index.js
+++ b/packages/core/src/index.js
@@ -1,2 +1,3 @@
-import fetchMock from './FetchMock.js';
+import fetchMock, { FetchMock } from './FetchMock.js';
 export default fetchMock;
+export { FetchMock };
diff --git a/packages/core/types/CallHistory.d.ts b/packages/core/types/CallHistory.d.ts
index f50b9a3..902e048 100644
--- a/packages/core/types/CallHistory.d.ts
+++ b/packages/core/types/CallHistory.d.ts
@@ -5,7 +5,7 @@ export type NormalizedRequestOptions = import("./RequestUtils.js").NormalizedReq
 export type RouteMatcher = import("./Matchers.js").RouteMatcher;
 export type FetchMockConfig = import("./FetchMock.js").FetchMockConfig;
 export type CallLog = {
-    arguments: any[];
+    args: any[];
     url: string;
     options: NormalizedRequestOptions;
     request?: Request;
diff --git a/packages/core/types/FetchMock.d.ts b/packages/core/types/FetchMock.d.ts
index 152a6b2..8d1e028 100644
--- a/packages/core/types/FetchMock.d.ts
+++ b/packages/core/types/FetchMock.d.ts
@@ -1,31 +1,10 @@
-export default fetchMock;
-export type RouteMatcher = import("./Router.js").RouteMatcher;
-export type RouteName = import("./Route.js").RouteName;
-export type UserRouteConfig = import("./Route.js").UserRouteConfig;
-export type RouteResponse = import("./Router.js").RouteResponse;
-export type MatcherDefinition = import("./Matchers.js").MatcherDefinition;
-export type CallLog = import("./CallHistory.js").CallLog;
-export type RouteResponseFunction = import("./Route.js").RouteResponseFunction;
-export type FetchMockGlobalConfig = {
-    sendAsJson?: boolean;
-    includeContentLength?: boolean;
-    matchPartialBody?: boolean;
-};
-export type FetchImplementations = {
-    fetch?: (arg0: string | Request, arg1: RequestInit) => Promise<Response>;
-    Headers?: typeof Headers;
-    Request?: typeof Request;
-    Response?: typeof Response;
-};
-export type FetchMockConfig = FetchMockGlobalConfig & FetchImplementations;
-declare const fetchMock: FetchMock;
-declare class FetchMock {
+export class FetchMock {
     constructor(config: FetchMockConfig, router?: Router);
     config: FetchMockConfig;
     router: Router;
     callHistory: CallHistory;
     createInstance(): FetchMock;
-    fetchHandler(this: FetchMock, requestInput: string | Request, requestInit?: RequestInit): Promise<Response>;
+    fetchHandler(this: FetchMock, requestInput: string | URL | Request, requestInit?: RequestInit): Promise<Response>;
     route(matcher: UserRouteConfig): FetchMock;
     route(matcher: RouteMatcher, response: RouteResponse, options?: UserRouteConfig | string): FetchMock;
     catch(this: FetchMock, response?: RouteResponse): FetchMock;
@@ -34,8 +13,8 @@ declare class FetchMock {
         names?: string[];
         includeSticky?: boolean;
         includeFallback?: boolean;
-    }): FetchMock;
-    clearHistory(): FetchMock;
+    }): this;
+    clearHistory(this: FetchMock): FetchMock;
     sticky: {
         (this: FetchMock, matcher: UserRouteConfig): FetchMock;
         (this: FetchMock, matcher: RouteMatcher, response: RouteResponse, options?: UserRouteConfig | string): FetchMock;
@@ -95,5 +74,34 @@ declare class FetchMock {
         (this: FetchMock, matcher: RouteMatcher, response: RouteResponse, options?: UserRouteConfig | string): FetchMock;
     };
 }
+export default fetchMock;
+export type RouteMatcher = import("./Router.js").RouteMatcher;
+export type RouteName = import("./Route.js").RouteName;
+export type UserRouteConfig = import("./Route.js").UserRouteConfig;
+export type RouteResponse = import("./Router.js").RouteResponse;
+export type MatcherDefinition = import("./Matchers.js").MatcherDefinition;
+export type CallLog = import("./CallHistory.js").CallLog;
+export type RouteResponseFunction = import("./Route.js").RouteResponseFunction;
+export type FetchMockGlobalConfig = {
+    sendAsJson?: boolean;
+    includeContentLength?: boolean;
+    matchPartialBody?: boolean;
+};
+export type FetchImplementations = {
+    fetch?: typeof fetch;
+    Headers?: typeof Headers;
+    Request?: typeof Request;
+    Response?: typeof Response;
+};
+export type FetchMockConfig = FetchMockGlobalConfig & FetchImplementations;
 import Router from './Router.js';
 import CallHistory from './CallHistory.js';
+declare const fetchMock: FetchMockStandalone;
+declare class FetchMockStandalone extends FetchMock {
+    mockGlobal(this: FetchMockStandalone): FetchMockStandalone;
+    unmockGlobal(this: FetchMockStandalone): FetchMockStandalone;
+    spy(this: FetchMockStandalone, matcher?: RouteMatcher | UserRouteConfig, name?: RouteName): FetchMockStandalone;
+    spyGlobal(this: FetchMockStandalone): FetchMockStandalone;
+    createInstance(): FetchMockStandalone;
+    #private;
+}
diff --git a/packages/core/types/index.d.ts b/packages/core/types/index.d.ts
index 1ae7427..79c8611 100644
--- a/packages/core/types/index.d.ts
+++ b/packages/core/types/index.d.ts
@@ -1,2 +1,4 @@
 export default fetchMock;
+export { FetchMock };
 import fetchMock from './FetchMock.js';
+import { FetchMock } from './FetchMock.js';
diff --git a/packages/standalone/fragments.js b/packages/standalone/fragments.js
deleted file mode 100644
index 3e4196f..0000000
--- a/packages/standalone/fragments.js
+++ /dev/null
@@ -1,69 +0,0 @@
-FetchHandler.getNativeFetch = function () {
-    const func = this.realFetch || (this.isSandbox && this.config.fetch);
-    if (!func) {
-        throw new Error(
-            'fetch-mock: Falling back to network only available on global fetch-mock, or by setting config.fetch on sandboxed fetch-mock',
-        );
-    }
-    return func;
-};
-
-
-FetchMock.resetBehavior = function (options = {}) {
-    const removeRoutes = getRouteRemover(options);
-
-    this.routes = removeRoutes(this.routes);
-    this._uncompiledRoutes = removeRoutes(this._uncompiledRoutes);
-
-    if (this.realFetch && !this.routes.length) {
-        globalThis.fetch = this.realFetch;
-        this.realFetch = undefined;
-    }
-
-    this.fallbackResponse = undefined;
-    return this;
-};
-
-FetchMock.resetHistory = function () {
-    this._calls = [];
-    this._holdingPromises = [];
-    this.routes.forEach((route) => route.reset && route.reset());
-    return this;
-};
-
-FetchMock.restore = FetchMock.reset = function (options) {
-    this.resetBehavior(options);
-    this.resetHistory();
-    return this;
-};
-
-FetchMock._mock = function () {
-    if (!this.isSandbox) {
-        // Do this here rather than in the constructor to ensure it's scoped to the test
-        this.realFetch = this.realFetch || globalThis.fetch;
-        globalThis.fetch = this.fetchHandler;
-    }
-    return this;
-};
-
-if (this.getOption('fallbackToNetwork') === 'always') {
-    return {
-        route: { response: this.getNativeFetch(), responseIsFetch: true },
-        // BUG - this callLog never used to get sent. Discovered the bug
-        // but can't fix outside a major release as it will potentially
-        // cause too much disruption
-        //
-        // callLog,
-    };
-}
-
-  if (!this.getOption('fallbackToNetwork')) {
-        throw new Error(
-            `fetch-mock: No fallback response defined for ${(options && options.method) || 'GET'
-            } to ${url}`,
-        );
-    }
-    return {
-        route: { response: this.getNativeFetch(), responseIsFetch: true },
-        callLog,
-    };
\ No newline at end of file
diff --git a/packages/standalone/types.ts b/packages/standalone/types.ts
deleted file mode 100644
index f57bedf..0000000
--- a/packages/standalone/types.ts
+++ /dev/null
@@ -1,30 +0,0 @@
-// /**
-//  * Chainable method that records the call history of unmatched calls,
-//  * but instead of responding with a stubbed response, the request is
-//  * passed through to native fetch() and is allowed to communicate
-//  * over the network. Similar to catch().
-//  */
-// spy(response?: MockResponse | MockResponseFunction): this;
-
-// /**
-//  * Restores fetch() to its unstubbed state and clears all data recorded
-//  * for its calls. reset() is an alias for restore().
-//  */
-// restore(): this;
-
-// /**
-//  * Restores fetch() to its unstubbed state and clears all data recorded
-//  * for its calls. reset() is an alias for restore().
-//  */
-// reset(): this;
-
-// /**
-//  * Clears all data recorded for fetch()’s calls. It will not restore
-//  * fetch to its default implementation.
-//  */
-// resetHistory(): this;
-
-// /**
-//  * Removes mocking behaviour without resetting call history.
-//  */
-// resetBehavior(): this;
\ No newline at end of file
diff --git a/packages/wip/generated-types/CallHistory.d.ts b/packages/wip/generated-types/CallHistory.d.ts
deleted file mode 100644
index b4cc425..0000000
--- a/packages/wip/generated-types/CallHistory.d.ts
+++ /dev/null
@@ -1,11 +0,0 @@
-export default FetchMock;
-declare namespace FetchMock {
-    export function filterCalls(nameOrMatcher: any, options: any): any;
-    export function calls(nameOrMatcher: any, options: any): any;
-    export function lastCall(nameOrMatcher: any, options: any): any;
-    export function lastUrl(nameOrMatcher: any, options: any): any;
-    export function lastOptions(nameOrMatcher: any, options: any): any;
-    export function lastResponse(nameOrMatcher: any, options: any): any;
-    export function called(nameOrMatcher: any, options: any): boolean;
-    export function done(nameOrMatcher: any): any;
-}
diff --git a/packages/wip/generated-types/FetchHandler.d.ts b/packages/wip/generated-types/FetchHandler.d.ts
deleted file mode 100644
index b345c68..0000000
--- a/packages/wip/generated-types/FetchHandler.d.ts
+++ /dev/null
@@ -1,17 +0,0 @@
-export default FetchHandler;
-/**
- * An object that contains the fetch handler function - used as the mock for
- * fetch - and various utilities to help it operate
- * This object will never be accessed as a separate entity by the end user as it
- * gets munged with Router and CallHistory objects by FetchMockWrapper
- */
-export type FetchHandler = any;
-declare namespace FetchHandler {
-    export function fetchHandler(url: any, options: any): Promise<any>;
-    export namespace fetchHandler {
-        export const isMock: boolean;
-    }
-    export function generateResponse({ route, url, options, request, callLog, }: {
-        route: any;
-    }): Promise<any>;
-}
diff --git a/packages/wip/generated-types/FetchMockWrapper.d.ts b/packages/wip/generated-types/FetchMockWrapper.d.ts
deleted file mode 100644
index e384567..0000000
--- a/packages/wip/generated-types/FetchMockWrapper.d.ts
+++ /dev/null
@@ -1,2 +0,0 @@
-declare var _default: any;
-export default _default;
diff --git a/packages/wip/generated-types/Matchers.d.ts b/packages/wip/generated-types/Matchers.d.ts
deleted file mode 100644
index 2197135..0000000
--- a/packages/wip/generated-types/Matchers.d.ts
+++ /dev/null
@@ -1,16 +0,0 @@
-declare var _default: ({
-    name: string;
-    matcher: (route: any) => any;
-    usesBody: boolean;
-} | {
-    name: string;
-    matcher: ({ functionMatcher }: {
-        functionMatcher: any;
-    }) => (...args: any[]) => any;
-    usesBody?: undefined;
-} | {
-    name: string;
-    matcher: (route: any) => any;
-    usesBody?: undefined;
-})[];
-export default _default;
diff --git a/packages/wip/generated-types/RequestUtils.d.ts b/packages/wip/generated-types/RequestUtils.d.ts
deleted file mode 100644
index 314012f..0000000
--- a/packages/wip/generated-types/RequestUtils.d.ts
+++ /dev/null
@@ -1,27 +0,0 @@
-export function normalizeUrl(url: any): any;
-/**
- *
- * @param {string|Request} urlOrRequest
- * @param {Object} options
- * @param {Class} Request
- * @returns
- */
-export function normalizeRequest(urlOrRequest: string | Request, options: Object, Request: any): {
-    url: any;
-    options: {
-        method: any;
-    } & Object;
-    request: RequestInfo;
-    signal: any;
-} | {
-    url: any;
-    options: Object;
-    signal: any;
-};
-export function getPath(url: any): string;
-export function getQuery(url: any): string;
-export namespace headers {
-    export function normalize(headers: any): any;
-    export function toLowerCase(headers: any): {};
-    export function equal(actualHeader: any, expectedHeader: any): any;
-}
diff --git a/packages/wip/generated-types/ResponseBuilder.d.ts b/packages/wip/generated-types/ResponseBuilder.d.ts
deleted file mode 100644
index 27e4190..0000000
--- a/packages/wip/generated-types/ResponseBuilder.d.ts
+++ /dev/null
@@ -1,2 +0,0 @@
-declare function _default(options: any): any[];
-export default _default;
diff --git a/packages/wip/generated-types/Route.d.ts b/packages/wip/generated-types/Route.d.ts
deleted file mode 100644
index 1516d43..0000000
--- a/packages/wip/generated-types/Route.d.ts
+++ /dev/null
@@ -1,44 +0,0 @@
-export default Route;
-declare class Route {
-    /**
-     * @param {MatcherDefinition} matcher
-     */
-    static defineMatcher(matcher: any): void;
-    /**
-     * @overload
-     * @param {MockOptions} matcher
-     * @param {undefined} response
-     * @param {undefined} options
-     * @param {FetchMockConfig} globalConfig
-     */
-    /**
-     * @overload
-     * @param {MockMatcher } matcher
-     * @param {MockResponse} response
-     * @param {MockOptions | string} options
-     * @param {FetchMockConfig} globalConfig
-     */
-    /**
-     * @param {MockMatcher | MockOptions} matcher
-     * @param {MockResponse} [response]
-     * @param {MockOptions | string} [options]
-     * @param {FetchMockConfig} [globalConfig]
-     */
-    constructor(matcher: any | any, response?: any, options?: any | string, globalConfig?: any);
-    originalInput: {
-        matcher: any;
-        response: any;
-        options: any;
-    };
-    method: any;
-    url: (url: any, options: {}, request: any) => boolean;
-    functionMatcher: any;
-    usesBody: boolean;
-    matcher: (url: any, options: {}, request: any) => boolean;
-    reset: () => void;
-    response: () => Promise<any>;
-    #private;
-}
-declare namespace Route {
-    export const registeredMatchers: any[];
-}
diff --git a/packages/wip/generated-types/Router.d.ts b/packages/wip/generated-types/Router.d.ts
deleted file mode 100644
index 3ec2ae8..0000000
--- a/packages/wip/generated-types/Router.d.ts
+++ /dev/null
@@ -1,3 +0,0 @@
-declare var routes: any;
-declare function defineShorthand(methodName: any, underlyingMethod: any, shorthandOptions: any): void;
-declare function defineGreedyShorthand(methodName: any, underlyingMethod: any): void;
diff --git a/packages/wip/generated-types/StatusTextMap.d.ts b/packages/wip/generated-types/StatusTextMap.d.ts
deleted file mode 100644
index b98f5db..0000000
--- a/packages/wip/generated-types/StatusTextMap.d.ts
+++ /dev/null
@@ -1,7 +0,0 @@
-export default statusTextMap;
-/**
- * @type {Object.<number, string>}
- */
-declare const statusTextMap: {
-    [x: number]: string;
-};
diff --git a/packages/wip/old-types/CallHistory.d.ts b/packages/wip/old-types/CallHistory.d.ts
deleted file mode 100644
index b77845c..0000000
--- a/packages/wip/old-types/CallHistory.d.ts
+++ /dev/null
@@ -1,159 +0,0 @@
-export default FetchMock;
-declare namespace FetchMock {
-    export function filterCalls(nameOrMatcher: any, options: any): any;
-    export function calls(nameOrMatcher: any, options: any): any;
-    export function lastCall(nameOrMatcher: any, options: any): any;
-    export function lastUrl(nameOrMatcher: any, options: any): any;
-    export function lastOptions(nameOrMatcher: any, options: any): any;
-    export function lastResponse(nameOrMatcher: any, options: any): any;
-    export function called(nameOrMatcher: any, options: any): boolean;
-    export function done(nameOrMatcher: any): any;
-}
-
-interface MockCall extends Array<string | RequestInit | undefined> {
-    0: string;
-    1: RequestInit | undefined;
-    identifier: string;
-    isUnmatched: boolean | undefined;
-    request: Request | undefined;
-    response: Response | undefined;
-}
-
-
-/**
- * Returns a promise that resolves once all fetches handled by fetch-mock
- * have resolved.
- * @param [waitForBody] Wait for all body parsing methods(res.json(),
- * res.text(), etc.) to resolve too.
- */
-flush(waitForBody?: boolean): Promise<MockResponse[]>;
-
-/**
- * Inspection filter. Can be one of the following:
- * boolean:
- *   * true retrieves all calls matched by fetch.
- *     fetchMock.MATCHED is an alias for true and may be used to make tests
- *     more readable.
- *   * false retrieves all calls not matched by fetch (i.e. those handled
- *     by catch() or spy(). fetchMock.UNMATCHED is an alias for false and
- *     may be used to make tests more readable.
- * MockMatcher (routeIdentifier):
- *   All routes have an identifier:
- *    * If it’s a named route, the identifier is the route’s name
- *    * If the route is unnamed, the identifier is the matcher passed in to
- *      .mock()
- *   All calls that were handled by the route with the given identifier
- *   will be retrieved
- * MockMatcher (matcher):
- *   Any matcher compatible with the mocking api can be passed in to filter
- *   the calls arbitrarily.
- */
-type InspectionFilter = MockMatcher | boolean;
-
-/**
- * Either an object compatible with the mocking api or a string specifying
- * a http method to filter by. This will be used to filter the list of
- * calls further.
- */
-type InspectionOptions = MockOptions | string;
-
-
-
-// /**
-//  * Returns an array of all calls to fetch matching the given filters.
-//  * Each call is returned as a [url, options] array. If fetch was called
-//  * using a Request instance, this will be available as a request
-//  * property on this array.
-//  * @param [filter] Allows filtering of calls to fetch based on various
-//  * criteria
-//  * @param [options] Either an object compatible with the mocking api or
-//  * a string specifying a http method to filter by. This will be used to
-//  * filter the list of calls further.
-//  */
-// calls(filter?: InspectionFilter, options?: InspectionOptions): MockCall[];
-
-// /**
-//  * Returns a Boolean indicating whether any calls to fetch matched the
-//  * given filter.
-//  * @param [filter] Allows filtering of calls to fetch based on various
-//  * criteria
-//  * @param [options] Either an object compatible with the mocking api or
-//  * a string specifying a http method to filter by. This will be used to
-//  * filter the list of calls further.
-//  */
-// called(filter?: InspectionFilter, options?: InspectionOptions): boolean;
-
-// /**
-//  * Returns a Boolean indicating whether fetch was called the expected
-//  * number of times (or has been called at least once if repeat is
-//  * undefined for the route).
-//  * @param [filter] Rule for matching calls to fetch.
-//  */
-// done(filter?: InspectionFilter): boolean;
-
-// /**
-//  * Returns the arguments for the last call to fetch matching the given
-//  * filter.
-//  * @param [filter] Allows filtering of calls to fetch based on various
-//  * criteria
-//  * @param [options] Either an object compatible with the mocking api or
-//  * a string specifying a http method to filter by. This will be used to
-//  * filter the list of calls further.
-//  */
-// lastCall(
-//     filter?: InspectionFilter,
-//     options?: InspectionOptions,
-// ): MockCall | undefined;
-
-// /**
-//  * Returns the url for the last call to fetch matching the given
-//  * filter. If fetch was last called using a Request instance, the url
-//  * will be extracted from this.
-//  * @param [filter] Allows filtering of calls to fetch based on various
-//  * criteria
-//  * @param [options] Either an object compatible with the mocking api or
-//  * a string specifying a http method to filter by. This will be used to
-//  * filter the list of calls further.
-//  */
-// lastUrl(
-//     filter?: InspectionFilter,
-//     options?: InspectionOptions,
-// ): string | undefined;
-
-// /**
-//  * Returns the options for the call to fetch matching the given filter.
-//  * If fetch was last called using a Request instance, a set of options
-//  * inferred from the Request will be returned.
-//  * @param [filter] Allows filtering of calls to fetch based on various
-//  * criteria
-//  * @param [options] Either an object compatible with the mocking api or
-//  * a string specifying a http method to filter by. This will be used to
-//  * filter the list of calls further.
-//  */
-// lastOptions(
-//     filter?: InspectionFilter,
-//     options?: InspectionOptions,
-// ): MockOptions | undefined;
-
-// /**
-//  * Returns the options for the call to fetch matching the given filter.
-//  * This is an experimental feature, very difficult to implement well given
-//  * fetch’s very private treatment of response bodies.
-//  * When doing all the following:
-//    -  using node-fetch
-//    -  responding with a real network response (using spy() or fallbackToNetwork)
-//    -  using `fetchMock.LastResponse()`
-//    -  awaiting the body content
-//        … the response will hang unless your source code also awaits the response body.
-//        This is an unavoidable consequence of the nodejs implementation of streams.
-//  * @param [filter] Allows filtering of calls to fetch based on various
-//  * criteria
-//  * @param [options] Either an object compatible with the mocking api or
-//  * a string specifying a http method to filter by. This will be used to
-//  * filter the list of calls further.
-//  */
-// lastResponse(
-//     filter?: InspectionFilter,
-//     options?: InspectionOptions,
-// ): Response | undefined;
-
diff --git a/packages/wip/old-types/FetchMockWrapper.d.ts b/packages/wip/old-types/FetchMockWrapper.d.ts
deleted file mode 100644
index 0d313fa..0000000
--- a/packages/wip/old-types/FetchMockWrapper.d.ts
+++ /dev/null
@@ -1,84 +0,0 @@
-interface FetchMockConfig {
-
-    /**
-     * Convert objects into JSON before delivering as stub responses.
-     * Can be useful to set to false globally if e.g. dealing with a
-     * lot of array buffers. If true, will also add
-     * content-type: application/json header.
-     * @default true
-     */
-    sendAsJson?: boolean;
-
-    /**
-     * Automatically sets a content-length header on each response.
-     * @default true
-     */
-    includeContentLength?: boolean;
-
-    // /**
-    //  * - true: Unhandled calls fall through to the network
-    //  * - false: Unhandled calls throw an error
-    //  * - 'always': All calls fall through to the network, effectively
-    //  * disabling fetch-mock.
-    //  * @default false
-    //  */
-    // fallbackToNetwork?: boolean | 'always';
-
-    /**
-     * Print a warning if any call is caught by a fallback handler (set
-     * using the fallbackToNetwork option or catch())
-     * @default true
-     */
-    warnOnFallback?: boolean;
-
-    /**
-     * Reference to a custom fetch implementation.
-     */
-    fetch?: (
-        input?: string | Request,
-        init?: RequestInit,
-    ) => Promise<Response>;
-
-    /**
-     * Reference to the Headers constructor of a custom fetch
-     * implementation.
-     */
-    Headers?: new () => Headers;
-
-    /**
-     * Reference to the Request constructor of a custom fetch
-     * implementation.
-     */
-    Request?: new (input: string | Request, init?: RequestInit) => Request;
-
-    /**
-     * Reference to the Response constructor of a custom fetch
-     * implementation.
-     */
-    Response?: new () => Response;
-}
-
-
-
-
-interface FetchMockInstance {
-
-    // MATCHED: true;
-    // UNMATCHED: false;
-
-
-
-    /**
-     * Returns a promise that resolves once all fetches handled by fetch-mock
-     * have resolved.
-     * @param [waitForBody] Wait for all body parsing methods(res.json(),
-     * res.text(), etc.) to resolve too.
-     */
-    flush(waitForBody?: boolean): Promise<MockResponse[]>;
-
-    statusTextMap: {
-        [key: number]: string
-    }
-
-    config: FetchMockConfig;
-}
\ No newline at end of file
diff --git a/packages/wip/old-types/RequestUtils.d.ts b/packages/wip/old-types/RequestUtils.d.ts
deleted file mode 100644
index 314012f..0000000
--- a/packages/wip/old-types/RequestUtils.d.ts
+++ /dev/null
@@ -1,27 +0,0 @@
-export function normalizeUrl(url: any): any;
-/**
- *
- * @param {string|Request} urlOrRequest
- * @param {Object} options
- * @param {Class} Request
- * @returns
- */
-export function normalizeRequest(urlOrRequest: string | Request, options: Object, Request: any): {
-    url: any;
-    options: {
-        method: any;
-    } & Object;
-    request: RequestInfo;
-    signal: any;
-} | {
-    url: any;
-    options: Object;
-    signal: any;
-};
-export function getPath(url: any): string;
-export function getQuery(url: any): string;
-export namespace headers {
-    export function normalize(headers: any): any;
-    export function toLowerCase(headers: any): {};
-    export function equal(actualHeader: any, expectedHeader: any): any;
-}
diff --git a/packages/wip/old-types/ResponseBuilder.d.ts b/packages/wip/old-types/ResponseBuilder.d.ts
deleted file mode 100644
index 4f5665d..0000000
--- a/packages/wip/old-types/ResponseBuilder.d.ts
+++ /dev/null
@@ -1,54 +0,0 @@
-
-/**
- * Mock response object
- */
-interface MockResponseObject {
-    /**
-     * Set the response body
-     */
-    body?: string | {};
-
-    /**
-     * Set the response status
-     * @default 200
-     */
-    status?: number;
-
-    /**
-     * Set the response headers.
-     */
-    headers?: { [key: string]: string };
-
-    /**
-     * If this property is present then a Promise rejected with the value
-     * of throws is returned
-     */
-    throws?: Error;
-
-    /**
-     * The URL the response should be from (to imitate followed redirects
-     *  - will set redirected: true on the response)
-     */
-    redirectUrl?: string;
-}
-
-/**
- * Response: A Response instance - will be used unaltered
- * number: Creates a response with this status
- * string: Creates a 200 response with the string as the response body
- * object: As long as the object is not a MockResponseObject it is
- *  converted into a json string and returned as the body of a 200 response
- * If MockResponseObject was given then it's used to configure response
- * Function(url, opts): A function that is passed the url and opts fetch()
- *  is called with and that returns any of the responses listed above
- */
-type MockResponse = Response | Promise<Response>
-    | number | Promise<number>
-    | string | Promise<string>
-    | {} | Promise<{}>
-    | MockResponseObject | Promise<MockResponseObject>;
-
-/**
- * Mock response function
- */
-type MockResponseFunction = (url: string, opts: MockRequest) => MockResponse;
diff --git a/packages/wip/old-types/StatusTextMap.d.ts b/packages/wip/old-types/StatusTextMap.d.ts
deleted file mode 100644
index b98f5db..0000000
--- a/packages/wip/old-types/StatusTextMap.d.ts
+++ /dev/null
@@ -1,7 +0,0 @@
-export default statusTextMap;
-/**
- * @type {Object.<number, string>}
- */
-declare const statusTextMap: {
-    [x: number]: string;
-};
diff --git a/packages/wip/old-types/index.d.ts b/packages/wip/old-types/index.d.ts
deleted file mode 100644
index 3ed4b3f..0000000
--- a/packages/wip/old-types/index.d.ts
+++ /dev/null
@@ -1,16 +0,0 @@
-// TypeScript Version: 2.2
-import Route from "./Route";
-import CallHistory from "./CallHistory";
-import FetchHandler from "./FetchHandler";
-import FetchMockWrapper from "./FetchMockWrapper";
-import RequestUtils from "./RequestUtils";
-import ResponseBuilder from "./ResponseBuilder";
-import Router from "./Router";
-import StatusTextMap from "./StatusTextMap";
-
-
-
-
-   
-
-


Test patch:
diff --git a/packages/core/src/__tests__/FetchMock/mock-and-spy.test.js b/packages/core/src/__tests__/FetchMock/mock-and-spy.test.js
new file mode 100644
index 0000000..06ac174
--- /dev/null
+++ b/packages/core/src/__tests__/FetchMock/mock-and-spy.test.js
@@ -0,0 +1,134 @@
+import { beforeEach, afterEach, describe, expect, it, vi } from 'vitest';
+import fetchMock from '../../FetchMock.js';
+
+describe('mock and spy', () => {
+	let fm;
+	const nativeFetch = globalThis.fetch;
+	beforeEach(() => {
+		fm = fetchMock.createInstance();
+	});
+	afterEach(() => {
+		globalThis.fetch = nativeFetch;
+	});
+
+	const testChainableMethod = (method, ...args) => {
+		it(`${method}() is chainable`, () => {
+			expect(fm[method](...args)).toEqual(fm);
+		});
+
+		it(`${method}() has "this"`, () => {
+			vi.spyOn(fm, method).mockReturnThis();
+			expect(fm[method](...args)).toBe(fm);
+			fm[method].mockRestore();
+		});
+	};
+
+	describe('.mockGlobal()', () => {
+		testChainableMethod('mockGlobal');
+		testChainableMethod('unmockGlobal');
+
+		it('replaces global fetch with fetchMock.fetchHandler', async () => {
+			vi.spyOn(fm, 'fetchHandler');
+			fm.mockGlobal();
+			try {
+				await fetch('http://a.com', { method: 'post' });
+			} catch (err) {}
+			// cannot just check globalThis.fetch === fm.fetchHandler because we apply .bind() to fetchHandler
+			expect(fm.fetchHandler).toHaveBeenCalledWith('http://a.com', {
+				method: 'post',
+			});
+		});
+
+		it('calls to fetch are successfully handled by fetchMock.fetchHandler', async () => {
+			fm.mockGlobal().catch(200);
+			const response = await fetch('http://a.com', { method: 'post' });
+			expect(response.status).toEqual(200);
+			const callLog = fm.callHistory.lastCall();
+			expect(callLog.args).toEqual(['http://a.com/', { method: 'post' }]);
+		});
+
+		it('restores global fetch', () => {
+			fm.mockGlobal().unmockGlobal();
+			expect(globalThis.fetch).toEqual(nativeFetch);
+		});
+	});
+	describe('.spy()', () => {
+		testChainableMethod('spy');
+		testChainableMethod('spyGlobal');
+		it('passes all requests through to the network by default', async () => {
+			vi.spyOn(fm.config, 'fetch');
+			fm.spy();
+			try {
+				await fm.fetchHandler('http://a.com/', { method: 'post' });
+			} catch (err) {}
+			expect(fm.config.fetch).toHaveBeenCalledWith('http://a.com/', {
+				method: 'post',
+			});
+			fm.config.fetch.mockRestore();
+		});
+		it('falls through to network for a specific route', async () => {
+			vi.spyOn(fm.config, 'fetch');
+			fm.spy('http://a.com').route('http://b.com', 200);
+			try {
+				await fm.fetchHandler('http://a.com/', { method: 'post' });
+				await fm.fetchHandler('http://b.com/', { method: 'post' });
+			} catch (err) {}
+
+			expect(fm.config.fetch).toHaveBeenCalledTimes(1);
+			expect(fm.config.fetch).toHaveBeenCalledWith('http://a.com/', {
+				method: 'post',
+			});
+			fm.config.fetch.mockRestore();
+		});
+
+		it('can apply the full range of matchers and route options', async () => {
+			vi.spyOn(fm.config, 'fetch');
+			fm.spy({ method: 'delete', headers: { check: 'this' } }).catch();
+			try {
+				await fm.fetchHandler('http://a.com/');
+				await fm.fetchHandler('http://a.com/', {
+					method: 'delete',
+					headers: { check: 'this' },
+				});
+			} catch (err) {}
+			expect(fm.config.fetch).toHaveBeenCalledTimes(1);
+			expect(fm.config.fetch).toHaveBeenCalledWith('http://a.com/', {
+				method: 'delete',
+				headers: { check: 'this' },
+			});
+			fm.config.fetch.mockRestore();
+		});
+
+		it('can name a route', async () => {
+			fm.spy('http://a.com/', 'myroute').catch();
+			try {
+				await fm.fetchHandler('http://a.com/');
+			} catch (err) {}
+			expect(fm.callHistory.called('myroute')).toBe(true);
+		});
+
+		it('plays nice with mockGlobal()', async () => {
+			globalThis.fetch = fm.config.fetch = vi.fn();
+			fm.mockGlobal().spy('http://a.com', 200);
+			try {
+				await fm.fetchHandler('http://a.com/', { method: 'post' });
+			} catch (err) {}
+			expect(fm.config.fetch).toHaveBeenCalledTimes(1);
+			expect(fm.config.fetch).toHaveBeenCalledWith('http://a.com/', {
+				method: 'post',
+			});
+		});
+
+		it('has spyGlobal() shorthand', async () => {
+			globalThis.fetch = fm.config.fetch = vi.fn();
+			fm.spyGlobal();
+			try {
+				await fm.fetchHandler('http://a.com/', { method: 'post' });
+			} catch (err) {}
+			expect(fm.config.fetch).toHaveBeenCalledTimes(1);
+			expect(fm.config.fetch).toHaveBeenCalledWith('http://a.com/', {
+				method: 'post',
+			});
+		});
+	});
+});
diff --git a/packages/core/src/__tests__/router-integration.test.js b/packages/core/src/__tests__/router-integration.test.js
index 3b4a63e..8c741b6 100644
--- a/packages/core/src/__tests__/router-integration.test.js
+++ b/packages/core/src/__tests__/router-integration.test.js
@@ -181,4 +181,85 @@ describe('Router', () => {
 			expect(response.status).toEqual(200);
 		});
 	});
+	describe.skip('random integration tests', () => {
+		// describe.skip('client-side only tests', () => {
+		//     it('not throw when passing unmatched calls through to native fetch', () => {
+		//         fetchMock.config.fallbackToNetwork = true;
+		//         fetchMock.route();
+		//         expect(() => fetch('http://a.com')).not.to.throw();
+		//         fetchMock.config.fallbackToNetwork = false;
+		//     });
+		//     // this is because we read the body once when normalising the request and
+		//     // want to make sure fetch can still use the sullied request
+		//     it.skip('can send a body on a Request instance when spying ', async () => {
+		//         fetchMock.spy();
+		//         const req = new fetchMock.config.Request('http://example.com', {
+		//             method: 'post',
+		//             body: JSON.stringify({ prop: 'val' }),
+		//         });
+		//         try {
+		//             await fetch(req);
+		//         } catch (err) {
+		//             console.log(err);
+		//             expect.unreachable('Fetch should not throw or reject');
+		//         }
+		//     });
+		//         it('not convert if `redirectUrl` property exists', async () => {
+		//             fm.route('*', {
+		//                 redirectUrl: 'http://url.to.hit',
+		//             });
+		//             const res = await fm.fetchHandler('http://a.com/');
+		//             expect(res.headers.get('content-type')).toBeNull();
+		//         });
+		//     if (globalThis.navigator?.serviceWorker) {
+		//         it('should work within a service worker', async () => {
+		//             const registration =
+		//                 await globalThis.navigator.serviceWorker.register('__sw.js');
+		//             await new Promise((resolve, reject) => {
+		//                 if (registration.installing) {
+		//                     registration.installing.onstatechange = function () {
+		//                         if (this.state === 'activated') {
+		//                             resolve();
+		//                         }
+		//                     };
+		//                 } else {
+		//                     reject('No idea what happened');
+		//                 }
+		//             });
+		//             await registration.unregister();
+		//         });
+		//     }
+		//         // only works in node-fetch@2
+		//         it.skip('can respond with a readable stream', () =>
+		//             new Promise((res) => {
+		//                 const readable = new Readable();
+		//                 const write = vi.fn().mockImplementation((chunk, enc, cb) => {
+		//                     cb();
+		//                 });
+		//                 const writable = new Writable({
+		//                     write,
+		//                 });
+		//                 readable.push('response string');
+		//                 readable.push(null);
+		//                 fetchMock.route(/a/, readable, { sendAsJson: false });
+		//                 fetchMock.fetchHandler('http://a.com').then((res) => {
+		//                     res.body.pipe(writable);
+		//                 });
+		//                 writable.on('finish', () => {
+		//                     expect(write.args[0][0].toString('utf8')).to.equal('response string');
+		//                     res();
+		//                 });
+		//             }));
+		//         // See http://github.com/wheresrhys/fetch-mock/issues/575
+		//         it('can respond with large bodies from the interweb', async () => {
+		//             const fm = fetchMock.sandbox();
+		//             fm.config.fallbackToNetwork = true;
+		//             fm.route();
+		//             // this is an adequate test because the response hangs if the
+		//             // bug referenced above creeps back in
+		//             await fm
+		//                 .fetchHandler('http://www.wheresrhys.co.uk/assets/img/chaffinch.jpg')
+		//                 .then((res) => res.blob());
+		//         });
+	});
 });
diff --git a/packages/standalone/fallbackToNetwork.test.js b/packages/standalone/fallbackToNetwork.test.js
deleted file mode 100644
index 5bef3e8..0000000
--- a/packages/standalone/fallbackToNetwork.test.js
+++ /dev/null
@@ -1,214 +0,0 @@
-import { beforeEach, describe, expect, it } from 'vitest';
-
-const { fetchMock } = testGlobals;
-
-describe('fallbackToNetwork', () => {
-	let fm;
-	beforeEach(() => {
-		fm = fetchMock.createInstance();
-	});
-	it('error by default', () => {
-		expect(() => fm.fetchHandler('http://unmocked.com')).toThrow();
-	});
-
-	it('not error when configured globally', () => {
-		globalThis.fetch = async () => ({ status: 202 }); //eslint-disable-line require-await
-		fm.config.fallbackToNetwork = true;
-		fm.mock('http://mocked.com', 201);
-		expect(() => fm.fetchHandler('http://unmocked.com')).not.toThrow();
-		delete globalThis.fetch;
-	});
-
-	it('actually falls back to network when configured globally', async () => {
-		globalThis.fetch = async () => ({ status: 202 }); //eslint-disable-line require-await
-		fetchMock.config.fallbackToNetwork = true;
-		fetchMock.mock('http://mocked.com', 201);
-		const res = await fetchMock.fetchHandler('http://unmocked.com');
-		expect(res.status).toEqual(202);
-		fetchMock.restore();
-		fetchMock.config.fallbackToNetwork = false;
-		delete globalThis.fetch;
-	});
-
-	it('actually falls back to network when configured in a sandbox properly', async () => {
-		const sbx = fm.sandbox();
-		sbx.config.fetch = async () => ({ status: 202 }); //eslint-disable-line require-await
-		sbx.config.fallbackToNetwork = true;
-		sbx.mock('http://mocked.com', 201);
-		const res = await sbx('http://unmocked.com');
-		expect(res.status).toEqual(202);
-	});
-
-	it('calls fetch with original Request object', async () => {
-		const sbx = fm.sandbox();
-		let calledWith;
-		//eslint-disable-next-line require-await
-		sbx.config.fetch = async (req) => {
-			calledWith = req;
-			return { status: 202 };
-		};
-		sbx.config.fallbackToNetwork = true;
-		sbx.mock('http://mocked.com', 201);
-		const req = new sbx.config.Request('http://unmocked.com');
-		await sbx(req);
-		expect(calledWith).toEqual(req);
-	});
-
-	describe('always', () => {
-		it('ignores routes that are matched', async () => {
-			fm.realFetch = async () => ({ status: 202 }); //eslint-disable-line require-await
-			fm.config.fallbackToNetwork = 'always';
-
-			fm.mock('http://mocked.com', 201);
-			const res = await fm.fetchHandler('http://unmocked.com');
-			expect(res.status).toEqual(202);
-		});
-
-		it('ignores routes that are not matched', async () => {
-			fm.realFetch = async () => ({ status: 202 }); //eslint-disable-line require-await
-
-			fm.config.fallbackToNetwork = 'always';
-
-			fm.mock('http://mocked.com', 201);
-			const res = await fm.fetchHandler('http://unmocked.com');
-			expect(res.status).toEqual(202);
-		});
-	});
-
-	describe.skip('warnOnFallback', () => {
-		it('warn on fallback response by default', () => {}); //eslint-disable-line no-empty-function
-		it("don't warn on fallback response when configured false", () => {}); //eslint-disable-line no-empty-function
-	});
-});
-
-
-
-// import { Readable, Writable } from 'stream';
-// describe('nodejs only tests', () => {
-//     describe('support for nodejs body types', () => {
-
-
-
-//         // only works in node-fetch@2
-//         it.skip('can respond with a readable stream', () =>
-//             new Promise((res) => {
-//                 const readable = new Readable();
-//                 const write = vi.fn().mockImplementation((chunk, enc, cb) => {
-//                     cb();
-//                 });
-//                 const writable = new Writable({
-//                     write,
-//                 });
-//                 readable.push('response string');
-//                 readable.push(null);
-
-//                 fetchMock.route(/a/, readable, { sendAsJson: false });
-//                 fetchMock.fetchHandler('http://a.com').then((res) => {
-//                     res.body.pipe(writable);
-//                 });
-
-//                 writable.on('finish', () => {
-//                     expect(write.args[0][0].toString('utf8')).to.equal('response string');
-//                     res();
-//                 });
-//             }));
-
-//         // See https://github.com/wheresrhys/fetch-mock/issues/575
-//         it('can respond with large bodies from the interweb', async () => {
-//             const fm = fetchMock.sandbox();
-//             fm.config.fallbackToNetwork = true;
-//             fm.route();
-//             // this is an adequate test because the response hangs if the
-//             // bug referenced above creeps back in
-//             await fm
-//                 .fetchHandler('http://www.wheresrhys.co.uk/assets/img/chaffinch.jpg')
-//                 .then((res) => res.blob());
-//         });
-
-
-
-
-// describe.skip('client-side only tests', () => {
-//     it('not throw when passing unmatched calls through to native fetch', () => {
-//         fetchMock.config.fallbackToNetwork = true;
-//         fetchMock.route();
-//         expect(() => fetch('http://a.com')).not.to.throw();
-//         fetchMock.config.fallbackToNetwork = false;
-//     });
-
-//     // this is because we read the body once when normalising the request and
-//     // want to make sure fetch can still use the sullied request
-//     it.skip('can send a body on a Request instance when spying ', async () => {
-//         fetchMock.spy();
-//         const req = new fetchMock.config.Request('http://example.com', {
-//             method: 'post',
-//             body: JSON.stringify({ prop: 'val' }),
-//         });
-//         try {
-//             await fetch(req);
-//         } catch (err) {
-//             console.log(err);
-//             expect.unreachable('Fetch should not throw or reject');
-//         }
-//     });
-
-//     // in the browser the fetch spec disallows invoking res.headers on an
-//     // object that inherits from a response, thus breaking the ability to
-//     // read headers of a fake redirected response.
-//     if (typeof window === 'undefined') {
-//         it('not convert if `redirectUrl` property exists', async () => {
-//             fm.route('*', {
-//                 redirectUrl: 'http://url.to.hit',
-//             });
-//             const res = await fm.fetchHandler('http://a.com/');
-//             expect(res.headers.get('content-type')).toBeNull();
-//         });
-//     }
-
-
-
-//     it.skip('should cope when there is no global fetch defined', () => {
-//         const originalFetch = globalThis.fetch;
-//         delete globalThis.fetch;
-//         const originalRealFetch = fetchMock.realFetch;
-//         delete fetchMock.realFetch;
-//         fetchMock.route('*', 200);
-//         expect(() => {
-//             fetch('http://a.com');
-//         }).not.to.throw();
-
-//         expect(() => {
-//             fetchMock.calls();
-//         }).not.to.throw();
-//         fetchMock.restore();
-//         fetchMock.realFetch = originalRealFetch;
-//         globalThis.fetch = originalFetch;
-//     });
-
-//     if (globalThis.navigator?.serviceWorker) {
-//         it('should work within a service worker', async () => {
-//             const registration =
-//                 await globalThis.navigator.serviceWorker.register('__sw.js');
-//             await new Promise((resolve, reject) => {
-//                 if (registration.installing) {
-//                     registration.installing.onstatechange = function () {
-//                         if (this.state === 'activated') {
-//                             resolve();
-//                         }
-//                     };
-//                 } else {
-//                     reject('No idea what happened');
-//                 }
-//             });
-
-//             await registration.unregister();
-//         });
-//     }
-
-// });
-
-
-
-
-
-
diff --git a/packages/standalone/global-fetch.test.js b/packages/standalone/global-fetch.test.js
deleted file mode 100644
index e6c7bb2..0000000
--- a/packages/standalone/global-fetch.test.js
+++ /dev/null
@@ -1,136 +0,0 @@
-import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
-
-const { fetchMock } = testGlobals;
-
-describe('use with global fetch', () => {
-	let originalFetch;
-
-	const expectToBeStubbed = (yes = true) => {
-		expect(globalThis.fetch).toEqual(
-			yes ? fetchMock.fetchHandler : originalFetch,
-		);
-		expect(globalThis.fetch).not.toEqual(
-			yes ? originalFetch : fetchMock.fetchHandler,
-		);
-	};
-
-	beforeEach(() => {
-		originalFetch = globalThis.fetch = vi.fn().mockResolvedValue();
-	});
-	afterEach(fetchMock.restore);
-
-	it('replaces global fetch when mock called', () => {
-		fetchMock.mock('*', 200);
-		expectToBeStubbed();
-	});
-
-	it('replaces global fetch when catch called', () => {
-		fetchMock.catch(200);
-		expectToBeStubbed();
-	});
-
-	it('replaces global fetch when spy called', () => {
-		fetchMock.spy();
-		expectToBeStubbed();
-	});
-
-	it('restores global fetch after a mock', () => {
-		fetchMock.mock('*', 200).restore();
-		expectToBeStubbed(false);
-	});
-
-	it('restores global fetch after a complex mock', () => {
-		fetchMock.mock('a', 200).mock('b', 200).spy().catch(404).restore();
-		expectToBeStubbed(false);
-	});
-
-	it('not call default fetch when in mocked mode', async () => {
-		fetchMock.mock('*', 200);
-
-		await globalThis.fetch('http://a.com');
-		expect(originalFetch).not.toHaveBeenCalled();
-	});
-});
-let originalFetch;
-
-beforeAll(() => {
-	originalFetch = globalThis.fetch = vi.fn().mockResolvedValue('dummy');
-});
-
-it('return function', () => {
-	const sbx = fetchMock.sandbox();
-	expect(typeof sbx).toEqual('function');
-});
-
-
-
-it("don't interfere with global fetch", () => {
-	const sbx = fetchMock.sandbox().route('http://a.com', 200);
-
-	expect(globalThis.fetch).toEqual(originalFetch);
-	expect(globalThis.fetch).not.toEqual(sbx);
-});
-
-it("don't interfere with global fetch-mock", async () => {
-	const sbx = fetchMock.sandbox().route('http://a.com', 200).catch(302);
-
-	fetchMock.route('http://b.com', 200).catch(301);
-
-	expect(globalThis.fetch).toEqual(fetchMock.fetchHandler);
-	expect(fetchMock.fetchHandler).not.toEqual(sbx);
-	expect(fetchMock.fallbackResponse).not.toEqual(sbx.fallbackResponse);
-	expect(fetchMock.routes).not.toEqual(sbx.routes);
-
-	const [sandboxed, globally] = await Promise.all([
-		sbx('http://a.com'),
-		fetch('http://b.com'),
-	]);
-
-	expect(sandboxed.status).toEqual(200);
-	expect(globally.status).toEqual(200);
-	expect(sbx.called('http://a.com')).toBe(true);
-	expect(sbx.called('http://b.com')).toBe(false);
-	expect(fetchMock.called('http://b.com')).toBe(true);
-	expect(fetchMock.called('http://a.com')).toBe(false);
-	expect(sbx.called('http://a.com')).toBe(true);
-	fetchMock.restore();
-});
-
-describe('global mocking', () => {
-	let originalFetch;
-	beforeAll(() => {
-		originalFetch = globalThis.fetch = vi.fn().mockResolvedValue();
-	});
-	afterEach(() => fetchMock.restore({ sticky: true }));
-
-	it('global mocking resists resetBehavior calls', () => {
-		fetchMock.route('*', 200, { sticky: true }).resetBehavior();
-		expect(globalThis.fetch).not.toEqual(originalFetch);
-	});
-
-	it('global mocking does not resist resetBehavior calls when sent `sticky: true`', () => {
-		fetchMock
-			.route('*', 200, { sticky: true })
-			.resetBehavior({ sticky: true });
-		expect(globalThis.fetch).toEqual(originalFetch);
-	});
-});
-
-describe('sandboxes', () => {
-	it('sandboxed instances should inherit stickiness', () => {
-		const sbx1 = fetchMock
-			.sandbox()
-			.route('*', 200, { sticky: true })
-			.catch(300);
-
-		const sbx2 = sbx1.sandbox().resetBehavior();
-
-		expect(sbx1.routes.length).toEqual(1);
-		expect(sbx2.routes.length).toEqual(1);
-
-		sbx2.resetBehavior({ sticky: true });
-
-		expect(sbx1.routes.length).toEqual(1);
-		expect(sbx2.routes.length).toEqual(0);
-	});
-});
\ No newline at end of file
diff --git a/packages/standalone/set-up-and-tear-down.test.js b/packages/standalone/set-up-and-tear-down.test.js
deleted file mode 100644
index a4223a3..0000000
--- a/packages/standalone/set-up-and-tear-down.test.js
+++ /dev/null
@@ -1,198 +0,0 @@
-import {
-	afterEach,
-	beforeEach,
-	describe,
-	expect,
-	it,
-	beforeAll,
-	vi,
-} from 'vitest';
-
-const { fetchMock } = testGlobals;
-describe('Set up and tear down', () => {
-	let fm;
-	beforeAll(() => {
-		fm = fetchMock.createInstance();
-		fm.config.warnOnUnmatched = false;
-	});
-	afterEach(() => fm.restore());
-
-	const testChainableMethod = (method, ...args) => {
-		it(`${method}() is chainable`, () => {
-			expect(fm[method](...args)).toEqual(fm);
-		});
-
-		it(`${method}() has "this"`, () => {
-			vi.spyOn(fm, method).mockReturnThis();
-			expect(fm[method](...args)).toBe(fm);
-			fm[method].mockRestore();
-		});
-	};
-
-	describe('mock', () => {
-		testChainableMethod('mock', '*', 200);
-
-		it('can be called multiple times', () => {
-			expect(() => {
-				fm.mock('http://a.com', 200).mock('http://b.com', 200);
-			}).not.toThrow();
-		});
-
-		it('can be called after fetchMock is restored', () => {
-			expect(() => {
-				fm.mock('*', 200).restore().mock('*', 200);
-			}).not.toThrow();
-		});
-
-		describe('parameters', () => {
-			beforeEach(() => {
-				vi.spyOn(fm, 'compileRoute');
-				vi.spyOn(fm, '_mock').mockReturnValue(fm);
-			});
-
-			afterEach(() => {
-				fm.compileRoute.mockRestore();
-				fm._mock.mockRestore();
-			});
-
-			it('accepts single config object', () => {
-				const config = {
-					url: '*',
-					response: 200,
-				};
-				expect(() => fm.mock(config)).not.toThrow();
-				expect(fm.compileRoute).toHaveBeenCalledWith([config]);
-				expect(fm._mock).toHaveBeenCalled();
-			});
-
-			it('accepts matcher, route pairs', () => {
-				expect(() => fm.mock('*', 200)).not.toThrow();
-				expect(fm.compileRoute).toHaveBeenCalledWith(['*', 200]);
-				expect(fm._mock).toHaveBeenCalled();
-			});
-
-			it('accepts matcher, response, config triples', () => {
-				expect(() =>
-					fm.mock('*', 'ok', {
-						method: 'PUT',
-						some: 'prop',
-					}),
-				).not.toThrow();
-				expect(fm.compileRoute).toHaveBeenCalledWith([
-					'*',
-					'ok',
-					{
-						method: 'PUT',
-						some: 'prop',
-					},
-				]);
-				expect(fm._mock).toHaveBeenCalled();
-			});
-
-			it('expects a matcher', () => {
-				expect(() => fm.mock(null, 'ok')).toThrow();
-			});
-
-			it('expects a response', () => {
-				expect(() => fm.mock('*')).toThrow();
-			});
-
-			it('can be called with no parameters', () => {
-				expect(() => fm.mock()).not.toThrow();
-				expect(fm.compileRoute).not.toHaveBeenCalled();
-				expect(fm._mock).toHaveBeenCalled();
-			});
-
-			it('should accept object responses when also passing options', () => {
-				expect(() =>
-					fm.mock('*', { foo: 'bar' }, { method: 'GET' }),
-				).not.toThrow();
-			});
-		});
-	});
-
-	describe('reset', () => {
-		testChainableMethod('reset');
-
-		it('can be called even if no mocks set', () => {
-			expect(() => fm.restore()).not.toThrow();
-		});
-
-		it('calls resetHistory', () => {
-			vi.spyOn(fm, 'resetHistory');
-			fm.restore();
-			expect(fm.resetHistory).toHaveBeenCalledTimes(1);
-			fm.resetHistory.mockRestore();
-		});
-
-		it('removes all routing', () => {
-			fm.mock('*', 200).catch(200);
-
-			expect(fm.routes.length).toEqual(1);
-			expect(fm.fallbackResponse).toBeDefined();
-
-			fm.restore();
-
-			expect(fm.routes.length).toEqual(0);
-			expect(fm.fallbackResponse).toBeUndefined();
-		});
-
-		it('restore is an alias for reset', () => {
-			expect(fm.restore).toEqual(fm.reset);
-		});
-	});
-
-	describe('resetBehavior', () => {
-		testChainableMethod('resetBehavior');
-
-		it('can be called even if no mocks set', () => {
-			expect(() => fm.resetBehavior()).not.toThrow();
-		});
-
-		it('removes all routing', () => {
-			fm.mock('*', 200).catch(200);
-
-			expect(fm.routes.length).toEqual(1);
-			expect(fm.fallbackResponse).toBeDefined();
-
-			fm.resetBehavior();
-
-			expect(fm.routes.length).toEqual(0);
-			expect(fm.fallbackResponse).toBeUndefined();
-		});
-	});
-
-	describe('resetHistory', () => {
-		testChainableMethod('resetHistory');
-
-		it('can be called even if no mocks set', () => {
-			expect(() => fm.resetHistory()).not.toThrow();
-		});
-
-		it('resets call history', async () => {
-			fm.mock('*', 200).catch(200);
-			await fm.fetchHandler('a');
-			await fm.fetchHandler('b');
-			expect(fm.called()).toBe(true);
-
-			fm.resetHistory();
-			expect(fm.called()).toBe(false);
-			expect(fm.called('*')).toBe(false);
-			expect(fm.calls('*').length).toEqual(0);
-			expect(fm.calls(true).length).toEqual(0);
-			expect(fm.calls(false).length).toEqual(0);
-			expect(fm.calls().length).toEqual(0);
-		});
-	});
-
-	describe('spy', () => {
-		testChainableMethod('spy');
-
-		it('calls catch()', () => {
-			vi.spyOn(fm, 'catch');
-			fm.spy();
-			expect(fm.catch).toHaveBeenCalledTimes(1);
-			fm.catch.mockRestore();
-		});
-	});
-});
diff --git a/packages/standalone/spy.test.js b/packages/standalone/spy.test.js
deleted file mode 100644
index f8fa633..0000000
--- a/packages/standalone/spy.test.js
+++ /dev/null
@@ -1,89 +0,0 @@
-import { describe, expect, it, vi } from 'vitest';
-
-const { fetchMock } = testGlobals;
-describe('spy()', () => {
-	it('when mocking globally, spy falls through to global fetch', async () => {
-		const originalFetch = globalThis.fetch;
-		const fetchSpy = vi.fn().mockResolvedValue('example');
-
-		globalThis.fetch = fetchSpy;
-
-		fetchMock.spy();
-
-		await globalThis.fetch('http://a.com/', { method: 'get' });
-		expect(fetchSpy).toHaveBeenCalledWith(
-			'http://a.com/',
-			{ method: 'get' },
-			undefined,
-		);
-		fetchMock.restore();
-		globalThis.fetch = originalFetch;
-	});
-
-	it('when mocking locally, spy falls through to configured fetch', async () => {
-		const fetchSpy = vi.fn().mockResolvedValue('dummy');
-
-		const fm = fetchMock.sandbox();
-		fm.config.fetch = fetchSpy;
-
-		fm.spy();
-		await fm.fetchHandler('http://a.com/', { method: 'get' });
-		expect(fetchSpy).toHaveBeenCalledWith(
-			'http://a.com/',
-			{ method: 'get' },
-			undefined,
-		);
-		fm.restore();
-	});
-
-	it('can restrict spying to a route', async () => {
-		const fetchSpy = vi.fn().mockResolvedValue('dummy');
-
-		const fm = fetchMock.sandbox();
-		fm.config.fetch = fetchSpy;
-
-		fm.spy({ url: 'http://a.com/', method: 'get' });
-		await fm.fetchHandler('http://a.com/', { method: 'get' });
-		expect(fetchSpy).toHaveBeenCalledWith(
-			'http://a.com/',
-			{ method: 'get' },
-			undefined,
-		);
-
-		expect(() => fm.fetchHandler('http://b.com/', { method: 'get' })).toThrow();
-		expect(() =>
-			fm.fetchHandler('http://a.com/', { method: 'post' }),
-		).toThrow();
-		fm.restore();
-	});
-});
-
-
-it('error if spy() is called and no fetch defined in config', () => {
-	const fm = fetchMock.sandbox();
-	delete fm.config.fetch;
-	expect(() => fm.spy()).toThrow();
-});
-
-it("don't error if spy() is called and fetch defined in config", () => {
-	const fm = fetchMock.sandbox();
-	fm.config.fetch = originalFetch;
-	expect(() => fm.spy()).not.toThrow();
-});
-
-it('exports a properly mocked node-fetch module shape', () => {
-	// uses node-fetch default require pattern
-	const {
-		default: fetch,
-		Headers,
-		Request,
-		Response,
-	} = fetchMock.sandbox();
-
-	expect(fetch.name).toEqual('fetchMockProxy');
-	expect(new Headers()).toBeInstanceOf(fetchMock.config.Headers);
-	expect(new Request('http://a.com')).toBeInstanceOf(
-		fetchMock.config.Request,
-	);
-	expect(new Response()).toBeInstanceOf(fetchMock.config.Response);
-});
\ No newline at end of file
diff --git a/packages/wip/generated-types/__tests__/CallHistory.test.d.ts b/packages/wip/generated-types/__tests__/CallHistory.test.d.ts
deleted file mode 100644
index cb0ff5c..0000000
--- a/packages/wip/generated-types/__tests__/CallHistory.test.d.ts
+++ /dev/null
@@ -1,1 +0,0 @@
-export {};
diff --git a/packages/wip/generated-types/__tests__/FetchHandler.test.d.ts b/packages/wip/generated-types/__tests__/FetchHandler.test.d.ts
deleted file mode 100644
index cb0ff5c..0000000
--- a/packages/wip/generated-types/__tests__/FetchHandler.test.d.ts
+++ /dev/null
@@ -1,1 +0,0 @@
-export {};
diff --git a/packages/wip/generated-types/__tests__/FetchMockWrapper.test.d.ts b/packages/wip/generated-types/__tests__/FetchMockWrapper.test.d.ts
deleted file mode 100644
index cb0ff5c..0000000
--- a/packages/wip/generated-types/__tests__/FetchMockWrapper.test.d.ts
+++ /dev/null
@@ -1,1 +0,0 @@
-export {};
diff --git a/packages/wip/generated-types/__tests__/Matchers.test.d.ts b/packages/wip/generated-types/__tests__/Matchers.test.d.ts
deleted file mode 100644
index cb0ff5c..0000000
--- a/packages/wip/generated-types/__tests__/Matchers.test.d.ts
+++ /dev/null
@@ -1,1 +0,0 @@
-export {};
diff --git a/packages/wip/generated-types/__tests__/ResponseBuilder.test.d.ts b/packages/wip/generated-types/__tests__/ResponseBuilder.test.d.ts
deleted file mode 100644
index cb0ff5c..0000000
--- a/packages/wip/generated-types/__tests__/ResponseBuilder.test.d.ts
+++ /dev/null
@@ -1,1 +0,0 @@
-export {};
diff --git a/packages/wip/generated-types/__tests__/Router/Router.test.d.ts b/packages/wip/generated-types/__tests__/Router/Router.test.d.ts
deleted file mode 100644
index cb0ff5c..0000000
--- a/packages/wip/generated-types/__tests__/Router/Router.test.d.ts
+++ /dev/null
@@ -1,1 +0,0 @@
-export {};
diff --git a/packages/wip/generated-types/__tests__/Router/body-matching.test.d.ts b/packages/wip/generated-types/__tests__/Router/body-matching.test.d.ts
deleted file mode 100644
index cb0ff5c..0000000
--- a/packages/wip/generated-types/__tests__/Router/body-matching.test.d.ts
+++ /dev/null
@@ -1,1 +0,0 @@
-export {};
diff --git a/packages/wip/generated-types/__tests__/Router/edge-cases.test.d.ts b/packages/wip/generated-types/__tests__/Router/edge-cases.test.d.ts
deleted file mode 100644
index cb0ff5c..0000000
--- a/packages/wip/generated-types/__tests__/Router/edge-cases.test.d.ts
+++ /dev/null
@@ -1,1 +0,0 @@
-export {};
diff --git a/packages/wip/generated-types/__tests__/Router/function-matching.test.d.ts b/packages/wip/generated-types/__tests__/Router/function-matching.test.d.ts
deleted file mode 100644
index cb0ff5c..0000000
--- a/packages/wip/generated-types/__tests__/Router/function-matching.test.d.ts
+++ /dev/null
@@ -1,1 +0,0 @@
-export {};
diff --git a/packages/wip/generated-types/__tests__/Router/header-matching.test.d.ts b/packages/wip/generated-types/__tests__/Router/header-matching.test.d.ts
deleted file mode 100644
index cb0ff5c..0000000
--- a/packages/wip/generated-types/__tests__/Router/header-matching.test.d.ts
+++ /dev/null
@@ -1,1 +0,0 @@
-export {};
diff --git a/packages/wip/generated-types/__tests__/Router/matchPartialBody.test.d.ts b/packages/wip/generated-types/__tests__/Router/matchPartialBody.test.d.ts
deleted file mode 100644
index cb0ff5c..0000000
--- a/packages/wip/generated-types/__tests__/Router/matchPartialBody.test.d.ts
+++ /dev/null
@@ -1,1 +0,0 @@
-export {};
diff --git a/packages/wip/generated-types/__tests__/Router/matcher-object.test.d.ts b/packages/wip/generated-types/__tests__/Router/matcher-object.test.d.ts
deleted file mode 100644
index cb0ff5c..0000000
--- a/packages/wip/generated-types/__tests__/Router/matcher-object.test.d.ts
+++ /dev/null
@@ -1,1 +0,0 @@
-export {};
diff --git a/packages/wip/generated-types/__tests__/Router/method-matching.test.d.ts b/packages/wip/generated-types/__tests__/Router/method-matching.test.d.ts
deleted file mode 100644
index cb0ff5c..0000000
--- a/packages/wip/generated-types/__tests__/Router/method-matching.test.d.ts
+++ /dev/null
@@ -1,1 +0,0 @@
-export {};
diff --git a/packages/wip/generated-types/__tests__/Router/multiple-routes.test.d.ts b/packages/wip/generated-types/__tests__/Router/multiple-routes.test.d.ts
deleted file mode 100644
index cb0ff5c..0000000
--- a/packages/wip/generated-types/__tests__/Router/multiple-routes.test.d.ts
+++ /dev/null
@@ -1,1 +0,0 @@
-export {};
diff --git a/packages/wip/generated-types/__tests__/Router/naming-routes.test.d.ts b/packages/wip/generated-types/__tests__/Router/naming-routes.test.d.ts
deleted file mode 100644
index cb0ff5c..0000000
--- a/packages/wip/generated-types/__tests__/Router/naming-routes.test.d.ts
+++ /dev/null
@@ -1,1 +0,0 @@
-export {};
diff --git a/packages/wip/generated-types/__tests__/Router/path-parameter-matching.test.d.ts b/packages/wip/generated-types/__tests__/Router/path-parameter-matching.test.d.ts
deleted file mode 100644
index cb0ff5c..0000000
--- a/packages/wip/generated-types/__tests__/Router/path-parameter-matching.test.d.ts
+++ /dev/null
@@ -1,1 +0,0 @@
-export {};
diff --git a/packages/wip/generated-types/__tests__/Router/query-string-matching.test.d.ts b/packages/wip/generated-types/__tests__/Router/query-string-matching.test.d.ts
deleted file mode 100644
index cb0ff5c..0000000
--- a/packages/wip/generated-types/__tests__/Router/query-string-matching.test.d.ts
+++ /dev/null
@@ -1,1 +0,0 @@
-export {};
diff --git a/packages/wip/generated-types/__tests__/Router/sticky-routes.test.d.ts b/packages/wip/generated-types/__tests__/Router/sticky-routes.test.d.ts
deleted file mode 100644
index cb0ff5c..0000000
--- a/packages/wip/generated-types/__tests__/Router/sticky-routes.test.d.ts
+++ /dev/null
@@ -1,1 +0,0 @@
-export {};
diff --git a/packages/wip/generated-types/__tests__/Router/unmatched-calls.test.d.ts b/packages/wip/generated-types/__tests__/Router/unmatched-calls.test.d.ts
deleted file mode 100644
index cb0ff5c..0000000
--- a/packages/wip/generated-types/__tests__/Router/unmatched-calls.test.d.ts
+++ /dev/null
@@ -1,1 +0,0 @@
-export {};
diff --git a/packages/wip/generated-types/__tests__/Router/url-matching.test.d.ts b/packages/wip/generated-types/__tests__/Router/url-matching.test.d.ts
deleted file mode 100644
index cb0ff5c..0000000
--- a/packages/wip/generated-types/__tests__/Router/url-matching.test.d.ts
+++ /dev/null
@@ -1,1 +0,0 @@
-export {};