first commit
This commit is contained in:
@@ -0,0 +1,52 @@
|
||||
import type { Plugin } from 'vite'
|
||||
import { mockRules, type MockContext } from './index'
|
||||
|
||||
const MOCK_PREFIX = '/api/v1'
|
||||
|
||||
function readBody(req: NodeJS.ReadableStream): Promise<string> {
|
||||
return new Promise((resolve) => {
|
||||
let raw = ''
|
||||
req.on('data', (chunk) => (raw += chunk))
|
||||
req.on('end', () => resolve(raw))
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 本地 mock 中间件:仅在 dev 且 VITE_USE_MOCK=true 时拦截 /api/v1 请求。
|
||||
* 不引入三方 mock 依赖,避免污染生产依赖树。
|
||||
*/
|
||||
export function mockPlugin(enabled = true): Plugin {
|
||||
return {
|
||||
name: 'portal-mock',
|
||||
apply: 'serve',
|
||||
configureServer(server) {
|
||||
if (!enabled) return
|
||||
server.middlewares.use((req, res, next) => {
|
||||
if (!req.url?.startsWith(MOCK_PREFIX)) return next()
|
||||
|
||||
const requestUrl = new URL(req.url, 'http://localhost')
|
||||
void (async () => {
|
||||
const raw = req.method === 'GET' ? '' : await readBody(req)
|
||||
const rule = mockRules.find(
|
||||
(item) =>
|
||||
item.method === (req.method ?? 'GET').toUpperCase() &&
|
||||
item.pattern.test(requestUrl.pathname),
|
||||
)
|
||||
|
||||
if (!rule) return next()
|
||||
|
||||
const matched = requestUrl.pathname.match(rule.pattern)
|
||||
const ctx: MockContext = {
|
||||
url: requestUrl.pathname,
|
||||
params: matched ? matched.slice(1) : [],
|
||||
query: Object.fromEntries(requestUrl.searchParams.entries()),
|
||||
body: raw ? JSON.parse(raw) : {},
|
||||
}
|
||||
|
||||
res.setHeader('Content-Type', 'application/json;charset=utf-8')
|
||||
res.end(JSON.stringify({ code: '00000', data: rule.handler(ctx) ?? null, msg: 'success' }))
|
||||
})()
|
||||
})
|
||||
},
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user