aboutsummaryrefslogtreecommitdiffstats
path: root/vanilla/node_modules/@vitest/mocker/dist/browser.js
blob: 3e832476025eeb8af8ab5f1663cae0517df5c018 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
export { M as ModuleMocker, c as createCompilerHints } from './chunk-mocker.js';
import { M as MockerRegistry } from './chunk-registry.js';
import { c as createManualModuleSource, a as cleanUrl } from './chunk-utils.js';
export { M as ModuleMockerServerInterceptor } from './chunk-interceptor-native.js';
import './index.js';
import './chunk-pathe.M-eThtNZ.js';

class ModuleMockerMSWInterceptor {
	mocks = new MockerRegistry();
	startPromise;
	worker;
	constructor(options = {}) {
		this.options = options;
		if (!options.globalThisAccessor) {
			options.globalThisAccessor = "\"__vitest_mocker__\"";
		}
	}
	async register(module) {
		await this.init();
		this.mocks.add(module);
	}
	async delete(url) {
		await this.init();
		this.mocks.delete(url);
	}
	async invalidate() {
		this.mocks.clear();
	}
	async resolveManualMock(mock) {
		const exports$1 = Object.keys(await mock.resolve());
		const text = createManualModuleSource(mock.url, exports$1, this.options.globalThisAccessor);
		return new Response(text, { headers: { "Content-Type": "application/javascript" } });
	}
	async init() {
		if (this.worker) {
			return this.worker;
		}
		if (this.startPromise) {
			return this.startPromise;
		}
		const worker = this.options.mswWorker;
		this.startPromise = Promise.all([worker ? { setupWorker(handler) {
			worker.use(handler);
			return worker;
		} } : import('msw/browser'), import('msw/core/http')]).then(([{ setupWorker }, { http }]) => {
			const worker = setupWorker(http.get(/.+/, async ({ request }) => {
				const path = cleanQuery(request.url.slice(location.origin.length));
				if (!this.mocks.has(path)) {
					return passthrough();
				}
				const mock = this.mocks.get(path);
				switch (mock.type) {
					case "manual": return this.resolveManualMock(mock);
					case "automock":
					case "autospy": return Response.redirect(injectQuery(path, `mock=${mock.type}`));
					case "redirect": return Response.redirect(mock.redirect);
					default: throw new Error(`Unknown mock type: ${mock.type}`);
				}
			}));
			return worker.start(this.options.mswOptions).then(() => worker);
		}).finally(() => {
			this.worker = worker;
			this.startPromise = undefined;
		});
		return await this.startPromise;
	}
}
const trailingSeparatorRE = /[?&]$/;
const timestampRE = /\bt=\d{13}&?\b/;
const versionRE = /\bv=\w{8}&?\b/;
function cleanQuery(url) {
	return url.replace(timestampRE, "").replace(versionRE, "").replace(trailingSeparatorRE, "");
}
function passthrough() {
	return new Response(null, {
		status: 302,
		statusText: "Passthrough",
		headers: { "x-msw-intention": "passthrough" }
	});
}
const replacePercentageRE = /%/g;
function injectQuery(url, queryToInject) {
	// encode percents for consistent behavior with pathToFileURL
	// see #2614 for details
	const resolvedUrl = new URL(url.replace(replacePercentageRE, "%25"), location.href);
	const { search, hash } = resolvedUrl;
	const pathname = cleanUrl(url);
	return `${pathname}?${queryToInject}${search ? `&${search.slice(1)}` : ""}${hash ?? ""}`;
}

export { ModuleMockerMSWInterceptor };