rspack-plugin-mock 0.2.0 → 0.3.1

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.
@@ -0,0 +1,543 @@
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 data = { mockData: transformMockData(transformRawData(rawData)) };
333
+
334
+ mockWebSocket(data, server, { wsProxies, cookiesOptions, logger });
335
+
336
+ app.use(corsMiddleware());
337
+ app.use(baseMiddleware(data, {
338
+ formidableOptions: { multiples: true },
339
+ proxies,
340
+ priority,
341
+ cookiesOptions,
342
+ bodyParserOptions,
343
+ logger,
344
+ }));
345
+
346
+ server.listen(${serverPort});
347
+
348
+ console.log('listen: http://localhost:${serverPort}');
349
+ `;
350
+ }
351
+ async function getMockFileList({ cwd, include, exclude }) {
352
+ const filter = _pluginutils.createFilter.call(void 0, include, exclude, { resolve: false });
353
+ return await _fastglob2.default.call(void 0, include, { cwd }).then((files) => files.filter(filter));
354
+ }
355
+ async function writeMockEntryFile(entryFile, files, cwd) {
356
+ const importers = [];
357
+ const exporters = [];
358
+ for (const [index, filepath] of files.entries()) {
359
+ const file = _chunkZEC4FWWYcjs.normalizePath.call(void 0, _path2.default.join(cwd, filepath));
360
+ importers.push(`import * as m${index} from '${file}'`);
361
+ exporters.push(`[m${index}, '${filepath}']`);
362
+ }
363
+ const code = `${importers.join("\n")}
364
+
365
+ export default [
366
+ ${exporters.join(",\n ")}
367
+ ]`;
368
+ const dirname = _path2.default.dirname(entryFile);
369
+ if (!_fs2.default.existsSync(dirname)) {
370
+ await _promises2.default.mkdir(dirname, { recursive: true });
371
+ }
372
+ await _promises2.default.writeFile(entryFile, code, "utf8");
373
+ }
374
+ function getPluginPackageInfo() {
375
+ let pkg = {};
376
+ try {
377
+ const filepath = _path2.default.join(_chunkZEC4FWWYcjs.packageDir, "../package.json");
378
+ if (_fs2.default.existsSync(filepath)) {
379
+ pkg = JSON.parse(_fs2.default.readFileSync(filepath, "utf8"));
380
+ }
381
+ } catch (e2) {
382
+ }
383
+ return {
384
+ name: pkg.name || "rspack-plugin-mock",
385
+ version: pkg.version || "latest"
386
+ };
387
+ }
388
+ function getHostDependencies(context) {
389
+ let pkg = {};
390
+ try {
391
+ const content = _chunkZEC4FWWYcjs.lookupFile.call(void 0, context, ["package.json"]);
392
+ if (content)
393
+ pkg = JSON.parse(content);
394
+ } catch (e3) {
395
+ }
396
+ return { ...pkg.dependencies, ...pkg.devDependencies };
397
+ }
398
+
399
+ // src/core/mockCompiler.ts
400
+ var _events = require('events'); var _events2 = _interopRequireDefault(_events);
401
+
402
+
403
+
404
+ var _chokidar = require('chokidar'); var _chokidar2 = _interopRequireDefault(_chokidar);
405
+
406
+
407
+
408
+ // src/core/loadFromCode.ts
409
+
410
+
411
+ async function loadFromCode({
412
+ filepath,
413
+ code,
414
+ isESM,
415
+ cwd
416
+ }) {
417
+ filepath = _path2.default.resolve(cwd, filepath);
418
+ const fileBase = `${filepath}.timestamp-${Date.now()}`;
419
+ const ext = isESM ? ".mjs" : ".cjs";
420
+ const fileNameTmp = `${fileBase}${ext}`;
421
+ await _fs.promises.writeFile(fileNameTmp, code, "utf8");
422
+ try {
423
+ const result = await Promise.resolve().then(() => _interopRequireWildcard(require(fileNameTmp)));
424
+ return result.default || result;
425
+ } finally {
426
+ try {
427
+ _fs2.default.unlinkSync(fileNameTmp);
428
+ } catch (e4) {
429
+ }
430
+ }
431
+ }
432
+
433
+ // src/core/mockCompiler.ts
434
+ function createMockCompiler(options) {
435
+ return new MockCompiler(options);
436
+ }
437
+ var MockCompiler = (_class = class extends _events2.default {
438
+ constructor(options) {
439
+ super();_class.prototype.__init.call(this);_class.prototype.__init2.call(this);;
440
+ this.options = options;
441
+ this.cwd = options.cwd || _process2.default.cwd();
442
+ const { include, exclude } = this.options;
443
+ this.fileFilter = _pluginutils.createFilter.call(void 0, include, exclude, { resolve: false });
444
+ try {
445
+ const pkg = _chunkZEC4FWWYcjs.lookupFile.call(void 0, this.cwd, ["package.json"]);
446
+ this.moduleType = !!pkg && JSON.parse(pkg).type === "module" ? "esm" : "cjs";
447
+ } catch (e5) {
448
+ }
449
+ this.entryFile = _path2.default.resolve(_process2.default.cwd(), "node_modules/.cache/mock-server/mock-server.ts");
450
+ }
451
+
452
+
453
+ __init() {this.moduleType = "cjs"}
454
+
455
+ __init2() {this._mockData = {}}
456
+
457
+
458
+
459
+ get mockData() {
460
+ return this._mockData;
461
+ }
462
+ async run() {
463
+ await this.updateMockEntry();
464
+ this.watchMockFiles();
465
+ const { plugins, alias } = this.options;
466
+ const options = {
467
+ isEsm: this.moduleType === "esm",
468
+ cwd: this.cwd,
469
+ plugins,
470
+ entryFile: this.entryFile,
471
+ alias,
472
+ watch: true
473
+ };
474
+ this.compiler = createCompiler(options, async ({ code }) => {
475
+ try {
476
+ const result = await loadFromCode({
477
+ filepath: "mock.bundle.js",
478
+ code,
479
+ isESM: this.moduleType === "esm",
480
+ cwd: this.cwd
481
+ });
482
+ this._mockData = _chunkZEC4FWWYcjs.transformMockData.call(void 0, _chunkZEC4FWWYcjs.transformRawData.call(void 0, result));
483
+ this.emit("update", this.watchInfo || {});
484
+ } catch (e) {
485
+ this.options.logger.error(e.stack || e.message);
486
+ }
487
+ });
488
+ }
489
+ close() {
490
+ this.mockWatcher.close();
491
+ _optionalChain([this, 'access', _15 => _15.compiler, 'optionalAccess', _16 => _16.close, 'call', _17 => _17(() => {
492
+ })]);
493
+ this.emit("close");
494
+ }
495
+ updateAlias(alias) {
496
+ this.options.alias = {
497
+ ...this.options.alias,
498
+ ...alias
499
+ };
500
+ }
501
+ async updateMockEntry() {
502
+ const files = await this.getMockFiles();
503
+ await writeMockEntryFile(this.entryFile, files, this.cwd);
504
+ }
505
+ async getMockFiles() {
506
+ const { include } = this.options;
507
+ const files = await _fastglob2.default.call(void 0, include, { cwd: this.cwd });
508
+ return files.filter(this.fileFilter);
509
+ }
510
+ watchMockFiles() {
511
+ const { include } = this.options;
512
+ const [firstGlob, ...otherGlob] = _utils.toArray.call(void 0, include);
513
+ const watcher = this.mockWatcher = _chokidar2.default.watch(firstGlob, {
514
+ ignoreInitial: true,
515
+ cwd: this.cwd
516
+ });
517
+ if (otherGlob.length > 0)
518
+ otherGlob.forEach((glob) => watcher.add(glob));
519
+ watcher.on("add", (filepath) => {
520
+ if (this.fileFilter(filepath)) {
521
+ this.watchInfo = { filepath, type: "add" };
522
+ this.updateMockEntry();
523
+ }
524
+ });
525
+ watcher.on("change", (filepath) => {
526
+ if (this.fileFilter(filepath)) {
527
+ this.watchInfo = { filepath, type: "change" };
528
+ }
529
+ });
530
+ watcher.on("unlink", async (filepath) => {
531
+ this.watchInfo = { filepath, type: "unlink" };
532
+ this.updateMockEntry();
533
+ });
534
+ }
535
+ }, _class);
536
+
537
+
538
+
539
+
540
+
541
+
542
+
543
+ exports.createMockMiddleware = createMockMiddleware; exports.resolvePluginOptions = resolvePluginOptions; exports.buildMockServer = buildMockServer; exports.createMockCompiler = createMockCompiler; exports.MockCompiler = MockCompiler;