vite-plugin-mock-dev-server 2.0.7 → 2.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{types-C8ZwTU-4.d.mts → config-7dnQWJSY.d.ts} +501 -173
- package/dist/helper.d.ts +271 -0
- package/dist/index-x4QPVyiP.d.ts +270 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.js +48 -0
- package/dist/logger-C-7qpBNh.js +2 -0
- package/dist/server.d.ts +3 -0
- package/dist/server.js +1 -0
- package/dist/types.d.ts +7 -0
- package/package.json +27 -22
- package/dist/helper.d.mts +0 -126
- package/dist/index.d.mts +0 -9
- package/dist/index.mjs +0 -37
- package/dist/server-BEkc6AaK.mjs +0 -1
- package/dist/server-lwszq3fl.d.mts +0 -89
- package/dist/server.d.mts +0 -2
- package/dist/server.mjs +0 -1
- package/dist/types.d.mts +0 -2
- /package/dist/{helper.mjs → helper.js} +0 -0
- /package/dist/{types.mjs → types.js} +0 -0
package/dist/helper.d.ts
ADDED
|
@@ -0,0 +1,271 @@
|
|
|
1
|
+
import { C as MockResponse, D as SetCookieOption, E as GetCookieOption, S as MockRequest, T as CookiesOption, _ as RecordedRes, a as MockHttpItem, b as Headers, c as LogType, d as MockServerPluginOptions, f as ServerBuildOption, g as RecordedRequest, h as RecordedReq, i as MockErrorConfig, l as MockMatchPriority, m as RecordedMeta, n as MockWebsocketItem, o as BodyParserOptions, p as RecordOptions, r as WebSocketSetupContext, s as LogLevel, t as MockOptions, u as MockMatchSpecialPriority, v as ResolvedRecordOptions, w as ResponseBody, x as Method, y as ExtraRequest } from "./config-7dnQWJSY.js";
|
|
2
|
+
import { FormidableFile } from "./types.js";
|
|
3
|
+
import { IncomingMessage, OutgoingHttpHeaders, ServerResponse } from "node:http";
|
|
4
|
+
import { Transform } from "node:stream";
|
|
5
|
+
|
|
6
|
+
//#region src/helpers/createSSEStream.d.ts
|
|
7
|
+
/**
|
|
8
|
+
* Server-sent events message interface
|
|
9
|
+
*
|
|
10
|
+
* Server-sent events 消息接口
|
|
11
|
+
*/
|
|
12
|
+
interface SSEMessage {
|
|
13
|
+
/**
|
|
14
|
+
* Message data
|
|
15
|
+
*
|
|
16
|
+
* 消息数据
|
|
17
|
+
*/
|
|
18
|
+
data?: string | object;
|
|
19
|
+
/**
|
|
20
|
+
* Comment
|
|
21
|
+
*
|
|
22
|
+
* 注释
|
|
23
|
+
*/
|
|
24
|
+
comment?: string;
|
|
25
|
+
/**
|
|
26
|
+
* Event name
|
|
27
|
+
*
|
|
28
|
+
* 事件名称
|
|
29
|
+
*/
|
|
30
|
+
event?: string;
|
|
31
|
+
/**
|
|
32
|
+
* Event ID
|
|
33
|
+
*
|
|
34
|
+
* 事件 ID
|
|
35
|
+
*/
|
|
36
|
+
id?: string;
|
|
37
|
+
/**
|
|
38
|
+
* Retry interval
|
|
39
|
+
*
|
|
40
|
+
* 重试间隔
|
|
41
|
+
*/
|
|
42
|
+
retry?: number;
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Write headers interface
|
|
46
|
+
*
|
|
47
|
+
* 写入头信息接口
|
|
48
|
+
*/
|
|
49
|
+
interface WriteHeaders {
|
|
50
|
+
/**
|
|
51
|
+
* Write HTTP headers
|
|
52
|
+
*
|
|
53
|
+
* 写入 HTTP 头信息
|
|
54
|
+
*/
|
|
55
|
+
writeHead?: (statusCode: number, headers?: OutgoingHttpHeaders) => WriteHeaders;
|
|
56
|
+
/**
|
|
57
|
+
* Flush headers
|
|
58
|
+
*
|
|
59
|
+
* 刷新头信息
|
|
60
|
+
*/
|
|
61
|
+
flushHeaders?: () => void;
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Header stream type
|
|
65
|
+
*
|
|
66
|
+
* 头信息流类型
|
|
67
|
+
*/
|
|
68
|
+
type HeaderStream = NodeJS.WritableStream & WriteHeaders;
|
|
69
|
+
/**
|
|
70
|
+
* Transforms "messages" to W3C event stream content.
|
|
71
|
+
* See https://html.spec.whatwg.org/multipage/server-sent-events.html
|
|
72
|
+
* A message is an object with one or more of the following properties:
|
|
73
|
+
* - data (String or object, which gets turned into JSON)
|
|
74
|
+
* - event
|
|
75
|
+
* - id
|
|
76
|
+
* - retry
|
|
77
|
+
* - comment
|
|
78
|
+
*
|
|
79
|
+
* If constructed with a HTTP Request, it will optimise the socket for streaming.
|
|
80
|
+
* If this stream is piped to an HTTP Response, it will set appropriate headers.
|
|
81
|
+
*
|
|
82
|
+
* 将 "messages" 转换为 W3C 事件流内容。
|
|
83
|
+
* 参见 https://html.spec.whatwg.org/multipage/server-sent-events.html
|
|
84
|
+
* 消息是一个具有以下一个或多个属性的对象:
|
|
85
|
+
* - data (字符串或对象,会被转换为 JSON)
|
|
86
|
+
* - event
|
|
87
|
+
* - id
|
|
88
|
+
* - retry
|
|
89
|
+
* - comment
|
|
90
|
+
*
|
|
91
|
+
* 如果使用 HTTP 请求构造,它将优化套接字以进行流式传输。
|
|
92
|
+
* 如果此流被管道传输到 HTTP 响应,它将设置适当的头信息。
|
|
93
|
+
*/
|
|
94
|
+
declare class SSEStream extends Transform {
|
|
95
|
+
/**
|
|
96
|
+
* Constructor
|
|
97
|
+
*
|
|
98
|
+
* 构造函数
|
|
99
|
+
*
|
|
100
|
+
* @param req - HTTP request object / HTTP 请求对象
|
|
101
|
+
*/
|
|
102
|
+
constructor(req: IncomingMessage);
|
|
103
|
+
/**
|
|
104
|
+
* Pipe the stream to a destination
|
|
105
|
+
*
|
|
106
|
+
* 将流管道传输到目标
|
|
107
|
+
*
|
|
108
|
+
* @template T - Type of destination stream / 目标流的类型
|
|
109
|
+
* @param destination - Destination stream / 目标流
|
|
110
|
+
* @param options - Pipe options / 管道选项
|
|
111
|
+
* @param options.end - Whether to end the stream after piping / 是否在管道传输后结束流
|
|
112
|
+
* @returns Destination stream / 目标流
|
|
113
|
+
*/
|
|
114
|
+
pipe<T extends HeaderStream>(destination: T, options?: {
|
|
115
|
+
end?: boolean;
|
|
116
|
+
}): T;
|
|
117
|
+
/**
|
|
118
|
+
* Transform message to SSE format
|
|
119
|
+
*
|
|
120
|
+
* 将消息转换为 SSE 格式
|
|
121
|
+
*
|
|
122
|
+
* @param message - SSE message / SSE 消息
|
|
123
|
+
* @param encoding - Encoding / 编码
|
|
124
|
+
* @param callback - Callback function / 回调函数
|
|
125
|
+
*/
|
|
126
|
+
_transform(message: SSEMessage, encoding: string, callback: (error?: (Error | null), data?: any) => void): void;
|
|
127
|
+
/**
|
|
128
|
+
* Write message to the stream
|
|
129
|
+
*
|
|
130
|
+
* 向流写入消息
|
|
131
|
+
*
|
|
132
|
+
* @param message - SSE message / SSE 消息
|
|
133
|
+
* @param encoding - Encoding / 编码
|
|
134
|
+
* @param cb - Callback function / 回调函数
|
|
135
|
+
* @returns Whether the write was successful / 写入是否成功
|
|
136
|
+
*/
|
|
137
|
+
write(message: SSEMessage, encoding?: BufferEncoding, cb?: (error: Error | null | undefined) => void): boolean;
|
|
138
|
+
/**
|
|
139
|
+
* Write message to the stream
|
|
140
|
+
*
|
|
141
|
+
* 向流写入消息
|
|
142
|
+
*
|
|
143
|
+
* @param message - SSE message / SSE 消息
|
|
144
|
+
* @param cb - Callback function / 回调函数
|
|
145
|
+
* @returns Whether the write was successful / 写入是否成功
|
|
146
|
+
*/
|
|
147
|
+
write(message: SSEMessage, cb?: (error: Error | null | undefined) => void): boolean;
|
|
148
|
+
/**
|
|
149
|
+
* Destroy the stream
|
|
150
|
+
*
|
|
151
|
+
* 销毁流
|
|
152
|
+
*
|
|
153
|
+
* @param error - Error object / 错误对象
|
|
154
|
+
* @returns This stream / 此流
|
|
155
|
+
*/
|
|
156
|
+
destroy(error?: Error): this;
|
|
157
|
+
}
|
|
158
|
+
/**
|
|
159
|
+
* Create a Server-sent events write stream for simulating EventSource
|
|
160
|
+
*
|
|
161
|
+
* 创建一个 Server-sent events 写入流,用于支持模拟 EventSource
|
|
162
|
+
*
|
|
163
|
+
* @example
|
|
164
|
+
* ```ts
|
|
165
|
+
* import { createSSEStream, defineMock } from 'vite-plugin-mock-dev-server'
|
|
166
|
+
*
|
|
167
|
+
* export default defineMock({
|
|
168
|
+
* url: '/api',
|
|
169
|
+
* response: (req, res) => {
|
|
170
|
+
* const sse = createSSEStream(req, res)
|
|
171
|
+
* sse.write({ event: 'message', data: { message: 'hello world' } })
|
|
172
|
+
* }
|
|
173
|
+
* })
|
|
174
|
+
* ```
|
|
175
|
+
*
|
|
176
|
+
* @param req - HTTP request object / HTTP 请求对象
|
|
177
|
+
* @param res - HTTP response object / HTTP 响应对象
|
|
178
|
+
* @returns SSE stream instance / SSE 流实例
|
|
179
|
+
*/
|
|
180
|
+
declare function createSSEStream(req: IncomingMessage, res: ServerResponse): SSEStream;
|
|
181
|
+
//#endregion
|
|
182
|
+
//#region src/helpers/defineMock.d.ts
|
|
183
|
+
/**
|
|
184
|
+
* Mock config Type helper
|
|
185
|
+
*
|
|
186
|
+
* mock配置 类型帮助函数
|
|
187
|
+
* @param config see config docs:
|
|
188
|
+
* {@link https://vite-plugin-mock-dev-server.netlify.app/guide/mock-config en-US DOC} |
|
|
189
|
+
* {@link https://vite-plugin-mock-dev-server.netlify.app/zh/guide/mock-config zh-CN DOC}
|
|
190
|
+
*
|
|
191
|
+
* @example
|
|
192
|
+
* Mock Http Request
|
|
193
|
+
* ```ts
|
|
194
|
+
* export default defineMock({
|
|
195
|
+
* url: '/api/example',
|
|
196
|
+
* method: ['GET', 'POST'],
|
|
197
|
+
* body: { a: 1 },
|
|
198
|
+
* })
|
|
199
|
+
* ```
|
|
200
|
+
* ```ts
|
|
201
|
+
* export default defineMock({
|
|
202
|
+
* url: '/api/example',
|
|
203
|
+
* method: 'GET',
|
|
204
|
+
* body: ({ query }) => ({ a: 1, b: query.b }),
|
|
205
|
+
* })
|
|
206
|
+
* ```
|
|
207
|
+
* @example
|
|
208
|
+
* Mock WebSocket
|
|
209
|
+
* ```ts
|
|
210
|
+
* export default defineMock({
|
|
211
|
+
* url: '/socket.io',
|
|
212
|
+
* ws: true,
|
|
213
|
+
* setup(wss) {
|
|
214
|
+
* wss.on('connection', (ws) => {
|
|
215
|
+
* ws.on('message', (rawData) => console.log(rawData))
|
|
216
|
+
* ws.send('data')
|
|
217
|
+
* })
|
|
218
|
+
* },
|
|
219
|
+
* })
|
|
220
|
+
* ```
|
|
221
|
+
*/
|
|
222
|
+
declare function defineMock(config: MockHttpItem): MockHttpItem;
|
|
223
|
+
declare function defineMock(config: MockWebsocketItem): MockWebsocketItem;
|
|
224
|
+
declare function defineMock(config: MockOptions): MockOptions;
|
|
225
|
+
/**
|
|
226
|
+
* Return a custom defineMock function to support preprocessing of mock config.
|
|
227
|
+
*
|
|
228
|
+
* 返回一个自定义的 defineMock 函数,用于支持对 mock config 的预处理。
|
|
229
|
+
* @param transformer preprocessing function
|
|
230
|
+
* @example
|
|
231
|
+
* ```ts
|
|
232
|
+
* const definePostMock = createDefineMock((mock) => {
|
|
233
|
+
* mock.url = '/api/post/' + mock.url
|
|
234
|
+
* })
|
|
235
|
+
* export default definePostMock({
|
|
236
|
+
* url: 'list',
|
|
237
|
+
* body: [{ title: '1' }, { title: '2' }],
|
|
238
|
+
* })
|
|
239
|
+
* ```
|
|
240
|
+
*/
|
|
241
|
+
declare function createDefineMock(transformer: (mock: MockHttpItem | MockWebsocketItem) => MockHttpItem | MockWebsocketItem | void): typeof defineMock;
|
|
242
|
+
//#endregion
|
|
243
|
+
//#region src/helpers/defineMockData.d.ts
|
|
244
|
+
/**
|
|
245
|
+
* Mock data type with getter, setter, and value property
|
|
246
|
+
*
|
|
247
|
+
* 带有 getter、setter 和 value 属性的 Mock 数据类型
|
|
248
|
+
*
|
|
249
|
+
* @template T - Type of mock data / Mock 数据的类型
|
|
250
|
+
*/
|
|
251
|
+
type MockData<T = any> = readonly [() => T, (val: T | ((val: T) => T | void)) => void] & {
|
|
252
|
+
/**
|
|
253
|
+
* Current value
|
|
254
|
+
*
|
|
255
|
+
* 当前值
|
|
256
|
+
*/
|
|
257
|
+
value: T;
|
|
258
|
+
};
|
|
259
|
+
/**
|
|
260
|
+
* Define mock data with memory-based sharing mechanism
|
|
261
|
+
*
|
|
262
|
+
* 定义带有基于内存的共享机制的 Mock 数据
|
|
263
|
+
*
|
|
264
|
+
* @template T - Type of mock data / Mock 数据的类型
|
|
265
|
+
* @param key - Unique key for mock data / Mock 数据的唯一键
|
|
266
|
+
* @param initialData - Initial data value / 初始数据值
|
|
267
|
+
* @returns MockData object with getter, setter, and value property / 带有 getter、setter 和 value 属性的 MockData 对象
|
|
268
|
+
*/
|
|
269
|
+
declare function defineMockData<T = any>(key: string, initialData: T): MockData<T>;
|
|
270
|
+
//#endregion
|
|
271
|
+
export { BodyParserOptions, CookiesOption, ExtraRequest, FormidableFile, GetCookieOption, HeaderStream, Headers, LogLevel, LogType, Method, MockData, MockErrorConfig, MockHttpItem, MockMatchPriority, MockMatchSpecialPriority, MockOptions, MockRequest, MockResponse, MockServerPluginOptions, MockWebsocketItem, RecordOptions, RecordedMeta, RecordedReq, RecordedRequest, RecordedRes, ResolvedRecordOptions, ResponseBody, SSEMessage, ServerBuildOption, SetCookieOption, WebSocketSetupContext, createDefineMock, createSSEStream, defineMock, defineMockData };
|
|
@@ -0,0 +1,270 @@
|
|
|
1
|
+
import { a as MockHttpItem, d as MockServerPluginOptions, f as ServerBuildOption, n as MockWebsocketItem, s as LogLevel, t as MockOptions, v as ResolvedRecordOptions } from "./config-7dnQWJSY.js";
|
|
2
|
+
import { Matcher } from "picomatch";
|
|
3
|
+
import EventEmitter from "node:events";
|
|
4
|
+
import { CorsOptions } from "cors";
|
|
5
|
+
import { Server } from "node:http";
|
|
6
|
+
import { Alias, Connect, Plugin } from "vite";
|
|
7
|
+
import { Http2SecureServer } from "node:http2";
|
|
8
|
+
|
|
9
|
+
//#region src/core/logger.d.ts
|
|
10
|
+
/**
|
|
11
|
+
* Logger interface
|
|
12
|
+
*
|
|
13
|
+
* 日志接口
|
|
14
|
+
*/
|
|
15
|
+
interface Logger {
|
|
16
|
+
/**
|
|
17
|
+
* Debug log
|
|
18
|
+
*
|
|
19
|
+
* 调试日志
|
|
20
|
+
*/
|
|
21
|
+
debug: (msg: string, level?: boolean | LogLevel) => void;
|
|
22
|
+
/**
|
|
23
|
+
* Info log
|
|
24
|
+
*
|
|
25
|
+
* 信息日志
|
|
26
|
+
*/
|
|
27
|
+
info: (msg: string, level?: boolean | LogLevel) => void;
|
|
28
|
+
/**
|
|
29
|
+
* Warning log
|
|
30
|
+
*
|
|
31
|
+
* 警告日志
|
|
32
|
+
*/
|
|
33
|
+
warn: (msg: string, level?: boolean | LogLevel) => void;
|
|
34
|
+
/**
|
|
35
|
+
* Error log
|
|
36
|
+
*
|
|
37
|
+
* 错误日志
|
|
38
|
+
*/
|
|
39
|
+
error: (msg: string, level?: boolean | LogLevel) => void;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Log levels mapping
|
|
43
|
+
*
|
|
44
|
+
* 日志级别映射
|
|
45
|
+
*/
|
|
46
|
+
declare const logLevels: Record<LogLevel, number>;
|
|
47
|
+
/**
|
|
48
|
+
* Create logger instance
|
|
49
|
+
*
|
|
50
|
+
* 创建日志实例
|
|
51
|
+
*
|
|
52
|
+
* @param prefix - Log prefix / 日志前缀
|
|
53
|
+
* @param defaultLevel - Default log level / 默认日志级别
|
|
54
|
+
* @returns Logger instance / 日志实例
|
|
55
|
+
*/
|
|
56
|
+
declare function createLogger(prefix: string, defaultLevel?: LogLevel): Logger;
|
|
57
|
+
//#endregion
|
|
58
|
+
//#region src/core/options.d.ts
|
|
59
|
+
type ResolvedMockServerPluginOptions = Required<Omit<MockServerPluginOptions, "build" | "cors" | "wsPrefix" | "prefix" | "record">> & {
|
|
60
|
+
context: string;
|
|
61
|
+
logger: Logger;
|
|
62
|
+
alias: Alias[];
|
|
63
|
+
define: Record<string, any>;
|
|
64
|
+
proxies: string[];
|
|
65
|
+
wsProxies: string[];
|
|
66
|
+
build: false | ServerBuildOption;
|
|
67
|
+
cors: false | CorsOptions;
|
|
68
|
+
record: ResolvedRecordOptions;
|
|
69
|
+
};
|
|
70
|
+
//#endregion
|
|
71
|
+
//#region src/core/plugin.d.ts
|
|
72
|
+
/**
|
|
73
|
+
* Create mock dev server plugin
|
|
74
|
+
*
|
|
75
|
+
* 创建 Mock 开发服务器插件
|
|
76
|
+
*
|
|
77
|
+
* @param options - Plugin options / 插件配置项
|
|
78
|
+
* @returns Array of Vite plugin objects / Vite 插件对象数组
|
|
79
|
+
*/
|
|
80
|
+
declare function mockDevServerPlugin(options?: MockServerPluginOptions): Plugin[];
|
|
81
|
+
//#endregion
|
|
82
|
+
//#region src/compiler/types.d.ts
|
|
83
|
+
type MockRawData = MockOptions | MockHttpItem | MockWebsocketItem | Record<string, MockOptions | MockHttpItem | MockWebsocketItem>;
|
|
84
|
+
//#endregion
|
|
85
|
+
//#region src/compiler/processData.d.ts
|
|
86
|
+
declare function processRawData(raw: MockRawData, __filepath__: string): MockOptions | MockHttpItem | MockWebsocketItem;
|
|
87
|
+
declare function processMockData(mockList: Map<string, MockHttpItem | MockWebsocketItem | MockOptions> | (MockHttpItem | MockWebsocketItem | MockOptions)[]): Record<string, MockOptions>;
|
|
88
|
+
declare function sortByValidator(mocks: MockOptions): (MockHttpItem | MockWebsocketItem)[];
|
|
89
|
+
//#endregion
|
|
90
|
+
//#region src/compiler/compiler.d.ts
|
|
91
|
+
/**
|
|
92
|
+
* Mock file loading and compilation, converting to Mock data
|
|
93
|
+
*
|
|
94
|
+
* Mock 文件加载编译,并转换为 Mock 数据
|
|
95
|
+
*/
|
|
96
|
+
declare class Compiler extends EventEmitter {
|
|
97
|
+
/**
|
|
98
|
+
* Cache for mock modules
|
|
99
|
+
*
|
|
100
|
+
* Mock 模块缓存
|
|
101
|
+
*/
|
|
102
|
+
private moduleCache;
|
|
103
|
+
/**
|
|
104
|
+
* Dependencies mapping for mock modules
|
|
105
|
+
*
|
|
106
|
+
* Mock 模块依赖映射
|
|
107
|
+
*/
|
|
108
|
+
private moduleDeps;
|
|
109
|
+
/**
|
|
110
|
+
* Current working directory
|
|
111
|
+
*
|
|
112
|
+
* 当前工作目录
|
|
113
|
+
*/
|
|
114
|
+
cwd: string;
|
|
115
|
+
/**
|
|
116
|
+
* File watcher for mock files
|
|
117
|
+
*
|
|
118
|
+
* Mock 文件监视器
|
|
119
|
+
*/
|
|
120
|
+
private mockWatcher;
|
|
121
|
+
/**
|
|
122
|
+
* File watcher for dependency files
|
|
123
|
+
*
|
|
124
|
+
* 依赖文件监视器
|
|
125
|
+
*/
|
|
126
|
+
private depsWatcher;
|
|
127
|
+
/**
|
|
128
|
+
* Whether the project uses ES modules
|
|
129
|
+
*
|
|
130
|
+
* 项目是否使用 ES 模块
|
|
131
|
+
*/
|
|
132
|
+
private isESM;
|
|
133
|
+
/**
|
|
134
|
+
* Processed mock data
|
|
135
|
+
*
|
|
136
|
+
* 处理后的 Mock 数据
|
|
137
|
+
*/
|
|
138
|
+
private _mockData;
|
|
139
|
+
/**
|
|
140
|
+
* Resolved plugin options
|
|
141
|
+
*
|
|
142
|
+
* 解析后的插件配置项
|
|
143
|
+
*/
|
|
144
|
+
options: ResolvedMockServerPluginOptions;
|
|
145
|
+
/**
|
|
146
|
+
* Constructor
|
|
147
|
+
*
|
|
148
|
+
* 构造函数
|
|
149
|
+
*
|
|
150
|
+
* @param options - Resolved plugin options / 解析后的插件配置项
|
|
151
|
+
*/
|
|
152
|
+
constructor(options: ResolvedMockServerPluginOptions);
|
|
153
|
+
/**
|
|
154
|
+
* Get processed mock data
|
|
155
|
+
*
|
|
156
|
+
* 获取处理后的 Mock 数据
|
|
157
|
+
*
|
|
158
|
+
* @returns Processed mock data / 处理后的 Mock 数据
|
|
159
|
+
*/
|
|
160
|
+
get mockData(): Record<string, MockOptions>;
|
|
161
|
+
/**
|
|
162
|
+
* Run the compiler
|
|
163
|
+
*
|
|
164
|
+
* 运行编译器
|
|
165
|
+
*
|
|
166
|
+
* @param watch - Whether to watch for file changes / 是否监视文件变化
|
|
167
|
+
*/
|
|
168
|
+
run(watch?: boolean): void;
|
|
169
|
+
/**
|
|
170
|
+
* Close the compiler and watchers
|
|
171
|
+
*
|
|
172
|
+
* 关闭编译器和监视器
|
|
173
|
+
*/
|
|
174
|
+
close(): void;
|
|
175
|
+
/**
|
|
176
|
+
* Load and compile a mock file
|
|
177
|
+
*
|
|
178
|
+
* 加载并编译 Mock 文件
|
|
179
|
+
*
|
|
180
|
+
* @param filepath - Path to the mock file / Mock 文件路径
|
|
181
|
+
*/
|
|
182
|
+
private load;
|
|
183
|
+
/**
|
|
184
|
+
* Update mock data from module cache
|
|
185
|
+
*
|
|
186
|
+
* 从模块缓存更新 Mock 数据
|
|
187
|
+
*/
|
|
188
|
+
private updateMockData;
|
|
189
|
+
/**
|
|
190
|
+
* Update module dependencies
|
|
191
|
+
*
|
|
192
|
+
* 更新模块依赖
|
|
193
|
+
*
|
|
194
|
+
* @param filepath - Path to the mock file / Mock 文件路径
|
|
195
|
+
* @param deps - Dependencies of the mock file / Mock 文件的依赖
|
|
196
|
+
*/
|
|
197
|
+
private updateModuleDeps;
|
|
198
|
+
/**
|
|
199
|
+
* Watch mock entry files
|
|
200
|
+
*
|
|
201
|
+
* 监视 Mock 入口文件
|
|
202
|
+
*
|
|
203
|
+
* @param isMatch - Function to check if a file matches the include/exclude pattern / 检查文件是否匹配包含/排除模式的函数
|
|
204
|
+
*/
|
|
205
|
+
watchMockEntry(isMatch: Matcher): void;
|
|
206
|
+
/**
|
|
207
|
+
* Watch dependency files
|
|
208
|
+
*
|
|
209
|
+
* 监视依赖文件
|
|
210
|
+
*/
|
|
211
|
+
watchDeps(): void;
|
|
212
|
+
}
|
|
213
|
+
//#endregion
|
|
214
|
+
//#region src/mockHttp/middleware.d.ts
|
|
215
|
+
interface CreateMockMiddlewareOptions extends Pick<ResolvedMockServerPluginOptions, "formidableOptions" | "cookiesOptions" | "bodyParserOptions" | "priority" | "record" | "replay"> {
|
|
216
|
+
proxies: string[];
|
|
217
|
+
logger: Logger;
|
|
218
|
+
cors: false | CorsOptions;
|
|
219
|
+
}
|
|
220
|
+
/**
|
|
221
|
+
* Create mock middleware
|
|
222
|
+
*
|
|
223
|
+
* 创建 Mock 中间件
|
|
224
|
+
*
|
|
225
|
+
* @param compiler - Compiler instance / 编译器实例
|
|
226
|
+
* @param options - Middleware options / 中间件配置项
|
|
227
|
+
* @param options.formidableOptions - Formidable options / Formidable 配置项
|
|
228
|
+
* @param options.bodyParserOptions - Body parser options / 请求体解析配置项
|
|
229
|
+
* @param options.proxies - Proxy paths / 代理路径
|
|
230
|
+
* @param options.cookiesOptions - Cookies options / Cookies 配置项
|
|
231
|
+
* @param options.logger - Logger instance / 日志实例
|
|
232
|
+
* @param options.priority - Path matching priority / 路径匹配优先级
|
|
233
|
+
* @param options.cors - CORS options / CORS 配置项
|
|
234
|
+
* @param options.record - Record options / 录制配置项
|
|
235
|
+
* @param options.replay - Replay options / 回放配置项
|
|
236
|
+
*
|
|
237
|
+
* @returns Connect middleware function / Connect 中间件函数
|
|
238
|
+
*/
|
|
239
|
+
declare function createMockMiddleware(compiler: Compiler, {
|
|
240
|
+
formidableOptions,
|
|
241
|
+
bodyParserOptions,
|
|
242
|
+
proxies,
|
|
243
|
+
cookiesOptions,
|
|
244
|
+
logger,
|
|
245
|
+
priority,
|
|
246
|
+
cors: corsOptions,
|
|
247
|
+
record,
|
|
248
|
+
replay
|
|
249
|
+
}: CreateMockMiddlewareOptions): Connect.NextHandleFunction;
|
|
250
|
+
//#endregion
|
|
251
|
+
//#region src/mockWebsocket/server.d.ts
|
|
252
|
+
/**
|
|
253
|
+
* Mock WebSocket server
|
|
254
|
+
*
|
|
255
|
+
* Mock WebSocket 服务器
|
|
256
|
+
*
|
|
257
|
+
* @param compiler - Compiler instance / 编译器实例
|
|
258
|
+
* @param server - HTTP server instance / HTTP 服务器实例
|
|
259
|
+
* @param options - Resolved plugin options / 解析后的插件配置
|
|
260
|
+
* @param options.wsProxies - WebSocket proxy prefixes / WebSocket 代理前缀
|
|
261
|
+
* @param options.cookiesOptions - Cookies options / Cookies 配置项
|
|
262
|
+
* @param options.logger - Logger instance / 日志实例
|
|
263
|
+
*/
|
|
264
|
+
declare function mockWebSocket(compiler: Compiler, server: Server | Http2SecureServer | null, {
|
|
265
|
+
wsProxies: proxies,
|
|
266
|
+
cookiesOptions,
|
|
267
|
+
logger
|
|
268
|
+
}: ResolvedMockServerPluginOptions): void;
|
|
269
|
+
//#endregion
|
|
270
|
+
export { processRawData as a, Logger as c, processMockData as i, createLogger as l, CreateMockMiddlewareOptions as n, sortByValidator as o, createMockMiddleware as r, mockDevServerPlugin as s, mockWebSocket as t, logLevels as u };
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { C as MockResponse, D as SetCookieOption, E as GetCookieOption, S as MockRequest, T as CookiesOption, _ as RecordedRes, a as MockHttpItem, b as Headers, c as LogType, d as MockServerPluginOptions, f as ServerBuildOption, g as RecordedRequest, h as RecordedReq, i as MockErrorConfig, l as MockMatchPriority, m as RecordedMeta, n as MockWebsocketItem, o as BodyParserOptions, p as RecordOptions, r as WebSocketSetupContext, s as LogLevel, t as MockOptions, u as MockMatchSpecialPriority, v as ResolvedRecordOptions, w as ResponseBody, x as Method, y as ExtraRequest } from "./config-7dnQWJSY.js";
|
|
2
|
+
import { FormidableFile } from "./types.js";
|
|
3
|
+
import { HeaderStream, MockData, SSEMessage, createDefineMock, createSSEStream, defineMock, defineMockData } from "./helper.js";
|
|
4
|
+
import { a as processRawData, c as Logger, i as processMockData, l as createLogger, n as CreateMockMiddlewareOptions, o as sortByValidator, r as createMockMiddleware, s as mockDevServerPlugin, t as mockWebSocket, u as logLevels } from "./index-x4QPVyiP.js";
|
|
5
|
+
import "./server.js";
|
|
6
|
+
export { BodyParserOptions, CookiesOption, CreateMockMiddlewareOptions, ExtraRequest, type FormidableFile, GetCookieOption, HeaderStream, Headers, LogLevel, LogType, Logger, Method, MockData, MockErrorConfig, type MockHttpItem, MockMatchPriority, MockMatchSpecialPriority, type MockOptions, type MockRequest, MockResponse, type MockServerPluginOptions, type MockWebsocketItem, RecordOptions, RecordedMeta, RecordedReq, RecordedRequest, RecordedRes, ResolvedRecordOptions, ResponseBody, SSEMessage, ServerBuildOption, SetCookieOption, WebSocketSetupContext, createDefineMock, createLogger, createMockMiddleware, createSSEStream, defineMock, defineMockData, logLevels, mockDevServerPlugin, mockWebSocket, processMockData, processRawData, sortByValidator };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import{a as e,c as t,d as n,f as r,i,l as a,n as o,o as s,p as c,r as l,s as u,t as d,u as f}from"./logger-C-7qpBNh.js";import{createDefineMock as p,createSSEStream as m,defineMock as h,defineMockData as g}from"./helper.js";import"./server.js";import _ from"node:process";import{isArray as ee,isBoolean as v,promiseParallel as y,toArray as b,uniq as x}from"@pengzhanbo/utils";import S from"node:path";import{pathToFileURL as C}from"node:url";import w from"node:fs/promises";import T from"json5";import E,{promises as D}from"node:fs";import O from"node:events";import{watch as k}from"chokidar";import{getPackageInfoSync as A,loadPackageJSON as j,loadPackageJSONSync as M}from"local-pkg";import{glob as N}from"tinyglobby";import P from"ansis";import te from"is-core-module";function ne(e){let t={},n=_.env.NODE_ENV||e.mode;Object.assign(t,{"process.env.NODE_ENV":JSON.stringify(n),"global.process.env.NODE_ENV":JSON.stringify(n),"globalThis.process.env.NODE_ENV":JSON.stringify(n)});let r={},i={};for(let t in e.define){let n=e.define[t],a=t.startsWith(`import.meta.env.`);typeof n==`string`?ie(n)&&(r[t]=n,a&&(i[t.slice(16)]=n)):(r[t]=F(n),a&&(i[t.slice(16)]=n))}let a={},o={},s={};a[`import.meta.hot`]=`undefined`;for(let t in e.env){let n=JSON.stringify(e.env[t]);a[`import.meta.env.${t}`]=n,o[t]=n}s[`import.meta.env`]=`undefined`;let c={...t,...a,...r,...s};return`import.meta.env`in c&&(c[`import.meta.env`]=re({...o,...i})),c}function re(e){let t=`{`,n=Object.keys(e);for(let r=0;r<n.length;r++){let i=n[r],a=e[i];t+=`${JSON.stringify(i)}: ${F(a)}`,r!==n.length-1&&(t+=`, `)}return`${t}}`}function F(e){return e===void 0?`undefined`:typeof e==`string`?e:JSON.stringify(e)}function ie(e){try{return JSON.parse(e),!0}catch{return!1}}const ae={name:`externalize-deps`,setup(e){e.onResolve({filter:/.*/},({path:e})=>{if(e[0]!==`.`&&!S.isAbsolute(e))return{external:!0}})}},oe={name:`json5-loader`,setup(e){e.onLoad({filter:/\.json5$/},async({path:e})=>{let t=await w.readFile(e,`utf-8`);return{contents:`export default ${JSON.stringify(T.parse(t))}`,loader:`js`}})}},I={name:`json-loader`,setup(e){e.onLoad({filter:/\.json$/},async({path:e})=>({contents:`export default ${await w.readFile(e,`utf-8`)}`,loader:`js`}))}},L={name:`rename-plugin`,setup(e){e.onResolve({filter:/.*/},({path:e})=>e===`vite-plugin-mock-dev-server`?{path:`vite-plugin-mock-dev-server/helper`,external:!0}:null)}};function R(e){return{name:`alias-plugin`,setup(t){t.onResolve({filter:/.*/},async({path:n})=>{let r=e.find(({find:e})=>z(e,n));if(!r)return null;let{find:i,replacement:a}=r;return{path:(await t.resolve(n.replace(i,a),{kind:`import-statement`,resolveDir:a,namespace:`file`})).path,external:!1}})}}}function z(e,t){return e instanceof RegExp?e.test(t):t.length<e.length?!1:t===e?!0:t.startsWith(`${e}/`)}let B=null;async function V(){return B||=(await import(`esbuild`)).build,B}async function H(e,{isESM:t=!0,define:r,alias:i,cwd:a=_.cwd()}){let o=S.resolve(a,e),s=S.basename(e),c=S.dirname(o);try{let l=await(await V())({entryPoints:[e],outfile:`out.js`,write:!1,target:[`node18`],platform:`node`,bundle:!0,metafile:!0,format:t?`esm`:`cjs`,define:{...r,__dirname:JSON.stringify(c),__filename:JSON.stringify(s),...t?{}:{"import.meta.url":JSON.stringify(C(o))}},plugins:[R(i),L,ae,I,oe],absWorkingDir:a}),u=new Set,d=l.metafile?.inputs||{};return Object.keys(d).forEach(e=>d[e].imports.forEach(e=>u.add(n(e.path)))),{code:l.outputFiles[0].text,deps:Array.from(u)}}catch(e){console.error(e)}return{code:``,deps:[]}}async function U({filepath:e,code:t,isESM:n,cwd:r}){e=S.resolve(r,e);let i=n?`.mjs`:`.cjs`,a=`${e}.timestamp-${Date.now()}${i}`,o=C(a).toString();await D.writeFile(a,t,`utf8`);try{let e=await import(o);return e.default||e}finally{try{E.unlinkSync(a)}catch{}}}const W={name:`vite-mock:rename-plugin`,resolveId(e){if(e===`vite-plugin-mock-dev-server`)return{id:`vite-plugin-mock-dev-server/helper`,external:!0}}},G={name:`vite-mock:json5-plugin`,transform:{filter:{id:/\.json5$/},handler:e=>({code:`export default ${T.stringify(T.parse(e))}`})}};let K=null;async function se(){return K||={build:(await import(`rolldown`)).build,aliasPlugin:(await import(`rolldown/experimental`)).viteAliasPlugin},K}async function ce(e,{isESM:t=!0,define:r,alias:i,cwd:a=_.cwd()}){let o=S.resolve(a,e),s=S.basename(e),c=S.dirname(o),l=e=>!!i.find(({find:t})=>z(t,e));try{let{build:u,aliasPlugin:d}=await se(),f=await u({input:e,write:!1,cwd:a,output:{format:t?`esm`:`cjs`,sourcemap:!1,file:`out.js`},platform:`node`,transform:{define:{...r,__dirname:JSON.stringify(c),__filename:JSON.stringify(s),...t?{}:{"import.meta.url":JSON.stringify(C(o))}}},external(e){if(l(e))return!1;if(e[0]!==`.`&&!S.isAbsolute(e)&&e!==`vite-plugin-mock-dev-server`)return!0},plugins:[d({entries:i}),W,G],onLog(e,t,n){t.code===`PLUGIN_TIMINGS`&&t.message.includes(`vite-mock`)||n(e,t)}});return{code:f.output[0].code,deps:f.output[0].imports.map(n)}}catch(e){console.error(e)}return{code:``,deps:[]}}let q;async function J(e,t){if(q??=await r(`rolldown`)?`rolldown`:await r(`esbuild`)?`esbuild`:`none`,q===`rolldown`)return ce(e,t);if(q===`esbuild`)return H(e,t);throw Error(`rolldown or esbuild not found`)}async function le(e,t){let n=!1;n=/\.m[jt]s$/.test(e)?!0:/\.c[jt]s$/.test(e)?!1:t.isESM||!1;let{code:r,deps:i}=await J(e,{...t,isESM:n});return{data:await U({filepath:e,code:r,isESM:n,cwd:t.cwd||_.cwd()})||{},deps:i}}var ue=class extends O{moduleCache=new Map;moduleDeps=new Map;cwd;mockWatcher;depsWatcher;isESM=!1;_mockData={};options;constructor(e){super(),this.options=e,this.cwd=e.cwd||_.cwd();try{this.isESM=M(this.cwd)?.type===`module`}catch{}}get mockData(){return this._mockData}run(e){let{include:t,exclude:r}=this.options,{pattern:i,ignore:a,isMatch:o}=c(t,r);if(N(i,{ignore:a,cwd:S.join(this.cwd,this.options.dir)}).then(e=>e.map(e=>()=>this.load(n(S.join(this.options.dir,e))))).then(e=>y(e,64)).then(()=>this.updateMockData()),!e)return;this.watchMockEntry(o),this.watchDeps();let s=null;this.on(`mock:update`,async e=>{o(e)&&(await this.load(e),s&&clearImmediate(s),s=setImmediate(()=>{this.updateMockData(),this.emit(`mock:update-end`,n(e)),s=null}))}),this.on(`mock:unlink`,async e=>{o(e)&&(e=n(S.join(this.options.dir,e)),this.moduleCache.delete(e),this.updateMockData(),this.emit(`mock:update-end`,e))})}close(){this.mockWatcher?.close(),this.depsWatcher?.close()}async load(e){if(e)try{let{define:n,alias:r}=this.options,{data:i,deps:a}=await le(e,{cwd:this.cwd,isESM:this.isESM,define:n,alias:r});this.moduleCache.set(e,t(i,e)),this.updateModuleDeps(e,a)}catch(e){console.error(e)}}updateMockData(){this._mockData=u(this.moduleCache)}updateModuleDeps(e,t){for(let n of t)this.moduleDeps.has(n)||this.moduleDeps.set(n,new Set),this.moduleDeps.get(n).add(e);this.emit(`update:deps`)}watchMockEntry(e){let t=this.mockWatcher=k(this.options.dir,{ignoreInitial:!0,cwd:this.cwd,ignored:(t,r)=>t.includes(`node_modules`)?!0:!!r?.isFile()&&!e(n(t))});t.on(`add`,async e=>{e=n(e),this.emit(`mock:update`,e),f(`watcher:add`,e)}),t.on(`change`,async e=>{e=n(e),this.emit(`mock:update`,e),f(`watcher:change`,e)}),t.on(`unlink`,async e=>{e=n(e),this.emit(`mock:unlink`,e),f(`watcher:unlink`,e)})}watchDeps(){let e=[...this.moduleDeps.keys()],t=this.depsWatcher=k([...e],{ignoreInitial:!0,cwd:this.cwd});t.on(`change`,e=>{e=n(e),this.moduleDeps.get(e)?.forEach(e=>this.emit(`mock:update`,e))}),t.on(`unlink`,e=>{e=n(e),this.moduleDeps.delete(e)}),this.on(`update:deps`,()=>{let n=[...this.moduleDeps.keys()],r=n.filter(t=>!e.includes(t));e=n,r.length>0&&t.add(r)})}};function Y(e,t,n){let r=new ue(e);r.run(!!t),r.on(`mock:update-end`,()=>{e.reload&&n?.send({type:`full-reload`})}),t?.on(`close`,()=>r.close()),l(r,t,e);let a=[];return a.push(i(r,e)),a}function X({prefix:e=[],wsPrefix:t=[],cwd:n,dir:r=`mock`,include:i=[`**/*.mock.{js,ts,cjs,mjs,json,json5}`],exclude:a=[],reload:o=!1,log:s=`info`,cors:c=!0,formidableOptions:l={},build:u=!1,cookiesOptions:f={},bodyParserOptions:p={},priority:m={},record:h=!1,replay:g},y){let S=n||_.cwd(),C=d(`vite:mock`,v(s)?s?`info`:`error`:s),{httpProxies:w}=de(y.server.proxy||{}),T=x([...b(e),...w]),E=b(t);!T.length&&!E.length&&C.warn(`No proxy was configured, mock server will not work. See ${P.cyan(`https://vite-plugin-mock-dev-server.netlify.app/guide/usage`)}`);let D=c===!1?!1:y.server.cors!==!1,O={};D&&y.server.cors!==!1&&(O={...O,...typeof y.server.cors==`boolean`?{}:y.server.cors}),D&&c!==!1&&(O={...O,...typeof c==`boolean`?{}:c});let k=[],A=y.resolve.alias||[];ee(A)?k.push(...A):Object.entries(A).forEach(([e,t])=>{k.push({find:e,replacement:t})});let j=Z(S,r,h);return{cwd:S,dir:r,include:i,exclude:a,context:y.root,reload:o,cors:D?O:!1,cookiesOptions:f,log:s,formidableOptions:{multiples:!0,...l},bodyParserOptions:p,priority:m,build:u?{serverPort:8080,dist:`mockServer`,log:`error`,includeRecord:g??j.enabled??!1,...typeof u==`object`?u:{}}:!1,proxies:T,wsProxies:E,logger:C,alias:k,define:ne(y),record:j,replay:g??j.enabled??!1}}function de(e={}){let t=[],n=[];return Object.keys(e).forEach(r=>{let i=e[r];typeof i==`string`||!i.ws&&!i.target?.toString().startsWith(`ws:`)&&!i.target?.toString().startsWith(`wss:`)?t.push(r):n.push(r)}),{httpProxies:t,wsProxies:n}}function Z(e,t,n){let r=typeof n==`boolean`?{enabled:n}:n,i=r?.expires??0;return{enabled:r?.enabled??!1,cwd:e,dir:S.join(t,r?.dir||`.recordings`),overwrite:r?.overwrite??!0,status:b(r?.status).map(Number),expires:i===0?2**53-1:i*1e3,gitignore:r?.gitignore??!0,filter:r?.filter||(()=>!0)}}async function fe(e,t,r,i){let{pattern:a,ignore:o}=c(r,i),s=await N(a,{ignore:o,cwd:S.join(e,t)}),l=``,u=[];return s.forEach((r,i)=>{let a=n(S.join(e,t,r));l+=`import * as m${i} from '${a}';\n`,u.push(`[m${i}, '${n(S.join(t,r))}']`)}),`import { processMockData, processRawData } from 'vite-plugin-mock-dev-server/server';
|
|
2
|
+
${l}
|
|
3
|
+
const exporters = [\n ${u.join(`,
|
|
4
|
+
`)}\n];
|
|
5
|
+
const mockList = exporters.map(([mod, filepath]) => processRawData(mod.default || mod, filepath));
|
|
6
|
+
export default processMockData(mockList);`}var Q=`vite-plugin-mock-dev-server`,pe=`2.1.0`;function me(e,t){let n=new Set,r=[Q,`connect`,`cors`],i=e=>t.find(({find:t})=>z(t,e));return e.forEach(e=>{let t=he(e);t.startsWith(`<define:`)||i(t)||te(t)||t[0]===`/`||t.startsWith(`./`)||t.startsWith(`../`)||r.includes(t)||n.add(t)}),Array.from(n)}function he(e){let[t,n]=e.split(`/`);return t[0]===`@`?`${t}/${n}`:t}function ge(e,t){let{dependencies:n={},devDependencies:r={}}=e,i={...n,...r},a={name:`mock-server`,type:`module`,scripts:{start:`node index.js`},dependencies:{connect:`^3.7.0`,[Q]:`^${pe}`,cors:`^2.8.5`},pnpm:{peerDependencyRules:{ignoreMissing:[`vite`]}}},o=[`catalog:`,`file:`,`workspace:`];for(let e of t){let t=i[e];if(!t||o.some(e=>t.startsWith(e))){let t=A(e);a.dependencies[e]=t?.version?`^${t.version}`:`latest`}else a.dependencies[e]=`latest`}return JSON.stringify(a,null,2)}function $({proxies:e,wsProxies:t,cookiesOptions:n,bodyParserOptions:r,priority:i,build:a,cors:o,record:s,replay:c}){let{serverPort:l,log:u}=a;return`import { createServer } from 'node:http';
|
|
7
|
+
import process from 'node:process';
|
|
8
|
+
import connect from 'connect';
|
|
9
|
+
import { createMockMiddleware, createLogger, mockWebSocket } from 'vite-plugin-mock-dev-server/server';
|
|
10
|
+
import mockData from './mock-data.js';
|
|
11
|
+
|
|
12
|
+
const app = connect();
|
|
13
|
+
const server = createServer(app);
|
|
14
|
+
const logger = createLogger('mock-server', '${u}');
|
|
15
|
+
const proxies = ${JSON.stringify(e)};
|
|
16
|
+
const wsProxies = ${JSON.stringify(t)};
|
|
17
|
+
const cookiesOptions = ${JSON.stringify(n)};
|
|
18
|
+
const bodyParserOptions = ${JSON.stringify(r)};
|
|
19
|
+
const priority = ${JSON.stringify(i)};
|
|
20
|
+
const cors = ${JSON.stringify(o)};
|
|
21
|
+
const record = {
|
|
22
|
+
enabled: ${s.enabled?`true`:`false`},
|
|
23
|
+
cwd: process.cwd(),
|
|
24
|
+
dir: ${JSON.stringify(s.dir)},
|
|
25
|
+
expires: ${s.expires===2**53-1?`Number.MAX_SAFE_INTEGER`:s.expires},
|
|
26
|
+
status: ${JSON.stringify(s.status)},
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
const compiler = { mockData }
|
|
30
|
+
|
|
31
|
+
mockWebSocket(compiler, server, { wsProxies, cookiesOptions, logger });
|
|
32
|
+
|
|
33
|
+
app.use(createMockMiddleware(compiler, {
|
|
34
|
+
formidableOptions: { multiples: true },
|
|
35
|
+
proxies,
|
|
36
|
+
priority,
|
|
37
|
+
cookiesOptions,
|
|
38
|
+
bodyParserOptions,
|
|
39
|
+
logger,
|
|
40
|
+
cors,
|
|
41
|
+
record,
|
|
42
|
+
replay: ${c?`true`:`false`},
|
|
43
|
+
}));
|
|
44
|
+
|
|
45
|
+
server.listen(${l});
|
|
46
|
+
|
|
47
|
+
console.log('listen: http://localhost:${l}');
|
|
48
|
+
`}async function _e(e,t){let n=b(t.include),r=b(t.exclude),i=t.cwd||_.cwd(),a=t.dir,o=t.build,s=await j(t.context)||{},c=o.dist,l=await fe(i,a,n,r),u=S.join(i,`mock-data-${Date.now()}.js`);await w.writeFile(u,l,`utf-8`);let{code:d,deps:f}=await J(u,t),p=me(f,t.alias);await w.unlink(u);let m=[{filename:S.join(c,`mock-data.js`),source:d},{filename:S.join(c,`index.js`),source:$(t)},{filename:S.join(c,`package.json`),source:ge(s,p)}];if(t.record.enabled&&o.includeRecord){let e=await N(S.join(t.record.dir,`**/*.json`),{cwd:t.cwd,dot:!0});for(let n of e)m.push({filename:S.join(c,n),source:await w.readFile(S.join(t.cwd,n),`utf-8`)})}try{if(S.isAbsolute(c)){for(let{filename:e}of m)E.existsSync(e)&&await w.rm(e);t.logger.info(`${P.green(`✓`)} generate mock server in ${P.cyan(c)}`);for(let{filename:e,source:n}of m){E.mkdirSync(S.dirname(e),{recursive:!0}),await w.writeFile(e,n,`utf-8`);let r=(n.length/1024).toFixed(2),i=S.relative(c,e),a=i.length<30?` `.repeat(30-i.length):``;t.logger.info(` ${P.green(i)}${a}${P.bold.dim(`${r} kB`)}`)}}else for(let{filename:t,source:n}of m)e.emitFile({type:`asset`,fileName:t,source:n})}catch(e){console.error(e)}}function ve(e={}){if(e.enabled===!1)return[];let t=[be(e)];return e.build&&t.push(ye(e)),t}function ye(e){let t={},n;return{name:`vite-plugin-mock-dev-server-generator`,enforce:`post`,apply:`build`,configResolved(r){t=r,n=X(e,r),r.logger.warn(``)},async buildEnd(e){e||t.command!==`build`||await _e(this,n)}}}function be(t){let n;return{name:`vite-plugin-mock-dev-server`,enforce:`pre`,apply:`serve`,config(n){let r=b(t.wsPrefix);if(r.length&&n.server?.proxy){let e={};Object.keys(n.server.proxy).forEach(t=>{r.includes(t)||(e[t]=n.server.proxy[t])}),n.server.proxy=e}e(n);let{cwd:i,dir:a}=t,o=Z(i||_.cwd(),a||`mock`,t.record);o.enabled&&new s(o).setup(n)},configResolved(e){n=X(t,e),e.logger.warn(``)},configureServer({middlewares:e,httpServer:t,ws:r}){Y(n,t,r).forEach(t=>e.use(t))},configurePreviewServer({middlewares:e,httpServer:t}){Y(n,t).forEach(t=>e.use(t))}}}export{p as createDefineMock,d as createLogger,i as createMockMiddleware,m as createSSEStream,h as defineMock,g as defineMockData,o as logLevels,ve as mockDevServerPlugin,l as mockWebSocket,u as processMockData,t as processRawData,a as sortByValidator};
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{attempt as e,attemptAsync as t,deepEqual as n,hasOwn as r,isArray as i,isBoolean as a,isEmptyObject as o,isFunction as s,isPlainObject as c,kebabCase as l,objectKeys as u,partition as d,random as f,sleep as p,sortBy as m,timestamp as h,toArray as g,uniq as _}from"@pengzhanbo/utils";import v from"picomatch";import{match as y,parse as b,pathToRegexp as x}from"path-to-regexp";import S from"node:os";import C from"node:path";import w from"debug";import{parse as T}from"node:querystring";import E from"node:fs";import D from"cors";import O from"ansis";import k from"co-body";import ee from"formidable";import A from"node:http";import j from"node:crypto";import{Buffer as M}from"node:buffer";import N from"node:zlib";import P from"http-status";import*as F from"mime-types";import{WebSocketServer as I}from"ws";function L(e,t){let n=[],r=[`**/node_modules/**`,...g(t)];return g(e).forEach(e=>{e[0]===`!`?r.push(e.slice(1)):n.push(e)}),{pattern:n,ignore:r,isMatch:v(n,{ignore:r})}}function te(e,t){return e[0]===`^`&&new RegExp(e).test(t)||t.startsWith(e)}function ne(e){return typeof e==`object`&&!!e&&typeof e.pipe==`function`}function re(e){return ne(e)&&e.readable!==!1&&typeof e._read==`function`&&typeof e._readableState==`object`}const R={};async function ie(e){if(r(R,e))return R[e];try{return import.meta.resolve?R[e]=!!import.meta.resolve(e):(await import(e),R[e]=!0),R[e]}catch{}return R[e]=!1,!1}function ae(e){return[`text`,`json`,`xml`].some(t=>e.includes(t))}function z(e,t){if(!t)return!0;for(let n in t)if(!oe(e[n],t[n]))return!1;return!0}function oe(e,t){if(i(e)&&i(t)){let n=new Set;return t.every(t=>e.some((e,r)=>{if(n.has(r))return!1;let i=oe(e,t);return i&&n.add(r),i}))}return c(e)&&c(t)?z(e,t):Object.is(e,t)}const se=new Map;function B(e,t){let n=se.get(e);return n||(n=x(e).regexp,se.set(e,n)),n.test(t)}const ce=w(`vite:mock-dev-server`),le=/\\/g,ue=S.platform()===`win32`;function de(e){return e.replace(le,`/`)}function fe(e){return C.posix.normalize(ue?de(e):e)}function V(e){let t=new URL(e,`http://example.com`);return{pathname:decodeURIComponent(t.pathname),query:T(t.search.replace(/^\?/,``))}}function pe(e,t){let n;return i(e)?n=e.map(e=>({...e,__filepath__:t})):`url`in e?n={...e,__filepath__:t}:(n=[],Object.keys(e).forEach(r=>{let a=e[r];i(a)?n.push(...a.map(e=>({...e,__filepath__:t}))):n.push({...a,__filepath__:t})})),n}function me(e){let t=[];for(let[,n]of e.entries())n&&t.push(...g(n));let n={};return t.filter(e=>c(e)&&e.enabled!==!1&&e.url).forEach(e=>{let{pathname:t,query:r}=V(e.url),i=n[t]??=[],a={...e,url:t};if(a.ws!==!0){let e=a.validator;o(r)||(s(e)?a.validator=function(t){return z(t.query,r)&&e(t)}:e?(a.validator={...e},a.validator.query=a.validator.query?{...r,...a.validator.query}:r):a.validator={query:r})}i.push(a)}),Object.keys(n).forEach(e=>{n[e]=he(n[e])}),n}function he(e){return m(e,e=>{if(e.ws===!0)return 0;let{validator:t}=e;return!t||o(t)?2:s(t)?0:1/Object.keys(t).reduce((e,n)=>e+ge(t[n]),0)})}function ge(e){return e?Object.keys(e).length:0}function _e(e){let t=e?D(e):void 0;return t?(e,n)=>new Promise((r,i)=>t(e,n,e=>{e?i(e):r()})):void 0}async function ve(e,t,n,r={}){let i=e.method.toUpperCase();if([`HEAD`,`OPTIONS`].includes(i))return;let a=e.headers[`content-type`]?.toLocaleLowerCase()||``,{limit:o,formLimit:s,jsonLimit:c,textLimit:l,...u}=r;try{if(a.startsWith(`application/json`))return await k.json(e,{limit:c||o,...u});if(a.startsWith(`application/x-www-form-urlencoded`))return await k.form(e,{limit:s||o,...u});if(a.startsWith(`text/plain`))return await k.text(e,{limit:l||o,...u});if(a.startsWith(`multipart/form-data`))return await be(e,n)}catch(e){t.error(e)}}const ye={keepExtensions:!0,filename(e,t,n){return n?.originalFilename||`${e}.${Date.now()}${t?`.${t}`:``}`}};async function be(e,t){let n=ee({...ye,...t});return new Promise((t,r)=>{n.parse(e,(e,n,i)=>{if(e){r(e);return}t({...n,...i})})})}const xe=new Map;function H(e,t){let n=xe.get(e);n||(n=y(e,{decode:decodeURIComponent}),xe.set(e,n));let r=n(t);return r?r.params:{}}function Se(e,t){return z(e.headers,t.headers)&&z(e.body,t.body)&&z(e.params,t.params)&&z(e.query,t.query)&&z(e.refererQuery,t.refererQuery)}function U(e,t){return!t||o(t)?``:` ${O.gray(`${e}:`)}${JSON.stringify(t)}`}function Ce(e,t,n){let{url:r,method:i,query:a,params:o,body:s}=e,{pathname:c}=new URL(r,`http://example.com`);c=O.green(decodeURIComponent(c));let l=O.magenta.bold(i),u=U(`query`,a),d=U(`params`,o),f=U(`body`,s),p=n?` 🎲 ${O.bgYellow(`ERR`)}`:``,m=` ${O.dim.underline(`(${t})`)}`;return`${l}${p} ${c}${u}${d}${f}${m}`}function we(t,n,{pathname:r,method:a,request:o}){return t.find(t=>{if(!r||!t||!t.url||t.ws||!(t.method?i(t.method)?t.method:[t.method]:[`GET`,`POST`]).includes(a))return!1;let c=B(t.url,r);if(c&&t.validator){let i=H(t.url,r);if(s(t.validator))return t.validator({params:i,...o});{let[a,s]=e(Se,{params:i,...o},t.validator);if(a){let e=t.__filepath__;return n.error(`${O.red(`mock error at ${r}`)}\n${a}\n at validator (${O.underline(e)})`,t.log),!1}return s}}return c})}const W={};function G(e){if(W[e])return W[e];let t=[],n=(e,r=!1)=>{for(let i of e)if(i.type===`text`){let e=i.value.split(`/`).filter(Boolean);e.length&&t.push(...e.map(e=>({type:`text`,value:e})))}else i.type===`group`?n(i.tokens,!0):(r&&(i.optional=!0),t.push(i))};return n(b(e).tokens),W[e]=t,t}function Te(e){let t=e.map(e=>G(e).length);return t=t.length===0?[1]:t,Math.max(...t)+2}function Ee(e,t){let n=G(e),r=n.filter(e=>e.type!==`text`);if(r.length===0)return 0;let i=r.length,a=0;for(let e=0;e<n.length;e++){let r=n[e],o=r.type!==`text`,s=r.type===`wildcard`,c=!!r.optional;a+=o?1:0,e===n.length-1&&s?i+=(c?5:4)*10**(n.length===1?t+1:t):(s?i+=3*10**(t-1):i+=2*10**a,c&&(i+=10**a))}return i}function De(e){let t=Te(e);return e.sort((e,n)=>Ee(e,t)-Ee(n,t))}function Oe(e,t,n){let r=De(e.filter(e=>B(e,t))),{global:a=[],special:s={}}=n;if(a.length===0&&o(s)||r.length===0)return r;let[c,l]=d(r,e=>G(e).filter(e=>e.type!==`text`).length>0),u=a.filter(e=>c.includes(e));if(u.length>0&&(r=_([...l,...u,...c])),o(s))return r;let f=Object.keys(s).filter(e=>r.includes(e))[0];if(!f)return r;let p=s[f],{rules:m,when:h}=i(p)?{rules:p,when:[]}:p;return m.includes(r[0])&&(h.length===0||h.some(e=>x(e).regexp.test(t)))&&(r=_([f,...r])),r}const K=/^[\t\u0020-\u007E\u0080-\u00FF]+$/,ke=/^(?:low|medium|high)$/i,q=Object.create(null),Ae=/[\^$\\.*+?()[\]{}|]/g,je=/[;=]/,Me=/;/,Ne=/^(?:lax|none|strict)$/i;var Pe=class{name;value;maxAge;expires;path=`/`;domain;secure=!1;httpOnly=!0;sameSite=!1;overwrite=!1;priority;partitioned;constructor(e,t,n={}){if(!K.test(e)||je.test(e))throw TypeError(`argument name is invalid`);if(t&&(!K.test(t)||Me.test(t)))throw TypeError(`argument value is invalid`);if(this.name=e,this.value=t,Object.assign(this,n),this.value||(this.expires=new Date(0),this.maxAge=void 0),this.path&&!K.test(this.path))throw TypeError(`[Cookie] option path is invalid`);if(this.domain&&!K.test(this.domain))throw TypeError(`[Cookie] option domain is invalid`);if(typeof this.maxAge==`number`?Number.isNaN(this.maxAge)||!Number.isFinite(this.maxAge):this.maxAge)throw TypeError(`[Cookie] option maxAge is invalid`);if(this.priority&&!ke.test(this.priority))throw TypeError(`[Cookie] option priority is invalid`);if(this.sameSite&&this.sameSite!==!0&&!Ne.test(this.sameSite))throw TypeError(`[Cookie] option sameSite is invalid`)}toString(){return`${this.name}=${this.value}`}toHeader(){let e=this.toString();return this.maxAge&&(this.expires=new Date(Date.now()+this.maxAge)),this.path&&(e+=`; path=${this.path}`),this.expires&&(e+=`; expires=${this.expires.toUTCString()}`),this.domain&&(e+=`; domain=${this.domain}`),this.priority&&(e+=`; priority=${this.priority.toLowerCase()}`),this.sameSite&&(e+=`; samesite=${this.sameSite===!0?`strict`:this.sameSite.toLowerCase()}`),this.secure&&(e+=`; secure`),this.httpOnly&&(e+=`; httponly`),this.partitioned&&(e+=`; partitioned`),e}};function Fe(e,t){if(e.length!==t.length)return!1;if(j.timingSafeEqual)return j.timingSafeEqual(e,t);for(let n=0;n<e.length;n++)if(e[n]!==t[n])return!1;return!0}function Ie(e,t){return j.createHmac(`sha256`,e).update(t).digest()}function Le(e,t){let n=String(e),r=String(t),i=j.randomBytes(32);return Fe(Ie(i,n),Ie(i,r))&&e===t}const Re=/[/+=]/g,ze={"/":`_`,"+":`-`,"=":``};var Be=class{algorithm;encoding;keys=[];constructor(e,t,n){this.keys=e,this.algorithm=t||`sha256`,this.encoding=n||`base64`}sign(e,t=this.keys[0]){return j.createHmac(this.algorithm,t).update(e).digest(this.encoding).replace(Re,e=>ze[e])}index(e,t){for(let n=0,r=this.keys.length;n<r;n++)if(Le(t,this.sign(e,this.keys[n])))return n;return-1}verify(e,t){return this.index(e,t)>-1}},Ve=class{request;response;secure;keys;constructor(e,t,n={}){this.request=e,this.response=t,this.secure=n.secure,n.keys instanceof Be?this.keys=n.keys:i(n.keys)&&(this.keys=new Be(n.keys))}set(e,t,n){let r=this.request,i=this.response,a=g(i.getHeader(`Set-Cookie`)),o=new Pe(e,t,n),s=n?.signed??!!this.keys,c=this.secure===void 0?r.protocol===`https`||Ue(r):!!this.secure;if(!c&&n?.secure)throw Error(`Cannot send secure cookie over unencrypted connection`);if(o.secure=n?.secure??c,We(a,o),s&&n){if(!this.keys)throw Error(`.keys required for signed cookies`);o.value=this.keys.sign(o.toString()),o.name+=`.sig`,We(a,o)}return(i.set?A.OutgoingMessage.prototype.setHeader:i.setHeader).call(i,`Set-Cookie`,a),this}get(e,t){let n=`${e}.sig`,r=t?.signed??!!this.keys,i=this.request.headers.cookie;if(!i)return;let a=i.match(He(e));if(!a)return;let o=a[1];if(o[0]===`"`&&(o=o.slice(1,-1)),!t||!r)return o;let s=this.get(n);if(!s)return;let c=`${e}=${o}`;if(!this.keys)throw Error(`.keys required for signed cookies`);let l=this.keys.index(c,s);if(l<0)this.set(n,null,{path:`/`,signed:!1});else return l&&this.set(n,this.keys.sign(c),{signed:!1}),o}};function He(e){return q[e]||(q[e]=RegExp(`(?:^|;) *${e.replace(Ae,`\\$&`)}=([^;]*)`)),q[e]}function Ue(e){return!!(e.socket?e.socket.encrypted:e.connection.encrypted)}function We(e,t){if(t.overwrite)for(let n=e.length-1;n>=0;n--)e[n].indexOf(`${t.name}=`)===0&&e.splice(n,1);e.push(t.toHeader())}const Ge=`date.expires.last-modified.server.x-powered-by.x-aspnet-version.x-nginx-version.via.cache-control.etag.age.connection.keep-alive.proxy-authenticate.proxy-authorization.proxy-connection.trailer.access-control-allow-origin.access-control-allow-credentials.access-control-allow-methods.access-control-allow-headers.access-control-expose-headers.access-control-max-age.origin.p3p.pragma.x-request-id.x-correlation-id.x-trace-id.x-varnish.x-cache.x-cache-hits.x-cache-status.cf-cache-status.cf-ray.cf-request-id.server-timing.x-dns-prefetch-control`.split(`.`);async function Ke(e,t){try{switch(t.toLowerCase()){case`gzip`:case`x-gzip`:return{body:await Ye(e),encoding:`identity`};case`deflate`:case`x-deflate`:return{body:await Xe(e),encoding:`identity`};case`br`:return{body:await Je(e),encoding:`identity`};case`zstd`:return{body:await qe(e),encoding:`identity`}}}catch{}return{body:e,encoding:t}}let J=null;async function qe(e){if(N.zstdDecompress)return new Promise((t,n)=>{N.zstdDecompress(e,(e,r)=>{e?n(e):t(r)})});if(!J){let{ZstdCodec:e}=await import(`zstd-codec`);J=await new Promise(t=>{e.run(e=>{t(new e.Streaming)})})}return J.decompress(e,e.length)}async function Je(e){return new Promise((t,n)=>{N.brotliDecompress(e,(e,r)=>{e?n(e):t(r)})})}async function Ye(e){return new Promise((t,n)=>{N.gunzip(e,(e,r)=>{e?n(e):t(r)})})}async function Xe(e){return new Promise((t,n)=>{N.inflate(e,(e,r)=>{e?n(e):t(r)})})}const Ze=new Intl.DateTimeFormat(`en-US`,{year:`numeric`,month:`numeric`,day:`numeric`,hour:`numeric`,minute:`numeric`,second:`numeric`,hour12:!1});function Qe(e,t,n){let{query:i}=V(e.url),a=e.method.toUpperCase(),o=(e.headers[`content-type`]||``).split(`;`)[0].trim();return o.startsWith(`multipart/form-data`)&&c(n)&&(n={...n},u(n).forEach(e=>{let t=n[e];c(t)&&r(t,`filepath`)&&r(t,`mimetype`)&&delete n[e]})),M.isBuffer(n)&&(n=n.toString(),o=`buffer`),{method:a,pathname:t,query:i,bodyType:o,body:n}}async function $e(e,t){let n=e.statusCode||200,r=e.statusMessage||`OK`,i={};for(let[t,n]of Object.entries(e.headers)){let e=t.toLowerCase();n!==void 0&&!Ge.includes(e)&&(i[t]=String(n))}let a=ae(i[`content-type`]||``);if(a){let{body:e,encoding:n}=await Ke(t,i[`content-encoding`]||``);t=M.from(e),i[`content-encoding`]=n}return{status:n,statusText:r,headers:i,body:t.toString(a?`utf-8`:`base64`)}}function et(e,t){if(e.pathname!==t.pathname||e.method!==t.method||e.bodyType!==t.bodyType||!n(e.query,t.query))return!1;if(t.bodyType===`buffer`&&e.bodyType===`buffer`){let n=M.from(t.body),r=M.from(e.body);if(n.length!==r.length||!n.equals(r))return!1}return!!n(e.body,t.body)}function tt(e){if(s(e))return e;let{mode:t=`glob`}=e,n=g(e.include),r=g(e.exclude);if(t===`glob`){let{isMatch:e}=L(n,r);return t=>e(t.pathname)}return e=>n.some(t=>B(t,e.pathname))&&r.every(t=>!B(t,e.pathname))}function nt(e,t){return C.join(t,`${l(e)}.json`)}const Y=new Map;async function rt(e){if(Y.has(e))return Y.get(e);try{if(!E.existsSync(e))return[];let t=await E.promises.readFile(e,`utf-8`)||`[]`,n=JSON.parse(t);return Y.set(e,n),n}catch(t){return console.error(`Error reading record file ${e}:`,t),[]}}async function it(e,t){try{Y.set(e,t),await E.promises.mkdir(C.dirname(e),{recursive:!0}),await E.promises.writeFile(e,JSON.stringify(t,null,2),`utf-8`)}catch(t){console.error(`Error writing record file ${e}:`,t)}}const X=new WeakMap;function at(e,t,n){X.set(e,{body:n,pathname:t,timestamp:Date.now()})}var ot=class{options;filter;constructor(e){this.options=e,this.filter=tt(e.filter)}setup(e){let t=this.options;if(!e.server||!t.enabled)return;let n=this.record.bind(this),r=e.server.proxy||{};u(r).forEach(e=>{let t=r[e],i=typeof t==`string`?{target:t}:t;if(i.ws)return;let{configure:a,...o}=i;r[e]={...o,configure(e,t){a?.call(this,e,t),e.on(`proxyRes`,(e,t)=>{let r=[];e.on(`data`,e=>e&&r.push(e)),e.on(`end`,()=>{n(t,e,M.concat(r)),r=null})})}}}),this.addGitignore()}async record(e,t,n){if(!X.has(e))return;let{body:r,pathname:i,timestamp:a}=X.get(e);if(X.delete(e),!i)return;let o=Qe(e,i,r);if(!this.filter(o))return;let{cwd:s,dir:c,status:l,expires:u,overwrite:d}=this.options;if(l.length!==0&&!l.includes(t.statusCode||200))return;let f={meta:{timestamp:a,filepath:``,createAt:Ze.format(a),referer:e.headers.referer||`unknown`},req:o,res:await $e(t,n)},p=nt(i,c);f.meta.filepath=p;let m=C.join(s,p),h=(await rt(m)).filter(e=>a-e.meta.timestamp<=u),g=h.findIndex(e=>et(e.req,f.req)&&e.res.status===f.res.status);g===-1?h.push(f):(d||a-h[g].meta.timestamp>u)&&(h[g]=f),await it(m,h)}async addGitignore(){let e=this.options;if(!e.gitignore)return;let t=C.join(e.cwd,e.dir);await E.promises.mkdir(t,{recursive:!0}),E.existsSync(C.join(t,`.gitignore`))||await E.promises.writeFile(C.join(t,`.gitignore`),`*
|
|
2
|
+
`,`utf-8`)}};async function st(e,t,n,r){let i=Qe(e,t,n),a=C.join(r.cwd,nt(i.pathname,r.dir)),o=Date.now(),s=await rt(a),c=s.filter(e=>o-e.meta.timestamp<r.expires&&et(e.req,i)),l;if(l=r.status.length===0?c.find(e=>e.res.status===200)||s[0]:c.find(e=>r.status.includes(e.res.status)),l){let e=ae(l.res.headers[`content-type`]||``);return{url:l.req.pathname,status:l.res.status,statusText:l.res.statusText,headers:l.res.headers,body:M.from(l.res.body,e?`utf-8`:`base64`),type:`buffer`,__filepath__:l.meta.filepath}}}const Z=new WeakMap;function ct(e){let t=[];e.addListener(`data`,e=>{t?.push(M.from(e))}),e.addListener(`end`,()=>{t?.length&&Z.set(e,M.concat(t)),t=null})}function lt(e){if(!e.server)return;let t=e.server.proxy||{};u(t).forEach(e=>{let n=t[e],r=typeof n==`string`?{target:n}:n;if(r.ws)return;let{configure:i,...a}=r;t[e]={...a,configure(e,t){i?.(e,t),e.on(`proxyReq`,(e,t)=>{let n=Z.get(t);n&&(Z.delete(t),e.headersSent||e.setHeader(`Content-Length`,n.byteLength),e.writableEnded||e.write(n))})}}})}function ut(e){return P[e]||`Unknown`}function Q(e,t=200,n){e.statusCode=t,e.statusMessage=n||ut(t)}async function dt(e,n,r,i){let{headers:a,type:o=`json`}=r,c=r.__filepath__,l=F.contentType(o)||F.contentType(F.lookup(o)||``);if(l&&n.setHeader(`Content-Type`,l),n.setHeader(`Cache-Control`,`no-cache,max-age=0`),n.setHeader(`X-Mock-Power-By`,`vite-plugin-mock-dev-server`),c&&n.setHeader(`X-File-Path`,c),!a)return;let[d,f]=await t(async()=>s(a)?await a(e):a);if(d){i.error(`${O.red(`mock error at ${e.url.split(`?`)[0]}`)}\n${d}\n at headers (${O.underline(c)})`,r.log);return}u(f).forEach(e=>n.setHeader(e,f[e]))}async function ft(e,n,r,a){let{cookies:o}=r;if(!o)return;let[c,l]=await t(async()=>s(o)?await o(e):o);if(c){let t=r.__filepath__;a.error(`${O.red(`mock error at ${e.url.split(`?`)[0]}`)}\n${c}\n at cookies (${O.underline(t)})`,r.log);return}u(l).forEach(e=>{let t=l[e],[r,a]=i(t)?t:[t];n.setCookie(e,r,a)})}function pt(e,t,n){if(re(t))t.pipe(e);else if(M.isBuffer(t))e.end(n===`text`||n===`json`?t.toString(`utf-8`):t);else{let r=typeof t==`string`?t:JSON.stringify(t);e.end(n===`buffer`?M.from(r):r)}}async function mt(e,t){if(!t||typeof t==`number`&&t<=0||i(t)&&t.length!==2)return;let n=0;if(i(t)){let[e,r]=t;n=f(e,r)}else n=t-(h()-e);n>0&&await p(n)}function ht(e,{formidableOptions:n={},bodyParserOptions:r={},proxies:i,cookiesOptions:a,logger:o,priority:c={},cors:l,record:u,replay:d}){let f=_e(l);return async function(l,p,m){let g=h(),{query:_,pathname:v}=V(l.url);if(!v||i.length===0||!i.some(e=>te(e,l.url)))return m();let y=e.mockData,b=Oe(Object.keys(y),v,c);if(b.length===0&&!u.enabled)return m();ct(l);let x=new Ve(l,p,a),S,C,w=l.method.toUpperCase(),T={query:_,refererQuery:V(l.headers.referer||``).query,body:await ve(l,o,n,r),headers:l.headers,getCookie:x.get.bind(x)};for(let e of b)if(S=we(y[e],o,{pathname:v,method:w,request:T}),S){C=e;break}if(d&&!S&&(S=await st(l,v,T.body,u)),!S){u.enabled&&at(l,v,T.body);let e=b.map(e=>e===C?O.underline.bold(e):O.dim(e)).join(`, `);return e.length&&o.warn(`${O.green(v)} matches ${e}, but mock data is not found.`),m()}if(f){let[e]=await t(f,l,p);if(e)return o.error(`CORS error: ${e}`),m(e)}let E=l,D=p;Object.assign(E,T),E.params=H(S.url,v),D.setCookie=x.set.bind(x);let{delay:k,type:ee=`json`,response:A,log:j,error:M,__filepath__:N}=S,{body:P,status:F=200,statusText:I}=S,L=M&&(M.probability??.5)>Math.random();if(L&&(F=M.status??500,I=M.statusText,P=M.body),Q(D,F,I),await dt(E,D,S,o),await ft(E,D,S,o),o.info(Ce(E,N,L),j),o.debug(`${O.magenta(`DEBUG`)} ${O.underline(v)} matches: [ ${b.map(e=>e===C?O.underline.bold(e):O.dim(e)).join(`, `)} ]\n`),P){let[e]=await t(async()=>{let e=s(P)?await P(E):P;await mt(g,k),pt(D,e,ee)});e&&(o.error(`${O.red(`mock error at ${v}`)}\n${e}\n at body (${O.underline(N)})`,j),Q(D,500),p.end(``));return}if(A){let[e]=await t(async()=>{await mt(g,k),await A(E,D,m)});e&&(o.error(`${O.red(`mock error at ${v}`)}\n${e}\n at response (${O.underline(N)})`,j),Q(D,500),p.end(``));return}p.end(``)}}function gt(e,t,{wsProxies:n,cookiesOptions:r,logger:i}){let a=new Map,o=new Map,s=new WeakMap,c=e=>{let t=o.get(e);return t||o.set(e,t=new Map),t},l=(e,t)=>{let n=e.get(t);return n||e.set(t,n=new I({noServer:!0})),n},u=(e,t)=>{let n=a.get(e);n||a.set(e,n=new Set),n.add(t)},d=(e,t,n,r,a,o)=>{try{n.setup?.(t,r),t.on(`close`,()=>e.delete(a)),t.on(`error`,e=>{i.error(`${O.red(`WebSocket mock error at ${t.path}`)}\n${e}\n at setup (${o})`,n.log)})}catch(e){i.error(`${O.red(`WebSocket mock error at ${t.path}`)}\n${e}\n at setup (${o})`,n.log)}},f=(e,t,n,r)=>{e.emit(`connection`,t,n),t.on(`close`,()=>{let e=r.findIndex(e=>e.ws===t);e!==-1&&r.splice(e,1)})},p=(e,t,n,r,i)=>{let{cleanupList:a,connectionList:o,context:c}=s.get(t);_t(a),o.forEach(({ws:e})=>e.removeAllListeners()),t.removeAllListeners(),d(e,t,n,c,r,i),o.forEach(({ws:e,req:n})=>f(t,e,n,o))};e.on?.(`mock:update-end`,t=>{if(!a.has(t))return;let n=a.get(t);if(n)for(let r of n.values())for(let n of e.mockData[r]){if(!n.ws||n.__filepath__!==t)return;let e=c(r);for(let[r,i]of e.entries())p(e,i,n,r,t)}}),t?.on(`upgrade`,(t,a,o)=>{let{pathname:p,query:m}=V(t.url);if(!p||n.length===0||!n.some(e=>te(e,t.url)))return;let h=e.mockData,g=Object.keys(h).find(e=>B(e,p));if(!g)return;let _=h[g].find(e=>e.url&&e.ws&&B(e.url,p));if(!_)return;let v=_.__filepath__;u(v,g);let y=c(g),b=l(y,p),x=s.get(b);if(!x){let e=[],t={onCleanup:t=>e.push(t)};x={cleanupList:e,context:t,connectionList:[]},s.set(b,x),d(y,b,_,t,p,v)}let S=t,C=new Ve(t,t,r),{query:w}=V(t.headers.referer||``);S.query=m,S.refererQuery=w,S.params=H(g,p),S.getCookie=C.get.bind(C),b.handleUpgrade(S,a,o,e=>{i.info(`${O.magenta.bold(`WebSocket`)} ${O.green(t.url)} connected ${O.dim(`(${v})`)}`,_.log),x.connectionList.push({req:S,ws:e}),f(b,e,S,x.connectionList)})}),t?.on(`close`,()=>{for(let e of o.values()){for(let t of e.values())_t(s.get(t).cleanupList),t.close();e.clear()}o.clear(),a.clear()})}function _t(e){let t;for(;t=e.shift();)t?.()}const $={silent:0,error:1,warn:2,info:3,debug:4};function vt(e,t=`info`){e=`[${e}]`;function n(n,r,i){if(i=a(i)?i?t:`error`:i,$[i]>=$[n]){let t=n===`info`||n===`debug`?`log`:n,i=n===`debug`?O.magenta.bold(e):n===`info`?O.cyan.bold(e):n===`warn`?O.yellow.bold(e):O.red.bold(e),a=`${O.dim(new Date().toLocaleTimeString())} ${i} ${r}`;console[t](a)}}return{debug(e,r=t){n(`debug`,e,r)},info(e,r=t){n(`info`,e,r)},warn(e,r=t){n(`warn`,e,r)},error(e,r=t){n(`error`,e,r)}}}export{lt as a,pe as c,fe as d,ie as f,ht as i,he as l,$ as n,ot as o,L as p,gt as r,me as s,vt as t,ce as u};
|
package/dist/server.d.ts
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import "./config-7dnQWJSY.js";
|
|
2
|
+
import { a as processRawData, c as Logger, i as processMockData, l as createLogger, n as CreateMockMiddlewareOptions, o as sortByValidator, r as createMockMiddleware, t as mockWebSocket, u as logLevels } from "./index-x4QPVyiP.js";
|
|
3
|
+
export { CreateMockMiddlewareOptions, Logger, createLogger, createMockMiddleware, logLevels, mockWebSocket, processMockData, processRawData, sortByValidator };
|