rspack-plugin-mock 2.0.0 → 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/README.md +406 -65
- package/README.zh-CN.md +406 -66
- package/dist/helper.d.ts +46 -8
- package/dist/helper.js +109 -14
- package/dist/{types-GT6M6WuI.d.ts → index-BMMGM-eD.d.ts} +537 -172
- package/dist/index.d.ts +9 -6
- package/dist/index.js +70 -67
- package/dist/json5-loader.mjs +2 -2
- package/dist/{ws-BcLCWVaK.js → logger-CzeuHKAL.js} +662 -102
- package/dist/{options-Bd0PSZeT.js → options-CI0LRpJZ.js} +48 -7
- package/dist/rsbuild.d.ts +4 -3
- package/dist/rsbuild.js +29 -41
- package/dist/{server-_doRwsZm.d.ts → server-pC78IYdH.d.ts} +48 -24
- package/dist/server.d.ts +2 -2
- package/dist/server.js +2 -2
- package/package.json +8 -3
|
@@ -1,26 +1,16 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import crypto from "node:crypto";
|
|
1
|
+
import { DevServerProxyConfigArrayItem } from "@rspack/core";
|
|
3
2
|
import { CorsOptions } from "cors";
|
|
4
3
|
import { Options } from "co-body";
|
|
5
4
|
import formidable from "formidable";
|
|
6
|
-
import http
|
|
5
|
+
import http from "node:http";
|
|
7
6
|
import { Buffer } from "node:buffer";
|
|
8
7
|
import { WebSocketServer } from "ws";
|
|
8
|
+
import { Readable } from "node:stream";
|
|
9
|
+
import { ProxyOptions } from "@rsbuild/core";
|
|
9
10
|
|
|
10
|
-
//#region src/cookies
|
|
11
|
-
declare class Keygrip {
|
|
12
|
-
private algorithm!;
|
|
13
|
-
private encoding!;
|
|
14
|
-
private keys;
|
|
15
|
-
constructor(keys: string[], algorithm?: string, encoding?: crypto.BinaryToTextEncoding);
|
|
16
|
-
sign(data: string, key?: string): string;
|
|
17
|
-
index(data: string, digest: string): number;
|
|
18
|
-
verify(data: string, digest: string): boolean;
|
|
19
|
-
}
|
|
20
|
-
//#endregion
|
|
21
|
-
//#region src/cookies/types.d.ts
|
|
11
|
+
//#region src/types/cookies.d.ts
|
|
22
12
|
interface CookiesOption {
|
|
23
|
-
keys?: string[]
|
|
13
|
+
keys?: string[];
|
|
24
14
|
secure?: boolean;
|
|
25
15
|
}
|
|
26
16
|
interface SetCookieOption {
|
|
@@ -118,18 +108,426 @@ interface GetCookieOption {
|
|
|
118
108
|
signed: boolean;
|
|
119
109
|
}
|
|
120
110
|
//#endregion
|
|
121
|
-
//#region src/
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
111
|
+
//#region src/types/http.d.ts
|
|
112
|
+
type Method = "GET" | "POST" | "PUT" | "DELETE" | "PATCH" | "HEAD" | "TRACE" | "OPTIONS";
|
|
113
|
+
type Headers = http.IncomingHttpHeaders;
|
|
114
|
+
type ResponseBody = Record<string, any> | any[] | string | number | Readable | Buffer | null;
|
|
115
|
+
/**
|
|
116
|
+
* 扩展 request,添加额外的属性和方法
|
|
117
|
+
*/
|
|
118
|
+
interface ExtraRequest {
|
|
119
|
+
/**
|
|
120
|
+
* The query string located after `?` in the request address has been parsed into JSON.
|
|
121
|
+
*
|
|
122
|
+
* 请求地址中位于 `?` 后面的 queryString,已解析为 json
|
|
123
|
+
*/
|
|
124
|
+
query: Record<string, any>;
|
|
125
|
+
/**
|
|
126
|
+
* The queryString located after `?` in the referer request has been parsed as JSON.
|
|
127
|
+
*
|
|
128
|
+
* 请求 referer 中位于 `?` 后面的 queryString,已解析为 json
|
|
129
|
+
*/
|
|
130
|
+
refererQuery: Record<string, any>;
|
|
131
|
+
/**
|
|
132
|
+
* Body data in the request
|
|
133
|
+
*
|
|
134
|
+
* 请求体中 body 数据
|
|
135
|
+
*/
|
|
136
|
+
body: Record<string, any>;
|
|
137
|
+
/**
|
|
138
|
+
* The params parameter parsed from the `/api/id/:id` in the request address.
|
|
139
|
+
*
|
|
140
|
+
* 请求地址中,`/api/id/:id` 解析后的 params 参数
|
|
141
|
+
*/
|
|
142
|
+
params: Record<string, any>;
|
|
143
|
+
/**
|
|
144
|
+
* headers data in the request
|
|
145
|
+
* 请求体中 headers
|
|
146
|
+
*/
|
|
147
|
+
headers: Headers;
|
|
148
|
+
/**
|
|
149
|
+
* Get the cookie carried in the request.
|
|
150
|
+
*
|
|
151
|
+
* 获取 请求中携带的 cookie
|
|
152
|
+
* @see [cookies](https://github.com/pillarjs/cookies#cookiesgetname--options)
|
|
153
|
+
*/
|
|
154
|
+
getCookie: (name: string, options?: GetCookieOption) => string | void;
|
|
130
155
|
}
|
|
156
|
+
type MockRequest = http.IncomingMessage & ExtraRequest;
|
|
157
|
+
type MockResponse = http.ServerResponse<http.IncomingMessage> & {
|
|
158
|
+
/**
|
|
159
|
+
* Set cookie in response
|
|
160
|
+
*
|
|
161
|
+
* 向请求响应中设置 cookie
|
|
162
|
+
* @see [cookies](https://github.com/pillarjs/cookies#cookiessetname--values--options)
|
|
163
|
+
*/
|
|
164
|
+
setCookie: (name: string, value: string, options?: SetCookieOption) => void;
|
|
165
|
+
};
|
|
166
|
+
type NextFunction = (err?: any) => void;
|
|
167
|
+
type SimpleHandleFunction = (req: http.IncomingMessage, res: http.ServerResponse) => Promise<void>;
|
|
168
|
+
type NextHandleFunction = (req: http.IncomingMessage, res: http.ServerResponse, next: NextFunction) => Promise<void>;
|
|
169
|
+
type HandleFunction = SimpleHandleFunction | NextHandleFunction;
|
|
131
170
|
//#endregion
|
|
132
|
-
//#region src/types.d.ts
|
|
171
|
+
//#region src/types/record.d.ts
|
|
172
|
+
/**
|
|
173
|
+
* Record configuration options
|
|
174
|
+
*
|
|
175
|
+
* 录制配置选项
|
|
176
|
+
*/
|
|
177
|
+
interface RecordOptions {
|
|
178
|
+
/**
|
|
179
|
+
* Whether to enable the record feature
|
|
180
|
+
* - true: Enable, automatically record proxy responses
|
|
181
|
+
* - false: Disable (default)
|
|
182
|
+
*
|
|
183
|
+
* 是否启用录制功能
|
|
184
|
+
* - true: 启用,自动录制 proxy 响应
|
|
185
|
+
* - false: 禁用(默认)
|
|
186
|
+
*
|
|
187
|
+
* @default false
|
|
188
|
+
*/
|
|
189
|
+
enabled?: boolean;
|
|
190
|
+
/**
|
|
191
|
+
* Filter requests to record
|
|
192
|
+
* - Function: Custom filter function, return true to record
|
|
193
|
+
* - Object: Include/exclude patterns with glob or path-to-regexp mode
|
|
194
|
+
*
|
|
195
|
+
* 过滤要录制的请求
|
|
196
|
+
* - 函数:自定义过滤函数,返回 true 表示录制
|
|
197
|
+
* - 对象:包含/排除模式,支持 glob 或 path-to-regexp 模式
|
|
198
|
+
*
|
|
199
|
+
* @example
|
|
200
|
+
* ```ts
|
|
201
|
+
* // Record all requests
|
|
202
|
+
* filter: (req) => true
|
|
203
|
+
* // Record requests using glob pattern
|
|
204
|
+
* filter: { mode: 'glob', include: '/api/**' }
|
|
205
|
+
* // Record requests using path-to-regexp pattern
|
|
206
|
+
* filter: { mode: 'path-to-regexp', include: '/api/:id' }
|
|
207
|
+
* ```
|
|
208
|
+
*/
|
|
209
|
+
filter?: ((req: RecordedReq) => boolean) | {
|
|
210
|
+
/**
|
|
211
|
+
* Include the request links that need to be recorded
|
|
212
|
+
*
|
|
213
|
+
* String: Glob pattern or path-to-regexp pattern
|
|
214
|
+
* (Use the mode option to set the mode, default is glob)
|
|
215
|
+
*
|
|
216
|
+
* 包含需要录制的请求链接
|
|
217
|
+
*
|
|
218
|
+
* glob 模式或 path-to-regexp 模式
|
|
219
|
+
* (使用 mode 选项设置模式,默认为 glob)
|
|
220
|
+
*/
|
|
221
|
+
include?: string | string[];
|
|
222
|
+
/**
|
|
223
|
+
* Exclude request links that do not need to be recorded
|
|
224
|
+
*
|
|
225
|
+
* String: Glob pattern or path-to-regexp pattern
|
|
226
|
+
* (Use the mode option to set the mode, default is glob)
|
|
227
|
+
*
|
|
228
|
+
* 排除不需要录制的请求链接
|
|
229
|
+
*
|
|
230
|
+
* glob 模式或 path-to-regexp 模式
|
|
231
|
+
* (使用 mode 选项设置模式,默认为 glob)
|
|
232
|
+
*/
|
|
233
|
+
exclude?: string | string[];
|
|
234
|
+
/**
|
|
235
|
+
* Matching mode for include/exclude patterns
|
|
236
|
+
* - 'glob': Glob pattern matching (default)
|
|
237
|
+
* - 'path-to-regexp': Path-to-regexp pattern matching
|
|
238
|
+
*
|
|
239
|
+
* 包含/排除模式的匹配模式
|
|
240
|
+
* - 'glob': glob 模式匹配(默认)
|
|
241
|
+
* - 'path-to-regexp': path-to-regexp 模式匹配
|
|
242
|
+
*/
|
|
243
|
+
mode: "glob" | "path-to-regexp";
|
|
244
|
+
};
|
|
245
|
+
/**
|
|
246
|
+
* Directory to store recorded data
|
|
247
|
+
* Relative to project root
|
|
248
|
+
*
|
|
249
|
+
* 录制数据存储目录
|
|
250
|
+
* 相对于项目根目录
|
|
251
|
+
*
|
|
252
|
+
* @default 'mock/.recordings'
|
|
253
|
+
*/
|
|
254
|
+
dir?: string;
|
|
255
|
+
/**
|
|
256
|
+
* Whether to overwrite existing recorded data
|
|
257
|
+
* - true: Overwrite old data for the same request (default)
|
|
258
|
+
* - false: Keep old data, do not record new data
|
|
259
|
+
*
|
|
260
|
+
* 是否覆盖已有录制数据
|
|
261
|
+
* - true: 相同请求覆盖旧数据(默认)
|
|
262
|
+
* - false: 保留旧数据,不录制新数据
|
|
263
|
+
*
|
|
264
|
+
* @default true
|
|
265
|
+
*/
|
|
266
|
+
overwrite?: boolean;
|
|
267
|
+
/**
|
|
268
|
+
* Expiration time for recorded data in seconds
|
|
269
|
+
* - 0: Never expire (default)
|
|
270
|
+
* - Positive number: Expire after specified seconds
|
|
271
|
+
*
|
|
272
|
+
* 录制数据过期时间(秒)
|
|
273
|
+
* - 0: 永不过期(默认)
|
|
274
|
+
* - 正数:指定秒数后过期
|
|
275
|
+
*
|
|
276
|
+
* @default 0
|
|
277
|
+
*/
|
|
278
|
+
expires?: number;
|
|
279
|
+
/**
|
|
280
|
+
* Status codes to record
|
|
281
|
+
* - Empty array: Record all status codes (default)
|
|
282
|
+
* - Specify one or more status codes to filter
|
|
283
|
+
*
|
|
284
|
+
* 要录制的状态码
|
|
285
|
+
* - 为空数组时记录所有状态码(默认)
|
|
286
|
+
* - 指定一个或多个状态码进行过滤
|
|
287
|
+
*
|
|
288
|
+
* @default []
|
|
289
|
+
*/
|
|
290
|
+
status?: number | number[];
|
|
291
|
+
/**
|
|
292
|
+
* Should a .gitignore be added to the recording directory
|
|
293
|
+
* - true: Add (default)
|
|
294
|
+
* - false: Do not add
|
|
295
|
+
*
|
|
296
|
+
* 是否在录制目录中添加 .gitignore
|
|
297
|
+
* - true: 添加(默认)
|
|
298
|
+
* - false: 不添加
|
|
299
|
+
*
|
|
300
|
+
* @default true
|
|
301
|
+
*/
|
|
302
|
+
gitignore?: boolean;
|
|
303
|
+
}
|
|
304
|
+
interface RecordedMeta {
|
|
305
|
+
/**
|
|
306
|
+
* Recording timestamp
|
|
307
|
+
*
|
|
308
|
+
* 录制数据创建时间戳
|
|
309
|
+
*/
|
|
310
|
+
timestamp: number;
|
|
311
|
+
/**
|
|
312
|
+
* Recorded data create time
|
|
313
|
+
*
|
|
314
|
+
* 录制数据创建时间
|
|
315
|
+
*/
|
|
316
|
+
createAt: string;
|
|
317
|
+
/**
|
|
318
|
+
* Recorded data file path
|
|
319
|
+
*
|
|
320
|
+
* 录制数据文件路径
|
|
321
|
+
*/
|
|
322
|
+
filepath: string;
|
|
323
|
+
/**
|
|
324
|
+
* Reference the source of the original request
|
|
325
|
+
*
|
|
326
|
+
* 对原始请求的来源引用
|
|
327
|
+
*/
|
|
328
|
+
referer?: string;
|
|
329
|
+
}
|
|
330
|
+
interface RecordedReq {
|
|
331
|
+
/**
|
|
332
|
+
* Request method
|
|
333
|
+
*
|
|
334
|
+
* 请求方法
|
|
335
|
+
*/
|
|
336
|
+
method: string;
|
|
337
|
+
/**
|
|
338
|
+
* Request pathname
|
|
339
|
+
*
|
|
340
|
+
* 请求路径
|
|
341
|
+
*/
|
|
342
|
+
pathname: string;
|
|
343
|
+
/**
|
|
344
|
+
* Request query parameters
|
|
345
|
+
*
|
|
346
|
+
* 请求参数
|
|
347
|
+
*/
|
|
348
|
+
query: Record<string, any>;
|
|
349
|
+
/**
|
|
350
|
+
* Request body
|
|
351
|
+
*
|
|
352
|
+
* 请求体
|
|
353
|
+
*/
|
|
354
|
+
body: unknown;
|
|
355
|
+
/**
|
|
356
|
+
* Request body type
|
|
357
|
+
*
|
|
358
|
+
* 请求体类型
|
|
359
|
+
*/
|
|
360
|
+
bodyType: string;
|
|
361
|
+
}
|
|
362
|
+
interface RecordedRes {
|
|
363
|
+
/**
|
|
364
|
+
* Response status code
|
|
365
|
+
*
|
|
366
|
+
* 响应状态码
|
|
367
|
+
*/
|
|
368
|
+
status: number;
|
|
369
|
+
/**
|
|
370
|
+
* Response status text
|
|
371
|
+
*
|
|
372
|
+
* 响应状态文本
|
|
373
|
+
*/
|
|
374
|
+
statusText: string;
|
|
375
|
+
/**
|
|
376
|
+
* Response headers
|
|
377
|
+
*
|
|
378
|
+
* 响应头
|
|
379
|
+
*/
|
|
380
|
+
headers: Record<string, string>;
|
|
381
|
+
/**
|
|
382
|
+
* Response body
|
|
383
|
+
*
|
|
384
|
+
* 响应体
|
|
385
|
+
*/
|
|
386
|
+
body: string;
|
|
387
|
+
}
|
|
388
|
+
/**
|
|
389
|
+
* Recorded request data structure
|
|
390
|
+
*
|
|
391
|
+
* 录制的请求数据结构
|
|
392
|
+
*/
|
|
393
|
+
interface RecordedRequest {
|
|
394
|
+
/**
|
|
395
|
+
* Recorded request metadata
|
|
396
|
+
*
|
|
397
|
+
* 录制请求元数据
|
|
398
|
+
*/
|
|
399
|
+
meta: RecordedMeta;
|
|
400
|
+
/**
|
|
401
|
+
* Recorded request data
|
|
402
|
+
*
|
|
403
|
+
* 录制请求数据
|
|
404
|
+
*/
|
|
405
|
+
req: RecordedReq;
|
|
406
|
+
/**
|
|
407
|
+
* Recorded response data
|
|
408
|
+
*
|
|
409
|
+
* 录制响应数据
|
|
410
|
+
*/
|
|
411
|
+
res: RecordedRes;
|
|
412
|
+
}
|
|
413
|
+
/**
|
|
414
|
+
* Resolved record options with all fields required
|
|
415
|
+
*
|
|
416
|
+
* 解析后的录制配置选项,所有字段为必填
|
|
417
|
+
*/
|
|
418
|
+
interface ResolvedRecordOptions extends Omit<Required<RecordOptions>, "status"> {
|
|
419
|
+
cwd: string;
|
|
420
|
+
status: number[];
|
|
421
|
+
}
|
|
422
|
+
//#endregion
|
|
423
|
+
//#region src/types/options.d.ts
|
|
424
|
+
type BodyParserOptions = Options & {
|
|
425
|
+
jsonLimit?: string | number;
|
|
426
|
+
formLimit?: string | number;
|
|
427
|
+
textLimit?: string | number;
|
|
428
|
+
};
|
|
429
|
+
type LogType = "info" | "warn" | "error" | "debug";
|
|
430
|
+
type LogLevel = LogType | "silent";
|
|
431
|
+
interface ServerBuildOption {
|
|
432
|
+
/**
|
|
433
|
+
* Service startup port
|
|
434
|
+
*
|
|
435
|
+
* 服务启动端口
|
|
436
|
+
* @default 8080
|
|
437
|
+
*/
|
|
438
|
+
serverPort?: number;
|
|
439
|
+
/**
|
|
440
|
+
* Service application output directory
|
|
441
|
+
*
|
|
442
|
+
* 服务应用输出目录
|
|
443
|
+
* @default 'dist/mockServer'
|
|
444
|
+
*/
|
|
445
|
+
dist?: string;
|
|
446
|
+
/**
|
|
447
|
+
* Service application log level
|
|
448
|
+
*
|
|
449
|
+
* 服务应用日志级别
|
|
450
|
+
* @default 'error'
|
|
451
|
+
*/
|
|
452
|
+
log?: LogLevel;
|
|
453
|
+
/**
|
|
454
|
+
* Whether to include record files in the build output
|
|
455
|
+
*
|
|
456
|
+
* 是否在构建输出中包含录制文件
|
|
457
|
+
*
|
|
458
|
+
* @default true
|
|
459
|
+
*/
|
|
460
|
+
includeRecord?: boolean;
|
|
461
|
+
}
|
|
462
|
+
interface MockMatchPriority {
|
|
463
|
+
/**
|
|
464
|
+
* The priority of matching rules is global.
|
|
465
|
+
* The rules declared in this option will take priority over the default rules.
|
|
466
|
+
* The higher the position of the rule in the array, the higher the priority.
|
|
467
|
+
*
|
|
468
|
+
* Do not declare general rules in this option, such as /api/(.*),
|
|
469
|
+
* as it will prevent subsequent rules from taking effect.
|
|
470
|
+
* Unless you are clear about the priority of the rules,
|
|
471
|
+
* most of the time you do not need to configure this option.
|
|
472
|
+
*
|
|
473
|
+
* 匹配规则优先级, 全局生效。
|
|
474
|
+
* 声明在该选项中的规则将优先于默认规则生效。
|
|
475
|
+
* 规则在数组越靠前的位置,优先级越高。
|
|
476
|
+
*
|
|
477
|
+
* 不要在此选项中声明通用性的规则,比如 `/api/(.*)`,这将导致后续的规则无法生效。
|
|
478
|
+
* 除非你明确知道规则的优先级,否则大多数情况下都不需要配置该选项。
|
|
479
|
+
* @default []
|
|
480
|
+
*/
|
|
481
|
+
global?: string[];
|
|
482
|
+
/**
|
|
483
|
+
* For some special cases where the priority of certain rules needs to be adjusted,
|
|
484
|
+
* this option can be used. For example, when a request matches both Rule A and Rule B,
|
|
485
|
+
* and Rule A has a higher priority than Rule B, but it is desired for Rule B to take effect.
|
|
486
|
+
*
|
|
487
|
+
* 对于一些特殊情况,需要调整部分规则的优先级,可以使用此选项。
|
|
488
|
+
* 比如一个请求同时命中了规则 A 和 B,且 A 比 B 优先级高, 但期望规则 B 生效时。
|
|
489
|
+
*
|
|
490
|
+
* @example
|
|
491
|
+
* ```ts
|
|
492
|
+
* {
|
|
493
|
+
* special: {
|
|
494
|
+
* // /api/a/:b/c 优先级将提升到 /api/a/b/:c 前面
|
|
495
|
+
* // The /api/a/:b/c priority is promoted to /api/a/b/:c
|
|
496
|
+
* '/api/a/:b/c': ['/api/a/b/:c'],
|
|
497
|
+
* // 仅在请求满足 /api/a/b/c 时生效
|
|
498
|
+
* // Only when the request satisfies /api/a/b/c
|
|
499
|
+
* '/api/:a/b/c': {
|
|
500
|
+
* rules: ['/api/a/:b/c'],
|
|
501
|
+
* when: ['/api/a/b/c']
|
|
502
|
+
* }
|
|
503
|
+
* }
|
|
504
|
+
* }
|
|
505
|
+
* ```
|
|
506
|
+
*/
|
|
507
|
+
special?: MockMatchSpecialPriority;
|
|
508
|
+
}
|
|
509
|
+
interface MockMatchSpecialPriority {
|
|
510
|
+
/**
|
|
511
|
+
* When both A and B or C match, and B or C is at the top of the sort order,
|
|
512
|
+
* insert A into the top position.The `when` option is used to further constrain
|
|
513
|
+
* the priority adjustment to be effective only for certain requests.
|
|
514
|
+
*
|
|
515
|
+
* 当 A 与 B或 C 同时满足匹配,`B` 或 `C` 在排序首位时,将A插入到首位。
|
|
516
|
+
* when 选项用于进一步约束该优先级调整仅针对哪些请求有效。
|
|
517
|
+
*
|
|
518
|
+
* @example
|
|
519
|
+
* ```ts
|
|
520
|
+
* {
|
|
521
|
+
* A: ['B', 'C'],
|
|
522
|
+
* A: { rules: ['B', 'C'], when: ['/api/a/b/c'] }
|
|
523
|
+
* }
|
|
524
|
+
* ```
|
|
525
|
+
*/
|
|
526
|
+
[key: string]: string[] | {
|
|
527
|
+
rules: string[];
|
|
528
|
+
when: string[];
|
|
529
|
+
};
|
|
530
|
+
}
|
|
133
531
|
/**
|
|
134
532
|
* Configure plugin
|
|
135
533
|
*
|
|
@@ -161,6 +559,13 @@ interface MockServerPluginOptions {
|
|
|
161
559
|
*/
|
|
162
560
|
wsPrefix?: string | string[];
|
|
163
561
|
/**
|
|
562
|
+
* Whether to enable mock server
|
|
563
|
+
*
|
|
564
|
+
* 是否开启 mock 服务
|
|
565
|
+
* @default true
|
|
566
|
+
*/
|
|
567
|
+
enabled?: boolean;
|
|
568
|
+
/**
|
|
164
569
|
* Configure the matching context for `include` and `exclude`.
|
|
165
570
|
*
|
|
166
571
|
* 配置 `include` 和 `exclude` 的匹配上下文
|
|
@@ -267,158 +672,49 @@ interface MockServerPluginOptions {
|
|
|
267
672
|
* ```
|
|
268
673
|
*/
|
|
269
674
|
priority?: MockMatchPriority;
|
|
270
|
-
}
|
|
271
|
-
interface MockMatchPriority {
|
|
272
675
|
/**
|
|
273
|
-
*
|
|
274
|
-
*
|
|
275
|
-
*
|
|
276
|
-
*
|
|
277
|
-
*
|
|
278
|
-
*
|
|
279
|
-
*
|
|
280
|
-
*
|
|
281
|
-
*
|
|
282
|
-
* 匹配规则优先级, 全局生效。
|
|
283
|
-
* 声明在该选项中的规则将优先于默认规则生效。
|
|
284
|
-
* 规则在数组越靠前的位置,优先级越高。
|
|
285
|
-
*
|
|
286
|
-
* 不要在此选项中声明通用性的规则,比如 `/api/(.*)`,这将导致后续的规则无法生效。
|
|
287
|
-
* 除非你明确知道规则的优先级,否则大多数情况下都不需要配置该选项。
|
|
288
|
-
* @default []
|
|
676
|
+
* Active scenario(s) for filtering mocks.
|
|
677
|
+
* Only mocks whose `scene` intersects with this value (or have no `scene` configured)
|
|
678
|
+
* will be considered for matching.
|
|
679
|
+
* Can be overridden per-request via the `X-Mock-Scene` header.
|
|
680
|
+
*
|
|
681
|
+
* 当前激活的场景,用于过滤 mock。
|
|
682
|
+
* 只有 `scene` 与此有交集的 mock(或未配置 `scene` 的 mock)才会被考虑匹配。
|
|
683
|
+
* 可通过 `X-Mock-Scene` 请求头按请求覆盖。
|
|
289
684
|
*/
|
|
290
|
-
|
|
685
|
+
activeScene?: string | string[];
|
|
291
686
|
/**
|
|
292
|
-
*
|
|
293
|
-
*
|
|
294
|
-
* and Rule A has a higher priority than Rule B, but it is desired for Rule B to take effect.
|
|
687
|
+
* Record and replay configuration
|
|
688
|
+
* Can be abbreviated as: record: true
|
|
295
689
|
*
|
|
296
|
-
*
|
|
297
|
-
*
|
|
690
|
+
* 录制回放配置
|
|
691
|
+
* 可简写为:record: true
|
|
298
692
|
*
|
|
299
|
-
* @
|
|
300
|
-
* ```ts
|
|
301
|
-
* {
|
|
302
|
-
* special: {
|
|
303
|
-
* // /api/a/:b/c 优先级将提升到 /api/a/b/:c 前面
|
|
304
|
-
* // The /api/a/:b/c priority is promoted to /api/a/b/:c
|
|
305
|
-
* '/api/a/:b/c': ['/api/a/b/:c'],
|
|
306
|
-
* // 仅在请求满足 /api/a/b/c 时生效
|
|
307
|
-
* // Only when the request satisfies /api/a/b/c
|
|
308
|
-
* '/api/:a/b/c': {
|
|
309
|
-
* rules: ['/api/a/:b/c'],
|
|
310
|
-
* when: ['/api/a/b/c']
|
|
311
|
-
* }
|
|
312
|
-
* }
|
|
313
|
-
* }
|
|
314
|
-
* ```
|
|
315
|
-
*/
|
|
316
|
-
special?: MockMatchSpecialPriority;
|
|
317
|
-
}
|
|
318
|
-
interface MockMatchSpecialPriority {
|
|
319
|
-
/**
|
|
320
|
-
* When both A and B or C match, and B or C is at the top of the sort order,
|
|
321
|
-
* insert A into the top position.The `when` option is used to further constrain
|
|
322
|
-
* the priority adjustment to be effective only for certain requests.
|
|
323
|
-
*
|
|
324
|
-
* 当 A 与 B或 C 同时满足匹配,`B` 或 `C` 在排序首位时,将A插入到首位。
|
|
325
|
-
* when 选项用于进一步约束该优先级调整仅针对哪些请求有效。
|
|
693
|
+
* @default false
|
|
326
694
|
*
|
|
327
695
|
* @example
|
|
328
696
|
* ```ts
|
|
329
|
-
*
|
|
330
|
-
*
|
|
331
|
-
*
|
|
697
|
+
* // Enable with default settings
|
|
698
|
+
* record: true
|
|
699
|
+
*
|
|
700
|
+
* // Or with custom configuration
|
|
701
|
+
* record: {
|
|
702
|
+
* enabled: true,
|
|
703
|
+
* dir: 'mock/.recordings',
|
|
704
|
+
* overwrite: true,
|
|
332
705
|
* }
|
|
333
706
|
* ```
|
|
334
707
|
*/
|
|
335
|
-
|
|
336
|
-
rules: string[];
|
|
337
|
-
when: string[];
|
|
338
|
-
};
|
|
339
|
-
}
|
|
340
|
-
type BodyParserOptions = Options & {
|
|
341
|
-
jsonLimit?: string | number;
|
|
342
|
-
formLimit?: string | number;
|
|
343
|
-
textLimit?: string | number;
|
|
344
|
-
};
|
|
345
|
-
interface ServerBuildOption {
|
|
346
|
-
/**
|
|
347
|
-
* Service startup port
|
|
348
|
-
*
|
|
349
|
-
* 服务启动端口
|
|
350
|
-
* @default 8080
|
|
351
|
-
*/
|
|
352
|
-
serverPort?: number;
|
|
353
|
-
/**
|
|
354
|
-
* Service application output directory
|
|
355
|
-
*
|
|
356
|
-
* 服务应用输出目录
|
|
357
|
-
* @default 'dist/mockServer'
|
|
358
|
-
*/
|
|
359
|
-
dist?: string;
|
|
360
|
-
/**
|
|
361
|
-
* Service application log level
|
|
362
|
-
*
|
|
363
|
-
* 服务应用日志级别
|
|
364
|
-
* @default 'error'
|
|
365
|
-
*/
|
|
366
|
-
log?: LogLevel;
|
|
367
|
-
}
|
|
368
|
-
type Method = "GET" | "POST" | "PUT" | "DELETE" | "PATCH" | "HEAD" | "TRACE" | "OPTIONS";
|
|
369
|
-
type Headers = http.IncomingHttpHeaders;
|
|
370
|
-
type ResponseBody = Record<string, any> | any[] | string | number | Readable | Buffer | null;
|
|
371
|
-
/**
|
|
372
|
-
* 扩展 request,添加额外的属性和方法
|
|
373
|
-
*/
|
|
374
|
-
interface ExtraRequest {
|
|
375
|
-
/**
|
|
376
|
-
* The query string located after `?` in the request address has been parsed into JSON.
|
|
377
|
-
*
|
|
378
|
-
* 请求地址中位于 `?` 后面的 queryString,已解析为 json
|
|
379
|
-
*/
|
|
380
|
-
query: Record<string, any>;
|
|
381
|
-
/**
|
|
382
|
-
* The queryString located after `?` in the referer request has been parsed as JSON.
|
|
383
|
-
*
|
|
384
|
-
* 请求 referer 中位于 `?` 后面的 queryString,已解析为 json
|
|
385
|
-
*/
|
|
386
|
-
refererQuery: Record<string, any>;
|
|
387
|
-
/**
|
|
388
|
-
* Body data in the request
|
|
389
|
-
*
|
|
390
|
-
* 请求体中 body 数据
|
|
391
|
-
*/
|
|
392
|
-
body: Record<string, any>;
|
|
393
|
-
/**
|
|
394
|
-
* The params parameter parsed from the `/api/id/:id` in the request address.
|
|
395
|
-
*
|
|
396
|
-
* 请求地址中,`/api/id/:id` 解析后的 params 参数
|
|
397
|
-
*/
|
|
398
|
-
params: Record<string, any>;
|
|
708
|
+
record?: boolean | RecordOptions;
|
|
399
709
|
/**
|
|
400
|
-
*
|
|
401
|
-
* 请求体中 headers
|
|
402
|
-
*/
|
|
403
|
-
headers: Headers;
|
|
404
|
-
/**
|
|
405
|
-
* Get the cookie carried in the request.
|
|
710
|
+
* Replay recorded requests, default enabled when record enabled
|
|
406
711
|
*
|
|
407
|
-
*
|
|
408
|
-
* @see [cookies](https://github.com/pillarjs/cookies#cookiesgetname--options)
|
|
712
|
+
* 回放已记录的请求,默认请求录制启用时自动启用回放功能
|
|
409
713
|
*/
|
|
410
|
-
|
|
714
|
+
replay?: boolean;
|
|
411
715
|
}
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
/**
|
|
415
|
-
* Set cookie in response
|
|
416
|
-
*
|
|
417
|
-
* 向请求响应中设置 cookie
|
|
418
|
-
* @see [cookies](https://github.com/pillarjs/cookies#cookiessetname--values--options)
|
|
419
|
-
*/
|
|
420
|
-
setCookie: Cookies["set"];
|
|
421
|
-
};
|
|
716
|
+
//#endregion
|
|
717
|
+
//#region src/types/basicConfig.d.ts
|
|
422
718
|
type ResponseBodyFn = (request: MockRequest) => ResponseBody | Promise<ResponseBody>;
|
|
423
719
|
type ResponseHeaderFn = (request: MockRequest) => Headers | Promise<Headers>;
|
|
424
720
|
type CookieValue = string | [string, SetCookieOption];
|
|
@@ -427,16 +723,16 @@ type ResponseCookiesFn = (request: MockRequest) => ResponseCookies | Promise<Res
|
|
|
427
723
|
interface MockBaseItem {
|
|
428
724
|
/**
|
|
429
725
|
* The interface address that needs to be mocked,
|
|
430
|
-
* supported by `path-to-regexp` for path matching.
|
|
726
|
+
* supported by `path-to-regexp@8.3.0` for path matching.
|
|
431
727
|
*
|
|
432
|
-
* 需要进行 mock 的接口地址, 由 `path-to-regexp` 提供路径匹配支持
|
|
728
|
+
* 需要进行 mock 的接口地址, 由 `path-to-regexp@8.3.0` 提供路径匹配支持
|
|
433
729
|
* @see [path-to-regexp](https://github.com/pillarjs/path-to-regexp)
|
|
434
730
|
* @example
|
|
435
731
|
* ```txt
|
|
436
732
|
* /api/login
|
|
437
733
|
* /api/post/:id
|
|
438
|
-
* /api/
|
|
439
|
-
* /api/
|
|
734
|
+
* /api/users{/:id}
|
|
735
|
+
* /api/files/*path
|
|
440
736
|
* ```
|
|
441
737
|
*/
|
|
442
738
|
url: string;
|
|
@@ -450,7 +746,7 @@ interface MockBaseItem {
|
|
|
450
746
|
ws?: boolean;
|
|
451
747
|
/**
|
|
452
748
|
* Whether to enable mock for this interface.
|
|
453
|
-
* In most
|
|
749
|
+
* In most scenerios, we only need to mock some interfaces instead of all requests that
|
|
454
750
|
* have been configured with mock.
|
|
455
751
|
* Therefore, it is important to be able to configure whether to enable it or not.
|
|
456
752
|
*
|
|
@@ -466,6 +762,49 @@ interface MockBaseItem {
|
|
|
466
762
|
* @default 'info'
|
|
467
763
|
*/
|
|
468
764
|
log?: boolean | LogLevel;
|
|
765
|
+
/**
|
|
766
|
+
* Scenario identifier for this mock.
|
|
767
|
+
* When not configured, the mock is universal and always matches regardless of active scenario.
|
|
768
|
+
* When configured, the mock only matches when at least one of its scenarios matches
|
|
769
|
+
* one of the active scenarios.
|
|
770
|
+
*
|
|
771
|
+
* 该 mock 的场景标识。
|
|
772
|
+
* 未配置时,该 mock 为全场景通用,不受 activeScene 限制。
|
|
773
|
+
* 配置后,只有 scene 中任意一项与 activeScene 中任意一项匹配时,该 mock 才会激活。
|
|
774
|
+
*/
|
|
775
|
+
scene?: string | string[];
|
|
776
|
+
}
|
|
777
|
+
//#endregion
|
|
778
|
+
//#region src/types/httpConfig.d.ts
|
|
779
|
+
interface MockErrorConfig {
|
|
780
|
+
/**
|
|
781
|
+
* Error probability (0-1), default is 0.5
|
|
782
|
+
*
|
|
783
|
+
* 错误概率(0-1),默认 0.5
|
|
784
|
+
* @default 0.5
|
|
785
|
+
*/
|
|
786
|
+
probability?: number;
|
|
787
|
+
/**
|
|
788
|
+
* Error status code, default is 500
|
|
789
|
+
*
|
|
790
|
+
* 错误状态码,默认 500
|
|
791
|
+
* @default 500
|
|
792
|
+
*/
|
|
793
|
+
status?: number;
|
|
794
|
+
/**
|
|
795
|
+
* Error status text
|
|
796
|
+
*
|
|
797
|
+
* 错误状态文本
|
|
798
|
+
*/
|
|
799
|
+
statusText?: string;
|
|
800
|
+
/**
|
|
801
|
+
* Custom error response body, suitable for when the status is 200, but the response body needs to simulate an error scenario
|
|
802
|
+
*
|
|
803
|
+
* 自定义错误响应体,适用于 status 为 200,但响应体需要模拟错误场景
|
|
804
|
+
* @example
|
|
805
|
+
* { code: 500, msg: 'Internal Server Error', result: null }
|
|
806
|
+
*/
|
|
807
|
+
body?: ResponseBody | ResponseBodyFn;
|
|
469
808
|
}
|
|
470
809
|
interface MockHttpItem extends MockBaseItem {
|
|
471
810
|
/**
|
|
@@ -613,7 +952,7 @@ interface MockHttpItem extends MockBaseItem {
|
|
|
613
952
|
* ```
|
|
614
953
|
*
|
|
615
954
|
*/
|
|
616
|
-
response?: (req: MockRequest, res: MockResponse, next:
|
|
955
|
+
response?: (req: MockRequest, res: MockResponse, next: NextFunction) => void | Promise<void>;
|
|
617
956
|
/**
|
|
618
957
|
* Request Validator
|
|
619
958
|
*
|
|
@@ -647,8 +986,26 @@ interface MockHttpItem extends MockBaseItem {
|
|
|
647
986
|
* ```
|
|
648
987
|
*/
|
|
649
988
|
validator?: Partial<Omit<ExtraRequest, "getCookie">> | ((request: ExtraRequest) => boolean);
|
|
989
|
+
/**
|
|
990
|
+
* Configure error simulation
|
|
991
|
+
*
|
|
992
|
+
* 配置错误模拟
|
|
993
|
+
* @example
|
|
994
|
+
* ```ts
|
|
995
|
+
* export default {
|
|
996
|
+
* error: {
|
|
997
|
+
* probability: 0.5,
|
|
998
|
+
* status: 500,
|
|
999
|
+
* message: 'Internal Server Error'
|
|
1000
|
+
* }
|
|
1001
|
+
* }
|
|
1002
|
+
* ```
|
|
1003
|
+
*/
|
|
1004
|
+
error?: MockErrorConfig;
|
|
650
1005
|
ws?: false;
|
|
651
1006
|
}
|
|
1007
|
+
//#endregion
|
|
1008
|
+
//#region src/types/wsConfig.d.ts
|
|
652
1009
|
interface MockWebsocketItem extends MockBaseItem {
|
|
653
1010
|
ws: true;
|
|
654
1011
|
/**
|
|
@@ -693,9 +1050,17 @@ interface WebSocketSetupContext {
|
|
|
693
1050
|
*/
|
|
694
1051
|
onCleanup: (cleanup: () => void) => void;
|
|
695
1052
|
}
|
|
1053
|
+
//#endregion
|
|
1054
|
+
//#region src/types/config.d.ts
|
|
696
1055
|
type MockOptions = (MockHttpItem | MockWebsocketItem)[];
|
|
1056
|
+
//#endregion
|
|
1057
|
+
//#region src/types/internal.d.ts
|
|
1058
|
+
/** @internal */
|
|
1059
|
+
type PathFilter = string | ((pathname: string, req: http.IncomingMessage) => boolean);
|
|
1060
|
+
/** @internal */
|
|
1061
|
+
type HttpProxyPlugin = NonNullable<(DevServerProxyConfigArrayItem & ProxyOptions)["plugins"]>[number];
|
|
1062
|
+
//#endregion
|
|
1063
|
+
//#region src/types/index.d.ts
|
|
697
1064
|
type FormidableFile = formidable.File | formidable.File[];
|
|
698
|
-
type LogType = "info" | "warn" | "error" | "debug";
|
|
699
|
-
type LogLevel = LogType | "silent";
|
|
700
1065
|
//#endregion
|
|
701
|
-
export {
|
|
1066
|
+
export { ResponseBody as A, HandleFunction as C, MockResponse as D, MockRequest as E, CookiesOption as M, GetCookieOption as N, NextFunction as O, SetCookieOption as P, ExtraRequest as S, Method as T, RecordedMeta as _, MockWebsocketItem as a, RecordedRes as b, MockHttpItem as c, LogType as d, MockMatchPriority as f, RecordOptions as g, ServerBuildOption as h, MockOptions as i, SimpleHandleFunction as j, NextHandleFunction as k, BodyParserOptions as l, MockServerPluginOptions as m, HttpProxyPlugin as n, WebSocketSetupContext as o, MockMatchSpecialPriority as p, PathFilter as r, MockErrorConfig as s, FormidableFile as t, LogLevel as u, RecordedReq as v, Headers as w, ResolvedRecordOptions as x, RecordedRequest as y };
|