vite-plugin-mock-dev-server 0.3.16 → 0.3.18
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 +47 -1
- package/README.zh-CN.md +42 -1
- package/dist/index.cjs +473 -213
- package/dist/index.d.ts +68 -2
- package/dist/index.js +469 -210
- package/package.json +4 -1
package/dist/index.cjs
CHANGED
|
@@ -6,8 +6,8 @@ var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
|
6
6
|
var __getProtoOf = Object.getPrototypeOf;
|
|
7
7
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
8
|
var __export = (target, all) => {
|
|
9
|
-
for (var
|
|
10
|
-
__defProp(target,
|
|
9
|
+
for (var name2 in all)
|
|
10
|
+
__defProp(target, name2, { get: all[name2], enumerable: true });
|
|
11
11
|
};
|
|
12
12
|
var __copyProps = (to, from, except, desc) => {
|
|
13
13
|
if (from && typeof from === "object" || typeof from === "function") {
|
|
@@ -26,31 +26,70 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
26
26
|
// src/index.ts
|
|
27
27
|
var src_exports = {};
|
|
28
28
|
__export(src_exports, {
|
|
29
|
+
baseMiddleware: () => baseMiddleware,
|
|
29
30
|
default: () => src_default,
|
|
30
31
|
defineMock: () => defineMock,
|
|
31
32
|
mockDevServerPlugin: () => mockDevServerPlugin
|
|
32
33
|
});
|
|
33
34
|
module.exports = __toCommonJS(src_exports);
|
|
34
35
|
|
|
35
|
-
// src/
|
|
36
|
-
var import_node_url3 = require("url");
|
|
37
|
-
var import_path_to_regexp = require("path-to-regexp");
|
|
38
|
-
|
|
39
|
-
// src/MockLoader.ts
|
|
40
|
-
var import_node_events = __toESM(require("events"), 1);
|
|
36
|
+
// src/build.ts
|
|
41
37
|
var import_node_fs2 = __toESM(require("fs"), 1);
|
|
42
|
-
var
|
|
43
|
-
var
|
|
44
|
-
var import_node_url2 = require("url");
|
|
45
|
-
var import_chokidar = __toESM(require("chokidar"), 1);
|
|
38
|
+
var import_promises2 = __toESM(require("fs/promises"), 1);
|
|
39
|
+
var import_node_path3 = __toESM(require("path"), 1);
|
|
46
40
|
var import_esbuild = require("esbuild");
|
|
47
41
|
var import_fast_glob = __toESM(require("fast-glob"), 1);
|
|
48
|
-
var
|
|
42
|
+
var import_is_core_module = __toESM(require("is-core-module"), 1);
|
|
49
43
|
var import_vite = require("vite");
|
|
50
44
|
|
|
45
|
+
// package.json
|
|
46
|
+
var name = "vite-plugin-mock-dev-server";
|
|
47
|
+
var version = "0.3.18";
|
|
48
|
+
|
|
49
|
+
// src/esbuildPlugin.ts
|
|
50
|
+
var import_promises = __toESM(require("fs/promises"), 1);
|
|
51
|
+
var import_node_path = __toESM(require("path"), 1);
|
|
52
|
+
var import_json5 = __toESM(require("json5"), 1);
|
|
53
|
+
var externalizeDeps = {
|
|
54
|
+
name: "externalize-deps",
|
|
55
|
+
setup(build3) {
|
|
56
|
+
build3.onResolve({ filter: /.*/ }, ({ path: id }) => {
|
|
57
|
+
if (id[0] !== "." && !import_node_path.default.isAbsolute(id)) {
|
|
58
|
+
return {
|
|
59
|
+
external: true
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
};
|
|
65
|
+
var json5Loader = {
|
|
66
|
+
name: "json5-loader",
|
|
67
|
+
setup(build3) {
|
|
68
|
+
build3.onLoad({ filter: /\.json5$/ }, async ({ path: path5 }) => {
|
|
69
|
+
const content = await import_promises.default.readFile(path5, "utf-8");
|
|
70
|
+
return {
|
|
71
|
+
contents: `export default ${JSON.stringify(import_json5.default.parse(content))}`,
|
|
72
|
+
loader: "js"
|
|
73
|
+
};
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
};
|
|
77
|
+
var jsonLoader = {
|
|
78
|
+
name: "json-loader",
|
|
79
|
+
setup(build3) {
|
|
80
|
+
build3.onLoad({ filter: /\.json$/ }, async ({ path: path5 }) => {
|
|
81
|
+
const content = await import_promises.default.readFile(path5, "utf-8");
|
|
82
|
+
return {
|
|
83
|
+
contents: `export default ${content}`,
|
|
84
|
+
loader: "js"
|
|
85
|
+
};
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
};
|
|
89
|
+
|
|
51
90
|
// src/utils.ts
|
|
52
91
|
var import_node_fs = __toESM(require("fs"), 1);
|
|
53
|
-
var
|
|
92
|
+
var import_node_path2 = __toESM(require("path"), 1);
|
|
54
93
|
var import_node_url = require("url");
|
|
55
94
|
var import_debug = __toESM(require("debug"), 1);
|
|
56
95
|
var isArray = (val) => Array.isArray(val);
|
|
@@ -59,12 +98,12 @@ function sleep(timeout) {
|
|
|
59
98
|
return new Promise((resolve) => setTimeout(resolve, timeout));
|
|
60
99
|
}
|
|
61
100
|
function getDirname(importMetaUrl) {
|
|
62
|
-
return
|
|
101
|
+
return import_node_path2.default.dirname((0, import_node_url.fileURLToPath)(importMetaUrl));
|
|
63
102
|
}
|
|
64
103
|
var debug = (0, import_debug.default)("vite:plugin-mock-dev-server");
|
|
65
104
|
function lookupFile(dir, formats, options) {
|
|
66
105
|
for (const format of formats) {
|
|
67
|
-
const fullPath =
|
|
106
|
+
const fullPath = import_node_path2.default.join(dir, format);
|
|
68
107
|
if (import_node_fs.default.existsSync(fullPath) && import_node_fs.default.statSync(fullPath).isFile()) {
|
|
69
108
|
const result = (options == null ? void 0 : options.pathOnly) ? fullPath : import_node_fs.default.readFileSync(fullPath, "utf-8");
|
|
70
109
|
if (!(options == null ? void 0 : options.predicate) || options.predicate(result)) {
|
|
@@ -72,13 +111,355 @@ function lookupFile(dir, formats, options) {
|
|
|
72
111
|
}
|
|
73
112
|
}
|
|
74
113
|
}
|
|
75
|
-
const parentDir =
|
|
114
|
+
const parentDir = import_node_path2.default.dirname(dir);
|
|
76
115
|
if (parentDir !== dir && (!(options == null ? void 0 : options.rootDir) || parentDir.startsWith(options == null ? void 0 : options.rootDir))) {
|
|
77
116
|
return lookupFile(parentDir, formats, options);
|
|
78
117
|
}
|
|
79
118
|
}
|
|
80
119
|
|
|
120
|
+
// src/build.ts
|
|
121
|
+
async function generateMockServer(ctx, config, options) {
|
|
122
|
+
const include = isArray(options.include) ? options.include : [options.include];
|
|
123
|
+
const exclude = isArray(options.exclude) ? options.exclude : [options.exclude];
|
|
124
|
+
const define = {};
|
|
125
|
+
if (config.define) {
|
|
126
|
+
for (const key in config.define) {
|
|
127
|
+
const val = config.define[key];
|
|
128
|
+
define[key] = typeof val === "string" ? val : JSON.stringify(val);
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
let pkg = {};
|
|
132
|
+
try {
|
|
133
|
+
const pkgStr = lookupFile(config.root, ["package.json"]);
|
|
134
|
+
if (pkgStr) {
|
|
135
|
+
pkg = JSON.parse(pkgStr);
|
|
136
|
+
}
|
|
137
|
+
} catch {
|
|
138
|
+
}
|
|
139
|
+
const outputDir = options.build.dist;
|
|
140
|
+
const content = await generateMockEntryCode(process.cwd(), include, exclude);
|
|
141
|
+
const mockEntry = import_node_path3.default.join(config.root, `mock-data-${Date.now()}.js`);
|
|
142
|
+
await import_promises2.default.writeFile(mockEntry, content, "utf-8");
|
|
143
|
+
const { code, deps } = await buildMockEntry(mockEntry, define);
|
|
144
|
+
const mockDeps = getMockDependencies(deps);
|
|
145
|
+
await import_promises2.default.unlink(mockEntry);
|
|
146
|
+
const outputList = [
|
|
147
|
+
{
|
|
148
|
+
filename: import_node_path3.default.join(outputDir, "mock-data.js"),
|
|
149
|
+
source: code
|
|
150
|
+
},
|
|
151
|
+
{
|
|
152
|
+
filename: import_node_path3.default.join(outputDir, "index.js"),
|
|
153
|
+
source: generatorServerEntryCode(
|
|
154
|
+
config.server.proxy || {},
|
|
155
|
+
options.build.serverPort
|
|
156
|
+
)
|
|
157
|
+
},
|
|
158
|
+
{
|
|
159
|
+
filename: import_node_path3.default.join(outputDir, "package.json"),
|
|
160
|
+
source: generatePackageJson(pkg, mockDeps)
|
|
161
|
+
}
|
|
162
|
+
];
|
|
163
|
+
try {
|
|
164
|
+
if (import_node_path3.default.isAbsolute(outputDir)) {
|
|
165
|
+
await import_promises2.default.rm(outputDir, { recursive: true });
|
|
166
|
+
import_node_fs2.default.mkdirSync(outputDir, { recursive: true });
|
|
167
|
+
for (const { filename, source } of outputList) {
|
|
168
|
+
await import_promises2.default.writeFile(filename, source, "utf-8");
|
|
169
|
+
}
|
|
170
|
+
} else {
|
|
171
|
+
for (const { filename, source } of outputList) {
|
|
172
|
+
ctx.emitFile({
|
|
173
|
+
type: "asset",
|
|
174
|
+
fileName: filename,
|
|
175
|
+
source
|
|
176
|
+
});
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
} catch {
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
function getMockDependencies(deps) {
|
|
183
|
+
const list = /* @__PURE__ */ new Set();
|
|
184
|
+
const excludeDeps = [name, "connect"];
|
|
185
|
+
Object.keys(deps).forEach((mPath) => {
|
|
186
|
+
const imports = deps[mPath].imports.filter((_) => _.external).map((_) => _.path);
|
|
187
|
+
imports.forEach((dep) => {
|
|
188
|
+
if (!excludeDeps.includes(dep) && !(0, import_is_core_module.default)(dep)) {
|
|
189
|
+
list.add(dep);
|
|
190
|
+
}
|
|
191
|
+
});
|
|
192
|
+
});
|
|
193
|
+
return Array.from(list);
|
|
194
|
+
}
|
|
195
|
+
function generatePackageJson(pkg, mockDeps) {
|
|
196
|
+
const { dependencies = {}, devDependencies = {} } = pkg;
|
|
197
|
+
const dependents = { ...dependencies, ...devDependencies };
|
|
198
|
+
const mockPkg = {
|
|
199
|
+
name: "mock-server",
|
|
200
|
+
type: "module",
|
|
201
|
+
scripts: {
|
|
202
|
+
start: "node index.js"
|
|
203
|
+
},
|
|
204
|
+
dependencies: {
|
|
205
|
+
"connect": "^3.7.0",
|
|
206
|
+
"vite-plugin-mock-dev-server": `^${version}`
|
|
207
|
+
}
|
|
208
|
+
};
|
|
209
|
+
mockDeps.forEach((dep) => {
|
|
210
|
+
mockPkg.dependencies[dep] = dependents[dep] || "latest";
|
|
211
|
+
});
|
|
212
|
+
return JSON.stringify(mockPkg, null, 2);
|
|
213
|
+
}
|
|
214
|
+
function generatorServerEntryCode(proxy = {}, port = 8080) {
|
|
215
|
+
const proxies = Object.keys(proxy || {});
|
|
216
|
+
return `import connect from 'connect'
|
|
217
|
+
import { baseMiddleware } from 'vite-plugin-mock-dev-server'
|
|
218
|
+
import mockData from './mock-data.js'
|
|
219
|
+
const app = connect()
|
|
220
|
+
app.use(baseMiddleware(mockData, {
|
|
221
|
+
formidableOptions: { multiples: true },
|
|
222
|
+
proxies: ${JSON.stringify(proxies)}
|
|
223
|
+
}))
|
|
224
|
+
app.listen(${port})
|
|
225
|
+
console.log('listen: http://localhost:${port}')
|
|
226
|
+
`;
|
|
227
|
+
}
|
|
228
|
+
async function generateMockEntryCode(cwd, include, exclude) {
|
|
229
|
+
const includePaths = await (0, import_fast_glob.default)(include, { cwd });
|
|
230
|
+
const includeFilter = (0, import_vite.createFilter)(include, exclude, {
|
|
231
|
+
resolve: false
|
|
232
|
+
});
|
|
233
|
+
const mockFiles = includePaths.filter(includeFilter);
|
|
234
|
+
let importers = "";
|
|
235
|
+
let exporters = "";
|
|
236
|
+
mockFiles.forEach((filepath, index) => {
|
|
237
|
+
const file = import_node_path3.default.join(cwd, filepath);
|
|
238
|
+
importers += `import * as m${index} from '${file}'
|
|
239
|
+
`;
|
|
240
|
+
exporters += `m${index}, `;
|
|
241
|
+
});
|
|
242
|
+
return `${importers}const mockData = [${exporters}];
|
|
243
|
+
|
|
244
|
+
const data = [];
|
|
245
|
+
const mocks = {};
|
|
246
|
+
mockData.forEach(mock => {
|
|
247
|
+
Object.keys(mock).forEach(key => {
|
|
248
|
+
const mockData = mock[key];
|
|
249
|
+
if (Array.isArray(mockData)) {
|
|
250
|
+
data.push(...mockData);
|
|
251
|
+
} else {
|
|
252
|
+
if (typeof mockData === 'object' && Object.prototype.hasOwnProperty.call(mockData, 'url')) {
|
|
253
|
+
data.push(mockData);
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
})
|
|
257
|
+
})
|
|
258
|
+
data
|
|
259
|
+
.filter((mock) => mock.enabled || typeof mock.enabled === "undefined")
|
|
260
|
+
.forEach((mock) => {
|
|
261
|
+
if (!mocks[mock.url]) {
|
|
262
|
+
mocks[mock.url] = [];
|
|
263
|
+
}
|
|
264
|
+
const list = mocks[mock.url];
|
|
265
|
+
mock.validator ? list.unshift(mock) : list.push(mock);
|
|
266
|
+
});
|
|
267
|
+
export default mocks;
|
|
268
|
+
`;
|
|
269
|
+
}
|
|
270
|
+
async function buildMockEntry(inputFile, define) {
|
|
271
|
+
var _a;
|
|
272
|
+
try {
|
|
273
|
+
const result = await (0, import_esbuild.build)({
|
|
274
|
+
entryPoints: [inputFile],
|
|
275
|
+
outfile: "out.js",
|
|
276
|
+
write: false,
|
|
277
|
+
target: ["node14.18", "node16"],
|
|
278
|
+
platform: "node",
|
|
279
|
+
bundle: true,
|
|
280
|
+
metafile: true,
|
|
281
|
+
format: "esm",
|
|
282
|
+
define,
|
|
283
|
+
plugins: [externalizeDeps, json5Loader, jsonLoader]
|
|
284
|
+
});
|
|
285
|
+
return {
|
|
286
|
+
code: result.outputFiles[0].text,
|
|
287
|
+
deps: ((_a = result.metafile) == null ? void 0 : _a.inputs) || {}
|
|
288
|
+
};
|
|
289
|
+
} catch (e) {
|
|
290
|
+
console.error(e);
|
|
291
|
+
}
|
|
292
|
+
return { code: "", deps: {} };
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
// src/baseMiddleware.ts
|
|
296
|
+
var import_node_url2 = require("url");
|
|
297
|
+
var import_path_to_regexp = require("path-to-regexp");
|
|
298
|
+
|
|
299
|
+
// src/parseReqBody.ts
|
|
300
|
+
var import_co_body = __toESM(require("co-body"), 1);
|
|
301
|
+
var import_formidable = __toESM(require("formidable"), 1);
|
|
302
|
+
async function parseReqBody(req, options) {
|
|
303
|
+
const method = req.method.toUpperCase();
|
|
304
|
+
if (["GET", "DELETE", "HEAD"].includes(method))
|
|
305
|
+
return void 0;
|
|
306
|
+
const type = req.headers["content-type"];
|
|
307
|
+
try {
|
|
308
|
+
if (type === "application/json") {
|
|
309
|
+
return await import_co_body.default.json(req);
|
|
310
|
+
}
|
|
311
|
+
if (type === "application/x-www-form-urlencoded") {
|
|
312
|
+
return await import_co_body.default.form(req);
|
|
313
|
+
}
|
|
314
|
+
if (type === "text/plain") {
|
|
315
|
+
return await import_co_body.default.text(req);
|
|
316
|
+
}
|
|
317
|
+
if (type == null ? void 0 : type.startsWith("multipart/form-data;")) {
|
|
318
|
+
return await parseMultipart(req, options);
|
|
319
|
+
}
|
|
320
|
+
} catch (e) {
|
|
321
|
+
console.error(e);
|
|
322
|
+
}
|
|
323
|
+
return void 0;
|
|
324
|
+
}
|
|
325
|
+
async function parseMultipart(req, options) {
|
|
326
|
+
const form = (0, import_formidable.default)(options);
|
|
327
|
+
return new Promise((resolve, reject) => {
|
|
328
|
+
form.parse(req, (error, fields, files) => {
|
|
329
|
+
if (error) {
|
|
330
|
+
reject(error);
|
|
331
|
+
return;
|
|
332
|
+
}
|
|
333
|
+
resolve({ ...fields, ...files });
|
|
334
|
+
});
|
|
335
|
+
});
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
// src/validator.ts
|
|
339
|
+
function validate(request, validator) {
|
|
340
|
+
return equalObj(request.headers, validator.headers) && equalObj(request.body, validator.body) && equalObj(request.params, validator.params) && equalObj(request.query, validator.query);
|
|
341
|
+
}
|
|
342
|
+
function equalObj(left, right) {
|
|
343
|
+
if (!right)
|
|
344
|
+
return true;
|
|
345
|
+
for (const key in right) {
|
|
346
|
+
if (right[key] !== left[key])
|
|
347
|
+
return false;
|
|
348
|
+
}
|
|
349
|
+
return true;
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
// src/baseMiddleware.ts
|
|
353
|
+
function baseMiddleware(mockData, { formidableOptions = {}, proxies }) {
|
|
354
|
+
return async function(req, res, next) {
|
|
355
|
+
const method = req.method.toUpperCase();
|
|
356
|
+
const { query, pathname } = (0, import_node_url2.parse)(req.url, true);
|
|
357
|
+
if (!pathname || proxies.length === 0 || !proxies.some((context) => doesProxyContextMatchUrl(context, req.url))) {
|
|
358
|
+
return next();
|
|
359
|
+
}
|
|
360
|
+
const mockUrl = Object.keys(mockData).find((key) => {
|
|
361
|
+
return (0, import_path_to_regexp.pathToRegexp)(key).test(pathname);
|
|
362
|
+
});
|
|
363
|
+
if (!mockUrl) {
|
|
364
|
+
return next();
|
|
365
|
+
}
|
|
366
|
+
const mockList = mockData[mockUrl];
|
|
367
|
+
const reqBody = await parseReqBody(req, formidableOptions);
|
|
368
|
+
const currentMock = mockList.find((mock) => {
|
|
369
|
+
if (!pathname || !mock || !mock.url)
|
|
370
|
+
return false;
|
|
371
|
+
const methods = mock.method ? isArray(mock.method) ? mock.method : [mock.method] : ["GET", "POST"];
|
|
372
|
+
if (!methods.includes(req.method.toUpperCase()))
|
|
373
|
+
return false;
|
|
374
|
+
const hasMock = (0, import_path_to_regexp.pathToRegexp)(mock.url).test(pathname);
|
|
375
|
+
if (hasMock && mock.validator) {
|
|
376
|
+
const urlMatch2 = (0, import_path_to_regexp.match)(mock.url, { decode: decodeURIComponent })(
|
|
377
|
+
pathname
|
|
378
|
+
) || { params: {} };
|
|
379
|
+
const params2 = urlMatch2.params || {};
|
|
380
|
+
const request = {
|
|
381
|
+
query,
|
|
382
|
+
params: params2,
|
|
383
|
+
body: reqBody,
|
|
384
|
+
headers: req.headers
|
|
385
|
+
};
|
|
386
|
+
if (isFunction(mock.validator)) {
|
|
387
|
+
return mock.validator(request);
|
|
388
|
+
} else {
|
|
389
|
+
return validate(request, mock.validator);
|
|
390
|
+
}
|
|
391
|
+
}
|
|
392
|
+
return hasMock;
|
|
393
|
+
});
|
|
394
|
+
if (!currentMock)
|
|
395
|
+
return next();
|
|
396
|
+
debug("middleware: ", method, pathname);
|
|
397
|
+
if (currentMock.delay && currentMock.delay > 0) {
|
|
398
|
+
await sleep(currentMock.delay);
|
|
399
|
+
}
|
|
400
|
+
res.statusCode = currentMock.status || 200;
|
|
401
|
+
res.statusMessage = currentMock.statusText || "OK";
|
|
402
|
+
const urlMatch = (0, import_path_to_regexp.match)(currentMock.url, { decode: decodeURIComponent })(
|
|
403
|
+
pathname
|
|
404
|
+
) || { params: {} };
|
|
405
|
+
const params = urlMatch.params || {};
|
|
406
|
+
req.body = reqBody;
|
|
407
|
+
req.query = query;
|
|
408
|
+
req.params = params;
|
|
409
|
+
res.setHeader("Content-Type", "application/json");
|
|
410
|
+
res.setHeader("X-Mock", "generate by vite:mock-dev-server");
|
|
411
|
+
if (currentMock.headers) {
|
|
412
|
+
const headers = isFunction(currentMock.headers) ? await currentMock.headers({
|
|
413
|
+
query,
|
|
414
|
+
body: reqBody,
|
|
415
|
+
params,
|
|
416
|
+
headers: req.headers
|
|
417
|
+
}) : currentMock.headers;
|
|
418
|
+
Object.keys(headers).forEach((key) => {
|
|
419
|
+
res.setHeader(key, headers[key]);
|
|
420
|
+
});
|
|
421
|
+
}
|
|
422
|
+
if (currentMock.body) {
|
|
423
|
+
let body;
|
|
424
|
+
if (isFunction(currentMock.body)) {
|
|
425
|
+
body = await currentMock.body({
|
|
426
|
+
query,
|
|
427
|
+
body: reqBody,
|
|
428
|
+
params,
|
|
429
|
+
headers: req.headers
|
|
430
|
+
});
|
|
431
|
+
} else {
|
|
432
|
+
body = currentMock.body;
|
|
433
|
+
}
|
|
434
|
+
res.end(JSON.stringify(body));
|
|
435
|
+
return;
|
|
436
|
+
}
|
|
437
|
+
if (currentMock.response) {
|
|
438
|
+
await currentMock.response(
|
|
439
|
+
req,
|
|
440
|
+
res,
|
|
441
|
+
next
|
|
442
|
+
);
|
|
443
|
+
return;
|
|
444
|
+
}
|
|
445
|
+
res.end("");
|
|
446
|
+
};
|
|
447
|
+
}
|
|
448
|
+
function doesProxyContextMatchUrl(context, url) {
|
|
449
|
+
return context.startsWith("^") && new RegExp(context).test(url) || url.startsWith(context);
|
|
450
|
+
}
|
|
451
|
+
|
|
81
452
|
// src/MockLoader.ts
|
|
453
|
+
var import_node_events = __toESM(require("events"), 1);
|
|
454
|
+
var import_node_fs3 = __toESM(require("fs"), 1);
|
|
455
|
+
var import_node_module = require("module");
|
|
456
|
+
var import_node_path4 = __toESM(require("path"), 1);
|
|
457
|
+
var import_node_url3 = require("url");
|
|
458
|
+
var import_chokidar = __toESM(require("chokidar"), 1);
|
|
459
|
+
var import_esbuild2 = require("esbuild");
|
|
460
|
+
var import_fast_glob2 = __toESM(require("fast-glob"), 1);
|
|
461
|
+
var import_json52 = __toESM(require("json5"), 1);
|
|
462
|
+
var import_vite2 = require("vite");
|
|
82
463
|
var import_meta = {};
|
|
83
464
|
var _dirname = typeof __dirname !== "undefined" ? __dirname : getDirname(import_meta.url);
|
|
84
465
|
var _require = (0, import_node_module.createRequire)(_dirname);
|
|
@@ -88,8 +469,8 @@ var _MockLoader = class extends import_node_events.default {
|
|
|
88
469
|
this.options = options;
|
|
89
470
|
this.moduleCache = /* @__PURE__ */ new Map();
|
|
90
471
|
this.moduleDeps = /* @__PURE__ */ new Map();
|
|
91
|
-
this._mockList = {};
|
|
92
472
|
this.moduleType = "cjs";
|
|
473
|
+
this._mockData = {};
|
|
93
474
|
this.cwd = options.cwd || process.cwd();
|
|
94
475
|
try {
|
|
95
476
|
const pkg = lookupFile(this.cwd, ["package.json"]);
|
|
@@ -97,15 +478,15 @@ var _MockLoader = class extends import_node_events.default {
|
|
|
97
478
|
} catch (e) {
|
|
98
479
|
}
|
|
99
480
|
}
|
|
100
|
-
get
|
|
101
|
-
return this.
|
|
481
|
+
get mockData() {
|
|
482
|
+
return this._mockData;
|
|
102
483
|
}
|
|
103
484
|
async load() {
|
|
104
485
|
const { include, exclude } = this.options;
|
|
105
|
-
const includePaths = await (0,
|
|
486
|
+
const includePaths = await (0, import_fast_glob2.default)(include, {
|
|
106
487
|
cwd: this.cwd
|
|
107
488
|
});
|
|
108
|
-
const includeFilter = (0,
|
|
489
|
+
const includeFilter = (0, import_vite2.createFilter)(include, exclude, {
|
|
109
490
|
resolve: false
|
|
110
491
|
});
|
|
111
492
|
this.watchMockEntry();
|
|
@@ -191,7 +572,7 @@ var _MockLoader = class extends import_node_events.default {
|
|
|
191
572
|
const list = mocks[mock.url];
|
|
192
573
|
mock.validator ? list.unshift(mock) : list.push(mock);
|
|
193
574
|
});
|
|
194
|
-
this.
|
|
575
|
+
this._mockData = mocks;
|
|
195
576
|
}
|
|
196
577
|
updateModuleDeps(filepath, deps) {
|
|
197
578
|
Object.keys(deps).forEach((mPath) => {
|
|
@@ -216,9 +597,9 @@ var _MockLoader = class extends import_node_events.default {
|
|
|
216
597
|
}
|
|
217
598
|
}
|
|
218
599
|
async loadJson(filepath) {
|
|
219
|
-
const content = await
|
|
600
|
+
const content = await import_node_fs3.default.promises.readFile(filepath, "utf-8");
|
|
220
601
|
try {
|
|
221
|
-
const mockConfig =
|
|
602
|
+
const mockConfig = import_json52.default.parse(content);
|
|
222
603
|
this.moduleCache.set(filepath, mockConfig);
|
|
223
604
|
} catch (e) {
|
|
224
605
|
}
|
|
@@ -248,20 +629,20 @@ var _MockLoader = class extends import_node_events.default {
|
|
|
248
629
|
if (isESM) {
|
|
249
630
|
const fileBase = `${filepath}.timestamp-${Date.now()}`;
|
|
250
631
|
const fileNameTmp = `${fileBase}.mjs`;
|
|
251
|
-
const fileUrl = `${(0,
|
|
252
|
-
await
|
|
632
|
+
const fileUrl = `${(0, import_node_url3.pathToFileURL)(fileBase)}.mjs`;
|
|
633
|
+
await import_node_fs3.default.promises.writeFile(fileNameTmp, code, "utf8");
|
|
253
634
|
try {
|
|
254
635
|
return await import(fileUrl);
|
|
255
636
|
} finally {
|
|
256
637
|
try {
|
|
257
|
-
|
|
638
|
+
import_node_fs3.default.unlinkSync(fileNameTmp);
|
|
258
639
|
} catch {
|
|
259
640
|
}
|
|
260
641
|
}
|
|
261
642
|
} else {
|
|
262
|
-
filepath =
|
|
263
|
-
const extension =
|
|
264
|
-
const realFileName =
|
|
643
|
+
filepath = import_node_path4.default.resolve(this.cwd, filepath);
|
|
644
|
+
const extension = import_node_path4.default.extname(filepath);
|
|
645
|
+
const realFileName = import_node_fs3.default.realpathSync(filepath);
|
|
265
646
|
const loaderExt = extension in _require.extensions ? extension : ".js";
|
|
266
647
|
const defaultLoader = _require.extensions[loaderExt];
|
|
267
648
|
_require.extensions[loaderExt] = (module2, filename) => {
|
|
@@ -281,7 +662,7 @@ var _MockLoader = class extends import_node_events.default {
|
|
|
281
662
|
async transformWithEsbuild(filepath, isESM) {
|
|
282
663
|
var _a;
|
|
283
664
|
try {
|
|
284
|
-
const result = await (0,
|
|
665
|
+
const result = await (0, import_esbuild2.build)({
|
|
285
666
|
entryPoints: [filepath],
|
|
286
667
|
outfile: "out.js",
|
|
287
668
|
write: false,
|
|
@@ -291,20 +672,7 @@ var _MockLoader = class extends import_node_events.default {
|
|
|
291
672
|
metafile: true,
|
|
292
673
|
format: isESM ? "esm" : "cjs",
|
|
293
674
|
define: this.options.define,
|
|
294
|
-
plugins: [
|
|
295
|
-
{
|
|
296
|
-
name: "externalize-deps",
|
|
297
|
-
setup(build2) {
|
|
298
|
-
build2.onResolve({ filter: /.*/ }, ({ path: id }) => {
|
|
299
|
-
if (id[0] !== "." && !import_node_path2.default.isAbsolute(id)) {
|
|
300
|
-
return {
|
|
301
|
-
external: true
|
|
302
|
-
};
|
|
303
|
-
}
|
|
304
|
-
});
|
|
305
|
-
}
|
|
306
|
-
}
|
|
307
|
-
]
|
|
675
|
+
plugins: [externalizeDeps]
|
|
308
676
|
});
|
|
309
677
|
return {
|
|
310
678
|
code: result.outputFiles[0].text,
|
|
@@ -321,59 +689,6 @@ var _MockLoader = class extends import_node_events.default {
|
|
|
321
689
|
var MockLoader = _MockLoader;
|
|
322
690
|
MockLoader.EXT_JSON = /\.json5?$/;
|
|
323
691
|
|
|
324
|
-
// src/parseReqBody.ts
|
|
325
|
-
var import_co_body = __toESM(require("co-body"), 1);
|
|
326
|
-
var import_formidable = __toESM(require("formidable"), 1);
|
|
327
|
-
async function parseReqBody(req, options) {
|
|
328
|
-
const method = req.method.toUpperCase();
|
|
329
|
-
if (["GET", "DELETE", "HEAD"].includes(method))
|
|
330
|
-
return void 0;
|
|
331
|
-
const type = req.headers["content-type"];
|
|
332
|
-
try {
|
|
333
|
-
if (type === "application/json") {
|
|
334
|
-
return await import_co_body.default.json(req);
|
|
335
|
-
}
|
|
336
|
-
if (type === "application/x-www-form-urlencoded") {
|
|
337
|
-
return await import_co_body.default.form(req);
|
|
338
|
-
}
|
|
339
|
-
if (type === "text/plain") {
|
|
340
|
-
return await import_co_body.default.text(req);
|
|
341
|
-
}
|
|
342
|
-
if (type == null ? void 0 : type.startsWith("multipart/form-data;")) {
|
|
343
|
-
return await parseMultipart(req, options);
|
|
344
|
-
}
|
|
345
|
-
} catch (e) {
|
|
346
|
-
console.error(e);
|
|
347
|
-
}
|
|
348
|
-
return void 0;
|
|
349
|
-
}
|
|
350
|
-
async function parseMultipart(req, options) {
|
|
351
|
-
const form = (0, import_formidable.default)(options);
|
|
352
|
-
return new Promise((resolve, reject) => {
|
|
353
|
-
form.parse(req, (error, fields, files) => {
|
|
354
|
-
if (error) {
|
|
355
|
-
reject(error);
|
|
356
|
-
return;
|
|
357
|
-
}
|
|
358
|
-
resolve({ ...fields, ...files });
|
|
359
|
-
});
|
|
360
|
-
});
|
|
361
|
-
}
|
|
362
|
-
|
|
363
|
-
// src/validator.ts
|
|
364
|
-
function validate(request, validator) {
|
|
365
|
-
return equalObj(request.headers, validator.headers) && equalObj(request.body, validator.body) && equalObj(request.params, validator.params) && equalObj(request.query, validator.query);
|
|
366
|
-
}
|
|
367
|
-
function equalObj(left, right) {
|
|
368
|
-
if (!right)
|
|
369
|
-
return true;
|
|
370
|
-
for (const key in right) {
|
|
371
|
-
if (right[key] !== left[key])
|
|
372
|
-
return false;
|
|
373
|
-
}
|
|
374
|
-
return true;
|
|
375
|
-
}
|
|
376
|
-
|
|
377
692
|
// src/mockMiddleware.ts
|
|
378
693
|
async function mockServerMiddleware(httpServer, config, options) {
|
|
379
694
|
const include = isArray(options.include) ? options.include : [options.include];
|
|
@@ -393,106 +708,13 @@ async function mockServerMiddleware(httpServer, config, options) {
|
|
|
393
708
|
await loader.load();
|
|
394
709
|
httpServer == null ? void 0 : httpServer.on("close", () => loader.close());
|
|
395
710
|
const proxies = Object.keys(config.server.proxy || {});
|
|
396
|
-
return
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
return next();
|
|
401
|
-
}
|
|
402
|
-
const mockUrl = Object.keys(loader._mockList).find((key) => {
|
|
403
|
-
return (0, import_path_to_regexp.pathToRegexp)(key).test(pathname);
|
|
404
|
-
});
|
|
405
|
-
if (!mockUrl) {
|
|
406
|
-
return next();
|
|
407
|
-
}
|
|
408
|
-
const mockList = loader.mockList[mockUrl];
|
|
409
|
-
const reqBody = await parseReqBody(req, options.formidableOptions);
|
|
410
|
-
const currentMock = mockList.find((mock) => {
|
|
411
|
-
if (!pathname || !mock || !mock.url)
|
|
412
|
-
return false;
|
|
413
|
-
const methods = mock.method ? isArray(mock.method) ? mock.method : [mock.method] : ["GET", "POST"];
|
|
414
|
-
if (!methods.includes(req.method.toUpperCase()))
|
|
415
|
-
return false;
|
|
416
|
-
const hasMock = (0, import_path_to_regexp.pathToRegexp)(mock.url).test(pathname);
|
|
417
|
-
if (hasMock && mock.validator) {
|
|
418
|
-
const urlMatch2 = (0, import_path_to_regexp.match)(mock.url, { decode: decodeURIComponent })(
|
|
419
|
-
pathname
|
|
420
|
-
) || { params: {} };
|
|
421
|
-
const params2 = urlMatch2.params || {};
|
|
422
|
-
const request = {
|
|
423
|
-
query,
|
|
424
|
-
params: params2,
|
|
425
|
-
body: reqBody,
|
|
426
|
-
headers: req.headers
|
|
427
|
-
};
|
|
428
|
-
if (isFunction(mock.validator)) {
|
|
429
|
-
return mock.validator(request);
|
|
430
|
-
} else {
|
|
431
|
-
return validate(request, mock.validator);
|
|
432
|
-
}
|
|
433
|
-
}
|
|
434
|
-
return hasMock;
|
|
435
|
-
});
|
|
436
|
-
if (!currentMock)
|
|
437
|
-
return next();
|
|
438
|
-
debug("middleware: ", method, pathname);
|
|
439
|
-
if (currentMock.delay && currentMock.delay > 0) {
|
|
440
|
-
await sleep(currentMock.delay);
|
|
441
|
-
}
|
|
442
|
-
res.statusCode = currentMock.status || 200;
|
|
443
|
-
res.statusMessage = currentMock.statusText || "OK";
|
|
444
|
-
const urlMatch = (0, import_path_to_regexp.match)(currentMock.url, { decode: decodeURIComponent })(
|
|
445
|
-
pathname
|
|
446
|
-
) || { params: {} };
|
|
447
|
-
const params = urlMatch.params || {};
|
|
448
|
-
req.body = reqBody;
|
|
449
|
-
req.query = query;
|
|
450
|
-
req.params = params;
|
|
451
|
-
res.setHeader("Content-Type", "application/json");
|
|
452
|
-
res.setHeader("X-Mock", "generate by vite:mock-dev-server");
|
|
453
|
-
if (currentMock.headers) {
|
|
454
|
-
const headers = isFunction(currentMock.headers) ? await currentMock.headers({
|
|
455
|
-
query,
|
|
456
|
-
body: reqBody,
|
|
457
|
-
params,
|
|
458
|
-
headers: req.headers
|
|
459
|
-
}) : currentMock.headers;
|
|
460
|
-
Object.keys(headers).forEach((key) => {
|
|
461
|
-
res.setHeader(key, headers[key]);
|
|
462
|
-
});
|
|
463
|
-
}
|
|
464
|
-
if (currentMock.body) {
|
|
465
|
-
let body;
|
|
466
|
-
if (isFunction(currentMock.body)) {
|
|
467
|
-
body = await currentMock.body({
|
|
468
|
-
query,
|
|
469
|
-
body: reqBody,
|
|
470
|
-
params,
|
|
471
|
-
headers: req.headers
|
|
472
|
-
});
|
|
473
|
-
} else {
|
|
474
|
-
body = currentMock.body;
|
|
475
|
-
}
|
|
476
|
-
res.end(JSON.stringify(body));
|
|
477
|
-
return;
|
|
478
|
-
}
|
|
479
|
-
if (currentMock.response) {
|
|
480
|
-
await currentMock.response(
|
|
481
|
-
req,
|
|
482
|
-
res,
|
|
483
|
-
next
|
|
484
|
-
);
|
|
485
|
-
return;
|
|
486
|
-
}
|
|
487
|
-
res.end("");
|
|
488
|
-
};
|
|
489
|
-
}
|
|
490
|
-
function doesProxyContextMatchUrl(context, url) {
|
|
491
|
-
return context.startsWith("^") && new RegExp(context).test(url) || url.startsWith(context);
|
|
711
|
+
return baseMiddleware(loader.mockData, {
|
|
712
|
+
formidableOptions: options.formidableOptions,
|
|
713
|
+
proxies
|
|
714
|
+
});
|
|
492
715
|
}
|
|
493
716
|
|
|
494
717
|
// src/plugin.ts
|
|
495
|
-
var viteConfig = {};
|
|
496
718
|
function mockDevServerPlugin({
|
|
497
719
|
include = ["mock/**/*.mock.{js,ts,cjs,mjs,json,json5}"],
|
|
498
720
|
exclude = [
|
|
@@ -503,8 +725,51 @@ function mockDevServerPlugin({
|
|
|
503
725
|
"**/.git/**",
|
|
504
726
|
"**/dist/**"
|
|
505
727
|
],
|
|
506
|
-
formidableOptions = {}
|
|
728
|
+
formidableOptions = {},
|
|
729
|
+
build: build3 = false
|
|
507
730
|
} = {}) {
|
|
731
|
+
const pluginOptions = {
|
|
732
|
+
include,
|
|
733
|
+
exclude,
|
|
734
|
+
formidableOptions: {
|
|
735
|
+
multiples: true,
|
|
736
|
+
...formidableOptions
|
|
737
|
+
},
|
|
738
|
+
build: build3 ? Object.assign(
|
|
739
|
+
{
|
|
740
|
+
serverPort: 8080,
|
|
741
|
+
dist: "mockServer"
|
|
742
|
+
},
|
|
743
|
+
typeof build3 === "object" ? build3 : {}
|
|
744
|
+
) : false
|
|
745
|
+
};
|
|
746
|
+
const plugins = [serverPlugin(pluginOptions)];
|
|
747
|
+
if (pluginOptions.build) {
|
|
748
|
+
plugins.push(buildPlugin(pluginOptions));
|
|
749
|
+
}
|
|
750
|
+
return plugins;
|
|
751
|
+
}
|
|
752
|
+
function buildPlugin(pluginOptions) {
|
|
753
|
+
let viteConfig = {};
|
|
754
|
+
return {
|
|
755
|
+
name: "vite-plugin-mock-dev-server-generator",
|
|
756
|
+
enforce: "post",
|
|
757
|
+
apply: "build",
|
|
758
|
+
configResolved(config) {
|
|
759
|
+
viteConfig = config;
|
|
760
|
+
config.logger.warn("");
|
|
761
|
+
},
|
|
762
|
+
async buildEnd(error) {
|
|
763
|
+
if (error)
|
|
764
|
+
return;
|
|
765
|
+
if (viteConfig.command !== "build")
|
|
766
|
+
return;
|
|
767
|
+
await generateMockServer(this, viteConfig, pluginOptions);
|
|
768
|
+
}
|
|
769
|
+
};
|
|
770
|
+
}
|
|
771
|
+
function serverPlugin(pluginOptions) {
|
|
772
|
+
let viteConfig = {};
|
|
508
773
|
return {
|
|
509
774
|
name: "vite-plugin-mock-dev-server",
|
|
510
775
|
enforce: "pre",
|
|
@@ -514,25 +779,19 @@ function mockDevServerPlugin({
|
|
|
514
779
|
config.logger.warn("");
|
|
515
780
|
},
|
|
516
781
|
async configureServer({ middlewares, config, httpServer }) {
|
|
517
|
-
const middleware = await mockServerMiddleware(
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
...formidableOptions
|
|
523
|
-
}
|
|
524
|
-
});
|
|
782
|
+
const middleware = await mockServerMiddleware(
|
|
783
|
+
httpServer,
|
|
784
|
+
config,
|
|
785
|
+
pluginOptions
|
|
786
|
+
);
|
|
525
787
|
middlewares.use(middleware);
|
|
526
788
|
},
|
|
527
789
|
async configurePreviewServer({ middlewares, httpServer }) {
|
|
528
|
-
const middleware = await mockServerMiddleware(
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
...formidableOptions
|
|
534
|
-
}
|
|
535
|
-
});
|
|
790
|
+
const middleware = await mockServerMiddleware(
|
|
791
|
+
httpServer,
|
|
792
|
+
viteConfig,
|
|
793
|
+
pluginOptions
|
|
794
|
+
);
|
|
536
795
|
middlewares.use(middleware);
|
|
537
796
|
}
|
|
538
797
|
};
|
|
@@ -547,6 +806,7 @@ function defineMock(config) {
|
|
|
547
806
|
var src_default = mockDevServerPlugin;
|
|
548
807
|
// Annotate the CommonJS export names for ESM import in node:
|
|
549
808
|
0 && (module.exports = {
|
|
809
|
+
baseMiddleware,
|
|
550
810
|
defineMock,
|
|
551
811
|
mockDevServerPlugin
|
|
552
812
|
});
|