rspack-plugin-mock 0.1.0 → 0.3.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 +221 -19
- package/README.zh-CN.md +888 -0
- package/dist/{chunk-G53QRHGV.cjs → chunk-I54ZNZWL.cjs} +942 -607
- package/dist/chunk-OYBMX3GQ.cjs +97 -0
- package/dist/chunk-P5FOCSCE.js +97 -0
- package/dist/{chunk-5MGZAMDI.js → chunk-YSJVV4SH.js} +1104 -769
- package/dist/helper.d.cts +2 -2
- package/dist/helper.d.ts +2 -2
- package/dist/index.cjs +17 -3
- package/dist/index.d.cts +71 -4
- package/dist/index.d.ts +71 -4
- package/dist/index.js +21 -7
- package/dist/rsbuild.cjs +172 -93
- package/dist/rsbuild.d.cts +1 -1
- package/dist/rsbuild.d.ts +1 -1
- package/dist/rsbuild.js +173 -94
- package/dist/rspack-BB-Jtq4f.d.cts +32 -0
- package/dist/rspack-h3uerEgg.d.ts +32 -0
- package/dist/rspack.cjs +3 -3
- package/dist/rspack.d.cts +2 -2
- package/dist/rspack.d.ts +2 -2
- package/dist/rspack.js +4 -4
- package/dist/{types-DhT3pRJ3.d.cts → types-C770q3L0.d.cts} +4 -1
- package/dist/{types-DhT3pRJ3.d.ts → types-C770q3L0.d.ts} +4 -1
- package/package.json +11 -9
- package/dist/chunk-4BGDHRTO.cjs +0 -68
- package/dist/chunk-B56QNVSS.js +0 -68
- package/dist/rspack-BI-Ifj4a.d.cts +0 -28
- package/dist/rspack-Db7drzDm.d.ts +0 -28
|
@@ -1,99 +1,14 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { newObj[key] = obj[key]; } } } newObj.default = obj; return newObj; } } function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; } var _class;// src/core/
|
|
2
|
-
var _buffer = require('buffer');
|
|
3
|
-
var requestCollectCache = /* @__PURE__ */ new WeakMap();
|
|
4
|
-
function collectRequest(req) {
|
|
5
|
-
const chunks = [];
|
|
6
|
-
req.addListener("data", (chunk) => {
|
|
7
|
-
chunks.push(_buffer.Buffer.from(chunk));
|
|
8
|
-
});
|
|
9
|
-
req.addListener("end", () => {
|
|
10
|
-
if (chunks.length)
|
|
11
|
-
requestCollectCache.set(req, _buffer.Buffer.concat(chunks));
|
|
12
|
-
});
|
|
13
|
-
}
|
|
14
|
-
function rewriteRequest(proxyReq, req) {
|
|
15
|
-
const buffer = requestCollectCache.get(req);
|
|
16
|
-
if (buffer) {
|
|
17
|
-
requestCollectCache.delete(req);
|
|
18
|
-
if (!proxyReq.headersSent)
|
|
19
|
-
proxyReq.setHeader("Content-Length", buffer.byteLength);
|
|
20
|
-
if (!proxyReq.writableEnded)
|
|
21
|
-
proxyReq.write(buffer);
|
|
22
|
-
}
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
// src/core/mockMiddleware.ts
|
|
26
|
-
var _process = require('process'); var _process2 = _interopRequireDefault(_process);
|
|
27
|
-
var _utils = require('@pengzhanbo/utils');
|
|
28
|
-
var _cors = require('cors'); var _cors2 = _interopRequireDefault(_cors);
|
|
29
|
-
var _pathtoregexp = require('path-to-regexp');
|
|
30
|
-
|
|
31
|
-
// src/core/resolvePluginOptions.ts
|
|
32
|
-
|
|
33
|
-
function resolvePluginOptions({
|
|
34
|
-
prefix = [],
|
|
35
|
-
// wsPrefix = [],
|
|
36
|
-
cwd,
|
|
37
|
-
include = ["mock/**/*.mock.{js,ts,cjs,mjs,json,json5}"],
|
|
38
|
-
exclude = ["**/node_modules/**", "**/.vscode/**", "**/.git/**"],
|
|
39
|
-
// reload = false,
|
|
40
|
-
log = "info",
|
|
41
|
-
cors: cors2 = true,
|
|
42
|
-
formidableOptions = {},
|
|
43
|
-
// build = false,
|
|
44
|
-
cookiesOptions = {},
|
|
45
|
-
bodyParserOptions = {},
|
|
46
|
-
priority = {}
|
|
47
|
-
} = {}, context) {
|
|
48
|
-
const pluginOptions = {
|
|
49
|
-
prefix,
|
|
50
|
-
// wsPrefix,
|
|
51
|
-
cwd: cwd || context || _process2.default.cwd(),
|
|
52
|
-
include,
|
|
53
|
-
exclude,
|
|
54
|
-
// reload,
|
|
55
|
-
cors: cors2,
|
|
56
|
-
cookiesOptions,
|
|
57
|
-
log,
|
|
58
|
-
formidableOptions: {
|
|
59
|
-
multiples: true,
|
|
60
|
-
...formidableOptions
|
|
61
|
-
},
|
|
62
|
-
bodyParserOptions,
|
|
63
|
-
priority
|
|
64
|
-
// build: build
|
|
65
|
-
// ? Object.assign(
|
|
66
|
-
// {
|
|
67
|
-
// serverPort: 8080,
|
|
68
|
-
// dist: 'mockServer',
|
|
69
|
-
// log: 'error',
|
|
70
|
-
// },
|
|
71
|
-
// typeof build === 'object' ? build : {},
|
|
72
|
-
// )
|
|
73
|
-
// : false,
|
|
74
|
-
};
|
|
75
|
-
return pluginOptions;
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
// src/core/mockCompiler.ts
|
|
79
|
-
var _events = require('events'); var _events2 = _interopRequireDefault(_events);
|
|
1
|
+
"use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { newObj[key] = obj[key]; } } } newObj.default = obj; return newObj; } } function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; } var _class;// src/core/utils.ts
|
|
80
2
|
var _fs = require('fs'); var _fs2 = _interopRequireDefault(_fs);
|
|
81
|
-
|
|
82
3
|
var _path = require('path'); var _path2 = _interopRequireDefault(_path);
|
|
83
|
-
var _fastglob = require('fast-glob'); var _fastglob2 = _interopRequireDefault(_fastglob);
|
|
84
|
-
var _chokidar = require('chokidar'); var _chokidar2 = _interopRequireDefault(_chokidar);
|
|
85
|
-
var _pluginutils = require('@rollup/pluginutils');
|
|
86
|
-
var _core = require('@rspack/core'); var rspackCore = _interopRequireWildcard(_core);
|
|
87
|
-
var _memfs = require('memfs');
|
|
88
|
-
|
|
89
|
-
// src/core/utils.ts
|
|
90
|
-
|
|
91
|
-
|
|
92
4
|
var _querystring = require('querystring');
|
|
93
5
|
var _url = require('url');
|
|
94
6
|
var _os = require('os'); var _os2 = _interopRequireDefault(_os);
|
|
95
7
|
var _debug = require('debug'); var _debug2 = _interopRequireDefault(_debug);
|
|
96
|
-
|
|
8
|
+
var _pathtoregexp = require('path-to-regexp');
|
|
9
|
+
var _memfs = require('memfs');
|
|
10
|
+
var packageDir = getDirname(import.meta.url);
|
|
11
|
+
var vfs = _memfs.createFsFromVolume.call(void 0, new (0, _memfs.Volume)());
|
|
97
12
|
function isStream(stream) {
|
|
98
13
|
return stream !== null && typeof stream === "object" && typeof stream.pipe === "function";
|
|
99
14
|
}
|
|
@@ -103,7 +18,7 @@ function isReadableStream(stream) {
|
|
|
103
18
|
function getDirname(importMetaUrl) {
|
|
104
19
|
return _path2.default.dirname(_url.fileURLToPath.call(void 0, importMetaUrl));
|
|
105
20
|
}
|
|
106
|
-
var debug = _debug2.default.call(void 0, "rspack:mock
|
|
21
|
+
var debug = _debug2.default.call(void 0, "rspack:mock");
|
|
107
22
|
function lookupFile(dir, formats, options) {
|
|
108
23
|
for (const format of formats) {
|
|
109
24
|
const fullPath = _path2.default.join(dir, format);
|
|
@@ -144,33 +59,42 @@ function slash(p) {
|
|
|
144
59
|
function normalizePath(id) {
|
|
145
60
|
return _path2.default.posix.normalize(isWindows ? slash(id) : id);
|
|
146
61
|
}
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
isESM,
|
|
155
|
-
cwd
|
|
156
|
-
}) {
|
|
157
|
-
filepath = _path2.default.resolve(cwd, filepath);
|
|
158
|
-
const fileBase = `${filepath}.timestamp-${Date.now()}`;
|
|
159
|
-
const ext = isESM ? ".mjs" : ".cjs";
|
|
160
|
-
const fileNameTmp = `${fileBase}${ext}`;
|
|
161
|
-
await _fs.promises.writeFile(fileNameTmp, code, "utf8");
|
|
162
|
-
try {
|
|
163
|
-
const result = await Promise.resolve().then(() => _interopRequireWildcard(require(fileNameTmp)));
|
|
164
|
-
return result.default || result;
|
|
165
|
-
} finally {
|
|
166
|
-
try {
|
|
167
|
-
_fs2.default.unlinkSync(fileNameTmp);
|
|
168
|
-
} catch (e2) {
|
|
62
|
+
function waitingFor(onSuccess, maxRetry = 5) {
|
|
63
|
+
return function wait(getter, retry = 0) {
|
|
64
|
+
const value = getter();
|
|
65
|
+
if (value) {
|
|
66
|
+
onSuccess(value);
|
|
67
|
+
} else if (retry < maxRetry) {
|
|
68
|
+
setTimeout(() => wait(getter, retry + 1), 100);
|
|
169
69
|
}
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
// src/core/requestRecovery.ts
|
|
74
|
+
var _buffer = require('buffer');
|
|
75
|
+
var requestCollectCache = /* @__PURE__ */ new WeakMap();
|
|
76
|
+
function collectRequest(req) {
|
|
77
|
+
const chunks = [];
|
|
78
|
+
req.addListener("data", (chunk) => {
|
|
79
|
+
chunks.push(_buffer.Buffer.from(chunk));
|
|
80
|
+
});
|
|
81
|
+
req.addListener("end", () => {
|
|
82
|
+
if (chunks.length)
|
|
83
|
+
requestCollectCache.set(req, _buffer.Buffer.concat(chunks));
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
function rewriteRequest(proxyReq, req) {
|
|
87
|
+
const buffer = requestCollectCache.get(req);
|
|
88
|
+
if (buffer) {
|
|
89
|
+
requestCollectCache.delete(req);
|
|
90
|
+
if (!proxyReq.headersSent)
|
|
91
|
+
proxyReq.setHeader("Content-Length", buffer.byteLength);
|
|
92
|
+
if (!proxyReq.writableEnded)
|
|
93
|
+
proxyReq.write(buffer);
|
|
170
94
|
}
|
|
171
95
|
}
|
|
172
96
|
|
|
173
|
-
// src/core/
|
|
97
|
+
// src/core/baseMiddleware.ts
|
|
174
98
|
|
|
175
99
|
|
|
176
100
|
|
|
@@ -179,433 +103,106 @@ async function loadFromCode({
|
|
|
179
103
|
|
|
180
104
|
|
|
181
105
|
|
|
182
|
-
|
|
106
|
+
var _utils = require('@pengzhanbo/utils');
|
|
107
|
+
var _cookies = require('cookies'); var _cookies2 = _interopRequireDefault(_cookies);
|
|
108
|
+
var _httpstatus = require('http-status'); var _httpstatus2 = _interopRequireDefault(_httpstatus);
|
|
109
|
+
var _mimetypes = require('mime-types'); var mime = _interopRequireWildcard(_mimetypes);
|
|
183
110
|
|
|
184
|
-
|
|
185
|
-
|
|
111
|
+
var _picocolors = require('picocolors'); var _picocolors2 = _interopRequireDefault(_picocolors);
|
|
112
|
+
|
|
113
|
+
// src/core/matchingWeight.ts
|
|
114
|
+
|
|
115
|
+
|
|
116
|
+
|
|
117
|
+
|
|
118
|
+
|
|
119
|
+
|
|
120
|
+
|
|
121
|
+
|
|
122
|
+
var tokensCache = {};
|
|
123
|
+
function getTokens(rule) {
|
|
124
|
+
if (tokensCache[rule])
|
|
125
|
+
return tokensCache[rule];
|
|
126
|
+
const { tokens: tks } = _pathtoregexp.parse.call(void 0, rule);
|
|
127
|
+
const tokens = [];
|
|
128
|
+
for (const tk of tks) {
|
|
129
|
+
if (!_utils.isString.call(void 0, tk)) {
|
|
130
|
+
tokens.push(tk);
|
|
131
|
+
} else {
|
|
132
|
+
const hasPrefix = tk[0] === "/";
|
|
133
|
+
const subTks = hasPrefix ? tk.slice(1).split("/") : tk.split("/");
|
|
134
|
+
tokens.push(
|
|
135
|
+
`${hasPrefix ? "/" : ""}${subTks[0]}`,
|
|
136
|
+
...subTks.slice(1).map((t) => `/${t}`)
|
|
137
|
+
);
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
tokensCache[rule] = tokens;
|
|
141
|
+
return tokens;
|
|
186
142
|
}
|
|
187
|
-
function
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
143
|
+
function getHighest(rules) {
|
|
144
|
+
let weights = rules.map((rule) => getTokens(rule).length);
|
|
145
|
+
weights = weights.length === 0 ? [1] : weights;
|
|
146
|
+
return Math.max(...weights) + 2;
|
|
147
|
+
}
|
|
148
|
+
function sortFn(rule) {
|
|
149
|
+
const tokens = getTokens(rule);
|
|
150
|
+
let w = 0;
|
|
151
|
+
for (let i = 0; i < tokens.length; i++) {
|
|
152
|
+
const token = tokens[i];
|
|
153
|
+
if (!_utils.isString.call(void 0, token))
|
|
154
|
+
w += 10 ** (i + 1);
|
|
155
|
+
w += 10 ** (i + 1);
|
|
193
156
|
}
|
|
194
|
-
return
|
|
157
|
+
return w;
|
|
195
158
|
}
|
|
196
|
-
function
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
seen.add(i);
|
|
206
|
-
return included;
|
|
207
|
-
})
|
|
208
|
-
);
|
|
159
|
+
function preSort(rules) {
|
|
160
|
+
let matched = [];
|
|
161
|
+
const preMatch = [];
|
|
162
|
+
for (const rule of rules) {
|
|
163
|
+
const tokens = getTokens(rule);
|
|
164
|
+
const len = tokens.filter((token) => typeof token !== "string").length;
|
|
165
|
+
if (!preMatch[len])
|
|
166
|
+
preMatch[len] = [];
|
|
167
|
+
preMatch[len].push(rule);
|
|
209
168
|
}
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
return
|
|
169
|
+
for (const match2 of preMatch.filter((v) => v && v.length > 0))
|
|
170
|
+
matched = [...matched, ..._utils.sortBy.call(void 0, match2, sortFn).reverse()];
|
|
171
|
+
return matched;
|
|
213
172
|
}
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
if (
|
|
220
|
-
|
|
221
|
-
|
|
173
|
+
function defaultPriority(rules) {
|
|
174
|
+
const highest = getHighest(rules);
|
|
175
|
+
return _utils.sortBy.call(void 0, rules, (rule) => {
|
|
176
|
+
const tokens = getTokens(rule);
|
|
177
|
+
const dym = tokens.filter((token) => typeof token !== "string");
|
|
178
|
+
if (dym.length === 0)
|
|
179
|
+
return 0;
|
|
180
|
+
let weight = dym.length;
|
|
181
|
+
let exp = 0;
|
|
182
|
+
for (let i = 0; i < tokens.length; i++) {
|
|
183
|
+
const token = tokens[i];
|
|
184
|
+
const isDynamic = !_utils.isString.call(void 0, token);
|
|
185
|
+
const {
|
|
186
|
+
pattern = "",
|
|
187
|
+
modifier,
|
|
188
|
+
prefix,
|
|
189
|
+
name
|
|
190
|
+
} = isDynamic ? token : {};
|
|
191
|
+
const isGlob = pattern && pattern.includes(".*");
|
|
192
|
+
const isSlash = prefix === "/";
|
|
193
|
+
const isNamed = _utils.isString.call(void 0, name);
|
|
194
|
+
exp += isDynamic && isSlash ? 1 : 0;
|
|
195
|
+
if (i === tokens.length - 1 && isGlob) {
|
|
196
|
+
weight += 5 * 10 ** (tokens.length === 1 ? highest + 1 : highest);
|
|
222
197
|
} else {
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
mockConfig.push(...raw[key].map((item) => ({ ...item, __filepath__ })));
|
|
232
|
-
} else {
|
|
233
|
-
mockConfig.push({ ...raw[key], __filepath__ });
|
|
234
|
-
}
|
|
235
|
-
});
|
|
236
|
-
}
|
|
237
|
-
return mockConfig;
|
|
238
|
-
});
|
|
239
|
-
}
|
|
240
|
-
function transformMockData(mockList) {
|
|
241
|
-
const list = [];
|
|
242
|
-
for (const [, handle] of mockList.entries()) {
|
|
243
|
-
if (handle)
|
|
244
|
-
list.push(..._utils.toArray.call(void 0, handle));
|
|
245
|
-
}
|
|
246
|
-
const mocks = {};
|
|
247
|
-
list.filter((mock) => _utils.isObject.call(void 0, mock) && mock.enabled !== false && mock.url).forEach((mock) => {
|
|
248
|
-
const { pathname, query } = urlParse(mock.url);
|
|
249
|
-
const list2 = mocks[pathname] ??= [];
|
|
250
|
-
const current = { ...mock, url: pathname };
|
|
251
|
-
if (current.ws !== true) {
|
|
252
|
-
const validator = current.validator;
|
|
253
|
-
if (!_utils.isEmptyObject.call(void 0, query)) {
|
|
254
|
-
if (_utils.isFunction.call(void 0, validator)) {
|
|
255
|
-
current.validator = function(request) {
|
|
256
|
-
return isObjectSubset(request.query, query) && validator(request);
|
|
257
|
-
};
|
|
258
|
-
} else if (validator) {
|
|
259
|
-
current.validator = { ...validator };
|
|
260
|
-
current.validator.query = current.validator.query ? { ...query, ...current.validator.query } : query;
|
|
261
|
-
} else {
|
|
262
|
-
current.validator = { query };
|
|
263
|
-
}
|
|
264
|
-
}
|
|
265
|
-
}
|
|
266
|
-
list2.push(current);
|
|
267
|
-
});
|
|
268
|
-
Object.keys(mocks).forEach((key) => {
|
|
269
|
-
mocks[key] = sortByValidator(mocks[key]);
|
|
270
|
-
});
|
|
271
|
-
return mocks;
|
|
272
|
-
}
|
|
273
|
-
function sortByValidator(mocks) {
|
|
274
|
-
return _utils.sortBy.call(void 0, mocks, (item) => {
|
|
275
|
-
if (item.ws === true)
|
|
276
|
-
return 0;
|
|
277
|
-
const { validator } = item;
|
|
278
|
-
if (!validator || _utils.isEmptyObject.call(void 0, validator))
|
|
279
|
-
return 2;
|
|
280
|
-
if (_utils.isFunction.call(void 0, validator))
|
|
281
|
-
return 0;
|
|
282
|
-
const count = Object.keys(validator).reduce(
|
|
283
|
-
(prev, key) => prev + keysCount(validator[key]),
|
|
284
|
-
0
|
|
285
|
-
);
|
|
286
|
-
return 1 / count;
|
|
287
|
-
});
|
|
288
|
-
}
|
|
289
|
-
function keysCount(obj) {
|
|
290
|
-
if (!obj)
|
|
291
|
-
return 0;
|
|
292
|
-
return Object.keys(obj).length;
|
|
293
|
-
}
|
|
294
|
-
|
|
295
|
-
// src/core/resolveRspackOptions.ts
|
|
296
|
-
|
|
297
|
-
var _dirname = getDirname(import.meta.url);
|
|
298
|
-
function resolveRspackOptions({
|
|
299
|
-
cwd,
|
|
300
|
-
isEsm,
|
|
301
|
-
entryFile,
|
|
302
|
-
outputFile,
|
|
303
|
-
plugins,
|
|
304
|
-
alias,
|
|
305
|
-
watch = false
|
|
306
|
-
}) {
|
|
307
|
-
const targets = ["node >= 18.0.0"];
|
|
308
|
-
return {
|
|
309
|
-
mode: "production",
|
|
310
|
-
context: cwd,
|
|
311
|
-
entry: entryFile,
|
|
312
|
-
watch,
|
|
313
|
-
target: "node18.0",
|
|
314
|
-
externalsType: isEsm ? "module" : "commonjs2",
|
|
315
|
-
externals: /^[^./].*/,
|
|
316
|
-
resolve: {
|
|
317
|
-
alias,
|
|
318
|
-
extensions: [".js", ".ts", ".cjs", ".mjs", ".json5", ".json"]
|
|
319
|
-
},
|
|
320
|
-
plugins,
|
|
321
|
-
output: {
|
|
322
|
-
library: { type: !isEsm ? "commonjs2" : "module" },
|
|
323
|
-
filename: outputFile,
|
|
324
|
-
path: "/"
|
|
325
|
-
},
|
|
326
|
-
experiments: { outputModule: isEsm },
|
|
327
|
-
module: {
|
|
328
|
-
rules: [
|
|
329
|
-
{
|
|
330
|
-
test: /\.json5?$/,
|
|
331
|
-
loader: _path2.default.join(_dirname, "json5-loader.cjs"),
|
|
332
|
-
type: "javascript/auto"
|
|
333
|
-
},
|
|
334
|
-
{
|
|
335
|
-
test: /\.[cm]?js$/,
|
|
336
|
-
use: [
|
|
337
|
-
{
|
|
338
|
-
loader: "builtin:swc-loader",
|
|
339
|
-
options: {
|
|
340
|
-
jsc: { parser: { syntax: "ecmascript" } },
|
|
341
|
-
env: { targets }
|
|
342
|
-
}
|
|
343
|
-
}
|
|
344
|
-
]
|
|
345
|
-
},
|
|
346
|
-
{
|
|
347
|
-
test: /\.[cm]?ts$/,
|
|
348
|
-
use: [
|
|
349
|
-
{
|
|
350
|
-
loader: "builtin:swc-loader",
|
|
351
|
-
options: {
|
|
352
|
-
jsc: { parser: { syntax: "typescript" } },
|
|
353
|
-
env: { targets }
|
|
354
|
-
}
|
|
355
|
-
}
|
|
356
|
-
]
|
|
357
|
-
}
|
|
358
|
-
]
|
|
359
|
-
}
|
|
360
|
-
};
|
|
361
|
-
}
|
|
362
|
-
|
|
363
|
-
// src/core/mockCompiler.ts
|
|
364
|
-
var vfs = _memfs.createFsFromVolume.call(void 0, new (0, _memfs.Volume)());
|
|
365
|
-
function createMockCompiler(options) {
|
|
366
|
-
return new MockCompiler(options);
|
|
367
|
-
}
|
|
368
|
-
var MockCompiler = (_class = class extends _events2.default {
|
|
369
|
-
constructor(options) {
|
|
370
|
-
super();_class.prototype.__init.call(this);_class.prototype.__init2.call(this);;
|
|
371
|
-
this.options = options;
|
|
372
|
-
this.cwd = options.cwd || _process2.default.cwd();
|
|
373
|
-
const { include, exclude } = this.options;
|
|
374
|
-
this.fileFilter = _pluginutils.createFilter.call(void 0, include, exclude, {
|
|
375
|
-
resolve: false
|
|
376
|
-
});
|
|
377
|
-
try {
|
|
378
|
-
const pkg = lookupFile(this.cwd, ["package.json"]);
|
|
379
|
-
this.moduleType = !!pkg && JSON.parse(pkg).type === "module" ? "esm" : "cjs";
|
|
380
|
-
} catch (e3) {
|
|
381
|
-
}
|
|
382
|
-
this.entryFile = _path2.default.resolve(_process2.default.cwd(), "node_modules/.cache/mock-server/mock-server.ts");
|
|
383
|
-
this.outputFile = "mock.bundle.js";
|
|
384
|
-
}
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
__init() {this.moduleType = "cjs"}
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
__init2() {this._mockData = {}}
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
get mockData() {
|
|
394
|
-
return this._mockData;
|
|
395
|
-
}
|
|
396
|
-
async run() {
|
|
397
|
-
await this.updateMockEntry();
|
|
398
|
-
this.watchMockFiles();
|
|
399
|
-
this.createCompiler(async (err, stats) => {
|
|
400
|
-
const name = "[rspack:mock]";
|
|
401
|
-
if (err) {
|
|
402
|
-
const error = _optionalChain([stats, 'optionalAccess', _5 => _5.compilation, 'access', _6 => _6.getLogger, 'call', _7 => _7(name), 'access', _8 => _8.error]) || ((...args) => console.error(name, ...args));
|
|
403
|
-
error(err.stack || err);
|
|
404
|
-
if ("details" in err) {
|
|
405
|
-
error(err.details);
|
|
406
|
-
}
|
|
407
|
-
return;
|
|
408
|
-
}
|
|
409
|
-
if (_optionalChain([stats, 'optionalAccess', _9 => _9.hasErrors, 'call', _10 => _10()])) {
|
|
410
|
-
stats.compilation.getLogger(name).error(stats.toString({ colors: true }));
|
|
411
|
-
return;
|
|
412
|
-
}
|
|
413
|
-
const content = vfs.readFileSync(`/${this.outputFile}`, "utf-8");
|
|
414
|
-
try {
|
|
415
|
-
const result = await loadFromCode({
|
|
416
|
-
filepath: this.outputFile,
|
|
417
|
-
code: content,
|
|
418
|
-
isESM: this.moduleType === "esm",
|
|
419
|
-
cwd: this.cwd
|
|
420
|
-
});
|
|
421
|
-
this._mockData = transformMockData(transformRawData(result));
|
|
422
|
-
this.emit("update");
|
|
423
|
-
} catch (e) {
|
|
424
|
-
console.error("[rspack:mock-server]", e);
|
|
425
|
-
}
|
|
426
|
-
});
|
|
427
|
-
}
|
|
428
|
-
close() {
|
|
429
|
-
this.mockWatcher.close();
|
|
430
|
-
_optionalChain([this, 'access', _11 => _11.compiler, 'optionalAccess', _12 => _12.close, 'call', _13 => _13(() => {
|
|
431
|
-
})]);
|
|
432
|
-
this.emit("close");
|
|
433
|
-
}
|
|
434
|
-
updateAlias(alias) {
|
|
435
|
-
this.options.alias = {
|
|
436
|
-
...this.options.alias,
|
|
437
|
-
...alias
|
|
438
|
-
};
|
|
439
|
-
}
|
|
440
|
-
async updateMockEntry() {
|
|
441
|
-
const files = await this.getMockFiles();
|
|
442
|
-
await this.resolveEntryFile(files);
|
|
443
|
-
}
|
|
444
|
-
async getMockFiles() {
|
|
445
|
-
const { include } = this.options;
|
|
446
|
-
const files = await _fastglob2.default.call(void 0, include, { cwd: this.cwd });
|
|
447
|
-
return files.filter(this.fileFilter);
|
|
448
|
-
}
|
|
449
|
-
watchMockFiles() {
|
|
450
|
-
const { include } = this.options;
|
|
451
|
-
const [firstGlob, ...otherGlob] = include;
|
|
452
|
-
const watcher = this.mockWatcher = _chokidar2.default.watch(firstGlob, {
|
|
453
|
-
ignoreInitial: true,
|
|
454
|
-
cwd: this.cwd
|
|
455
|
-
});
|
|
456
|
-
if (otherGlob.length > 0)
|
|
457
|
-
otherGlob.forEach((glob) => watcher.add(glob));
|
|
458
|
-
watcher.on("add", () => {
|
|
459
|
-
this.updateMockEntry();
|
|
460
|
-
});
|
|
461
|
-
watcher.on("unlink", async () => {
|
|
462
|
-
this.updateMockEntry();
|
|
463
|
-
});
|
|
464
|
-
}
|
|
465
|
-
async resolveEntryFile(fileList) {
|
|
466
|
-
const importers = [];
|
|
467
|
-
const exporters = [];
|
|
468
|
-
for (const [index, filepath] of fileList.entries()) {
|
|
469
|
-
const file = normalizePath(_path2.default.join(this.cwd, filepath));
|
|
470
|
-
importers.push(`import * as m${index} from '${file}'`);
|
|
471
|
-
exporters.push(`[m${index}, '${filepath}']`);
|
|
472
|
-
}
|
|
473
|
-
const code = `${importers.join("\n")}
|
|
474
|
-
|
|
475
|
-
export default [
|
|
476
|
-
${exporters.join(",\n ")}
|
|
477
|
-
]`;
|
|
478
|
-
const dirname = _path2.default.dirname(this.entryFile);
|
|
479
|
-
if (!_fs2.default.existsSync(dirname)) {
|
|
480
|
-
await _fs.promises.mkdir(dirname, { recursive: true });
|
|
481
|
-
}
|
|
482
|
-
await _fs.promises.writeFile(this.entryFile, code, "utf8");
|
|
483
|
-
}
|
|
484
|
-
createCompiler(callback) {
|
|
485
|
-
const options = resolveRspackOptions({
|
|
486
|
-
isEsm: this.moduleType === "esm",
|
|
487
|
-
cwd: this.cwd,
|
|
488
|
-
plugins: this.options.plugins,
|
|
489
|
-
entryFile: this.entryFile,
|
|
490
|
-
outputFile: this.outputFile,
|
|
491
|
-
alias: this.options.alias,
|
|
492
|
-
watch: true
|
|
493
|
-
});
|
|
494
|
-
this.compiler = rspackCore.rspack(options, callback);
|
|
495
|
-
if (this.compiler)
|
|
496
|
-
this.compiler.outputFileSystem = vfs;
|
|
497
|
-
}
|
|
498
|
-
}, _class);
|
|
499
|
-
|
|
500
|
-
// src/core/baseMiddleware.ts
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
var _cookies = require('cookies'); var _cookies2 = _interopRequireDefault(_cookies);
|
|
511
|
-
var _httpstatus = require('http-status'); var _httpstatus2 = _interopRequireDefault(_httpstatus);
|
|
512
|
-
var _mimetypes = require('mime-types'); var mime = _interopRequireWildcard(_mimetypes);
|
|
513
|
-
|
|
514
|
-
var _picocolors = require('picocolors'); var _picocolors2 = _interopRequireDefault(_picocolors);
|
|
515
|
-
|
|
516
|
-
// src/core/matchingWeight.ts
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
var tokensCache = {};
|
|
526
|
-
function getTokens(rule) {
|
|
527
|
-
if (tokensCache[rule])
|
|
528
|
-
return tokensCache[rule];
|
|
529
|
-
const { tokens: tks } = _pathtoregexp.parse.call(void 0, rule);
|
|
530
|
-
const tokens = [];
|
|
531
|
-
for (const tk of tks) {
|
|
532
|
-
if (!_utils.isString.call(void 0, tk)) {
|
|
533
|
-
tokens.push(tk);
|
|
534
|
-
} else {
|
|
535
|
-
const hasPrefix = tk[0] === "/";
|
|
536
|
-
const subTks = hasPrefix ? tk.slice(1).split("/") : tk.split("/");
|
|
537
|
-
tokens.push(
|
|
538
|
-
`${hasPrefix ? "/" : ""}${subTks[0]}`,
|
|
539
|
-
...subTks.slice(1).map((t) => `/${t}`)
|
|
540
|
-
);
|
|
541
|
-
}
|
|
542
|
-
}
|
|
543
|
-
tokensCache[rule] = tokens;
|
|
544
|
-
return tokens;
|
|
545
|
-
}
|
|
546
|
-
function getHighest(rules) {
|
|
547
|
-
let weights = rules.map((rule) => getTokens(rule).length);
|
|
548
|
-
weights = weights.length === 0 ? [1] : weights;
|
|
549
|
-
return Math.max(...weights) + 2;
|
|
550
|
-
}
|
|
551
|
-
function sortFn(rule) {
|
|
552
|
-
const tokens = getTokens(rule);
|
|
553
|
-
let w = 0;
|
|
554
|
-
for (let i = 0; i < tokens.length; i++) {
|
|
555
|
-
const token = tokens[i];
|
|
556
|
-
if (!_utils.isString.call(void 0, token))
|
|
557
|
-
w += 10 ** (i + 1);
|
|
558
|
-
w += 10 ** (i + 1);
|
|
559
|
-
}
|
|
560
|
-
return w;
|
|
561
|
-
}
|
|
562
|
-
function preSort(rules) {
|
|
563
|
-
let matched = [];
|
|
564
|
-
const preMatch = [];
|
|
565
|
-
for (const rule of rules) {
|
|
566
|
-
const tokens = getTokens(rule);
|
|
567
|
-
const len = tokens.filter((token) => typeof token !== "string").length;
|
|
568
|
-
if (!preMatch[len])
|
|
569
|
-
preMatch[len] = [];
|
|
570
|
-
preMatch[len].push(rule);
|
|
571
|
-
}
|
|
572
|
-
for (const match2 of preMatch.filter((v) => v && v.length > 0))
|
|
573
|
-
matched = [...matched, ..._utils.sortBy.call(void 0, match2, sortFn).reverse()];
|
|
574
|
-
return matched;
|
|
575
|
-
}
|
|
576
|
-
function defaultPriority(rules) {
|
|
577
|
-
const highest = getHighest(rules);
|
|
578
|
-
return _utils.sortBy.call(void 0, rules, (rule) => {
|
|
579
|
-
const tokens = getTokens(rule);
|
|
580
|
-
const dym = tokens.filter((token) => typeof token !== "string");
|
|
581
|
-
if (dym.length === 0)
|
|
582
|
-
return 0;
|
|
583
|
-
let weight = dym.length;
|
|
584
|
-
let exp = 0;
|
|
585
|
-
for (let i = 0; i < tokens.length; i++) {
|
|
586
|
-
const token = tokens[i];
|
|
587
|
-
const isDynamic = !_utils.isString.call(void 0, token);
|
|
588
|
-
const {
|
|
589
|
-
pattern = "",
|
|
590
|
-
modifier,
|
|
591
|
-
prefix,
|
|
592
|
-
name
|
|
593
|
-
} = isDynamic ? token : {};
|
|
594
|
-
const isGlob = pattern && pattern.includes(".*");
|
|
595
|
-
const isSlash = prefix === "/";
|
|
596
|
-
const isNamed = _utils.isString.call(void 0, name);
|
|
597
|
-
exp += isDynamic && isSlash ? 1 : 0;
|
|
598
|
-
if (i === tokens.length - 1 && isGlob) {
|
|
599
|
-
weight += 5 * 10 ** (tokens.length === 1 ? highest + 1 : highest);
|
|
600
|
-
} else {
|
|
601
|
-
if (isGlob) {
|
|
602
|
-
weight += 3 * 10 ** (highest - 1);
|
|
603
|
-
} else if (pattern) {
|
|
604
|
-
if (isSlash) {
|
|
605
|
-
weight += (isNamed ? 2 : 1) * 10 ** (exp + 1);
|
|
606
|
-
} else {
|
|
607
|
-
weight -= 1 * 10 ** exp;
|
|
608
|
-
}
|
|
198
|
+
if (isGlob) {
|
|
199
|
+
weight += 3 * 10 ** (highest - 1);
|
|
200
|
+
} else if (pattern) {
|
|
201
|
+
if (isSlash) {
|
|
202
|
+
weight += (isNamed ? 2 : 1) * 10 ** (exp + 1);
|
|
203
|
+
} else {
|
|
204
|
+
weight -= 1 * 10 ** exp;
|
|
205
|
+
}
|
|
609
206
|
}
|
|
610
207
|
}
|
|
611
208
|
if (modifier === "+")
|
|
@@ -640,7 +237,7 @@ function matchingWeight(rules, url, priority) {
|
|
|
640
237
|
const options = special[specialRule];
|
|
641
238
|
const { rules: lowerRules, when } = _utils.isArray.call(void 0, options) ? { rules: options, when: [] } : options;
|
|
642
239
|
if (lowerRules.includes(matched[0])) {
|
|
643
|
-
if (when.length === 0 || when.some((
|
|
240
|
+
if (when.length === 0 || when.some((path6) => _pathtoregexp.pathToRegexp.call(void 0, path6).test(url))) {
|
|
644
241
|
matched = _utils.uniq.call(void 0, [specialRule, ...matched]);
|
|
645
242
|
}
|
|
646
243
|
}
|
|
@@ -666,7 +263,7 @@ async function parseReqBody(req, formidableOptions, bodyParserOptions = {}) {
|
|
|
666
263
|
const method = req.method.toUpperCase();
|
|
667
264
|
if (["GET", "DELETE", "HEAD"].includes(method))
|
|
668
265
|
return void 0;
|
|
669
|
-
const type = _optionalChain([req, 'access',
|
|
266
|
+
const type = _optionalChain([req, 'access', _5 => _5.headers, 'access', _6 => _6["content-type"], 'optionalAccess', _7 => _7.toLocaleLowerCase, 'call', _8 => _8()]) || "";
|
|
670
267
|
const { limit, formLimit, jsonLimit, textLimit, ...rest } = bodyParserOptions;
|
|
671
268
|
try {
|
|
672
269
|
if (type.startsWith("application/json")) {
|
|
@@ -707,6 +304,39 @@ async function parseMultipart(req, options) {
|
|
|
707
304
|
});
|
|
708
305
|
}
|
|
709
306
|
|
|
307
|
+
// src/core/validator.ts
|
|
308
|
+
|
|
309
|
+
function validate(request, validator) {
|
|
310
|
+
return isObjectSubset(request.headers, validator.headers) && isObjectSubset(request.body, validator.body) && isObjectSubset(request.params, validator.params) && isObjectSubset(request.query, validator.query) && isObjectSubset(request.refererQuery, validator.refererQuery);
|
|
311
|
+
}
|
|
312
|
+
function isObjectSubset(source, target) {
|
|
313
|
+
if (!target)
|
|
314
|
+
return true;
|
|
315
|
+
for (const key in target) {
|
|
316
|
+
if (!isIncluded(source[key], target[key]))
|
|
317
|
+
return false;
|
|
318
|
+
}
|
|
319
|
+
return true;
|
|
320
|
+
}
|
|
321
|
+
function isIncluded(source, target) {
|
|
322
|
+
if (_utils.isArray.call(void 0, source) && _utils.isArray.call(void 0, target)) {
|
|
323
|
+
const seen = /* @__PURE__ */ new Set();
|
|
324
|
+
return target.every(
|
|
325
|
+
(ti) => source.some((si, i) => {
|
|
326
|
+
if (seen.has(i))
|
|
327
|
+
return false;
|
|
328
|
+
const included = isIncluded(si, ti);
|
|
329
|
+
if (included)
|
|
330
|
+
seen.add(i);
|
|
331
|
+
return included;
|
|
332
|
+
})
|
|
333
|
+
);
|
|
334
|
+
}
|
|
335
|
+
if (_utils.isObject.call(void 0, source) && _utils.isObject.call(void 0, target))
|
|
336
|
+
return isObjectSubset(source, target);
|
|
337
|
+
return Object.is(source, target);
|
|
338
|
+
}
|
|
339
|
+
|
|
710
340
|
// src/core/baseMiddleware.ts
|
|
711
341
|
function baseMiddleware(compiler, {
|
|
712
342
|
formidableOptions = {},
|
|
@@ -970,6 +600,50 @@ function requestLog(request, filepath) {
|
|
|
970
600
|
return `${ms} ${pathname}${qs}${ps}${bs}${file}`;
|
|
971
601
|
}
|
|
972
602
|
|
|
603
|
+
// src/core/mockMiddleware.ts
|
|
604
|
+
var _cors = require('cors'); var _cors2 = _interopRequireDefault(_cors);
|
|
605
|
+
|
|
606
|
+
function createMockMiddleware(compiler, options) {
|
|
607
|
+
function mockMiddleware(middlewares, reload) {
|
|
608
|
+
middlewares.unshift(baseMiddleware(compiler, options));
|
|
609
|
+
const corsMiddleware = createCorsMiddleware(compiler, options);
|
|
610
|
+
if (corsMiddleware) {
|
|
611
|
+
middlewares.unshift(corsMiddleware);
|
|
612
|
+
}
|
|
613
|
+
if (options.reload) {
|
|
614
|
+
compiler.on("update", () => _optionalChain([reload, 'optionalCall', _9 => _9()]));
|
|
615
|
+
}
|
|
616
|
+
return middlewares;
|
|
617
|
+
}
|
|
618
|
+
return mockMiddleware;
|
|
619
|
+
}
|
|
620
|
+
function createCorsMiddleware(compiler, options) {
|
|
621
|
+
let corsOptions = {};
|
|
622
|
+
const enabled = options.cors !== false;
|
|
623
|
+
if (enabled) {
|
|
624
|
+
corsOptions = {
|
|
625
|
+
...corsOptions,
|
|
626
|
+
...typeof options.cors === "boolean" ? {} : options.cors
|
|
627
|
+
};
|
|
628
|
+
}
|
|
629
|
+
const proxies = options.proxies;
|
|
630
|
+
return !enabled ? void 0 : function(req, res, next) {
|
|
631
|
+
const { pathname } = urlParse(req.url);
|
|
632
|
+
if (!pathname || proxies.length === 0 || !proxies.some(
|
|
633
|
+
(context) => doesProxyContextMatchUrl(context, req.url, req)
|
|
634
|
+
)) {
|
|
635
|
+
return next();
|
|
636
|
+
}
|
|
637
|
+
const mockData = compiler.mockData;
|
|
638
|
+
const mockUrl = Object.keys(mockData).find(
|
|
639
|
+
(key) => _pathtoregexp.pathToRegexp.call(void 0, key).test(pathname)
|
|
640
|
+
);
|
|
641
|
+
if (!mockUrl)
|
|
642
|
+
return next();
|
|
643
|
+
_cors2.default.call(void 0, corsOptions)(req, res, next);
|
|
644
|
+
};
|
|
645
|
+
}
|
|
646
|
+
|
|
973
647
|
// src/core/logger.ts
|
|
974
648
|
|
|
975
649
|
|
|
@@ -994,96 +668,757 @@ function createLogger(prefix, defaultLevel = "info") {
|
|
|
994
668
|
console[method](format);
|
|
995
669
|
}
|
|
996
670
|
}
|
|
997
|
-
const logger = {
|
|
998
|
-
debug(msg, level = defaultLevel) {
|
|
999
|
-
output("debug", msg, level);
|
|
1000
|
-
},
|
|
1001
|
-
info(msg, level = defaultLevel) {
|
|
1002
|
-
output("info", msg, level);
|
|
1003
|
-
},
|
|
1004
|
-
warn(msg, level = defaultLevel) {
|
|
1005
|
-
output("warn", msg, level);
|
|
671
|
+
const logger = {
|
|
672
|
+
debug(msg, level = defaultLevel) {
|
|
673
|
+
output("debug", msg, level);
|
|
674
|
+
},
|
|
675
|
+
info(msg, level = defaultLevel) {
|
|
676
|
+
output("info", msg, level);
|
|
677
|
+
},
|
|
678
|
+
warn(msg, level = defaultLevel) {
|
|
679
|
+
output("warn", msg, level);
|
|
680
|
+
},
|
|
681
|
+
error(msg, level = defaultLevel) {
|
|
682
|
+
output("error", msg, level);
|
|
683
|
+
}
|
|
684
|
+
};
|
|
685
|
+
return logger;
|
|
686
|
+
}
|
|
687
|
+
|
|
688
|
+
// src/core/resolvePluginOptions.ts
|
|
689
|
+
var _process = require('process'); var _process2 = _interopRequireDefault(_process);
|
|
690
|
+
|
|
691
|
+
function resolvePluginOptions({
|
|
692
|
+
prefix = [],
|
|
693
|
+
wsPrefix = [],
|
|
694
|
+
cwd,
|
|
695
|
+
include = ["mock/**/*.mock.{js,ts,cjs,mjs,json,json5}"],
|
|
696
|
+
exclude = ["**/node_modules/**", "**/.vscode/**", "**/.git/**"],
|
|
697
|
+
reload = false,
|
|
698
|
+
log = "info",
|
|
699
|
+
cors: cors2 = true,
|
|
700
|
+
formidableOptions = {},
|
|
701
|
+
build = false,
|
|
702
|
+
cookiesOptions = {},
|
|
703
|
+
bodyParserOptions = {},
|
|
704
|
+
priority = {}
|
|
705
|
+
} = {}, { alias, context, plugins, proxies }) {
|
|
706
|
+
const logger = createLogger(
|
|
707
|
+
"rspack:mock",
|
|
708
|
+
_utils.isBoolean.call(void 0, log) ? log ? "info" : "error" : log
|
|
709
|
+
);
|
|
710
|
+
return {
|
|
711
|
+
prefix,
|
|
712
|
+
wsPrefix,
|
|
713
|
+
cwd: cwd || context || _process2.default.cwd(),
|
|
714
|
+
include,
|
|
715
|
+
exclude,
|
|
716
|
+
reload,
|
|
717
|
+
cors: cors2,
|
|
718
|
+
cookiesOptions,
|
|
719
|
+
log,
|
|
720
|
+
formidableOptions: {
|
|
721
|
+
multiples: true,
|
|
722
|
+
...formidableOptions
|
|
723
|
+
},
|
|
724
|
+
bodyParserOptions,
|
|
725
|
+
priority,
|
|
726
|
+
build: build ? Object.assign(
|
|
727
|
+
{
|
|
728
|
+
serverPort: 8080,
|
|
729
|
+
dist: "mockServer",
|
|
730
|
+
log: "error"
|
|
731
|
+
},
|
|
732
|
+
typeof build === "object" ? build : {}
|
|
733
|
+
) : false,
|
|
734
|
+
alias,
|
|
735
|
+
plugins,
|
|
736
|
+
proxies,
|
|
737
|
+
wsProxies: _utils.toArray.call(void 0, wsPrefix),
|
|
738
|
+
logger
|
|
739
|
+
};
|
|
740
|
+
}
|
|
741
|
+
|
|
742
|
+
// src/core/transform.ts
|
|
743
|
+
|
|
744
|
+
|
|
745
|
+
|
|
746
|
+
|
|
747
|
+
|
|
748
|
+
|
|
749
|
+
|
|
750
|
+
function transformRawData(rawData) {
|
|
751
|
+
return rawData.filter((item) => item[0]).map(([raw, __filepath__]) => {
|
|
752
|
+
let mockConfig;
|
|
753
|
+
if (raw.default) {
|
|
754
|
+
if (Array.isArray(raw.default)) {
|
|
755
|
+
mockConfig = raw.default.map((item) => ({ ...item, __filepath__ }));
|
|
756
|
+
} else {
|
|
757
|
+
mockConfig = { ...raw.default, __filepath__ };
|
|
758
|
+
}
|
|
759
|
+
} else if ("url" in raw) {
|
|
760
|
+
mockConfig = { ...raw, __filepath__ };
|
|
761
|
+
} else {
|
|
762
|
+
mockConfig = [];
|
|
763
|
+
Object.keys(raw || {}).forEach((key) => {
|
|
764
|
+
if (Array.isArray(raw[key])) {
|
|
765
|
+
mockConfig.push(...raw[key].map((item) => ({ ...item, __filepath__ })));
|
|
766
|
+
} else {
|
|
767
|
+
mockConfig.push({ ...raw[key], __filepath__ });
|
|
768
|
+
}
|
|
769
|
+
});
|
|
770
|
+
}
|
|
771
|
+
return mockConfig;
|
|
772
|
+
});
|
|
773
|
+
}
|
|
774
|
+
function transformMockData(mockList) {
|
|
775
|
+
const list = [];
|
|
776
|
+
for (const [, handle] of mockList.entries()) {
|
|
777
|
+
if (handle)
|
|
778
|
+
list.push(..._utils.toArray.call(void 0, handle));
|
|
779
|
+
}
|
|
780
|
+
const mocks = {};
|
|
781
|
+
list.filter((mock) => _utils.isObject.call(void 0, mock) && mock.enabled !== false && mock.url).forEach((mock) => {
|
|
782
|
+
const { pathname, query } = urlParse(mock.url);
|
|
783
|
+
const list2 = mocks[pathname] ??= [];
|
|
784
|
+
const current = { ...mock, url: pathname };
|
|
785
|
+
if (current.ws !== true) {
|
|
786
|
+
const validator = current.validator;
|
|
787
|
+
if (!_utils.isEmptyObject.call(void 0, query)) {
|
|
788
|
+
if (_utils.isFunction.call(void 0, validator)) {
|
|
789
|
+
current.validator = function(request) {
|
|
790
|
+
return isObjectSubset(request.query, query) && validator(request);
|
|
791
|
+
};
|
|
792
|
+
} else if (validator) {
|
|
793
|
+
current.validator = { ...validator };
|
|
794
|
+
current.validator.query = current.validator.query ? { ...query, ...current.validator.query } : query;
|
|
795
|
+
} else {
|
|
796
|
+
current.validator = { query };
|
|
797
|
+
}
|
|
798
|
+
}
|
|
799
|
+
}
|
|
800
|
+
list2.push(current);
|
|
801
|
+
});
|
|
802
|
+
Object.keys(mocks).forEach((key) => {
|
|
803
|
+
mocks[key] = sortByValidator(mocks[key]);
|
|
804
|
+
});
|
|
805
|
+
return mocks;
|
|
806
|
+
}
|
|
807
|
+
function sortByValidator(mocks) {
|
|
808
|
+
return _utils.sortBy.call(void 0, mocks, (item) => {
|
|
809
|
+
if (item.ws === true)
|
|
810
|
+
return 0;
|
|
811
|
+
const { validator } = item;
|
|
812
|
+
if (!validator || _utils.isEmptyObject.call(void 0, validator))
|
|
813
|
+
return 2;
|
|
814
|
+
if (_utils.isFunction.call(void 0, validator))
|
|
815
|
+
return 0;
|
|
816
|
+
const count = Object.keys(validator).reduce(
|
|
817
|
+
(prev, key) => prev + keysCount(validator[key]),
|
|
818
|
+
0
|
|
819
|
+
);
|
|
820
|
+
return 1 / count;
|
|
821
|
+
});
|
|
822
|
+
}
|
|
823
|
+
function keysCount(obj) {
|
|
824
|
+
if (!obj)
|
|
825
|
+
return 0;
|
|
826
|
+
return Object.keys(obj).length;
|
|
827
|
+
}
|
|
828
|
+
|
|
829
|
+
// src/core/build.ts
|
|
830
|
+
|
|
831
|
+
var _promises = require('fs/promises'); var _promises2 = _interopRequireDefault(_promises);
|
|
832
|
+
|
|
833
|
+
|
|
834
|
+
var _fastglob = require('fast-glob'); var _fastglob2 = _interopRequireDefault(_fastglob);
|
|
835
|
+
var _pluginutils = require('@rollup/pluginutils');
|
|
836
|
+
|
|
837
|
+
|
|
838
|
+
|
|
839
|
+
// src/core/createRspackCompiler.ts
|
|
840
|
+
|
|
841
|
+
var _core = require('@rspack/core'); var rspackCore = _interopRequireWildcard(_core);
|
|
842
|
+
|
|
843
|
+
var _iscoremodule = require('is-core-module'); var _iscoremodule2 = _interopRequireDefault(_iscoremodule);
|
|
844
|
+
function createCompiler(options, callback) {
|
|
845
|
+
const rspackOptions = resolveRspackOptions(options);
|
|
846
|
+
const isWatch = rspackOptions.watch === true;
|
|
847
|
+
async function handler(err, stats) {
|
|
848
|
+
const name = "[rspack:mock]";
|
|
849
|
+
const logError = _optionalChain([stats, 'optionalAccess', _10 => _10.compilation, 'access', _11 => _11.getLogger, 'call', _12 => _12(name), 'access', _13 => _13.error]) || ((...args) => console.error(_picocolors2.default.red(name), ...args));
|
|
850
|
+
if (err) {
|
|
851
|
+
logError(err.stack || err);
|
|
852
|
+
if ("details" in err) {
|
|
853
|
+
logError(err.details);
|
|
854
|
+
}
|
|
855
|
+
return;
|
|
856
|
+
}
|
|
857
|
+
if (_optionalChain([stats, 'optionalAccess', _14 => _14.hasErrors, 'call', _15 => _15()])) {
|
|
858
|
+
const info = stats.toJson();
|
|
859
|
+
logError(info.errors);
|
|
860
|
+
}
|
|
861
|
+
const code = vfs.readFileSync("/output.js", "utf-8");
|
|
862
|
+
const externals = [];
|
|
863
|
+
if (!isWatch) {
|
|
864
|
+
const modules = _optionalChain([stats, 'optionalAccess', _16 => _16.toJson, 'call', _17 => _17(), 'access', _18 => _18.modules]) || [];
|
|
865
|
+
const aliasList = Object.keys(options.alias || {}).map((key) => key.replace(/\$$/g, ""));
|
|
866
|
+
for (const { name: name2 } of modules) {
|
|
867
|
+
if (_optionalChain([name2, 'optionalAccess', _19 => _19.startsWith, 'call', _20 => _20("external")])) {
|
|
868
|
+
const packageName = normalizePackageName(name2);
|
|
869
|
+
if (!_iscoremodule2.default.call(void 0, packageName) && !aliasList.includes(packageName))
|
|
870
|
+
externals.push(normalizePackageName(name2));
|
|
871
|
+
}
|
|
872
|
+
}
|
|
873
|
+
}
|
|
874
|
+
await callback({ code, externals });
|
|
875
|
+
}
|
|
876
|
+
const compiler = rspackCore.rspack(rspackOptions, isWatch ? handler : void 0);
|
|
877
|
+
if (compiler)
|
|
878
|
+
compiler.outputFileSystem = vfs;
|
|
879
|
+
if (!isWatch) {
|
|
880
|
+
_optionalChain([compiler, 'optionalAccess', _21 => _21.run, 'call', _22 => _22(async (...args) => {
|
|
881
|
+
await handler(...args);
|
|
882
|
+
compiler.close(() => {
|
|
883
|
+
});
|
|
884
|
+
})]);
|
|
885
|
+
}
|
|
886
|
+
return compiler;
|
|
887
|
+
}
|
|
888
|
+
function transformWithRspack(options) {
|
|
889
|
+
return new Promise((resolve) => {
|
|
890
|
+
createCompiler({ ...options, watch: false }, (result) => {
|
|
891
|
+
resolve(result);
|
|
892
|
+
});
|
|
893
|
+
});
|
|
894
|
+
}
|
|
895
|
+
function normalizePackageName(name) {
|
|
896
|
+
const filepath = name.replace("external ", "").slice(1, -1);
|
|
897
|
+
const [scope, packageName] = filepath.split("/");
|
|
898
|
+
if (filepath[0] === "@") {
|
|
899
|
+
return `${scope}/${packageName}`;
|
|
900
|
+
}
|
|
901
|
+
return scope;
|
|
902
|
+
}
|
|
903
|
+
function resolveRspackOptions({
|
|
904
|
+
cwd,
|
|
905
|
+
isEsm = true,
|
|
906
|
+
entryFile,
|
|
907
|
+
plugins,
|
|
908
|
+
alias,
|
|
909
|
+
watch = false
|
|
910
|
+
}) {
|
|
911
|
+
const targets = ["node >= 18.0.0"];
|
|
912
|
+
return {
|
|
913
|
+
mode: "production",
|
|
914
|
+
context: cwd,
|
|
915
|
+
entry: entryFile,
|
|
916
|
+
watch,
|
|
917
|
+
target: "node18.0",
|
|
918
|
+
externalsType: isEsm ? "module" : "commonjs2",
|
|
919
|
+
externals: /^[^./].*/,
|
|
920
|
+
resolve: {
|
|
921
|
+
alias,
|
|
922
|
+
extensions: [".js", ".ts", ".cjs", ".mjs", ".json5", ".json"]
|
|
923
|
+
},
|
|
924
|
+
plugins,
|
|
925
|
+
output: {
|
|
926
|
+
library: { type: !isEsm ? "commonjs2" : "module" },
|
|
927
|
+
filename: "output.js",
|
|
928
|
+
path: "/"
|
|
929
|
+
},
|
|
930
|
+
experiments: { outputModule: isEsm },
|
|
931
|
+
optimization: { minimize: !watch },
|
|
932
|
+
module: {
|
|
933
|
+
rules: [
|
|
934
|
+
{
|
|
935
|
+
test: /\.json5?$/,
|
|
936
|
+
loader: _path2.default.join(packageDir, "json5-loader.cjs"),
|
|
937
|
+
type: "javascript/auto"
|
|
938
|
+
},
|
|
939
|
+
{
|
|
940
|
+
test: /\.[cm]?js$/,
|
|
941
|
+
use: [
|
|
942
|
+
{
|
|
943
|
+
loader: "builtin:swc-loader",
|
|
944
|
+
options: {
|
|
945
|
+
jsc: { parser: { syntax: "ecmascript" } },
|
|
946
|
+
env: { targets }
|
|
947
|
+
}
|
|
948
|
+
}
|
|
949
|
+
]
|
|
950
|
+
},
|
|
951
|
+
{
|
|
952
|
+
test: /\.[cm]?ts$/,
|
|
953
|
+
use: [
|
|
954
|
+
{
|
|
955
|
+
loader: "builtin:swc-loader",
|
|
956
|
+
options: {
|
|
957
|
+
jsc: { parser: { syntax: "typescript" } },
|
|
958
|
+
env: { targets }
|
|
959
|
+
}
|
|
960
|
+
}
|
|
961
|
+
]
|
|
962
|
+
}
|
|
963
|
+
]
|
|
964
|
+
}
|
|
965
|
+
};
|
|
966
|
+
}
|
|
967
|
+
|
|
968
|
+
// src/core/build.ts
|
|
969
|
+
async function buildMockServer(options, outputDir) {
|
|
970
|
+
const entryFile = _path2.default.resolve(_process2.default.cwd(), "node_modules/.cache/mock-server/mock-server.ts");
|
|
971
|
+
const mockFileList = await getMockFileList(options);
|
|
972
|
+
await writeMockEntryFile(entryFile, mockFileList, options.cwd);
|
|
973
|
+
const { code, externals } = await transformWithRspack({
|
|
974
|
+
entryFile,
|
|
975
|
+
cwd: options.cwd,
|
|
976
|
+
plugins: options.plugins,
|
|
977
|
+
alias: options.alias
|
|
978
|
+
});
|
|
979
|
+
await _promises2.default.unlink(entryFile);
|
|
980
|
+
const outputList = [
|
|
981
|
+
{ filename: "mock-data.js", source: code },
|
|
982
|
+
{ filename: "index.js", source: generatorServerEntryCode(options) },
|
|
983
|
+
{ filename: "package.json", source: generatePackageJson(options, externals) }
|
|
984
|
+
];
|
|
985
|
+
const dist = _path2.default.resolve(outputDir, options.build.dist);
|
|
986
|
+
options.logger.info(
|
|
987
|
+
`${_picocolors2.default.green("\u2713")} generate mock server in ${_picocolors2.default.cyan(_path2.default.relative(_process2.default.cwd(), dist))}`
|
|
988
|
+
);
|
|
989
|
+
if (!_fs2.default.existsSync(dist)) {
|
|
990
|
+
await _promises2.default.mkdir(dist, { recursive: true });
|
|
991
|
+
}
|
|
992
|
+
for (const { filename, source } of outputList) {
|
|
993
|
+
await _promises2.default.writeFile(_path2.default.join(dist, filename), source, "utf8");
|
|
994
|
+
const sourceSize = (source.length / 1024).toFixed(2);
|
|
995
|
+
const space = filename.length < 24 ? " ".repeat(24 - filename.length) : "";
|
|
996
|
+
options.logger.info(` ${_picocolors2.default.green(filename)}${space}${_picocolors2.default.bold(_picocolors2.default.dim(`${sourceSize} kB`))}`);
|
|
997
|
+
}
|
|
998
|
+
}
|
|
999
|
+
function generatePackageJson(options, externals) {
|
|
1000
|
+
const deps = getHostDependencies(options.cwd);
|
|
1001
|
+
const { name, version } = getPluginPackageInfo();
|
|
1002
|
+
const mockPkg = {
|
|
1003
|
+
name: "mock-server",
|
|
1004
|
+
type: "module",
|
|
1005
|
+
scripts: {
|
|
1006
|
+
start: "node index.js"
|
|
1006
1007
|
},
|
|
1007
|
-
|
|
1008
|
-
|
|
1008
|
+
dependencies: {
|
|
1009
|
+
connect: "^3.7.0",
|
|
1010
|
+
[name]: `^${version}`,
|
|
1011
|
+
cors: "^2.8.5"
|
|
1009
1012
|
}
|
|
1010
1013
|
};
|
|
1011
|
-
|
|
1014
|
+
externals.forEach((dep) => {
|
|
1015
|
+
mockPkg.dependencies[dep] = deps[dep] || "latest";
|
|
1016
|
+
});
|
|
1017
|
+
return JSON.stringify(mockPkg, null, 2);
|
|
1012
1018
|
}
|
|
1019
|
+
function generatorServerEntryCode({
|
|
1020
|
+
proxies,
|
|
1021
|
+
wsPrefix,
|
|
1022
|
+
cookiesOptions,
|
|
1023
|
+
bodyParserOptions,
|
|
1024
|
+
priority,
|
|
1025
|
+
build
|
|
1026
|
+
}) {
|
|
1027
|
+
const { serverPort, log } = build;
|
|
1028
|
+
return `import { createServer } from 'node:http';
|
|
1029
|
+
import connect from 'connect';
|
|
1030
|
+
import corsMiddleware from 'cors';
|
|
1031
|
+
import {
|
|
1032
|
+
baseMiddleware,
|
|
1033
|
+
createLogger,
|
|
1034
|
+
mockWebSocket,
|
|
1035
|
+
transformMockData,
|
|
1036
|
+
transformRawData
|
|
1037
|
+
} from 'rspack-plugin-mock';
|
|
1038
|
+
import rawData from './mock-data.js';
|
|
1013
1039
|
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
|
|
1017
|
-
|
|
1018
|
-
|
|
1019
|
-
|
|
1020
|
-
|
|
1021
|
-
|
|
1022
|
-
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
|
|
1029
|
-
|
|
1030
|
-
|
|
1031
|
-
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
|
|
1035
|
-
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
+
const app = connect();
|
|
1041
|
+
const server = createServer(app);
|
|
1042
|
+
const logger = createLogger('mock-server', '${log}');
|
|
1043
|
+
const proxies = ${JSON.stringify(proxies)};
|
|
1044
|
+
const wsProxies = ${JSON.stringify(_utils.toArray.call(void 0, wsPrefix))};
|
|
1045
|
+
const cookiesOptions = ${JSON.stringify(cookiesOptions)};
|
|
1046
|
+
const bodyParserOptions = ${JSON.stringify(bodyParserOptions)};
|
|
1047
|
+
const priority = ${JSON.stringify(priority)};
|
|
1048
|
+
const data = { mockData: transformMockData(transformRawData(rawData)) };
|
|
1049
|
+
|
|
1050
|
+
mockWebSocket(data, server, { wsProxies, cookiesOptions, logger });
|
|
1051
|
+
|
|
1052
|
+
app.use(corsMiddleware());
|
|
1053
|
+
app.use(baseMiddleware(data, {
|
|
1054
|
+
formidableOptions: { multiples: true },
|
|
1055
|
+
proxies,
|
|
1056
|
+
priority,
|
|
1057
|
+
cookiesOptions,
|
|
1058
|
+
bodyParserOptions,
|
|
1059
|
+
logger,
|
|
1060
|
+
}));
|
|
1061
|
+
|
|
1062
|
+
server.listen(${serverPort});
|
|
1063
|
+
|
|
1064
|
+
console.log('listen: http://localhost:${serverPort}');
|
|
1065
|
+
`;
|
|
1066
|
+
}
|
|
1067
|
+
async function getMockFileList({ cwd, include, exclude }) {
|
|
1068
|
+
const filter = _pluginutils.createFilter.call(void 0, include, exclude, { resolve: false });
|
|
1069
|
+
return await _fastglob2.default.call(void 0, include, { cwd }).then((files) => files.filter(filter));
|
|
1070
|
+
}
|
|
1071
|
+
async function writeMockEntryFile(entryFile, files, cwd) {
|
|
1072
|
+
const importers = [];
|
|
1073
|
+
const exporters = [];
|
|
1074
|
+
for (const [index, filepath] of files.entries()) {
|
|
1075
|
+
const file = normalizePath(_path2.default.join(cwd, filepath));
|
|
1076
|
+
importers.push(`import * as m${index} from '${file}'`);
|
|
1077
|
+
exporters.push(`[m${index}, '${filepath}']`);
|
|
1078
|
+
}
|
|
1079
|
+
const code = `${importers.join("\n")}
|
|
1080
|
+
|
|
1081
|
+
export default [
|
|
1082
|
+
${exporters.join(",\n ")}
|
|
1083
|
+
]`;
|
|
1084
|
+
const dirname = _path2.default.dirname(entryFile);
|
|
1085
|
+
if (!_fs2.default.existsSync(dirname)) {
|
|
1086
|
+
await _promises2.default.mkdir(dirname, { recursive: true });
|
|
1087
|
+
}
|
|
1088
|
+
await _promises2.default.writeFile(entryFile, code, "utf8");
|
|
1089
|
+
}
|
|
1090
|
+
function getPluginPackageInfo() {
|
|
1091
|
+
let pkg = {};
|
|
1092
|
+
try {
|
|
1093
|
+
const filepath = _path2.default.join(packageDir, "../package.json");
|
|
1094
|
+
if (_fs2.default.existsSync(filepath)) {
|
|
1095
|
+
pkg = JSON.parse(_fs2.default.readFileSync(filepath, "utf8"));
|
|
1040
1096
|
}
|
|
1041
|
-
|
|
1097
|
+
} catch (e2) {
|
|
1042
1098
|
}
|
|
1043
1099
|
return {
|
|
1044
|
-
|
|
1045
|
-
|
|
1046
|
-
close: () => compiler.close(),
|
|
1047
|
-
updateAlias: compiler.updateAlias.bind(compiler)
|
|
1100
|
+
name: pkg.name || "rspack-plugin-mock",
|
|
1101
|
+
version: pkg.version || "latest"
|
|
1048
1102
|
};
|
|
1049
1103
|
}
|
|
1050
|
-
function
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
|
|
1055
|
-
|
|
1056
|
-
|
|
1057
|
-
|
|
1104
|
+
function getHostDependencies(context) {
|
|
1105
|
+
let pkg = {};
|
|
1106
|
+
try {
|
|
1107
|
+
const content = lookupFile(context, ["package.json"]);
|
|
1108
|
+
if (content)
|
|
1109
|
+
pkg = JSON.parse(content);
|
|
1110
|
+
} catch (e3) {
|
|
1111
|
+
}
|
|
1112
|
+
return { ...pkg.dependencies, ...pkg.devDependencies };
|
|
1058
1113
|
}
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
|
|
1063
|
-
|
|
1064
|
-
|
|
1065
|
-
|
|
1114
|
+
|
|
1115
|
+
// src/core/mockCompiler.ts
|
|
1116
|
+
var _events = require('events'); var _events2 = _interopRequireDefault(_events);
|
|
1117
|
+
|
|
1118
|
+
|
|
1119
|
+
|
|
1120
|
+
var _chokidar = require('chokidar'); var _chokidar2 = _interopRequireDefault(_chokidar);
|
|
1121
|
+
|
|
1122
|
+
|
|
1123
|
+
|
|
1124
|
+
// src/core/loadFromCode.ts
|
|
1125
|
+
|
|
1126
|
+
|
|
1127
|
+
async function loadFromCode({
|
|
1128
|
+
filepath,
|
|
1129
|
+
code,
|
|
1130
|
+
isESM,
|
|
1131
|
+
cwd
|
|
1132
|
+
}) {
|
|
1133
|
+
filepath = _path2.default.resolve(cwd, filepath);
|
|
1134
|
+
const fileBase = `${filepath}.timestamp-${Date.now()}`;
|
|
1135
|
+
const ext = isESM ? ".mjs" : ".cjs";
|
|
1136
|
+
const fileNameTmp = `${fileBase}${ext}`;
|
|
1137
|
+
await _fs.promises.writeFile(fileNameTmp, code, "utf8");
|
|
1138
|
+
try {
|
|
1139
|
+
const result = await Promise.resolve().then(() => _interopRequireWildcard(require(fileNameTmp)));
|
|
1140
|
+
return result.default || result;
|
|
1141
|
+
} finally {
|
|
1142
|
+
try {
|
|
1143
|
+
_fs2.default.unlinkSync(fileNameTmp);
|
|
1144
|
+
} catch (e4) {
|
|
1145
|
+
}
|
|
1146
|
+
}
|
|
1147
|
+
}
|
|
1148
|
+
|
|
1149
|
+
// src/core/mockCompiler.ts
|
|
1150
|
+
function createMockCompiler(options) {
|
|
1151
|
+
return new MockCompiler(options);
|
|
1152
|
+
}
|
|
1153
|
+
var MockCompiler = (_class = class extends _events2.default {
|
|
1154
|
+
constructor(options) {
|
|
1155
|
+
super();_class.prototype.__init.call(this);_class.prototype.__init2.call(this);;
|
|
1156
|
+
this.options = options;
|
|
1157
|
+
this.cwd = options.cwd || _process2.default.cwd();
|
|
1158
|
+
const { include, exclude } = this.options;
|
|
1159
|
+
this.fileFilter = _pluginutils.createFilter.call(void 0, include, exclude, { resolve: false });
|
|
1160
|
+
try {
|
|
1161
|
+
const pkg = lookupFile(this.cwd, ["package.json"]);
|
|
1162
|
+
this.moduleType = !!pkg && JSON.parse(pkg).type === "module" ? "esm" : "cjs";
|
|
1163
|
+
} catch (e5) {
|
|
1164
|
+
}
|
|
1165
|
+
this.entryFile = _path2.default.resolve(_process2.default.cwd(), "node_modules/.cache/mock-server/mock-server.ts");
|
|
1166
|
+
}
|
|
1167
|
+
|
|
1168
|
+
|
|
1169
|
+
__init() {this.moduleType = "cjs"}
|
|
1170
|
+
|
|
1171
|
+
__init2() {this._mockData = {}}
|
|
1172
|
+
|
|
1173
|
+
|
|
1174
|
+
|
|
1175
|
+
get mockData() {
|
|
1176
|
+
return this._mockData;
|
|
1177
|
+
}
|
|
1178
|
+
async run() {
|
|
1179
|
+
await this.updateMockEntry();
|
|
1180
|
+
this.watchMockFiles();
|
|
1181
|
+
const { plugins, alias } = this.options;
|
|
1182
|
+
const options = {
|
|
1183
|
+
isEsm: this.moduleType === "esm",
|
|
1184
|
+
cwd: this.cwd,
|
|
1185
|
+
plugins,
|
|
1186
|
+
entryFile: this.entryFile,
|
|
1187
|
+
alias,
|
|
1188
|
+
watch: true
|
|
1066
1189
|
};
|
|
1190
|
+
this.compiler = createCompiler(options, async ({ code }) => {
|
|
1191
|
+
try {
|
|
1192
|
+
const result = await loadFromCode({
|
|
1193
|
+
filepath: "mock.bundle.js",
|
|
1194
|
+
code,
|
|
1195
|
+
isESM: this.moduleType === "esm",
|
|
1196
|
+
cwd: this.cwd
|
|
1197
|
+
});
|
|
1198
|
+
this._mockData = transformMockData(transformRawData(result));
|
|
1199
|
+
this.emit("update", this.watchInfo || {});
|
|
1200
|
+
} catch (e) {
|
|
1201
|
+
this.options.logger.error(e.stack || e.message);
|
|
1202
|
+
}
|
|
1203
|
+
});
|
|
1067
1204
|
}
|
|
1068
|
-
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
)
|
|
1073
|
-
|
|
1205
|
+
close() {
|
|
1206
|
+
this.mockWatcher.close();
|
|
1207
|
+
_optionalChain([this, 'access', _23 => _23.compiler, 'optionalAccess', _24 => _24.close, 'call', _25 => _25(() => {
|
|
1208
|
+
})]);
|
|
1209
|
+
this.emit("close");
|
|
1210
|
+
}
|
|
1211
|
+
updateAlias(alias) {
|
|
1212
|
+
this.options.alias = {
|
|
1213
|
+
...this.options.alias,
|
|
1214
|
+
...alias
|
|
1215
|
+
};
|
|
1216
|
+
}
|
|
1217
|
+
async updateMockEntry() {
|
|
1218
|
+
const files = await this.getMockFiles();
|
|
1219
|
+
await writeMockEntryFile(this.entryFile, files, this.cwd);
|
|
1220
|
+
}
|
|
1221
|
+
async getMockFiles() {
|
|
1222
|
+
const { include } = this.options;
|
|
1223
|
+
const files = await _fastglob2.default.call(void 0, include, { cwd: this.cwd });
|
|
1224
|
+
return files.filter(this.fileFilter);
|
|
1225
|
+
}
|
|
1226
|
+
watchMockFiles() {
|
|
1227
|
+
const { include } = this.options;
|
|
1228
|
+
const [firstGlob, ...otherGlob] = _utils.toArray.call(void 0, include);
|
|
1229
|
+
const watcher = this.mockWatcher = _chokidar2.default.watch(firstGlob, {
|
|
1230
|
+
ignoreInitial: true,
|
|
1231
|
+
cwd: this.cwd
|
|
1232
|
+
});
|
|
1233
|
+
if (otherGlob.length > 0)
|
|
1234
|
+
otherGlob.forEach((glob) => watcher.add(glob));
|
|
1235
|
+
watcher.on("add", (filepath) => {
|
|
1236
|
+
if (this.fileFilter(filepath)) {
|
|
1237
|
+
this.watchInfo = { filepath, type: "add" };
|
|
1238
|
+
this.updateMockEntry();
|
|
1239
|
+
}
|
|
1240
|
+
});
|
|
1241
|
+
watcher.on("change", (filepath) => {
|
|
1242
|
+
if (this.fileFilter(filepath)) {
|
|
1243
|
+
this.watchInfo = { filepath, type: "change" };
|
|
1244
|
+
}
|
|
1245
|
+
});
|
|
1246
|
+
watcher.on("unlink", async (filepath) => {
|
|
1247
|
+
this.watchInfo = { filepath, type: "unlink" };
|
|
1248
|
+
this.updateMockEntry();
|
|
1249
|
+
});
|
|
1250
|
+
}
|
|
1251
|
+
}, _class);
|
|
1252
|
+
|
|
1253
|
+
// src/core/mockWebsocket.ts
|
|
1254
|
+
|
|
1255
|
+
|
|
1256
|
+
|
|
1257
|
+
var _ws = require('ws');
|
|
1258
|
+
function mockWebSocket(compiler, httpServer, {
|
|
1259
|
+
wsProxies: proxies,
|
|
1260
|
+
cookiesOptions,
|
|
1261
|
+
logger
|
|
1262
|
+
}) {
|
|
1263
|
+
const hmrMap = /* @__PURE__ */ new Map();
|
|
1264
|
+
const poolMap = /* @__PURE__ */ new Map();
|
|
1265
|
+
const wssContextMap = /* @__PURE__ */ new WeakMap();
|
|
1266
|
+
const getWssMap = (mockUrl) => {
|
|
1267
|
+
let wssMap = poolMap.get(mockUrl);
|
|
1268
|
+
if (!wssMap)
|
|
1269
|
+
poolMap.set(mockUrl, wssMap = /* @__PURE__ */ new Map());
|
|
1270
|
+
return wssMap;
|
|
1271
|
+
};
|
|
1272
|
+
const getWss = (wssMap, pathname) => {
|
|
1273
|
+
let wss = wssMap.get(pathname);
|
|
1274
|
+
if (!wss)
|
|
1275
|
+
wssMap.set(pathname, wss = new (0, _ws.WebSocketServer)({ noServer: true }));
|
|
1276
|
+
return wss;
|
|
1277
|
+
};
|
|
1278
|
+
const addHmr = (filepath, mockUrl) => {
|
|
1279
|
+
let urlList = hmrMap.get(filepath);
|
|
1280
|
+
if (!urlList)
|
|
1281
|
+
hmrMap.set(filepath, urlList = /* @__PURE__ */ new Set());
|
|
1282
|
+
urlList.add(mockUrl);
|
|
1283
|
+
};
|
|
1284
|
+
const setupWss = (wssMap, wss, mock, context, pathname, filepath) => {
|
|
1285
|
+
try {
|
|
1286
|
+
_optionalChain([mock, 'access', _26 => _26.setup, 'optionalCall', _27 => _27(wss, context)]);
|
|
1287
|
+
wss.on("close", () => wssMap.delete(pathname));
|
|
1288
|
+
wss.on("error", (e) => {
|
|
1289
|
+
logger.error(
|
|
1290
|
+
`${_picocolors2.default.red(
|
|
1291
|
+
`WebSocket mock error at ${wss.path}`
|
|
1292
|
+
)}
|
|
1293
|
+
${e}
|
|
1294
|
+
at setup (${filepath})`,
|
|
1295
|
+
mock.log
|
|
1296
|
+
);
|
|
1297
|
+
});
|
|
1298
|
+
} catch (e) {
|
|
1299
|
+
logger.error(
|
|
1300
|
+
`${_picocolors2.default.red(
|
|
1301
|
+
`WebSocket mock error at ${wss.path}`
|
|
1302
|
+
)}
|
|
1303
|
+
${e}
|
|
1304
|
+
at setup (${filepath})`,
|
|
1305
|
+
mock.log
|
|
1306
|
+
);
|
|
1074
1307
|
}
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
|
|
1308
|
+
};
|
|
1309
|
+
const emitConnection = (wss, ws, req, connectionList) => {
|
|
1310
|
+
wss.emit("connection", ws, req);
|
|
1311
|
+
ws.on("close", () => {
|
|
1312
|
+
const i = connectionList.findIndex((item) => item.ws === ws);
|
|
1313
|
+
if (i !== -1)
|
|
1314
|
+
connectionList.splice(i, 1);
|
|
1315
|
+
});
|
|
1316
|
+
};
|
|
1317
|
+
const restartWss = (wssMap, wss, mock, pathname, filepath) => {
|
|
1318
|
+
const { cleanupList, connectionList, context } = wssContextMap.get(wss);
|
|
1319
|
+
cleanupRunner(cleanupList);
|
|
1320
|
+
connectionList.forEach(({ ws }) => ws.removeAllListeners());
|
|
1321
|
+
wss.removeAllListeners();
|
|
1322
|
+
setupWss(wssMap, wss, mock, context, pathname, filepath);
|
|
1323
|
+
connectionList.forEach(
|
|
1324
|
+
({ ws, req }) => emitConnection(wss, ws, req, connectionList)
|
|
1078
1325
|
);
|
|
1079
|
-
if (!mockUrl)
|
|
1080
|
-
return next();
|
|
1081
|
-
_cors2.default.call(void 0, corsOptions)(req, res, next);
|
|
1082
1326
|
};
|
|
1327
|
+
compiler.on("update", ({ filepath }) => {
|
|
1328
|
+
if (!hmrMap.has(filepath))
|
|
1329
|
+
return;
|
|
1330
|
+
const mockUrlList = hmrMap.get(filepath);
|
|
1331
|
+
if (!mockUrlList)
|
|
1332
|
+
return;
|
|
1333
|
+
for (const mockUrl of mockUrlList.values()) {
|
|
1334
|
+
for (const mock of compiler.mockData[mockUrl]) {
|
|
1335
|
+
if (!mock.ws || mock.__filepath__ !== filepath)
|
|
1336
|
+
return;
|
|
1337
|
+
const wssMap = getWssMap(mockUrl);
|
|
1338
|
+
for (const [pathname, wss] of wssMap.entries())
|
|
1339
|
+
restartWss(wssMap, wss, mock, pathname, filepath);
|
|
1340
|
+
}
|
|
1341
|
+
}
|
|
1342
|
+
});
|
|
1343
|
+
_optionalChain([httpServer, 'optionalAccess', _28 => _28.on, 'call', _29 => _29("upgrade", (req, socket, head) => {
|
|
1344
|
+
const { pathname, query } = urlParse(req.url);
|
|
1345
|
+
if (!pathname || proxies.length === 0 || !proxies.some((context) => doesProxyContextMatchUrl(context, req.url, req))) {
|
|
1346
|
+
return;
|
|
1347
|
+
}
|
|
1348
|
+
const mockData = compiler.mockData;
|
|
1349
|
+
const mockUrl = Object.keys(mockData).find((key) => {
|
|
1350
|
+
return _pathtoregexp.pathToRegexp.call(void 0, key).test(pathname);
|
|
1351
|
+
});
|
|
1352
|
+
if (!mockUrl)
|
|
1353
|
+
return;
|
|
1354
|
+
const mock = mockData[mockUrl].find((mock2) => {
|
|
1355
|
+
return mock2.url && mock2.ws && _pathtoregexp.pathToRegexp.call(void 0, mock2.url).test(pathname);
|
|
1356
|
+
});
|
|
1357
|
+
if (!mock)
|
|
1358
|
+
return;
|
|
1359
|
+
const filepath = mock.__filepath__;
|
|
1360
|
+
addHmr(filepath, mockUrl);
|
|
1361
|
+
const wssMap = getWssMap(mockUrl);
|
|
1362
|
+
const wss = getWss(wssMap, pathname);
|
|
1363
|
+
let wssContext = wssContextMap.get(wss);
|
|
1364
|
+
if (!wssContext) {
|
|
1365
|
+
const cleanupList = [];
|
|
1366
|
+
const context = {
|
|
1367
|
+
onCleanup: (cleanup) => cleanupList.push(cleanup)
|
|
1368
|
+
};
|
|
1369
|
+
wssContext = { cleanupList, context, connectionList: [] };
|
|
1370
|
+
wssContextMap.set(wss, wssContext);
|
|
1371
|
+
setupWss(wssMap, wss, mock, context, pathname, filepath);
|
|
1372
|
+
}
|
|
1373
|
+
const request = req;
|
|
1374
|
+
const cookies = new (0, _cookies2.default)(req, req, cookiesOptions);
|
|
1375
|
+
const { query: refererQuery } = urlParse(req.headers.referer || "");
|
|
1376
|
+
request.query = query;
|
|
1377
|
+
request.refererQuery = refererQuery;
|
|
1378
|
+
request.params = parseParams(mockUrl, pathname);
|
|
1379
|
+
request.getCookie = cookies.get.bind(cookies);
|
|
1380
|
+
wss.handleUpgrade(request, socket, head, (ws) => {
|
|
1381
|
+
logger.info(
|
|
1382
|
+
`${_picocolors2.default.magenta(_picocolors2.default.bold("WebSocket"))} ${_picocolors2.default.green(
|
|
1383
|
+
req.url
|
|
1384
|
+
)} connected ${_picocolors2.default.dim(`(${filepath})`)}`,
|
|
1385
|
+
mock.log
|
|
1386
|
+
);
|
|
1387
|
+
wssContext.connectionList.push({ req: request, ws });
|
|
1388
|
+
emitConnection(wss, ws, request, wssContext.connectionList);
|
|
1389
|
+
});
|
|
1390
|
+
})]);
|
|
1391
|
+
_optionalChain([httpServer, 'optionalAccess', _30 => _30.on, 'call', _31 => _31("close", () => {
|
|
1392
|
+
for (const wssMap of poolMap.values()) {
|
|
1393
|
+
for (const wss of wssMap.values()) {
|
|
1394
|
+
const wssContext = wssContextMap.get(wss);
|
|
1395
|
+
cleanupRunner(wssContext.cleanupList);
|
|
1396
|
+
wss.close();
|
|
1397
|
+
}
|
|
1398
|
+
wssMap.clear();
|
|
1399
|
+
}
|
|
1400
|
+
poolMap.clear();
|
|
1401
|
+
hmrMap.clear();
|
|
1402
|
+
})]);
|
|
1403
|
+
}
|
|
1404
|
+
function cleanupRunner(cleanupList) {
|
|
1405
|
+
let cleanup;
|
|
1406
|
+
while (cleanup = cleanupList.shift())
|
|
1407
|
+
_optionalChain([cleanup, 'optionalCall', _32 => _32()]);
|
|
1083
1408
|
}
|
|
1084
1409
|
|
|
1085
1410
|
|
|
1086
1411
|
|
|
1087
1412
|
|
|
1088
1413
|
|
|
1089
|
-
|
|
1414
|
+
|
|
1415
|
+
|
|
1416
|
+
|
|
1417
|
+
|
|
1418
|
+
|
|
1419
|
+
|
|
1420
|
+
|
|
1421
|
+
|
|
1422
|
+
|
|
1423
|
+
|
|
1424
|
+
exports.waitingFor = waitingFor; exports.rewriteRequest = rewriteRequest; exports.baseMiddleware = baseMiddleware; exports.createMockMiddleware = createMockMiddleware; exports.logLevels = logLevels; exports.createLogger = createLogger; exports.resolvePluginOptions = resolvePluginOptions; exports.transformRawData = transformRawData; exports.transformMockData = transformMockData; exports.sortByValidator = sortByValidator; exports.buildMockServer = buildMockServer; exports.createMockCompiler = createMockCompiler; exports.mockWebSocket = mockWebSocket;
|