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