|
1 | 1 | import { join } from 'node:path/posix'
|
| 2 | +import { readFile } from 'node:fs/promises' |
2 | 3 | import type { Plugin } from 'vite'
|
3 | 4 | import type { MockedModuleSerialized } from '../registry'
|
4 | 5 | import { ManualMockedModule, MockerRegistry } from '../registry'
|
5 | 6 | import { cleanUrl } from '../utils'
|
| 7 | +import { automockModule } from './automockPlugin' |
6 | 8 |
|
7 | 9 | export interface InterceptorPluginOptions {
|
8 | 10 | /**
|
@@ -36,41 +38,50 @@ export function interceptorPlugin(options: InterceptorPluginOptions): Plugin {
|
36 | 38 | .join('\n')
|
37 | 39 | return `${module}\n${keys}`
|
38 | 40 | }
|
39 |
| - }, |
40 |
| - async resolveId(id, importer) { |
41 |
| - const resolved = await this.resolve(id, importer) |
42 |
| - if (!resolved) { |
43 |
| - return |
44 |
| - } |
45 |
| - const mock = registry.get(resolved.id) |
46 |
| - if (!mock) { |
47 |
| - return |
48 |
| - } |
49 | 41 | if (mock.type === 'redirect') {
|
50 |
| - return mock.redirect |
51 |
| - } |
52 |
| - if (mock.type === 'automock' || mock.type === 'autospy') { |
53 |
| - // handled by automockPlugin |
54 |
| - return injectQuery(resolved.id, `mock=${mock.type}`) |
| 42 | + return readFile(mock.redirect, 'utf-8') |
55 | 43 | }
|
56 | 44 | },
|
| 45 | + transform: { |
| 46 | + order: 'post', |
| 47 | + handler(code, id) { |
| 48 | + const mock = registry.get(id) |
| 49 | + if (!mock) { |
| 50 | + return |
| 51 | + } |
| 52 | + if (mock.type === 'automock' || mock.type === 'autospy') { |
| 53 | + const m = automockModule(code, mock.type, this.parse, { |
| 54 | + globalThisAccessor: options.globalThisAccessor, |
| 55 | + }) |
| 56 | + |
| 57 | + return { |
| 58 | + code: m.toString(), |
| 59 | + map: m.generateMap({ hires: 'boundary', source: cleanUrl(id) }), |
| 60 | + } |
| 61 | + } |
| 62 | + }, |
| 63 | + }, |
57 | 64 | configureServer(server) {
|
58 | 65 | server.ws.on('vitest:interceptor:register', (event: MockedModuleSerialized) => {
|
59 | 66 | const serverUrl = event.url
|
| 67 | + // the browsers stores the url relative to the root |
| 68 | + // but on the server "id" operates on the file paths |
60 | 69 | event.url = join(server.config.root, event.url)
|
61 | 70 | if (event.type === 'manual') {
|
62 | 71 | const module = ManualMockedModule.fromJSON(event, async () => {
|
63 | 72 | const keys = await getFactoryExports(serverUrl)
|
64 | 73 | return Object.fromEntries(keys.map(key => [key, null]))
|
65 | 74 | })
|
66 | 75 | Object.assign(module, {
|
67 |
| - // the browsers stores the url relative to the root |
68 |
| - // but on the server "id" operates on the file paths |
69 | 76 | serverUrl,
|
70 | 77 | })
|
71 | 78 | registry.add(module)
|
72 | 79 | }
|
73 | 80 | else {
|
| 81 | + if (event.type === 'redirect') { |
| 82 | + const redirectUrl = new URL(event.redirect) |
| 83 | + event.redirect = join(server.config.root, redirectUrl.pathname) |
| 84 | + } |
74 | 85 | registry.register(event)
|
75 | 86 | }
|
76 | 87 | server.ws.send('vitest:interceptor:register:result')
|
@@ -102,18 +113,3 @@ export function interceptorPlugin(options: InterceptorPluginOptions): Plugin {
|
102 | 113 | },
|
103 | 114 | }
|
104 | 115 | }
|
105 |
| - |
106 |
| -const replacePercentageRE = /%/g |
107 |
| -function injectQuery(url: string, queryToInject: string): string { |
108 |
| - // encode percents for consistent behavior with pathToFileURL |
109 |
| - // see #2614 for details |
110 |
| - const resolvedUrl = new URL( |
111 |
| - url.replace(replacePercentageRE, '%25'), |
112 |
| - location.href, |
113 |
| - ) |
114 |
| - const { search, hash } = resolvedUrl |
115 |
| - const pathname = cleanUrl(url) |
116 |
| - return `${pathname}?${queryToInject}${search ? `&${search.slice(1)}` : ''}${ |
117 |
| - hash ?? '' |
118 |
| - }` |
119 |
| -} |
0 commit comments