rspack-plugin-mock 1.3.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 +413 -67
- package/README.zh-CN.md +412 -67
- package/dist/{helper.d.mts → helper.d.ts} +46 -8
- package/dist/helper.js +267 -0
- package/dist/{types-Bt_OTa7I.d.mts → index-BMMGM-eD.d.ts} +537 -172
- package/dist/index.d.ts +16 -0
- package/dist/index.js +87 -0
- package/dist/json5-loader.mjs +8 -0
- package/dist/logger-CzeuHKAL.js +1563 -0
- package/dist/options-CI0LRpJZ.js +487 -0
- package/dist/rsbuild.d.ts +8 -0
- package/dist/rsbuild.js +80 -0
- package/dist/server-pC78IYdH.d.ts +113 -0
- package/dist/server.d.ts +2 -0
- package/dist/server.js +2 -0
- package/package.json +38 -34
- package/dist/helper.mjs +0 -4
- package/dist/index.d.mts +0 -13
- package/dist/index.mjs +0 -1
- package/dist/json5-loader.cjs +0 -1
- package/dist/options-BUfaThYe.mjs +0 -43
- package/dist/rsbuild.d.mts +0 -7
- package/dist/rsbuild.mjs +0 -1
- package/dist/server-4ETytB7L.d.mts +0 -89
- package/dist/server.d.mts +0 -3
- package/dist/server.mjs +0 -1
- package/dist/ws-BM06pHhL.mjs +0 -1
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { _ as
|
|
2
|
-
import { Transform } from "node:stream";
|
|
1
|
+
import { A as ResponseBody, C as HandleFunction, D as MockResponse, E as MockRequest, M as CookiesOption, N as GetCookieOption, O as NextFunction, P as SetCookieOption, S as ExtraRequest, T as Method, _ as RecordedMeta, a as MockWebsocketItem, b as RecordedRes, c as MockHttpItem, d as LogType, f as MockMatchPriority, g as RecordOptions, h as ServerBuildOption, i as MockOptions, j as SimpleHandleFunction, k as NextHandleFunction, l as BodyParserOptions, m as MockServerPluginOptions, n as HttpProxyPlugin, o as WebSocketSetupContext, p as MockMatchSpecialPriority, r as PathFilter, s as MockErrorConfig, t as FormidableFile, u as LogLevel, v as RecordedReq, w as Headers, x as ResolvedRecordOptions, y as RecordedRequest } from "./index-BMMGM-eD.js";
|
|
3
2
|
import { IncomingMessage, OutgoingHttpHeaders, ServerResponse } from "node:http";
|
|
3
|
+
import { Transform } from "node:stream";
|
|
4
4
|
|
|
5
|
-
//#region src/
|
|
5
|
+
//#region src/helpers/createSSEStream.d.ts
|
|
6
6
|
interface SSEMessage {
|
|
7
7
|
data?: string | object;
|
|
8
8
|
comment?: string;
|
|
@@ -56,9 +56,9 @@ declare class SSEStream extends Transform {
|
|
|
56
56
|
*/
|
|
57
57
|
declare function createSSEStream(req: IncomingMessage, res: ServerResponse): SSEStream;
|
|
58
58
|
//#endregion
|
|
59
|
-
//#region src/
|
|
59
|
+
//#region src/helpers/defineMock.d.ts
|
|
60
60
|
/**
|
|
61
|
-
*
|
|
61
|
+
* Mock config Type helper
|
|
62
62
|
*
|
|
63
63
|
* mock配置 类型帮助函数
|
|
64
64
|
* @param config see config docs:
|
|
@@ -117,10 +117,48 @@ declare function defineMock(config: MockOptions): MockOptions;
|
|
|
117
117
|
*/
|
|
118
118
|
declare function createDefineMock(transformer: (mock: MockHttpItem | MockWebsocketItem) => MockHttpItem | MockWebsocketItem | void): typeof defineMock;
|
|
119
119
|
//#endregion
|
|
120
|
-
//#region src/
|
|
120
|
+
//#region src/helpers/defineMockData.d.ts
|
|
121
|
+
/**
|
|
122
|
+
* Options for defineMockData
|
|
123
|
+
*
|
|
124
|
+
* defineMockData 的选项
|
|
125
|
+
*/
|
|
126
|
+
interface DefineMockDataOptions {
|
|
127
|
+
/**
|
|
128
|
+
* Whether to persist the data value on HMR (Hot Module Replacement).
|
|
129
|
+
*
|
|
130
|
+
* 热更新时是否保持数据值
|
|
131
|
+
*
|
|
132
|
+
* @default false
|
|
133
|
+
*/
|
|
134
|
+
persistOnHMR?: boolean;
|
|
135
|
+
}
|
|
136
|
+
/**
|
|
137
|
+
* Mock data type with getter, setter, and value property
|
|
138
|
+
*
|
|
139
|
+
* 带有 getter、setter 和 value 属性的 Mock 数据类型
|
|
140
|
+
*
|
|
141
|
+
* @template T - Type of mock data / Mock 数据的类型
|
|
142
|
+
*/
|
|
121
143
|
type MockData<T = any> = readonly [() => T, (val: T | ((val: T) => T | void)) => void] & {
|
|
144
|
+
/**
|
|
145
|
+
* Current value
|
|
146
|
+
*
|
|
147
|
+
* 当前值
|
|
148
|
+
*/
|
|
122
149
|
value: T;
|
|
123
150
|
};
|
|
124
|
-
|
|
151
|
+
/**
|
|
152
|
+
* Define mock data with memory-based sharing mechanism
|
|
153
|
+
*
|
|
154
|
+
* 定义带有基于内存的共享机制的 Mock 数据
|
|
155
|
+
*
|
|
156
|
+
* @template T - Type of mock data / Mock 数据的类型
|
|
157
|
+
* @param key - Unique key for mock data / Mock 数据的唯一键
|
|
158
|
+
* @param initialData - Initial data value / 初始数据值
|
|
159
|
+
* @param options - Options / 选项
|
|
160
|
+
* @returns MockData object with getter, setter, and value property / 带有 getter、setter 和 value 属性的 MockData 对象
|
|
161
|
+
*/
|
|
162
|
+
declare function defineMockData<T = any>(key: string, initialData: T, options?: DefineMockDataOptions): MockData<T>;
|
|
125
163
|
//#endregion
|
|
126
|
-
export { BodyParserOptions, ExtraRequest, FormidableFile, HeaderStream, LogLevel, LogType, Method, MockData, MockHttpItem, MockMatchPriority, MockMatchSpecialPriority, MockOptions, MockRequest, MockResponse, MockServerPluginOptions, MockWebsocketItem, ResponseBody, SSEMessage, ServerBuildOption, WebSocketSetupContext, createDefineMock, createSSEStream, defineMock, defineMockData };
|
|
164
|
+
export { BodyParserOptions, CookiesOption, DefineMockDataOptions, ExtraRequest, FormidableFile, GetCookieOption, HandleFunction, HeaderStream, Headers, HttpProxyPlugin, LogLevel, LogType, Method, MockData, MockErrorConfig, MockHttpItem, MockMatchPriority, MockMatchSpecialPriority, MockOptions, MockRequest, MockResponse, MockServerPluginOptions, MockWebsocketItem, NextFunction, NextHandleFunction, PathFilter, RecordOptions, RecordedMeta, RecordedReq, RecordedRequest, RecordedRes, ResolvedRecordOptions, ResponseBody, SSEMessage, ServerBuildOption, SetCookieOption, SimpleHandleFunction, WebSocketSetupContext, createDefineMock, createSSEStream, defineMock, defineMockData };
|
package/dist/helper.js
ADDED
|
@@ -0,0 +1,267 @@
|
|
|
1
|
+
import { deepClone, isArray, isFunction } from "@pengzhanbo/utils";
|
|
2
|
+
import { createHash } from "node:crypto";
|
|
3
|
+
import { Transform } from "node:stream";
|
|
4
|
+
//#region src/helpers/createSSEStream.ts
|
|
5
|
+
/**
|
|
6
|
+
* Transforms "messages" to W3C event stream content.
|
|
7
|
+
* See https://html.spec.whatwg.org/multipage/server-sent-events.html
|
|
8
|
+
* A message is an object with one or more of the following properties:
|
|
9
|
+
* - data (String or object, which gets turned into JSON)
|
|
10
|
+
* - event
|
|
11
|
+
* - id
|
|
12
|
+
* - retry
|
|
13
|
+
* - comment
|
|
14
|
+
*
|
|
15
|
+
* If constructed with a HTTP Request, it will optimise the socket for streaming.
|
|
16
|
+
* If this stream is piped to an HTTP Response, it will set appropriate headers.
|
|
17
|
+
*/
|
|
18
|
+
var SSEStream = class extends Transform {
|
|
19
|
+
constructor(req) {
|
|
20
|
+
super({ objectMode: true });
|
|
21
|
+
req.socket.setKeepAlive(true);
|
|
22
|
+
req.socket.setNoDelay(true);
|
|
23
|
+
req.socket.setTimeout(0);
|
|
24
|
+
}
|
|
25
|
+
pipe(destination, options) {
|
|
26
|
+
if (destination.writeHead) {
|
|
27
|
+
destination.writeHead(200, {
|
|
28
|
+
"Content-Type": "text/event-stream; charset=utf-8",
|
|
29
|
+
"Transfer-Encoding": "identity",
|
|
30
|
+
"Cache-Control": "no-cache",
|
|
31
|
+
"Connection": "keep-alive"
|
|
32
|
+
});
|
|
33
|
+
destination.flushHeaders?.();
|
|
34
|
+
}
|
|
35
|
+
destination.write(":ok\n\n");
|
|
36
|
+
return super.pipe(destination, options);
|
|
37
|
+
}
|
|
38
|
+
_transform(message, encoding, callback) {
|
|
39
|
+
if (message.comment) this.push(`: ${message.comment}\n`);
|
|
40
|
+
if (message.event) this.push(`event: ${message.event}\n`);
|
|
41
|
+
if (message.id) this.push(`id: ${message.id}\n`);
|
|
42
|
+
if (message.retry) this.push(`retry: ${message.retry}\n`);
|
|
43
|
+
if (message.data) this.push(dataString(message.data));
|
|
44
|
+
this.push("\n");
|
|
45
|
+
callback();
|
|
46
|
+
}
|
|
47
|
+
write(message, ...args) {
|
|
48
|
+
return super.write(message, ...args);
|
|
49
|
+
}
|
|
50
|
+
destroy(error) {
|
|
51
|
+
if (error) this.write({
|
|
52
|
+
event: "error",
|
|
53
|
+
data: error.message
|
|
54
|
+
});
|
|
55
|
+
this.end();
|
|
56
|
+
return this;
|
|
57
|
+
}
|
|
58
|
+
};
|
|
59
|
+
function dataString(data) {
|
|
60
|
+
if (typeof data === "object") return dataString(JSON.stringify(data));
|
|
61
|
+
return data.split(/\r\n|\r|\n/).map((line) => `data: ${line}\n`).join("");
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* 创建一个 Server-sent events 写入流,用于支持模拟 EventSource
|
|
65
|
+
*
|
|
66
|
+
* @example
|
|
67
|
+
* ```ts
|
|
68
|
+
* import { createSSEStream, defineMock } from 'vite-plugin-mock-dev-server'
|
|
69
|
+
*
|
|
70
|
+
* export default defineMock({
|
|
71
|
+
* url: '/api',
|
|
72
|
+
* response: (req, res) => {
|
|
73
|
+
* const sse = createSSEStream(req, res)
|
|
74
|
+
* sse.write({ event: 'message', data: { message: 'hello world' } })
|
|
75
|
+
* }
|
|
76
|
+
* })
|
|
77
|
+
* ```
|
|
78
|
+
*/
|
|
79
|
+
function createSSEStream(req, res) {
|
|
80
|
+
const sse = new SSEStream(req);
|
|
81
|
+
sse.pipe(res);
|
|
82
|
+
return sse;
|
|
83
|
+
}
|
|
84
|
+
//#endregion
|
|
85
|
+
//#region src/helpers/defineMock.ts
|
|
86
|
+
function defineMock(config) {
|
|
87
|
+
return config;
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Return a custom defineMock function to support preprocessing of mock config.
|
|
91
|
+
*
|
|
92
|
+
* 返回一个自定义的 defineMock 函数,用于支持对 mock config 的预处理。
|
|
93
|
+
* @param transformer preprocessing function
|
|
94
|
+
* @example
|
|
95
|
+
* ```ts
|
|
96
|
+
* const definePostMock = createDefineMock((mock) => {
|
|
97
|
+
* mock.url = '/api/post/' + mock.url
|
|
98
|
+
* })
|
|
99
|
+
* export default definePostMock({
|
|
100
|
+
* url: 'list',
|
|
101
|
+
* body: [{ title: '1' }, { title: '2' }],
|
|
102
|
+
* })
|
|
103
|
+
* ```
|
|
104
|
+
*/
|
|
105
|
+
function createDefineMock(transformer) {
|
|
106
|
+
const define = (config) => {
|
|
107
|
+
if (isArray(config)) config = config.map((item) => transformer(item) || item);
|
|
108
|
+
else config = transformer(config) || config;
|
|
109
|
+
return config;
|
|
110
|
+
};
|
|
111
|
+
return define;
|
|
112
|
+
}
|
|
113
|
+
//#endregion
|
|
114
|
+
//#region src/helpers/defineMockData.ts
|
|
115
|
+
/**
|
|
116
|
+
* Since the plugin compiles `*.mock.*` files as separate independent entries,
|
|
117
|
+
* this leads to inconsistent dependency relationships after mock file compilation,
|
|
118
|
+
* with each mock file having its own scope.
|
|
119
|
+
* Even if multiple `*.mock.*` files import the same `data.ts` file, they are
|
|
120
|
+
* completely different instances of `data`, making operations on `data` not
|
|
121
|
+
* shareable across different `*.mock.*` files.
|
|
122
|
+
*
|
|
123
|
+
* To address this, the plugin provides a memory-based data sharing mechanism.
|
|
124
|
+
*
|
|
125
|
+
* 由于插件是分别独立对 `*.mock.*` 等文件作为单独入口进行编译的,
|
|
126
|
+
* 这导致了 mock 文件编译后的依赖关系不一致,每个 mock 文件拥有独立的作用域,
|
|
127
|
+
* 使得即使多个 `*.mock.*` 虽然引入了同一个 `data.ts` 文件,然而确是完全不同两份 `data`,
|
|
128
|
+
* 使得对 `data` 的操作,在不同的 `*.mock.*` 文件中并不能共享。
|
|
129
|
+
*
|
|
130
|
+
* 为此,插件提供了一种基于 memory 的数据共享机制。
|
|
131
|
+
*/
|
|
132
|
+
/**
|
|
133
|
+
* Mock data cache
|
|
134
|
+
*
|
|
135
|
+
* Mock 数据缓存
|
|
136
|
+
*/
|
|
137
|
+
const mockDataCache = /* @__PURE__ */ new Map();
|
|
138
|
+
/**
|
|
139
|
+
* Response cache for MockData objects
|
|
140
|
+
*
|
|
141
|
+
* MockData 对象的响应缓存
|
|
142
|
+
*/
|
|
143
|
+
const responseCache = /* @__PURE__ */ new WeakMap();
|
|
144
|
+
/**
|
|
145
|
+
* Stale interval in milliseconds
|
|
146
|
+
*
|
|
147
|
+
* 缓存过期间隔(毫秒)
|
|
148
|
+
*/
|
|
149
|
+
const staleInterval = 70;
|
|
150
|
+
/**
|
|
151
|
+
* Cache implementation for mock data
|
|
152
|
+
*
|
|
153
|
+
* Mock 数据缓存实现
|
|
154
|
+
*
|
|
155
|
+
* @template T - Type of cached data / 缓存数据的类型
|
|
156
|
+
*/
|
|
157
|
+
var CacheImpl = class {
|
|
158
|
+
/**
|
|
159
|
+
* Current cached value
|
|
160
|
+
*
|
|
161
|
+
* 当前缓存值
|
|
162
|
+
*/
|
|
163
|
+
value;
|
|
164
|
+
/**
|
|
165
|
+
* Initial value hash, used to detect if initial data has changed
|
|
166
|
+
*
|
|
167
|
+
* 初始化数据的哈希值,用于判断传入的初始化数据是否发生变更
|
|
168
|
+
*/
|
|
169
|
+
#hash;
|
|
170
|
+
/**
|
|
171
|
+
* Last update timestamp
|
|
172
|
+
*
|
|
173
|
+
* 最后更新时间戳
|
|
174
|
+
*/
|
|
175
|
+
#lastUpdate;
|
|
176
|
+
/**
|
|
177
|
+
* Whether to persist data on HMR
|
|
178
|
+
*
|
|
179
|
+
* 热更新时是否保持数据
|
|
180
|
+
*/
|
|
181
|
+
#persistOnHMR;
|
|
182
|
+
/**
|
|
183
|
+
* Constructor
|
|
184
|
+
*
|
|
185
|
+
* 构造函数
|
|
186
|
+
*
|
|
187
|
+
* @param value - Initial value / 初始值
|
|
188
|
+
* @param persistOnHMR - Whether to persist data on HMR / 热更新时是否保持数据
|
|
189
|
+
*/
|
|
190
|
+
constructor(value, persistOnHMR) {
|
|
191
|
+
this.value = value;
|
|
192
|
+
this.#hash = getHash(value);
|
|
193
|
+
this.#lastUpdate = Date.now();
|
|
194
|
+
this.#persistOnHMR = persistOnHMR ?? false;
|
|
195
|
+
}
|
|
196
|
+
/**
|
|
197
|
+
* Hot update cached value
|
|
198
|
+
*
|
|
199
|
+
* 热更新缓存值
|
|
200
|
+
*
|
|
201
|
+
* @param value - New value / 新值
|
|
202
|
+
*/
|
|
203
|
+
hotUpdate(value) {
|
|
204
|
+
if (this.#persistOnHMR) return;
|
|
205
|
+
if (Date.now() - this.#lastUpdate < staleInterval) return;
|
|
206
|
+
const hash = getHash(value);
|
|
207
|
+
if (this.#hash !== hash) {
|
|
208
|
+
this.value = deepClone(value);
|
|
209
|
+
this.#hash = hash;
|
|
210
|
+
this.#lastUpdate = Date.now();
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
/**
|
|
214
|
+
* Set persistOnHMR
|
|
215
|
+
*
|
|
216
|
+
* 设置 persistOnHMR
|
|
217
|
+
*
|
|
218
|
+
* @param persistOnHMR - Whether to persist data on HMR / 热更新时是否保持数据
|
|
219
|
+
*/
|
|
220
|
+
setPersistOnHMR(persistOnHMR) {
|
|
221
|
+
if (!this.#persistOnHMR) this.#persistOnHMR = persistOnHMR;
|
|
222
|
+
}
|
|
223
|
+
};
|
|
224
|
+
/**
|
|
225
|
+
* Define mock data with memory-based sharing mechanism
|
|
226
|
+
*
|
|
227
|
+
* 定义带有基于内存的共享机制的 Mock 数据
|
|
228
|
+
*
|
|
229
|
+
* @template T - Type of mock data / Mock 数据的类型
|
|
230
|
+
* @param key - Unique key for mock data / Mock 数据的唯一键
|
|
231
|
+
* @param initialData - Initial data value / 初始数据值
|
|
232
|
+
* @param options - Options / 选项
|
|
233
|
+
* @returns MockData object with getter, setter, and value property / 带有 getter、setter 和 value 属性的 MockData 对象
|
|
234
|
+
*/
|
|
235
|
+
function defineMockData(key, initialData, options) {
|
|
236
|
+
let cache = mockDataCache.get(key);
|
|
237
|
+
if (!cache) {
|
|
238
|
+
const newCache = new CacheImpl(initialData, options?.persistOnHMR);
|
|
239
|
+
const existing = mockDataCache.get(key);
|
|
240
|
+
if (existing) cache = existing;
|
|
241
|
+
else {
|
|
242
|
+
mockDataCache.set(key, newCache);
|
|
243
|
+
cache = newCache;
|
|
244
|
+
}
|
|
245
|
+
} else cache.setPersistOnHMR(options?.persistOnHMR ?? false);
|
|
246
|
+
cache.hotUpdate(initialData);
|
|
247
|
+
if (responseCache.has(cache)) return responseCache.get(cache);
|
|
248
|
+
const res = [() => cache.value, (val) => {
|
|
249
|
+
if (isFunction(val)) val = val(cache.value) ?? cache.value;
|
|
250
|
+
cache.value = val;
|
|
251
|
+
}];
|
|
252
|
+
Object.defineProperty(res, "value", {
|
|
253
|
+
get() {
|
|
254
|
+
return cache.value;
|
|
255
|
+
},
|
|
256
|
+
set(val) {
|
|
257
|
+
cache.value = val;
|
|
258
|
+
}
|
|
259
|
+
});
|
|
260
|
+
responseCache.set(cache, res);
|
|
261
|
+
return res;
|
|
262
|
+
}
|
|
263
|
+
function getHash(data) {
|
|
264
|
+
return createHash("sha256").update(JSON.stringify(data)).digest("hex");
|
|
265
|
+
}
|
|
266
|
+
//#endregion
|
|
267
|
+
export { createDefineMock, createSSEStream, defineMock, defineMockData };
|