rspack-plugin-mock 0.3.0 → 0.3.2

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 CHANGED
@@ -428,34 +428,34 @@ export default definePostMock({
428
428
 
429
429
  ### options.validator
430
430
 
431
- - **类型:** `Validator | (request: MockRequest) => boolean`
431
+ - **Type:** `Validator | (request: MockRequest) => boolean`
432
432
 
433
433
  ```ts
434
434
  interface Validator {
435
435
  /**
436
- * 请求地址中位于 `?` 后面的 queryString,已解析为 json
436
+ * The query string located after `?` in the request address has been parsed into JSON.
437
437
  */
438
438
  query: Record<string, any>
439
439
  /**
440
- * 请求 referer 中位于 `?` 后面的 queryString
440
+ * The queryString located after `?` in the referer request has been parsed as JSON.
441
441
  */
442
442
  refererQuery: Record<string, any>
443
443
  /**
444
- * 请求体中 body 数据
444
+ * Body data in the request
445
445
  */
446
446
  body: Record<string, any>
447
447
  /**
448
- * 请求地址中,`/api/id/:id` 解析后的 params 参数
448
+ * The params parameter parsed from the `/api/id/:id` in the request address.
449
449
  */
450
450
  params: Record<string, any>
451
451
  /**
452
- * 请求体中 headers
452
+ * headers data in the request
453
453
  */
454
454
  headers: Headers
455
455
  }
456
456
  ```
457
457
 
458
- - **详情:**
458
+ - **Details:**
459
459
 
460
460
  Request Validator
461
461
 
@@ -0,0 +1,546 @@
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;
2
+
3
+
4
+
5
+
6
+
7
+
8
+
9
+
10
+
11
+
12
+ var _chunkZEC4FWWYcjs = require('./chunk-ZEC4FWWY.cjs');
13
+
14
+ // src/core/mockMiddleware.ts
15
+ var _cors = require('cors'); var _cors2 = _interopRequireDefault(_cors);
16
+ var _pathtoregexp = require('path-to-regexp');
17
+ function createMockMiddleware(compiler, options) {
18
+ function mockMiddleware(middlewares, reload) {
19
+ middlewares.unshift(_chunkZEC4FWWYcjs.baseMiddleware.call(void 0, compiler, options));
20
+ const corsMiddleware = createCorsMiddleware(compiler, options);
21
+ if (corsMiddleware) {
22
+ middlewares.unshift(corsMiddleware);
23
+ }
24
+ if (options.reload) {
25
+ compiler.on("update", () => _optionalChain([reload, 'optionalCall', _ => _()]));
26
+ }
27
+ return middlewares;
28
+ }
29
+ return mockMiddleware;
30
+ }
31
+ function createCorsMiddleware(compiler, options) {
32
+ let corsOptions = {};
33
+ const enabled = options.cors !== false;
34
+ if (enabled) {
35
+ corsOptions = {
36
+ ...corsOptions,
37
+ ...typeof options.cors === "boolean" ? {} : options.cors
38
+ };
39
+ }
40
+ const proxies = options.proxies;
41
+ return !enabled ? void 0 : function(req, res, next) {
42
+ const { pathname } = _chunkZEC4FWWYcjs.urlParse.call(void 0, req.url);
43
+ if (!pathname || proxies.length === 0 || !proxies.some(
44
+ (context) => _chunkZEC4FWWYcjs.doesProxyContextMatchUrl.call(void 0, context, req.url, req)
45
+ )) {
46
+ return next();
47
+ }
48
+ const mockData = compiler.mockData;
49
+ const mockUrl = Object.keys(mockData).find(
50
+ (key) => _pathtoregexp.pathToRegexp.call(void 0, key).test(pathname)
51
+ );
52
+ if (!mockUrl)
53
+ return next();
54
+ _cors2.default.call(void 0, corsOptions)(req, res, next);
55
+ };
56
+ }
57
+
58
+ // src/core/resolvePluginOptions.ts
59
+ var _process = require('process'); var _process2 = _interopRequireDefault(_process);
60
+ var _utils = require('@pengzhanbo/utils');
61
+ function resolvePluginOptions({
62
+ prefix = [],
63
+ wsPrefix = [],
64
+ cwd,
65
+ include = ["mock/**/*.mock.{js,ts,cjs,mjs,json,json5}"],
66
+ exclude = ["**/node_modules/**", "**/.vscode/**", "**/.git/**"],
67
+ reload = false,
68
+ log = "info",
69
+ cors: cors2 = true,
70
+ formidableOptions = {},
71
+ build = false,
72
+ cookiesOptions = {},
73
+ bodyParserOptions = {},
74
+ priority = {}
75
+ } = {}, { alias, context, plugins, proxies }) {
76
+ const logger = _chunkZEC4FWWYcjs.createLogger.call(void 0,
77
+ "rspack:mock",
78
+ _utils.isBoolean.call(void 0, log) ? log ? "info" : "error" : log
79
+ );
80
+ return {
81
+ prefix,
82
+ wsPrefix,
83
+ cwd: cwd || context || _process2.default.cwd(),
84
+ include,
85
+ exclude,
86
+ reload,
87
+ cors: cors2,
88
+ cookiesOptions,
89
+ log,
90
+ formidableOptions: {
91
+ multiples: true,
92
+ ...formidableOptions
93
+ },
94
+ bodyParserOptions,
95
+ priority,
96
+ build: build ? Object.assign(
97
+ {
98
+ serverPort: 8080,
99
+ dist: "mockServer",
100
+ log: "error"
101
+ },
102
+ typeof build === "object" ? build : {}
103
+ ) : false,
104
+ alias,
105
+ plugins,
106
+ proxies,
107
+ wsProxies: _utils.toArray.call(void 0, wsPrefix),
108
+ logger
109
+ };
110
+ }
111
+
112
+ // src/core/build.ts
113
+ var _fs = require('fs'); var _fs2 = _interopRequireDefault(_fs);
114
+ var _promises = require('fs/promises'); var _promises2 = _interopRequireDefault(_promises);
115
+ var _path = require('path'); var _path2 = _interopRequireDefault(_path);
116
+
117
+ var _fastglob = require('fast-glob'); var _fastglob2 = _interopRequireDefault(_fastglob);
118
+ var _pluginutils = require('@rollup/pluginutils');
119
+ var _picocolors = require('picocolors'); var _picocolors2 = _interopRequireDefault(_picocolors);
120
+
121
+
122
+ // src/core/createRspackCompiler.ts
123
+
124
+ var _core = require('@rspack/core'); var rspackCore = _interopRequireWildcard(_core);
125
+
126
+ var _iscoremodule = require('is-core-module'); var _iscoremodule2 = _interopRequireDefault(_iscoremodule);
127
+ function createCompiler(options, callback) {
128
+ const rspackOptions = resolveRspackOptions(options);
129
+ const isWatch = rspackOptions.watch === true;
130
+ async function handler(err, stats) {
131
+ const name = "[rspack:mock]";
132
+ const logError = _optionalChain([stats, 'optionalAccess', _2 => _2.compilation, 'access', _3 => _3.getLogger, 'call', _4 => _4(name), 'access', _5 => _5.error]) || ((...args) => console.error(_picocolors2.default.red(name), ...args));
133
+ if (err) {
134
+ logError(err.stack || err);
135
+ if ("details" in err) {
136
+ logError(err.details);
137
+ }
138
+ return;
139
+ }
140
+ if (_optionalChain([stats, 'optionalAccess', _6 => _6.hasErrors, 'call', _7 => _7()])) {
141
+ const info = stats.toJson();
142
+ logError(info.errors);
143
+ }
144
+ const code = _chunkZEC4FWWYcjs.vfs.readFileSync("/output.js", "utf-8");
145
+ const externals = [];
146
+ if (!isWatch) {
147
+ const modules = _optionalChain([stats, 'optionalAccess', _8 => _8.toJson, 'call', _9 => _9(), 'access', _10 => _10.modules]) || [];
148
+ const aliasList = Object.keys(options.alias || {}).map((key) => key.replace(/\$$/g, ""));
149
+ for (const { name: name2 } of modules) {
150
+ if (_optionalChain([name2, 'optionalAccess', _11 => _11.startsWith, 'call', _12 => _12("external")])) {
151
+ const packageName = normalizePackageName(name2);
152
+ if (!_iscoremodule2.default.call(void 0, packageName) && !aliasList.includes(packageName))
153
+ externals.push(normalizePackageName(name2));
154
+ }
155
+ }
156
+ }
157
+ await callback({ code, externals });
158
+ }
159
+ const compiler = rspackCore.rspack(rspackOptions, isWatch ? handler : void 0);
160
+ if (compiler)
161
+ compiler.outputFileSystem = _chunkZEC4FWWYcjs.vfs;
162
+ if (!isWatch) {
163
+ _optionalChain([compiler, 'optionalAccess', _13 => _13.run, 'call', _14 => _14(async (...args) => {
164
+ await handler(...args);
165
+ compiler.close(() => {
166
+ });
167
+ })]);
168
+ }
169
+ return compiler;
170
+ }
171
+ function transformWithRspack(options) {
172
+ return new Promise((resolve) => {
173
+ createCompiler({ ...options, watch: false }, (result) => {
174
+ resolve(result);
175
+ });
176
+ });
177
+ }
178
+ function normalizePackageName(name) {
179
+ const filepath = name.replace("external ", "").slice(1, -1);
180
+ const [scope, packageName] = filepath.split("/");
181
+ if (filepath[0] === "@") {
182
+ return `${scope}/${packageName}`;
183
+ }
184
+ return scope;
185
+ }
186
+ function resolveRspackOptions({
187
+ cwd,
188
+ isEsm = true,
189
+ entryFile,
190
+ plugins,
191
+ alias,
192
+ watch = false
193
+ }) {
194
+ const targets = ["node >= 18.0.0"];
195
+ return {
196
+ mode: "production",
197
+ context: cwd,
198
+ entry: entryFile,
199
+ watch,
200
+ target: "node18.0",
201
+ externalsType: isEsm ? "module" : "commonjs2",
202
+ externals: /^[^./].*/,
203
+ resolve: {
204
+ alias,
205
+ extensions: [".js", ".ts", ".cjs", ".mjs", ".json5", ".json"]
206
+ },
207
+ plugins,
208
+ output: {
209
+ library: { type: !isEsm ? "commonjs2" : "module" },
210
+ filename: "output.js",
211
+ path: "/"
212
+ },
213
+ experiments: { outputModule: isEsm },
214
+ optimization: { minimize: !watch },
215
+ module: {
216
+ rules: [
217
+ {
218
+ test: /\.json5?$/,
219
+ loader: _path2.default.join(_chunkZEC4FWWYcjs.packageDir, "json5-loader.cjs"),
220
+ type: "javascript/auto"
221
+ },
222
+ {
223
+ test: /\.[cm]?js$/,
224
+ use: [
225
+ {
226
+ loader: "builtin:swc-loader",
227
+ options: {
228
+ jsc: { parser: { syntax: "ecmascript" } },
229
+ env: { targets }
230
+ }
231
+ }
232
+ ]
233
+ },
234
+ {
235
+ test: /\.[cm]?ts$/,
236
+ use: [
237
+ {
238
+ loader: "builtin:swc-loader",
239
+ options: {
240
+ jsc: { parser: { syntax: "typescript" } },
241
+ env: { targets }
242
+ }
243
+ }
244
+ ]
245
+ }
246
+ ]
247
+ }
248
+ };
249
+ }
250
+
251
+ // src/core/build.ts
252
+ async function buildMockServer(options, outputDir) {
253
+ const entryFile = _path2.default.resolve(_process2.default.cwd(), "node_modules/.cache/mock-server/mock-server.ts");
254
+ const mockFileList = await getMockFileList(options);
255
+ await writeMockEntryFile(entryFile, mockFileList, options.cwd);
256
+ const { code, externals } = await transformWithRspack({
257
+ entryFile,
258
+ cwd: options.cwd,
259
+ plugins: options.plugins,
260
+ alias: options.alias
261
+ });
262
+ await _promises2.default.unlink(entryFile);
263
+ const outputList = [
264
+ { filename: "mock-data.js", source: code },
265
+ { filename: "index.js", source: generatorServerEntryCode(options) },
266
+ { filename: "package.json", source: generatePackageJson(options, externals) }
267
+ ];
268
+ const dist = _path2.default.resolve(outputDir, options.build.dist);
269
+ options.logger.info(
270
+ `${_picocolors2.default.green("\u2713")} generate mock server in ${_picocolors2.default.cyan(_path2.default.relative(_process2.default.cwd(), dist))}`
271
+ );
272
+ if (!_fs2.default.existsSync(dist)) {
273
+ await _promises2.default.mkdir(dist, { recursive: true });
274
+ }
275
+ for (const { filename, source } of outputList) {
276
+ await _promises2.default.writeFile(_path2.default.join(dist, filename), source, "utf8");
277
+ const sourceSize = (source.length / 1024).toFixed(2);
278
+ const space = filename.length < 24 ? " ".repeat(24 - filename.length) : "";
279
+ options.logger.info(` ${_picocolors2.default.green(filename)}${space}${_picocolors2.default.bold(_picocolors2.default.dim(`${sourceSize} kB`))}`);
280
+ }
281
+ }
282
+ function generatePackageJson(options, externals) {
283
+ const deps = getHostDependencies(options.cwd);
284
+ const { name, version } = getPluginPackageInfo();
285
+ const exclude = [name, "connect", "cors"];
286
+ const mockPkg = {
287
+ name: "mock-server",
288
+ type: "module",
289
+ scripts: {
290
+ start: "node index.js"
291
+ },
292
+ dependencies: {
293
+ connect: "^3.7.0",
294
+ [name]: `^${version}`,
295
+ cors: "^2.8.5"
296
+ }
297
+ };
298
+ externals.filter((dep) => !exclude.includes(dep)).forEach((dep) => {
299
+ mockPkg.dependencies[dep] = deps[dep] || "latest";
300
+ });
301
+ return JSON.stringify(mockPkg, null, 2);
302
+ }
303
+ function generatorServerEntryCode({
304
+ proxies,
305
+ wsPrefix,
306
+ cookiesOptions,
307
+ bodyParserOptions,
308
+ priority,
309
+ build
310
+ }) {
311
+ const { serverPort, log } = build;
312
+ return `import { createServer } from 'node:http';
313
+ import connect from 'connect';
314
+ import corsMiddleware from 'cors';
315
+ import {
316
+ baseMiddleware,
317
+ createLogger,
318
+ mockWebSocket,
319
+ transformMockData,
320
+ transformRawData
321
+ } from 'rspack-plugin-mock/server';
322
+ import rawData from './mock-data.js';
323
+
324
+ const app = connect();
325
+ const server = createServer(app);
326
+ const logger = createLogger('mock-server', '${log}');
327
+ const proxies = ${JSON.stringify(proxies)};
328
+ const wsProxies = ${JSON.stringify(_utils.toArray.call(void 0, wsPrefix))};
329
+ const cookiesOptions = ${JSON.stringify(cookiesOptions)};
330
+ const bodyParserOptions = ${JSON.stringify(bodyParserOptions)};
331
+ const priority = ${JSON.stringify(priority)};
332
+ const mockConfig = {
333
+ mockData: transformMockData(transformRawData(rawData)),
334
+ on: () => {},
335
+ };
336
+
337
+ mockWebSocket(mockConfig, server, { wsProxies, cookiesOptions, logger });
338
+
339
+ app.use(corsMiddleware());
340
+ app.use(baseMiddleware(mockConfig, {
341
+ formidableOptions: { multiples: true },
342
+ proxies,
343
+ priority,
344
+ cookiesOptions,
345
+ bodyParserOptions,
346
+ logger,
347
+ }));
348
+
349
+ server.listen(${serverPort});
350
+
351
+ console.log('listen: http://localhost:${serverPort}');
352
+ `;
353
+ }
354
+ async function getMockFileList({ cwd, include, exclude }) {
355
+ const filter = _pluginutils.createFilter.call(void 0, include, exclude, { resolve: false });
356
+ return await _fastglob2.default.call(void 0, include, { cwd }).then((files) => files.filter(filter));
357
+ }
358
+ async function writeMockEntryFile(entryFile, files, cwd) {
359
+ const importers = [];
360
+ const exporters = [];
361
+ for (const [index, filepath] of files.entries()) {
362
+ const file = _chunkZEC4FWWYcjs.normalizePath.call(void 0, _path2.default.join(cwd, filepath));
363
+ importers.push(`import * as m${index} from '${file}'`);
364
+ exporters.push(`[m${index}, '${filepath}']`);
365
+ }
366
+ const code = `${importers.join("\n")}
367
+
368
+ export default [
369
+ ${exporters.join(",\n ")}
370
+ ]`;
371
+ const dirname = _path2.default.dirname(entryFile);
372
+ if (!_fs2.default.existsSync(dirname)) {
373
+ await _promises2.default.mkdir(dirname, { recursive: true });
374
+ }
375
+ await _promises2.default.writeFile(entryFile, code, "utf8");
376
+ }
377
+ function getPluginPackageInfo() {
378
+ let pkg = {};
379
+ try {
380
+ const filepath = _path2.default.join(_chunkZEC4FWWYcjs.packageDir, "../package.json");
381
+ if (_fs2.default.existsSync(filepath)) {
382
+ pkg = JSON.parse(_fs2.default.readFileSync(filepath, "utf8"));
383
+ }
384
+ } catch (e2) {
385
+ }
386
+ return {
387
+ name: pkg.name || "rspack-plugin-mock",
388
+ version: pkg.version || "latest"
389
+ };
390
+ }
391
+ function getHostDependencies(context) {
392
+ let pkg = {};
393
+ try {
394
+ const content = _chunkZEC4FWWYcjs.lookupFile.call(void 0, context, ["package.json"]);
395
+ if (content)
396
+ pkg = JSON.parse(content);
397
+ } catch (e3) {
398
+ }
399
+ return { ...pkg.dependencies, ...pkg.devDependencies };
400
+ }
401
+
402
+ // src/core/mockCompiler.ts
403
+ var _events = require('events'); var _events2 = _interopRequireDefault(_events);
404
+
405
+
406
+
407
+ var _chokidar = require('chokidar'); var _chokidar2 = _interopRequireDefault(_chokidar);
408
+
409
+
410
+
411
+ // src/core/loadFromCode.ts
412
+
413
+
414
+ async function loadFromCode({
415
+ filepath,
416
+ code,
417
+ isESM,
418
+ cwd
419
+ }) {
420
+ filepath = _path2.default.resolve(cwd, filepath);
421
+ const fileBase = `${filepath}.timestamp-${Date.now()}`;
422
+ const ext = isESM ? ".mjs" : ".cjs";
423
+ const fileNameTmp = `${fileBase}${ext}`;
424
+ await _fs.promises.writeFile(fileNameTmp, code, "utf8");
425
+ try {
426
+ const result = await Promise.resolve().then(() => _interopRequireWildcard(require(fileNameTmp)));
427
+ return result.default || result;
428
+ } finally {
429
+ try {
430
+ _fs2.default.unlinkSync(fileNameTmp);
431
+ } catch (e4) {
432
+ }
433
+ }
434
+ }
435
+
436
+ // src/core/mockCompiler.ts
437
+ function createMockCompiler(options) {
438
+ return new MockCompiler(options);
439
+ }
440
+ var MockCompiler = (_class = class extends _events2.default {
441
+ constructor(options) {
442
+ super();_class.prototype.__init.call(this);_class.prototype.__init2.call(this);;
443
+ this.options = options;
444
+ this.cwd = options.cwd || _process2.default.cwd();
445
+ const { include, exclude } = this.options;
446
+ this.fileFilter = _pluginutils.createFilter.call(void 0, include, exclude, { resolve: false });
447
+ try {
448
+ const pkg = _chunkZEC4FWWYcjs.lookupFile.call(void 0, this.cwd, ["package.json"]);
449
+ this.moduleType = !!pkg && JSON.parse(pkg).type === "module" ? "esm" : "cjs";
450
+ } catch (e5) {
451
+ }
452
+ this.entryFile = _path2.default.resolve(_process2.default.cwd(), "node_modules/.cache/mock-server/mock-server.ts");
453
+ }
454
+
455
+
456
+ __init() {this.moduleType = "cjs"}
457
+
458
+ __init2() {this._mockData = {}}
459
+
460
+
461
+
462
+ get mockData() {
463
+ return this._mockData;
464
+ }
465
+ async run() {
466
+ await this.updateMockEntry();
467
+ this.watchMockFiles();
468
+ const { plugins, alias } = this.options;
469
+ const options = {
470
+ isEsm: this.moduleType === "esm",
471
+ cwd: this.cwd,
472
+ plugins,
473
+ entryFile: this.entryFile,
474
+ alias,
475
+ watch: true
476
+ };
477
+ this.compiler = createCompiler(options, async ({ code }) => {
478
+ try {
479
+ const result = await loadFromCode({
480
+ filepath: "mock.bundle.js",
481
+ code,
482
+ isESM: this.moduleType === "esm",
483
+ cwd: this.cwd
484
+ });
485
+ this._mockData = _chunkZEC4FWWYcjs.transformMockData.call(void 0, _chunkZEC4FWWYcjs.transformRawData.call(void 0, result));
486
+ this.emit("update", this.watchInfo || {});
487
+ } catch (e) {
488
+ this.options.logger.error(e.stack || e.message);
489
+ }
490
+ });
491
+ }
492
+ close() {
493
+ this.mockWatcher.close();
494
+ _optionalChain([this, 'access', _15 => _15.compiler, 'optionalAccess', _16 => _16.close, 'call', _17 => _17(() => {
495
+ })]);
496
+ this.emit("close");
497
+ }
498
+ updateAlias(alias) {
499
+ this.options.alias = {
500
+ ...this.options.alias,
501
+ ...alias
502
+ };
503
+ }
504
+ async updateMockEntry() {
505
+ const files = await this.getMockFiles();
506
+ await writeMockEntryFile(this.entryFile, files, this.cwd);
507
+ }
508
+ async getMockFiles() {
509
+ const { include } = this.options;
510
+ const files = await _fastglob2.default.call(void 0, include, { cwd: this.cwd });
511
+ return files.filter(this.fileFilter);
512
+ }
513
+ watchMockFiles() {
514
+ const { include } = this.options;
515
+ const [firstGlob, ...otherGlob] = _utils.toArray.call(void 0, include);
516
+ const watcher = this.mockWatcher = _chokidar2.default.watch(firstGlob, {
517
+ ignoreInitial: true,
518
+ cwd: this.cwd
519
+ });
520
+ if (otherGlob.length > 0)
521
+ otherGlob.forEach((glob) => watcher.add(glob));
522
+ watcher.on("add", (filepath) => {
523
+ if (this.fileFilter(filepath)) {
524
+ this.watchInfo = { filepath, type: "add" };
525
+ this.updateMockEntry();
526
+ }
527
+ });
528
+ watcher.on("change", (filepath) => {
529
+ if (this.fileFilter(filepath)) {
530
+ this.watchInfo = { filepath, type: "change" };
531
+ }
532
+ });
533
+ watcher.on("unlink", async (filepath) => {
534
+ this.watchInfo = { filepath, type: "unlink" };
535
+ this.updateMockEntry();
536
+ });
537
+ }
538
+ }, _class);
539
+
540
+
541
+
542
+
543
+
544
+
545
+
546
+ exports.createMockMiddleware = createMockMiddleware; exports.resolvePluginOptions = resolvePluginOptions; exports.buildMockServer = buildMockServer; exports.createMockCompiler = createMockCompiler; exports.MockCompiler = MockCompiler;