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 +7 -7
- package/dist/chunk-4HRWYJ3E.cjs +546 -0
- package/dist/{chunk-YSJVV4SH.js → chunk-EY46RSAC.js} +84 -604
- package/dist/{chunk-I54ZNZWL.cjs → chunk-ZEC4FWWY.cjs} +83 -603
- package/dist/chunk-ZYUUWKWW.js +546 -0
- package/dist/helper.cjs +16 -5
- package/dist/helper.d.cts +2 -2
- package/dist/helper.d.ts +2 -2
- package/dist/helper.js +15 -4
- package/dist/index.cjs +103 -34
- package/dist/index.d.cts +14 -69
- package/dist/index.d.ts +14 -69
- package/dist/index.js +93 -24
- package/dist/mockWebsocket-CPuTAvL0.d.ts +76 -0
- package/dist/mockWebsocket-Dc9CZBfv.d.cts +76 -0
- package/dist/rsbuild.cjs +11 -9
- package/dist/rsbuild.d.cts +1 -1
- package/dist/rsbuild.d.ts +1 -1
- package/dist/rsbuild.js +4 -2
- package/dist/server.cjs +18 -0
- package/dist/server.d.cts +31 -0
- package/dist/server.d.ts +31 -0
- package/dist/server.js +18 -0
- package/dist/{types-C770q3L0.d.cts → types-BgpcN3jm.d.cts} +1 -1
- package/dist/{types-C770q3L0.d.ts → types-BgpcN3jm.d.ts} +1 -1
- package/package.json +11 -6
- package/dist/chunk-HTOWPFQ7.js +0 -20
- package/dist/chunk-KE2LVHUP.cjs +0 -20
- package/dist/chunk-OYBMX3GQ.cjs +0 -97
- package/dist/chunk-P5FOCSCE.js +0 -97
- package/dist/rspack-BB-Jtq4f.d.cts +0 -32
- package/dist/rspack-h3uerEgg.d.ts +0 -32
- package/dist/rspack.cjs +0 -9
- package/dist/rspack.d.cts +0 -11
- package/dist/rspack.d.ts +0 -11
- package/dist/rspack.js +0 -9
|
@@ -1,75 +1,3 @@
|
|
|
1
|
-
// src/core/utils.ts
|
|
2
|
-
import fs from "fs";
|
|
3
|
-
import path from "path";
|
|
4
|
-
import { parse as queryParse } from "querystring";
|
|
5
|
-
import { URL as URL2, fileURLToPath } from "url";
|
|
6
|
-
import os from "os";
|
|
7
|
-
import Debug from "debug";
|
|
8
|
-
import { match } from "path-to-regexp";
|
|
9
|
-
import { Volume, createFsFromVolume } from "memfs";
|
|
10
|
-
var packageDir = getDirname(import.meta.url);
|
|
11
|
-
var vfs = createFsFromVolume(new Volume());
|
|
12
|
-
function isStream(stream) {
|
|
13
|
-
return stream !== null && typeof stream === "object" && typeof stream.pipe === "function";
|
|
14
|
-
}
|
|
15
|
-
function isReadableStream(stream) {
|
|
16
|
-
return isStream(stream) && stream.readable !== false && typeof stream._read === "function" && typeof stream._readableState === "object";
|
|
17
|
-
}
|
|
18
|
-
function getDirname(importMetaUrl) {
|
|
19
|
-
return path.dirname(fileURLToPath(importMetaUrl));
|
|
20
|
-
}
|
|
21
|
-
var debug = Debug("rspack:mock");
|
|
22
|
-
function lookupFile(dir, formats, options) {
|
|
23
|
-
for (const format of formats) {
|
|
24
|
-
const fullPath = path.join(dir, format);
|
|
25
|
-
if (fs.existsSync(fullPath) && fs.statSync(fullPath).isFile()) {
|
|
26
|
-
const result = options?.pathOnly ? fullPath : fs.readFileSync(fullPath, "utf-8");
|
|
27
|
-
if (!options?.predicate || options.predicate(result))
|
|
28
|
-
return result;
|
|
29
|
-
}
|
|
30
|
-
}
|
|
31
|
-
const parentDir = path.dirname(dir);
|
|
32
|
-
if (parentDir !== dir && (!options?.rootDir || parentDir.startsWith(options?.rootDir))) {
|
|
33
|
-
return lookupFile(parentDir, formats, options);
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
function doesProxyContextMatchUrl(context, url, req) {
|
|
37
|
-
if (typeof context === "function") {
|
|
38
|
-
return context(url, req);
|
|
39
|
-
}
|
|
40
|
-
return context[0] === "^" && new RegExp(context).test(url) || url.startsWith(context);
|
|
41
|
-
}
|
|
42
|
-
function parseParams(pattern, url) {
|
|
43
|
-
const urlMatch = match(pattern, { decode: decodeURIComponent })(url) || {
|
|
44
|
-
params: {}
|
|
45
|
-
};
|
|
46
|
-
return urlMatch.params || {};
|
|
47
|
-
}
|
|
48
|
-
function urlParse(input) {
|
|
49
|
-
const url = new URL2(input, "http://example.com");
|
|
50
|
-
const pathname = decodeURIComponent(url.pathname);
|
|
51
|
-
const query = queryParse(url.search.replace(/^\?/, ""));
|
|
52
|
-
return { pathname, query };
|
|
53
|
-
}
|
|
54
|
-
var windowsSlashRE = /\\/g;
|
|
55
|
-
var isWindows = os.platform() === "win32";
|
|
56
|
-
function slash(p) {
|
|
57
|
-
return p.replace(windowsSlashRE, "/");
|
|
58
|
-
}
|
|
59
|
-
function normalizePath(id) {
|
|
60
|
-
return path.posix.normalize(isWindows ? slash(id) : id);
|
|
61
|
-
}
|
|
62
|
-
function waitingFor(onSuccess, maxRetry = 5) {
|
|
63
|
-
return function wait(getter, retry = 0) {
|
|
64
|
-
const value = getter();
|
|
65
|
-
if (value) {
|
|
66
|
-
onSuccess(value);
|
|
67
|
-
} else if (retry < maxRetry) {
|
|
68
|
-
setTimeout(() => wait(getter, retry + 1), 100);
|
|
69
|
-
}
|
|
70
|
-
};
|
|
71
|
-
}
|
|
72
|
-
|
|
73
1
|
// src/core/requestRecovery.ts
|
|
74
2
|
import { Buffer } from "buffer";
|
|
75
3
|
var requestCollectCache = /* @__PURE__ */ new WeakMap();
|
|
@@ -237,7 +165,7 @@ function matchingWeight(rules, url, priority) {
|
|
|
237
165
|
const options = special[specialRule];
|
|
238
166
|
const { rules: lowerRules, when } = isArray(options) ? { rules: options, when: [] } : options;
|
|
239
167
|
if (lowerRules.includes(matched[0])) {
|
|
240
|
-
if (when.length === 0 || when.some((
|
|
168
|
+
if (when.length === 0 || when.some((path2) => pathToRegexp(path2).test(url))) {
|
|
241
169
|
matched = uniq([specialRule, ...matched]);
|
|
242
170
|
}
|
|
243
171
|
}
|
|
@@ -304,6 +232,78 @@ async function parseMultipart(req, options) {
|
|
|
304
232
|
});
|
|
305
233
|
}
|
|
306
234
|
|
|
235
|
+
// src/core/utils.ts
|
|
236
|
+
import fs from "fs";
|
|
237
|
+
import path from "path";
|
|
238
|
+
import { parse as queryParse } from "querystring";
|
|
239
|
+
import { URL as URL2, fileURLToPath } from "url";
|
|
240
|
+
import os from "os";
|
|
241
|
+
import Debug from "debug";
|
|
242
|
+
import { match } from "path-to-regexp";
|
|
243
|
+
import { Volume, createFsFromVolume } from "memfs";
|
|
244
|
+
var packageDir = getDirname(import.meta.url);
|
|
245
|
+
var vfs = createFsFromVolume(new Volume());
|
|
246
|
+
function isStream(stream) {
|
|
247
|
+
return stream !== null && typeof stream === "object" && typeof stream.pipe === "function";
|
|
248
|
+
}
|
|
249
|
+
function isReadableStream(stream) {
|
|
250
|
+
return isStream(stream) && stream.readable !== false && typeof stream._read === "function" && typeof stream._readableState === "object";
|
|
251
|
+
}
|
|
252
|
+
function getDirname(importMetaUrl) {
|
|
253
|
+
return path.dirname(fileURLToPath(importMetaUrl));
|
|
254
|
+
}
|
|
255
|
+
var debug = Debug("rspack:mock");
|
|
256
|
+
function lookupFile(dir, formats, options) {
|
|
257
|
+
for (const format of formats) {
|
|
258
|
+
const fullPath = path.join(dir, format);
|
|
259
|
+
if (fs.existsSync(fullPath) && fs.statSync(fullPath).isFile()) {
|
|
260
|
+
const result = options?.pathOnly ? fullPath : fs.readFileSync(fullPath, "utf-8");
|
|
261
|
+
if (!options?.predicate || options.predicate(result))
|
|
262
|
+
return result;
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
const parentDir = path.dirname(dir);
|
|
266
|
+
if (parentDir !== dir && (!options?.rootDir || parentDir.startsWith(options?.rootDir))) {
|
|
267
|
+
return lookupFile(parentDir, formats, options);
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
function doesProxyContextMatchUrl(context, url, req) {
|
|
271
|
+
if (typeof context === "function") {
|
|
272
|
+
return context(url, req);
|
|
273
|
+
}
|
|
274
|
+
return context[0] === "^" && new RegExp(context).test(url) || url.startsWith(context);
|
|
275
|
+
}
|
|
276
|
+
function parseParams(pattern, url) {
|
|
277
|
+
const urlMatch = match(pattern, { decode: decodeURIComponent })(url) || {
|
|
278
|
+
params: {}
|
|
279
|
+
};
|
|
280
|
+
return urlMatch.params || {};
|
|
281
|
+
}
|
|
282
|
+
function urlParse(input) {
|
|
283
|
+
const url = new URL2(input, "http://example.com");
|
|
284
|
+
const pathname = decodeURIComponent(url.pathname);
|
|
285
|
+
const query = queryParse(url.search.replace(/^\?/, ""));
|
|
286
|
+
return { pathname, query };
|
|
287
|
+
}
|
|
288
|
+
var windowsSlashRE = /\\/g;
|
|
289
|
+
var isWindows = os.platform() === "win32";
|
|
290
|
+
function slash(p) {
|
|
291
|
+
return p.replace(windowsSlashRE, "/");
|
|
292
|
+
}
|
|
293
|
+
function normalizePath(id) {
|
|
294
|
+
return path.posix.normalize(isWindows ? slash(id) : id);
|
|
295
|
+
}
|
|
296
|
+
function waitingFor(onSuccess, maxRetry = 5) {
|
|
297
|
+
return function wait(getter, retry = 0) {
|
|
298
|
+
const value = getter();
|
|
299
|
+
if (value) {
|
|
300
|
+
onSuccess(value);
|
|
301
|
+
} else if (retry < maxRetry) {
|
|
302
|
+
setTimeout(() => wait(getter, retry + 1), 100);
|
|
303
|
+
}
|
|
304
|
+
};
|
|
305
|
+
}
|
|
306
|
+
|
|
307
307
|
// src/core/validator.ts
|
|
308
308
|
import { isArray as isArray2, isObject } from "@pengzhanbo/utils";
|
|
309
309
|
function validate(request, validator) {
|
|
@@ -600,50 +600,6 @@ function requestLog(request, filepath) {
|
|
|
600
600
|
return `${ms} ${pathname}${qs}${ps}${bs}${file}`;
|
|
601
601
|
}
|
|
602
602
|
|
|
603
|
-
// src/core/mockMiddleware.ts
|
|
604
|
-
import cors from "cors";
|
|
605
|
-
import { pathToRegexp as pathToRegexp3 } from "path-to-regexp";
|
|
606
|
-
function createMockMiddleware(compiler, options) {
|
|
607
|
-
function mockMiddleware(middlewares, reload) {
|
|
608
|
-
middlewares.unshift(baseMiddleware(compiler, options));
|
|
609
|
-
const corsMiddleware = createCorsMiddleware(compiler, options);
|
|
610
|
-
if (corsMiddleware) {
|
|
611
|
-
middlewares.unshift(corsMiddleware);
|
|
612
|
-
}
|
|
613
|
-
if (options.reload) {
|
|
614
|
-
compiler.on("update", () => reload?.());
|
|
615
|
-
}
|
|
616
|
-
return middlewares;
|
|
617
|
-
}
|
|
618
|
-
return mockMiddleware;
|
|
619
|
-
}
|
|
620
|
-
function createCorsMiddleware(compiler, options) {
|
|
621
|
-
let corsOptions = {};
|
|
622
|
-
const enabled = options.cors !== false;
|
|
623
|
-
if (enabled) {
|
|
624
|
-
corsOptions = {
|
|
625
|
-
...corsOptions,
|
|
626
|
-
...typeof options.cors === "boolean" ? {} : options.cors
|
|
627
|
-
};
|
|
628
|
-
}
|
|
629
|
-
const proxies = options.proxies;
|
|
630
|
-
return !enabled ? void 0 : function(req, res, next) {
|
|
631
|
-
const { pathname } = urlParse(req.url);
|
|
632
|
-
if (!pathname || proxies.length === 0 || !proxies.some(
|
|
633
|
-
(context) => doesProxyContextMatchUrl(context, req.url, req)
|
|
634
|
-
)) {
|
|
635
|
-
return next();
|
|
636
|
-
}
|
|
637
|
-
const mockData = compiler.mockData;
|
|
638
|
-
const mockUrl = Object.keys(mockData).find(
|
|
639
|
-
(key) => pathToRegexp3(key).test(pathname)
|
|
640
|
-
);
|
|
641
|
-
if (!mockUrl)
|
|
642
|
-
return next();
|
|
643
|
-
cors(corsOptions)(req, res, next);
|
|
644
|
-
};
|
|
645
|
-
}
|
|
646
|
-
|
|
647
603
|
// src/core/logger.ts
|
|
648
604
|
import { isBoolean } from "@pengzhanbo/utils";
|
|
649
605
|
import colors2 from "picocolors";
|
|
@@ -685,67 +641,13 @@ function createLogger(prefix, defaultLevel = "info") {
|
|
|
685
641
|
return logger;
|
|
686
642
|
}
|
|
687
643
|
|
|
688
|
-
// src/core/resolvePluginOptions.ts
|
|
689
|
-
import process from "process";
|
|
690
|
-
import { isBoolean as isBoolean2, toArray } from "@pengzhanbo/utils";
|
|
691
|
-
function resolvePluginOptions({
|
|
692
|
-
prefix = [],
|
|
693
|
-
wsPrefix = [],
|
|
694
|
-
cwd,
|
|
695
|
-
include = ["mock/**/*.mock.{js,ts,cjs,mjs,json,json5}"],
|
|
696
|
-
exclude = ["**/node_modules/**", "**/.vscode/**", "**/.git/**"],
|
|
697
|
-
reload = false,
|
|
698
|
-
log = "info",
|
|
699
|
-
cors: cors2 = true,
|
|
700
|
-
formidableOptions = {},
|
|
701
|
-
build = false,
|
|
702
|
-
cookiesOptions = {},
|
|
703
|
-
bodyParserOptions = {},
|
|
704
|
-
priority = {}
|
|
705
|
-
} = {}, { alias, context, plugins, proxies }) {
|
|
706
|
-
const logger = createLogger(
|
|
707
|
-
"rspack:mock",
|
|
708
|
-
isBoolean2(log) ? log ? "info" : "error" : log
|
|
709
|
-
);
|
|
710
|
-
return {
|
|
711
|
-
prefix,
|
|
712
|
-
wsPrefix,
|
|
713
|
-
cwd: cwd || context || process.cwd(),
|
|
714
|
-
include,
|
|
715
|
-
exclude,
|
|
716
|
-
reload,
|
|
717
|
-
cors: cors2,
|
|
718
|
-
cookiesOptions,
|
|
719
|
-
log,
|
|
720
|
-
formidableOptions: {
|
|
721
|
-
multiples: true,
|
|
722
|
-
...formidableOptions
|
|
723
|
-
},
|
|
724
|
-
bodyParserOptions,
|
|
725
|
-
priority,
|
|
726
|
-
build: build ? Object.assign(
|
|
727
|
-
{
|
|
728
|
-
serverPort: 8080,
|
|
729
|
-
dist: "mockServer",
|
|
730
|
-
log: "error"
|
|
731
|
-
},
|
|
732
|
-
typeof build === "object" ? build : {}
|
|
733
|
-
) : false,
|
|
734
|
-
alias,
|
|
735
|
-
plugins,
|
|
736
|
-
proxies,
|
|
737
|
-
wsProxies: toArray(wsPrefix),
|
|
738
|
-
logger
|
|
739
|
-
};
|
|
740
|
-
}
|
|
741
|
-
|
|
742
644
|
// src/core/transform.ts
|
|
743
645
|
import {
|
|
744
646
|
isEmptyObject as isEmptyObject3,
|
|
745
647
|
isFunction as isFunction2,
|
|
746
648
|
isObject as isObject2,
|
|
747
649
|
sortBy as sortBy2,
|
|
748
|
-
toArray
|
|
650
|
+
toArray
|
|
749
651
|
} from "@pengzhanbo/utils";
|
|
750
652
|
function transformRawData(rawData) {
|
|
751
653
|
return rawData.filter((item) => item[0]).map(([raw, __filepath__]) => {
|
|
@@ -775,7 +677,7 @@ function transformMockData(mockList) {
|
|
|
775
677
|
const list = [];
|
|
776
678
|
for (const [, handle] of mockList.entries()) {
|
|
777
679
|
if (handle)
|
|
778
|
-
list.push(...
|
|
680
|
+
list.push(...toArray(handle));
|
|
779
681
|
}
|
|
780
682
|
const mocks = {};
|
|
781
683
|
list.filter((mock) => isObject2(mock) && mock.enabled !== false && mock.url).forEach((mock) => {
|
|
@@ -826,433 +728,9 @@ function keysCount(obj) {
|
|
|
826
728
|
return Object.keys(obj).length;
|
|
827
729
|
}
|
|
828
730
|
|
|
829
|
-
// src/core/build.ts
|
|
830
|
-
import fs2 from "fs";
|
|
831
|
-
import fsp from "fs/promises";
|
|
832
|
-
import path3 from "path";
|
|
833
|
-
import process2 from "process";
|
|
834
|
-
import fg from "fast-glob";
|
|
835
|
-
import { createFilter } from "@rollup/pluginutils";
|
|
836
|
-
import color2 from "picocolors";
|
|
837
|
-
import { toArray as toArray3 } from "@pengzhanbo/utils";
|
|
838
|
-
|
|
839
|
-
// src/core/createRspackCompiler.ts
|
|
840
|
-
import path2 from "path";
|
|
841
|
-
import * as rspackCore from "@rspack/core";
|
|
842
|
-
import color from "picocolors";
|
|
843
|
-
import isCore from "is-core-module";
|
|
844
|
-
function createCompiler(options, callback) {
|
|
845
|
-
const rspackOptions = resolveRspackOptions(options);
|
|
846
|
-
const isWatch = rspackOptions.watch === true;
|
|
847
|
-
async function handler(err, stats) {
|
|
848
|
-
const name = "[rspack:mock]";
|
|
849
|
-
const logError = stats?.compilation.getLogger(name).error || ((...args) => console.error(color.red(name), ...args));
|
|
850
|
-
if (err) {
|
|
851
|
-
logError(err.stack || err);
|
|
852
|
-
if ("details" in err) {
|
|
853
|
-
logError(err.details);
|
|
854
|
-
}
|
|
855
|
-
return;
|
|
856
|
-
}
|
|
857
|
-
if (stats?.hasErrors()) {
|
|
858
|
-
const info = stats.toJson();
|
|
859
|
-
logError(info.errors);
|
|
860
|
-
}
|
|
861
|
-
const code = vfs.readFileSync("/output.js", "utf-8");
|
|
862
|
-
const externals = [];
|
|
863
|
-
if (!isWatch) {
|
|
864
|
-
const modules = stats?.toJson().modules || [];
|
|
865
|
-
const aliasList = Object.keys(options.alias || {}).map((key) => key.replace(/\$$/g, ""));
|
|
866
|
-
for (const { name: name2 } of modules) {
|
|
867
|
-
if (name2?.startsWith("external")) {
|
|
868
|
-
const packageName = normalizePackageName(name2);
|
|
869
|
-
if (!isCore(packageName) && !aliasList.includes(packageName))
|
|
870
|
-
externals.push(normalizePackageName(name2));
|
|
871
|
-
}
|
|
872
|
-
}
|
|
873
|
-
}
|
|
874
|
-
await callback({ code, externals });
|
|
875
|
-
}
|
|
876
|
-
const compiler = rspackCore.rspack(rspackOptions, isWatch ? handler : void 0);
|
|
877
|
-
if (compiler)
|
|
878
|
-
compiler.outputFileSystem = vfs;
|
|
879
|
-
if (!isWatch) {
|
|
880
|
-
compiler?.run(async (...args) => {
|
|
881
|
-
await handler(...args);
|
|
882
|
-
compiler.close(() => {
|
|
883
|
-
});
|
|
884
|
-
});
|
|
885
|
-
}
|
|
886
|
-
return compiler;
|
|
887
|
-
}
|
|
888
|
-
function transformWithRspack(options) {
|
|
889
|
-
return new Promise((resolve) => {
|
|
890
|
-
createCompiler({ ...options, watch: false }, (result) => {
|
|
891
|
-
resolve(result);
|
|
892
|
-
});
|
|
893
|
-
});
|
|
894
|
-
}
|
|
895
|
-
function normalizePackageName(name) {
|
|
896
|
-
const filepath = name.replace("external ", "").slice(1, -1);
|
|
897
|
-
const [scope, packageName] = filepath.split("/");
|
|
898
|
-
if (filepath[0] === "@") {
|
|
899
|
-
return `${scope}/${packageName}`;
|
|
900
|
-
}
|
|
901
|
-
return scope;
|
|
902
|
-
}
|
|
903
|
-
function resolveRspackOptions({
|
|
904
|
-
cwd,
|
|
905
|
-
isEsm = true,
|
|
906
|
-
entryFile,
|
|
907
|
-
plugins,
|
|
908
|
-
alias,
|
|
909
|
-
watch = false
|
|
910
|
-
}) {
|
|
911
|
-
const targets = ["node >= 18.0.0"];
|
|
912
|
-
return {
|
|
913
|
-
mode: "production",
|
|
914
|
-
context: cwd,
|
|
915
|
-
entry: entryFile,
|
|
916
|
-
watch,
|
|
917
|
-
target: "node18.0",
|
|
918
|
-
externalsType: isEsm ? "module" : "commonjs2",
|
|
919
|
-
externals: /^[^./].*/,
|
|
920
|
-
resolve: {
|
|
921
|
-
alias,
|
|
922
|
-
extensions: [".js", ".ts", ".cjs", ".mjs", ".json5", ".json"]
|
|
923
|
-
},
|
|
924
|
-
plugins,
|
|
925
|
-
output: {
|
|
926
|
-
library: { type: !isEsm ? "commonjs2" : "module" },
|
|
927
|
-
filename: "output.js",
|
|
928
|
-
path: "/"
|
|
929
|
-
},
|
|
930
|
-
experiments: { outputModule: isEsm },
|
|
931
|
-
optimization: { minimize: !watch },
|
|
932
|
-
module: {
|
|
933
|
-
rules: [
|
|
934
|
-
{
|
|
935
|
-
test: /\.json5?$/,
|
|
936
|
-
loader: path2.join(packageDir, "json5-loader.cjs"),
|
|
937
|
-
type: "javascript/auto"
|
|
938
|
-
},
|
|
939
|
-
{
|
|
940
|
-
test: /\.[cm]?js$/,
|
|
941
|
-
use: [
|
|
942
|
-
{
|
|
943
|
-
loader: "builtin:swc-loader",
|
|
944
|
-
options: {
|
|
945
|
-
jsc: { parser: { syntax: "ecmascript" } },
|
|
946
|
-
env: { targets }
|
|
947
|
-
}
|
|
948
|
-
}
|
|
949
|
-
]
|
|
950
|
-
},
|
|
951
|
-
{
|
|
952
|
-
test: /\.[cm]?ts$/,
|
|
953
|
-
use: [
|
|
954
|
-
{
|
|
955
|
-
loader: "builtin:swc-loader",
|
|
956
|
-
options: {
|
|
957
|
-
jsc: { parser: { syntax: "typescript" } },
|
|
958
|
-
env: { targets }
|
|
959
|
-
}
|
|
960
|
-
}
|
|
961
|
-
]
|
|
962
|
-
}
|
|
963
|
-
]
|
|
964
|
-
}
|
|
965
|
-
};
|
|
966
|
-
}
|
|
967
|
-
|
|
968
|
-
// src/core/build.ts
|
|
969
|
-
async function buildMockServer(options, outputDir) {
|
|
970
|
-
const entryFile = path3.resolve(process2.cwd(), "node_modules/.cache/mock-server/mock-server.ts");
|
|
971
|
-
const mockFileList = await getMockFileList(options);
|
|
972
|
-
await writeMockEntryFile(entryFile, mockFileList, options.cwd);
|
|
973
|
-
const { code, externals } = await transformWithRspack({
|
|
974
|
-
entryFile,
|
|
975
|
-
cwd: options.cwd,
|
|
976
|
-
plugins: options.plugins,
|
|
977
|
-
alias: options.alias
|
|
978
|
-
});
|
|
979
|
-
await fsp.unlink(entryFile);
|
|
980
|
-
const outputList = [
|
|
981
|
-
{ filename: "mock-data.js", source: code },
|
|
982
|
-
{ filename: "index.js", source: generatorServerEntryCode(options) },
|
|
983
|
-
{ filename: "package.json", source: generatePackageJson(options, externals) }
|
|
984
|
-
];
|
|
985
|
-
const dist = path3.resolve(outputDir, options.build.dist);
|
|
986
|
-
options.logger.info(
|
|
987
|
-
`${color2.green("\u2713")} generate mock server in ${color2.cyan(path3.relative(process2.cwd(), dist))}`
|
|
988
|
-
);
|
|
989
|
-
if (!fs2.existsSync(dist)) {
|
|
990
|
-
await fsp.mkdir(dist, { recursive: true });
|
|
991
|
-
}
|
|
992
|
-
for (const { filename, source } of outputList) {
|
|
993
|
-
await fsp.writeFile(path3.join(dist, filename), source, "utf8");
|
|
994
|
-
const sourceSize = (source.length / 1024).toFixed(2);
|
|
995
|
-
const space = filename.length < 24 ? " ".repeat(24 - filename.length) : "";
|
|
996
|
-
options.logger.info(` ${color2.green(filename)}${space}${color2.bold(color2.dim(`${sourceSize} kB`))}`);
|
|
997
|
-
}
|
|
998
|
-
}
|
|
999
|
-
function generatePackageJson(options, externals) {
|
|
1000
|
-
const deps = getHostDependencies(options.cwd);
|
|
1001
|
-
const { name, version } = getPluginPackageInfo();
|
|
1002
|
-
const mockPkg = {
|
|
1003
|
-
name: "mock-server",
|
|
1004
|
-
type: "module",
|
|
1005
|
-
scripts: {
|
|
1006
|
-
start: "node index.js"
|
|
1007
|
-
},
|
|
1008
|
-
dependencies: {
|
|
1009
|
-
connect: "^3.7.0",
|
|
1010
|
-
[name]: `^${version}`,
|
|
1011
|
-
cors: "^2.8.5"
|
|
1012
|
-
}
|
|
1013
|
-
};
|
|
1014
|
-
externals.forEach((dep) => {
|
|
1015
|
-
mockPkg.dependencies[dep] = deps[dep] || "latest";
|
|
1016
|
-
});
|
|
1017
|
-
return JSON.stringify(mockPkg, null, 2);
|
|
1018
|
-
}
|
|
1019
|
-
function generatorServerEntryCode({
|
|
1020
|
-
proxies,
|
|
1021
|
-
wsPrefix,
|
|
1022
|
-
cookiesOptions,
|
|
1023
|
-
bodyParserOptions,
|
|
1024
|
-
priority,
|
|
1025
|
-
build
|
|
1026
|
-
}) {
|
|
1027
|
-
const { serverPort, log } = build;
|
|
1028
|
-
return `import { createServer } from 'node:http';
|
|
1029
|
-
import connect from 'connect';
|
|
1030
|
-
import corsMiddleware from 'cors';
|
|
1031
|
-
import {
|
|
1032
|
-
baseMiddleware,
|
|
1033
|
-
createLogger,
|
|
1034
|
-
mockWebSocket,
|
|
1035
|
-
transformMockData,
|
|
1036
|
-
transformRawData
|
|
1037
|
-
} from 'rspack-plugin-mock';
|
|
1038
|
-
import rawData from './mock-data.js';
|
|
1039
|
-
|
|
1040
|
-
const app = connect();
|
|
1041
|
-
const server = createServer(app);
|
|
1042
|
-
const logger = createLogger('mock-server', '${log}');
|
|
1043
|
-
const proxies = ${JSON.stringify(proxies)};
|
|
1044
|
-
const wsProxies = ${JSON.stringify(toArray3(wsPrefix))};
|
|
1045
|
-
const cookiesOptions = ${JSON.stringify(cookiesOptions)};
|
|
1046
|
-
const bodyParserOptions = ${JSON.stringify(bodyParserOptions)};
|
|
1047
|
-
const priority = ${JSON.stringify(priority)};
|
|
1048
|
-
const data = { mockData: transformMockData(transformRawData(rawData)) };
|
|
1049
|
-
|
|
1050
|
-
mockWebSocket(data, server, { wsProxies, cookiesOptions, logger });
|
|
1051
|
-
|
|
1052
|
-
app.use(corsMiddleware());
|
|
1053
|
-
app.use(baseMiddleware(data, {
|
|
1054
|
-
formidableOptions: { multiples: true },
|
|
1055
|
-
proxies,
|
|
1056
|
-
priority,
|
|
1057
|
-
cookiesOptions,
|
|
1058
|
-
bodyParserOptions,
|
|
1059
|
-
logger,
|
|
1060
|
-
}));
|
|
1061
|
-
|
|
1062
|
-
server.listen(${serverPort});
|
|
1063
|
-
|
|
1064
|
-
console.log('listen: http://localhost:${serverPort}');
|
|
1065
|
-
`;
|
|
1066
|
-
}
|
|
1067
|
-
async function getMockFileList({ cwd, include, exclude }) {
|
|
1068
|
-
const filter = createFilter(include, exclude, { resolve: false });
|
|
1069
|
-
return await fg(include, { cwd }).then((files) => files.filter(filter));
|
|
1070
|
-
}
|
|
1071
|
-
async function writeMockEntryFile(entryFile, files, cwd) {
|
|
1072
|
-
const importers = [];
|
|
1073
|
-
const exporters = [];
|
|
1074
|
-
for (const [index, filepath] of files.entries()) {
|
|
1075
|
-
const file = normalizePath(path3.join(cwd, filepath));
|
|
1076
|
-
importers.push(`import * as m${index} from '${file}'`);
|
|
1077
|
-
exporters.push(`[m${index}, '${filepath}']`);
|
|
1078
|
-
}
|
|
1079
|
-
const code = `${importers.join("\n")}
|
|
1080
|
-
|
|
1081
|
-
export default [
|
|
1082
|
-
${exporters.join(",\n ")}
|
|
1083
|
-
]`;
|
|
1084
|
-
const dirname = path3.dirname(entryFile);
|
|
1085
|
-
if (!fs2.existsSync(dirname)) {
|
|
1086
|
-
await fsp.mkdir(dirname, { recursive: true });
|
|
1087
|
-
}
|
|
1088
|
-
await fsp.writeFile(entryFile, code, "utf8");
|
|
1089
|
-
}
|
|
1090
|
-
function getPluginPackageInfo() {
|
|
1091
|
-
let pkg = {};
|
|
1092
|
-
try {
|
|
1093
|
-
const filepath = path3.join(packageDir, "../package.json");
|
|
1094
|
-
if (fs2.existsSync(filepath)) {
|
|
1095
|
-
pkg = JSON.parse(fs2.readFileSync(filepath, "utf8"));
|
|
1096
|
-
}
|
|
1097
|
-
} catch {
|
|
1098
|
-
}
|
|
1099
|
-
return {
|
|
1100
|
-
name: pkg.name || "rspack-plugin-mock",
|
|
1101
|
-
version: pkg.version || "latest"
|
|
1102
|
-
};
|
|
1103
|
-
}
|
|
1104
|
-
function getHostDependencies(context) {
|
|
1105
|
-
let pkg = {};
|
|
1106
|
-
try {
|
|
1107
|
-
const content = lookupFile(context, ["package.json"]);
|
|
1108
|
-
if (content)
|
|
1109
|
-
pkg = JSON.parse(content);
|
|
1110
|
-
} catch {
|
|
1111
|
-
}
|
|
1112
|
-
return { ...pkg.dependencies, ...pkg.devDependencies };
|
|
1113
|
-
}
|
|
1114
|
-
|
|
1115
|
-
// src/core/mockCompiler.ts
|
|
1116
|
-
import EventEmitter from "events";
|
|
1117
|
-
import process3 from "process";
|
|
1118
|
-
import path5 from "path";
|
|
1119
|
-
import fastGlob from "fast-glob";
|
|
1120
|
-
import chokidar from "chokidar";
|
|
1121
|
-
import { createFilter as createFilter2 } from "@rollup/pluginutils";
|
|
1122
|
-
import { toArray as toArray4 } from "@pengzhanbo/utils";
|
|
1123
|
-
|
|
1124
|
-
// src/core/loadFromCode.ts
|
|
1125
|
-
import path4 from "path";
|
|
1126
|
-
import fs3, { promises as fsp2 } from "fs";
|
|
1127
|
-
async function loadFromCode({
|
|
1128
|
-
filepath,
|
|
1129
|
-
code,
|
|
1130
|
-
isESM,
|
|
1131
|
-
cwd
|
|
1132
|
-
}) {
|
|
1133
|
-
filepath = path4.resolve(cwd, filepath);
|
|
1134
|
-
const fileBase = `${filepath}.timestamp-${Date.now()}`;
|
|
1135
|
-
const ext = isESM ? ".mjs" : ".cjs";
|
|
1136
|
-
const fileNameTmp = `${fileBase}${ext}`;
|
|
1137
|
-
await fsp2.writeFile(fileNameTmp, code, "utf8");
|
|
1138
|
-
try {
|
|
1139
|
-
const result = await import(fileNameTmp);
|
|
1140
|
-
return result.default || result;
|
|
1141
|
-
} finally {
|
|
1142
|
-
try {
|
|
1143
|
-
fs3.unlinkSync(fileNameTmp);
|
|
1144
|
-
} catch {
|
|
1145
|
-
}
|
|
1146
|
-
}
|
|
1147
|
-
}
|
|
1148
|
-
|
|
1149
|
-
// src/core/mockCompiler.ts
|
|
1150
|
-
function createMockCompiler(options) {
|
|
1151
|
-
return new MockCompiler(options);
|
|
1152
|
-
}
|
|
1153
|
-
var MockCompiler = class extends EventEmitter {
|
|
1154
|
-
constructor(options) {
|
|
1155
|
-
super();
|
|
1156
|
-
this.options = options;
|
|
1157
|
-
this.cwd = options.cwd || process3.cwd();
|
|
1158
|
-
const { include, exclude } = this.options;
|
|
1159
|
-
this.fileFilter = createFilter2(include, exclude, { resolve: false });
|
|
1160
|
-
try {
|
|
1161
|
-
const pkg = lookupFile(this.cwd, ["package.json"]);
|
|
1162
|
-
this.moduleType = !!pkg && JSON.parse(pkg).type === "module" ? "esm" : "cjs";
|
|
1163
|
-
} catch {
|
|
1164
|
-
}
|
|
1165
|
-
this.entryFile = path5.resolve(process3.cwd(), "node_modules/.cache/mock-server/mock-server.ts");
|
|
1166
|
-
}
|
|
1167
|
-
cwd;
|
|
1168
|
-
mockWatcher;
|
|
1169
|
-
moduleType = "cjs";
|
|
1170
|
-
entryFile;
|
|
1171
|
-
_mockData = {};
|
|
1172
|
-
fileFilter;
|
|
1173
|
-
watchInfo;
|
|
1174
|
-
compiler;
|
|
1175
|
-
get mockData() {
|
|
1176
|
-
return this._mockData;
|
|
1177
|
-
}
|
|
1178
|
-
async run() {
|
|
1179
|
-
await this.updateMockEntry();
|
|
1180
|
-
this.watchMockFiles();
|
|
1181
|
-
const { plugins, alias } = this.options;
|
|
1182
|
-
const options = {
|
|
1183
|
-
isEsm: this.moduleType === "esm",
|
|
1184
|
-
cwd: this.cwd,
|
|
1185
|
-
plugins,
|
|
1186
|
-
entryFile: this.entryFile,
|
|
1187
|
-
alias,
|
|
1188
|
-
watch: true
|
|
1189
|
-
};
|
|
1190
|
-
this.compiler = createCompiler(options, async ({ code }) => {
|
|
1191
|
-
try {
|
|
1192
|
-
const result = await loadFromCode({
|
|
1193
|
-
filepath: "mock.bundle.js",
|
|
1194
|
-
code,
|
|
1195
|
-
isESM: this.moduleType === "esm",
|
|
1196
|
-
cwd: this.cwd
|
|
1197
|
-
});
|
|
1198
|
-
this._mockData = transformMockData(transformRawData(result));
|
|
1199
|
-
this.emit("update", this.watchInfo || {});
|
|
1200
|
-
} catch (e) {
|
|
1201
|
-
this.options.logger.error(e.stack || e.message);
|
|
1202
|
-
}
|
|
1203
|
-
});
|
|
1204
|
-
}
|
|
1205
|
-
close() {
|
|
1206
|
-
this.mockWatcher.close();
|
|
1207
|
-
this.compiler?.close(() => {
|
|
1208
|
-
});
|
|
1209
|
-
this.emit("close");
|
|
1210
|
-
}
|
|
1211
|
-
updateAlias(alias) {
|
|
1212
|
-
this.options.alias = {
|
|
1213
|
-
...this.options.alias,
|
|
1214
|
-
...alias
|
|
1215
|
-
};
|
|
1216
|
-
}
|
|
1217
|
-
async updateMockEntry() {
|
|
1218
|
-
const files = await this.getMockFiles();
|
|
1219
|
-
await writeMockEntryFile(this.entryFile, files, this.cwd);
|
|
1220
|
-
}
|
|
1221
|
-
async getMockFiles() {
|
|
1222
|
-
const { include } = this.options;
|
|
1223
|
-
const files = await fastGlob(include, { cwd: this.cwd });
|
|
1224
|
-
return files.filter(this.fileFilter);
|
|
1225
|
-
}
|
|
1226
|
-
watchMockFiles() {
|
|
1227
|
-
const { include } = this.options;
|
|
1228
|
-
const [firstGlob, ...otherGlob] = toArray4(include);
|
|
1229
|
-
const watcher = this.mockWatcher = chokidar.watch(firstGlob, {
|
|
1230
|
-
ignoreInitial: true,
|
|
1231
|
-
cwd: this.cwd
|
|
1232
|
-
});
|
|
1233
|
-
if (otherGlob.length > 0)
|
|
1234
|
-
otherGlob.forEach((glob) => watcher.add(glob));
|
|
1235
|
-
watcher.on("add", (filepath) => {
|
|
1236
|
-
if (this.fileFilter(filepath)) {
|
|
1237
|
-
this.watchInfo = { filepath, type: "add" };
|
|
1238
|
-
this.updateMockEntry();
|
|
1239
|
-
}
|
|
1240
|
-
});
|
|
1241
|
-
watcher.on("change", (filepath) => {
|
|
1242
|
-
if (this.fileFilter(filepath)) {
|
|
1243
|
-
this.watchInfo = { filepath, type: "change" };
|
|
1244
|
-
}
|
|
1245
|
-
});
|
|
1246
|
-
watcher.on("unlink", async (filepath) => {
|
|
1247
|
-
this.watchInfo = { filepath, type: "unlink" };
|
|
1248
|
-
this.updateMockEntry();
|
|
1249
|
-
});
|
|
1250
|
-
}
|
|
1251
|
-
};
|
|
1252
|
-
|
|
1253
731
|
// src/core/mockWebsocket.ts
|
|
1254
732
|
import Cookies2 from "cookies";
|
|
1255
|
-
import { pathToRegexp as
|
|
733
|
+
import { pathToRegexp as pathToRegexp3 } from "path-to-regexp";
|
|
1256
734
|
import colors3 from "picocolors";
|
|
1257
735
|
import { WebSocketServer } from "ws";
|
|
1258
736
|
function mockWebSocket(compiler, httpServer, {
|
|
@@ -1347,12 +825,12 @@ ${e}
|
|
|
1347
825
|
}
|
|
1348
826
|
const mockData = compiler.mockData;
|
|
1349
827
|
const mockUrl = Object.keys(mockData).find((key) => {
|
|
1350
|
-
return
|
|
828
|
+
return pathToRegexp3(key).test(pathname);
|
|
1351
829
|
});
|
|
1352
830
|
if (!mockUrl)
|
|
1353
831
|
return;
|
|
1354
832
|
const mock = mockData[mockUrl].find((mock2) => {
|
|
1355
|
-
return mock2.url && mock2.ws &&
|
|
833
|
+
return mock2.url && mock2.ws && pathToRegexp3(mock2.url).test(pathname);
|
|
1356
834
|
});
|
|
1357
835
|
if (!mock)
|
|
1358
836
|
return;
|
|
@@ -1408,17 +886,19 @@ function cleanupRunner(cleanupList) {
|
|
|
1408
886
|
}
|
|
1409
887
|
|
|
1410
888
|
export {
|
|
889
|
+
packageDir,
|
|
890
|
+
vfs,
|
|
891
|
+
lookupFile,
|
|
892
|
+
doesProxyContextMatchUrl,
|
|
893
|
+
urlParse,
|
|
894
|
+
normalizePath,
|
|
1411
895
|
waitingFor,
|
|
1412
896
|
rewriteRequest,
|
|
1413
897
|
baseMiddleware,
|
|
1414
|
-
createMockMiddleware,
|
|
1415
898
|
logLevels,
|
|
1416
899
|
createLogger,
|
|
1417
|
-
resolvePluginOptions,
|
|
1418
900
|
transformRawData,
|
|
1419
901
|
transformMockData,
|
|
1420
902
|
sortByValidator,
|
|
1421
|
-
buildMockServer,
|
|
1422
|
-
createMockCompiler,
|
|
1423
903
|
mockWebSocket
|
|
1424
904
|
};
|