vite-plugin-mock-dev-server 0.2.3 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -33,13 +33,15 @@ __export(src_exports, {
33
33
  module.exports = __toCommonJS(src_exports);
34
34
 
35
35
  // src/mockMiddleware.ts
36
- var import_node_url = require("url");
36
+ var import_node_url2 = require("url");
37
37
  var import_path_to_regexp = require("path-to-regexp");
38
38
 
39
39
  // src/MockLoader.ts
40
40
  var import_node_events = __toESM(require("events"), 1);
41
- var import_promises2 = __toESM(require("fs/promises"), 1);
41
+ var import_node_fs2 = __toESM(require("fs"), 1);
42
+ var import_node_module = require("module");
42
43
  var import_node_path2 = __toESM(require("path"), 1);
44
+ var import_node_url = require("url");
43
45
  var import_pluginutils = require("@rollup/pluginutils");
44
46
  var import_chokidar = __toESM(require("chokidar"), 1);
45
47
  var import_esbuild = require("esbuild");
@@ -47,7 +49,7 @@ var import_fast_glob = __toESM(require("fast-glob"), 1);
47
49
  var import_json5 = __toESM(require("json5"), 1);
48
50
 
49
51
  // src/utils.ts
50
- var import_promises = __toESM(require("fs/promises"), 1);
52
+ var import_node_fs = __toESM(require("fs"), 1);
51
53
  var import_node_path = __toESM(require("path"), 1);
52
54
  var import_debug = __toESM(require("debug"), 1);
53
55
  var isArray = (val) => Array.isArray(val);
@@ -56,25 +58,39 @@ function sleep(timeout) {
56
58
  return new Promise((resolve) => setTimeout(resolve, timeout));
57
59
  }
58
60
  var debug = (0, import_debug.default)("vite:plugin-mock-dev-server");
59
- async function getPackageDeps(cwd) {
60
- const filepath = import_node_path.default.resolve(cwd, "package.json");
61
- const content = await import_promises.default.readFile(filepath, "utf-8");
62
- const pkg = JSON.parse(content);
63
- const { dependencies = {}, devDependencies = {} } = pkg;
64
- const deps = [...Object.keys(dependencies), ...Object.keys(devDependencies)];
65
- return deps;
61
+ function lookupFile(dir, formats, options) {
62
+ for (const format of formats) {
63
+ const fullPath = import_node_path.default.join(dir, format);
64
+ if (import_node_fs.default.existsSync(fullPath) && import_node_fs.default.statSync(fullPath).isFile()) {
65
+ const result = (options == null ? void 0 : options.pathOnly) ? fullPath : import_node_fs.default.readFileSync(fullPath, "utf-8");
66
+ if (!(options == null ? void 0 : options.predicate) || options.predicate(result)) {
67
+ return result;
68
+ }
69
+ }
70
+ }
71
+ const parentDir = import_node_path.default.dirname(dir);
72
+ if (parentDir !== dir && (!(options == null ? void 0 : options.rootDir) || parentDir.startsWith(options == null ? void 0 : options.rootDir))) {
73
+ return lookupFile(parentDir, formats, options);
74
+ }
66
75
  }
67
76
 
68
77
  // src/MockLoader.ts
78
+ var import_meta = {};
79
+ var _require = (0, import_node_module.createRequire)(import_meta.url);
69
80
  var _MockLoader = class extends import_node_events.default {
70
81
  constructor(options) {
71
82
  super();
72
83
  this.moduleCache = /* @__PURE__ */ new Map();
73
84
  this.moduleDeps = /* @__PURE__ */ new Map();
74
85
  this._mockList = [];
86
+ this.moduleType = "cjs";
75
87
  this.options = options;
76
88
  this.cwd = options.cwd || process.cwd();
77
- this.tempDir = options.tempDir || "node_modules/.cache/.mock_server";
89
+ try {
90
+ const pkg = lookupFile(this.cwd, ["package.json"]);
91
+ this.moduleType = !!pkg && JSON.parse(pkg).type === "module" ? "esm" : "cjs";
92
+ } catch (e) {
93
+ }
78
94
  }
79
95
  get mockList() {
80
96
  return this._mockList;
@@ -90,13 +106,13 @@ var _MockLoader = class extends import_node_events.default {
90
106
  this.watchMockEntry();
91
107
  this.watchDeps();
92
108
  for (const filepath of includePaths.filter(includeFilter)) {
93
- await this.loadModule(filepath);
109
+ await this.loadMock(filepath);
94
110
  }
95
111
  this.updateMockList();
96
112
  this.on("mock:update", async (filepath) => {
97
113
  if (!includeFilter(filepath))
98
114
  return;
99
- await this.loadModule(filepath);
115
+ await this.loadMock(filepath);
100
116
  this.updateMockList();
101
117
  });
102
118
  this.on("mock:unlink", async (filepath) => {
@@ -181,58 +197,105 @@ var _MockLoader = class extends import_node_events.default {
181
197
  });
182
198
  this.emit("update:deps");
183
199
  }
184
- async loadModule(filepath) {
200
+ async loadMock(filepath) {
185
201
  if (!filepath)
186
202
  return;
187
203
  if (_MockLoader.EXT_JSON.test(filepath)) {
188
204
  await this.loadJson(filepath);
189
205
  } else {
190
- await this.loadESModule(filepath);
206
+ await this.loadModule(filepath);
191
207
  }
192
208
  }
193
209
  async loadJson(filepath) {
194
- const content = await import_promises2.default.readFile(filepath, "utf-8");
210
+ const content = await import_node_fs2.default.promises.readFile(filepath, "utf-8");
195
211
  try {
196
212
  const mockConfig = import_json5.default.parse(content);
197
213
  this.moduleCache.set(filepath, mockConfig);
198
214
  } catch (e) {
199
215
  }
200
216
  }
201
- async loadESModule(filepath) {
217
+ async loadModule(filepath) {
202
218
  if (!filepath)
203
219
  return;
204
- const { code, deps } = await this.transformWithEsbuild(filepath);
205
- const tempFile = import_node_path2.default.join(
206
- this.cwd,
207
- this.tempDir,
208
- filepath.replace(/\.(ts|js|cjs)$/, ".mjs")
209
- );
210
- const tempDirname = import_node_path2.default.dirname(tempFile);
211
- await import_promises2.default.mkdir(tempDirname, { recursive: true });
212
- await import_promises2.default.writeFile(tempFile, code, "utf8");
220
+ let isESM = false;
221
+ if (/\.m[jt]s$/.test(filepath)) {
222
+ isESM = true;
223
+ } else if (/\.c[jt]s$/.test(filepath)) {
224
+ isESM = false;
225
+ } else {
226
+ isESM = this.moduleType === "esm";
227
+ }
228
+ const { code, deps } = await this.transformWithEsbuild(filepath, isESM);
213
229
  try {
214
- const handle = await import(`${tempFile}?${Date.now()}`);
215
- const mockConfig = handle && handle.default ? handle.default : Object.keys(handle || {}).map((key) => handle[key]);
230
+ const raw = await this.loadFromCode(filepath, code, isESM);
231
+ const mockConfig = raw && raw.default ? raw.default : Object.keys(raw || {}).map((key) => raw[key]);
216
232
  this.moduleCache.set(filepath, mockConfig);
217
233
  this.updateModuleDeps(filepath, deps);
218
234
  } catch (e) {
219
235
  console.error(e);
220
236
  }
221
237
  }
222
- async transformWithEsbuild(filepath) {
238
+ async loadFromCode(filepath, code, isESM) {
239
+ if (isESM) {
240
+ const fileBase = `${filepath}.timestamp-${Date.now()}`;
241
+ const fileNameTmp = `${fileBase}.mjs`;
242
+ const fileUrl = `${(0, import_node_url.pathToFileURL)(fileBase)}.mjs`;
243
+ await import_node_fs2.default.promises.writeFile(fileNameTmp, code, "utf8");
244
+ try {
245
+ return await import(fileUrl);
246
+ } finally {
247
+ try {
248
+ import_node_fs2.default.unlinkSync(fileNameTmp);
249
+ } catch {
250
+ }
251
+ }
252
+ } else {
253
+ filepath = import_node_path2.default.resolve(this.cwd, filepath);
254
+ const extension = import_node_path2.default.extname(filepath);
255
+ const realFileName = import_node_fs2.default.realpathSync(filepath);
256
+ const loaderExt = extension in _require.extensions ? extension : ".js";
257
+ const defaultLoader = _require.extensions[loaderExt];
258
+ _require.extensions[loaderExt] = (module2, filename) => {
259
+ if (filename === realFileName) {
260
+ ;
261
+ module2._compile(code, filename);
262
+ } else {
263
+ defaultLoader(module2, filename);
264
+ }
265
+ };
266
+ delete _require.cache[_require.resolve(filepath)];
267
+ const raw = _require(filepath);
268
+ _require.extensions[loaderExt] = defaultLoader;
269
+ return raw.__esModule ? raw : { default: raw };
270
+ }
271
+ }
272
+ async transformWithEsbuild(filepath, isESM) {
223
273
  var _a;
224
274
  try {
225
275
  const result = await (0, import_esbuild.build)({
226
276
  entryPoints: [filepath],
227
277
  outfile: "out.js",
228
278
  write: false,
229
- target: "es2020",
279
+ target: ["node14.18", "node16"],
230
280
  platform: "node",
231
281
  bundle: true,
232
- external: this.options.external,
233
282
  metafile: true,
234
- format: "esm",
235
- define: this.options.define
283
+ format: isESM ? "esm" : "cjs",
284
+ define: this.options.define,
285
+ plugins: [
286
+ {
287
+ name: "externalize-deps",
288
+ setup(build2) {
289
+ build2.onResolve({ filter: /.*/ }, ({ path: id }) => {
290
+ if (id[0] !== "." && !import_node_path2.default.isAbsolute(id)) {
291
+ return {
292
+ external: true
293
+ };
294
+ }
295
+ });
296
+ }
297
+ }
298
+ ]
236
299
  });
237
300
  return {
238
301
  code: result.outputFiles[0].text,
@@ -286,11 +349,9 @@ function equalObj(left, right) {
286
349
  async function mockServerMiddleware(httpServer, config, options) {
287
350
  const include = isArray(options.include) ? options.include : [options.include];
288
351
  const exclude = isArray(options.exclude) ? options.exclude : [options.exclude];
289
- const external = await getPackageDeps(process.cwd());
290
352
  const loader = new MockLoader({
291
353
  include,
292
354
  exclude,
293
- external,
294
355
  define: config.define || {}
295
356
  });
296
357
  await loader.load();
@@ -301,7 +362,7 @@ async function mockServerMiddleware(httpServer, config, options) {
301
362
  return next();
302
363
  }
303
364
  const method = req.method.toUpperCase();
304
- const { query, pathname } = (0, import_node_url.parse)(req.url, true);
365
+ const { query, pathname } = (0, import_node_url2.parse)(req.url, true);
305
366
  const reqBody = await parseReqBody(req);
306
367
  const currentMock = loader.mockList.find((mock) => {
307
368
  if (!pathname || !mock || !mock.url)
package/dist/index.js CHANGED
@@ -4,8 +4,10 @@ import { match, pathToRegexp } from "path-to-regexp";
4
4
 
5
5
  // src/MockLoader.ts
6
6
  import EventEmitter from "events";
7
- import fs2 from "fs/promises";
7
+ import fs2 from "fs";
8
+ import { createRequire } from "module";
8
9
  import path2 from "path";
10
+ import { pathToFileURL } from "url";
9
11
  import { createFilter } from "@rollup/pluginutils";
10
12
  import chokidar from "chokidar";
11
13
  import { build } from "esbuild";
@@ -13,7 +15,7 @@ import fastGlob from "fast-glob";
13
15
  import JSON5 from "json5";
14
16
 
15
17
  // src/utils.ts
16
- import fs from "fs/promises";
18
+ import fs from "fs";
17
19
  import path from "path";
18
20
  import Debug from "debug";
19
21
  var isArray = (val) => Array.isArray(val);
@@ -22,25 +24,38 @@ function sleep(timeout) {
22
24
  return new Promise((resolve) => setTimeout(resolve, timeout));
23
25
  }
24
26
  var debug = Debug("vite:plugin-mock-dev-server");
25
- async function getPackageDeps(cwd) {
26
- const filepath = path.resolve(cwd, "package.json");
27
- const content = await fs.readFile(filepath, "utf-8");
28
- const pkg = JSON.parse(content);
29
- const { dependencies = {}, devDependencies = {} } = pkg;
30
- const deps = [...Object.keys(dependencies), ...Object.keys(devDependencies)];
31
- return deps;
27
+ function lookupFile(dir, formats, options) {
28
+ for (const format of formats) {
29
+ const fullPath = path.join(dir, format);
30
+ if (fs.existsSync(fullPath) && fs.statSync(fullPath).isFile()) {
31
+ const result = (options == null ? void 0 : options.pathOnly) ? fullPath : fs.readFileSync(fullPath, "utf-8");
32
+ if (!(options == null ? void 0 : options.predicate) || options.predicate(result)) {
33
+ return result;
34
+ }
35
+ }
36
+ }
37
+ const parentDir = path.dirname(dir);
38
+ if (parentDir !== dir && (!(options == null ? void 0 : options.rootDir) || parentDir.startsWith(options == null ? void 0 : options.rootDir))) {
39
+ return lookupFile(parentDir, formats, options);
40
+ }
32
41
  }
33
42
 
34
43
  // src/MockLoader.ts
44
+ var _require = createRequire(import.meta.url);
35
45
  var _MockLoader = class extends EventEmitter {
36
46
  constructor(options) {
37
47
  super();
38
48
  this.moduleCache = /* @__PURE__ */ new Map();
39
49
  this.moduleDeps = /* @__PURE__ */ new Map();
40
50
  this._mockList = [];
51
+ this.moduleType = "cjs";
41
52
  this.options = options;
42
53
  this.cwd = options.cwd || process.cwd();
43
- this.tempDir = options.tempDir || "node_modules/.cache/.mock_server";
54
+ try {
55
+ const pkg = lookupFile(this.cwd, ["package.json"]);
56
+ this.moduleType = !!pkg && JSON.parse(pkg).type === "module" ? "esm" : "cjs";
57
+ } catch (e) {
58
+ }
44
59
  }
45
60
  get mockList() {
46
61
  return this._mockList;
@@ -56,13 +71,13 @@ var _MockLoader = class extends EventEmitter {
56
71
  this.watchMockEntry();
57
72
  this.watchDeps();
58
73
  for (const filepath of includePaths.filter(includeFilter)) {
59
- await this.loadModule(filepath);
74
+ await this.loadMock(filepath);
60
75
  }
61
76
  this.updateMockList();
62
77
  this.on("mock:update", async (filepath) => {
63
78
  if (!includeFilter(filepath))
64
79
  return;
65
- await this.loadModule(filepath);
80
+ await this.loadMock(filepath);
66
81
  this.updateMockList();
67
82
  });
68
83
  this.on("mock:unlink", async (filepath) => {
@@ -147,58 +162,105 @@ var _MockLoader = class extends EventEmitter {
147
162
  });
148
163
  this.emit("update:deps");
149
164
  }
150
- async loadModule(filepath) {
165
+ async loadMock(filepath) {
151
166
  if (!filepath)
152
167
  return;
153
168
  if (_MockLoader.EXT_JSON.test(filepath)) {
154
169
  await this.loadJson(filepath);
155
170
  } else {
156
- await this.loadESModule(filepath);
171
+ await this.loadModule(filepath);
157
172
  }
158
173
  }
159
174
  async loadJson(filepath) {
160
- const content = await fs2.readFile(filepath, "utf-8");
175
+ const content = await fs2.promises.readFile(filepath, "utf-8");
161
176
  try {
162
177
  const mockConfig = JSON5.parse(content);
163
178
  this.moduleCache.set(filepath, mockConfig);
164
179
  } catch (e) {
165
180
  }
166
181
  }
167
- async loadESModule(filepath) {
182
+ async loadModule(filepath) {
168
183
  if (!filepath)
169
184
  return;
170
- const { code, deps } = await this.transformWithEsbuild(filepath);
171
- const tempFile = path2.join(
172
- this.cwd,
173
- this.tempDir,
174
- filepath.replace(/\.(ts|js|cjs)$/, ".mjs")
175
- );
176
- const tempDirname = path2.dirname(tempFile);
177
- await fs2.mkdir(tempDirname, { recursive: true });
178
- await fs2.writeFile(tempFile, code, "utf8");
185
+ let isESM = false;
186
+ if (/\.m[jt]s$/.test(filepath)) {
187
+ isESM = true;
188
+ } else if (/\.c[jt]s$/.test(filepath)) {
189
+ isESM = false;
190
+ } else {
191
+ isESM = this.moduleType === "esm";
192
+ }
193
+ const { code, deps } = await this.transformWithEsbuild(filepath, isESM);
179
194
  try {
180
- const handle = await import(`${tempFile}?${Date.now()}`);
181
- const mockConfig = handle && handle.default ? handle.default : Object.keys(handle || {}).map((key) => handle[key]);
195
+ const raw = await this.loadFromCode(filepath, code, isESM);
196
+ const mockConfig = raw && raw.default ? raw.default : Object.keys(raw || {}).map((key) => raw[key]);
182
197
  this.moduleCache.set(filepath, mockConfig);
183
198
  this.updateModuleDeps(filepath, deps);
184
199
  } catch (e) {
185
200
  console.error(e);
186
201
  }
187
202
  }
188
- async transformWithEsbuild(filepath) {
203
+ async loadFromCode(filepath, code, isESM) {
204
+ if (isESM) {
205
+ const fileBase = `${filepath}.timestamp-${Date.now()}`;
206
+ const fileNameTmp = `${fileBase}.mjs`;
207
+ const fileUrl = `${pathToFileURL(fileBase)}.mjs`;
208
+ await fs2.promises.writeFile(fileNameTmp, code, "utf8");
209
+ try {
210
+ return await import(fileUrl);
211
+ } finally {
212
+ try {
213
+ fs2.unlinkSync(fileNameTmp);
214
+ } catch {
215
+ }
216
+ }
217
+ } else {
218
+ filepath = path2.resolve(this.cwd, filepath);
219
+ const extension = path2.extname(filepath);
220
+ const realFileName = fs2.realpathSync(filepath);
221
+ const loaderExt = extension in _require.extensions ? extension : ".js";
222
+ const defaultLoader = _require.extensions[loaderExt];
223
+ _require.extensions[loaderExt] = (module, filename) => {
224
+ if (filename === realFileName) {
225
+ ;
226
+ module._compile(code, filename);
227
+ } else {
228
+ defaultLoader(module, filename);
229
+ }
230
+ };
231
+ delete _require.cache[_require.resolve(filepath)];
232
+ const raw = _require(filepath);
233
+ _require.extensions[loaderExt] = defaultLoader;
234
+ return raw.__esModule ? raw : { default: raw };
235
+ }
236
+ }
237
+ async transformWithEsbuild(filepath, isESM) {
189
238
  var _a;
190
239
  try {
191
240
  const result = await build({
192
241
  entryPoints: [filepath],
193
242
  outfile: "out.js",
194
243
  write: false,
195
- target: "es2020",
244
+ target: ["node14.18", "node16"],
196
245
  platform: "node",
197
246
  bundle: true,
198
- external: this.options.external,
199
247
  metafile: true,
200
- format: "esm",
201
- define: this.options.define
248
+ format: isESM ? "esm" : "cjs",
249
+ define: this.options.define,
250
+ plugins: [
251
+ {
252
+ name: "externalize-deps",
253
+ setup(build2) {
254
+ build2.onResolve({ filter: /.*/ }, ({ path: id }) => {
255
+ if (id[0] !== "." && !path2.isAbsolute(id)) {
256
+ return {
257
+ external: true
258
+ };
259
+ }
260
+ });
261
+ }
262
+ }
263
+ ]
202
264
  });
203
265
  return {
204
266
  code: result.outputFiles[0].text,
@@ -252,11 +314,9 @@ function equalObj(left, right) {
252
314
  async function mockServerMiddleware(httpServer, config, options) {
253
315
  const include = isArray(options.include) ? options.include : [options.include];
254
316
  const exclude = isArray(options.exclude) ? options.exclude : [options.exclude];
255
- const external = await getPackageDeps(process.cwd());
256
317
  const loader = new MockLoader({
257
318
  include,
258
319
  exclude,
259
- external,
260
320
  define: config.define || {}
261
321
  });
262
322
  await loader.load();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vite-plugin-mock-dev-server",
3
- "version": "0.2.3",
3
+ "version": "0.3.0",
4
4
  "keywords": [
5
5
  "vite",
6
6
  "plugin",