vite-plugin-mock-dev-server 1.1.5 → 1.1.7

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
@@ -11,7 +11,7 @@
11
11
  <a href="https://www.npmjs.com/package/vite-plugin-mock-dev-server"><img alt="npm" src="https://img.shields.io/npm/v/vite-plugin-mock-dev-server?style=flat-square"></a>
12
12
  <img alt="node-current" src="https://img.shields.io/node/v/vite-plugin-mock-dev-server?style=flat-square">
13
13
  <img alt="npm peer dependency version" src="https://img.shields.io/npm/dependency-version/vite-plugin-mock-dev-server/peer/vite?style=flat-square">
14
- <img alt="npm" src="https://img.shields.io/npm/dm/vite-plugin-mock-dev-server?style=flat-square">
14
+ <img alt="npm" src="https://img.shields.io/npm/dt/vite-plugin-mock-dev-server?style=flat-square">
15
15
  <br>
16
16
  <img alt="GitHub Workflow Status" src="https://img.shields.io/github/actions/workflow/status/pengzhanbo/vite-plugin-mock-dev-server/lint.yml?style=flat-square">
17
17
  <a href="https://app.fossa.com/projects/git%2Bgithub.com%2Fpengzhanbo%2Fvite-plugin-mock-dev-server?ref=badge_shield"><img alt="fossa status" src="https://app.fossa.com/api/projects/git%2Bgithub.com%2Fpengzhanbo%2Fvite-plugin-mock-dev-server.svg?type=shield"></a>
@@ -43,6 +43,7 @@
43
43
  - 🌈 Support `vite preview` mode.
44
44
  - 📤 Support `multipart` content-type,mock upload file.
45
45
  - 📥 Support mock download file.
46
+ - ⚜️ Support `WebSocket Mock`
46
47
  - 🗂 Support building small independent deployable mock services.
47
48
 
48
49
 
@@ -148,6 +149,18 @@ export default defineConfig({
148
149
 
149
150
  **Default:** `[]`
150
151
 
152
+ - `options.wsPrefix`
153
+
154
+ **类型:** `string | string[]`
155
+
156
+ Configure the matching rules for WebSocket service. Any request path starting with the value of `wsPrefix` and using the `ws/wss` protocol will be proxied to the corresponding target.
157
+
158
+ If the value of `wsPrefix` starts with `^`, it will be recognized as a RegExp.
159
+
160
+ > Different from using `viteConfig.server.proxy` by default for http mock, `websocket mock` does not use the ws-related configuration in `viteConfig.server.proxy`. Also, rules configured in `wsPrefix` cannot be configured simultaneously in `viteConfig.server.proxy`, as it will cause conflicts when starting the vite server because multiple instances of WebSocketServer cannot be implemented for the same request.
161
+ > This conflict is neither a problem with Vite nor with the plugin; it belongs to a reasonable error type. When switching between WebSocket Mock and WebSocket Proxy, please pay attention to avoid duplicate configurations that may cause conflicts.
162
+
163
+
151
164
  - `option.include`
152
165
 
153
166
  **Type:** `string | string[]`
@@ -162,14 +175,7 @@ export default defineConfig({
162
175
 
163
176
  When reading mock files for configuration, the files that need to be excluded can be a directory, glob, or an array.
164
177
 
165
- **Default:**
166
- ```ts
167
- [
168
- '**/node_modules/**',
169
- '**/.vscode/**',
170
- '**/.git/**',
171
- ]
172
- ```
178
+ **Default:** `['**/node_modules/**','**/.vscode/**','**/.git/**']`
173
179
 
174
180
  - `options.reload`
175
181
 
@@ -258,6 +264,7 @@ export default defineApiMock({
258
264
  ## Mock Configuration
259
265
 
260
266
  ```ts
267
+ // Configure the http mock
261
268
  export default defineMock({
262
269
  /**
263
270
  * Request address, supports the `/api/user/:id` format.
@@ -380,7 +387,41 @@ export default defineMock({
380
387
  res.end()
381
388
  }
382
389
  })
383
-
390
+ ```
391
+ ```ts
392
+ // Configure the WebSocket mock
393
+ export default defineMock({
394
+ /**
395
+ * Request address, supports the `/api/user/:id` format.
396
+ * The plugin matches the path through `path-to-regexp`.
397
+ * @see https://github.com/pillarjs/path-to-regexp
398
+ */
399
+ url: '/api/test',
400
+ /**
401
+ * Value must be explicitly specified as `true`.
402
+ * The plugin needs to make a judgment based on this field.
403
+ */
404
+ ws: true,
405
+ /**
406
+ * Configure the WebSocketServer
407
+ * @see https://github.com/websockets/ws/blob/master/doc/ws.md#class-websocketserver
408
+ * If there are some additional automatically executed tasks or loop
409
+ * tasks in the setup function,a callback needs to be passed in
410
+ * `onCleanup()` to clear these tasks.
411
+ * This is because when the plugin is hot updated,
412
+ * it needs to re-execute setup and clear previous tasks; otherwise,
413
+ * duplicate tasks may cause conflicts.
414
+ * `onCleanup()` can be called multiple times within setup.
415
+ * @type `(wss: WebSocketServer, context: SetupContext) => void`
416
+ */
417
+ setup(wss, { onCleanup }) {
418
+ wss.on('connection', (ws, request) => {
419
+ ws.on('message', (rawData) => {})
420
+ const timer = setInterval(() => ws.send('data'), 1000)
421
+ onCleanup(() => clearInterval(timer))
422
+ })
423
+ }
424
+ })
384
425
  ```
385
426
 
386
427
  ### Request/Response Enhance
@@ -650,6 +691,76 @@ export default defineMock({
650
691
  })
651
692
  ```
652
693
 
694
+ **exp:** Graphql
695
+ ```ts
696
+ import { buildSchema, graphql } from 'graphql'
697
+ const schema = buildSchema(`
698
+ type Query {
699
+ hello: String
700
+ }
701
+ `)
702
+ const rootValue = { hello: () => 'Hello world!' }
703
+
704
+ export default defineMock({
705
+ url: '/api/graphql',
706
+ method: 'POST',
707
+ body: async (request) => {
708
+ const source = request.body.source
709
+ const { data } = await graphql({ schema, rootValue, source })
710
+ return data
711
+ },
712
+ })
713
+ ```
714
+
715
+ ```ts
716
+ fetch('/api/graphql', {
717
+ method: 'POST',
718
+ body: JSON.stringify({ source: '{ hello }' })
719
+ })
720
+ ```
721
+
722
+ **exp:** WebSocket Mock
723
+ ```ts
724
+ // ws.mock.ts
725
+ export default defineMock({
726
+ url: '/socket.io',
727
+ ws: true,
728
+ setup(wss, { onCleanup }) {
729
+ const wsMap = new Map()
730
+ wss.on('connection', (ws, req) => {
731
+ const token = req.getCookie('token')
732
+ wsMap.set(token, ws)
733
+ ws.on('message', (raw) => {
734
+ const data = JSON.parse(String(raw))
735
+ if (data.type === 'ping') return
736
+ // Broadcast
737
+ for (const [_token, _ws] of wsMap.entires()) {
738
+ if (_token !== token)
739
+ _ws.send(raw)
740
+ }
741
+ })
742
+ })
743
+ wss.on('error', (err) => {
744
+ console.error(err)
745
+ })
746
+ onCleanup(() => wsMap.clear())
747
+ }
748
+ })
749
+ ```
750
+ ```ts
751
+ // app.ts
752
+ const ws = new WebSocket('ws://localhost:5173/socket.io')
753
+ ws.addEventListener('open', () => {
754
+ setInterval(() => {
755
+ // heartbeat
756
+ ws.send(JSON.stringify({ type: 'ping' }))
757
+ }, 1000)
758
+ }, { once: true })
759
+ ws.addEventListener('message', (raw) => {
760
+ console.log(raw)
761
+ })
762
+ ```
763
+
653
764
  ## Mock Services
654
765
 
655
766
  In some scenarios, it may be necessary to use the data provided by mock services for display purposes, but the project may have already been packaged, built and deployed without support from `vite` and this plugin's mock service. Since this plugin supports importing various `node` modules in mock files at the design stage, the mock file cannot be inline into client build code.
package/README.zh-CN.md CHANGED
@@ -13,7 +13,7 @@
13
13
  <a href="https://www.npmjs.com/package/vite-plugin-mock-dev-server"><img alt="npm" src="https://img.shields.io/npm/v/vite-plugin-mock-dev-server?style=flat-square"></a>
14
14
  <img alt="node-current" src="https://img.shields.io/node/v/vite-plugin-mock-dev-server?style=flat-square">
15
15
  <img alt="npm peer dependency version" src="https://img.shields.io/npm/dependency-version/vite-plugin-mock-dev-server/peer/vite?style=flat-square">
16
- <img alt="npm" src="https://img.shields.io/npm/dm/vite-plugin-mock-dev-server?style=flat-square">
16
+ <img alt="npm" src="https://img.shields.io/npm/dt/vite-plugin-mock-dev-server?style=flat-square">
17
17
  <br>
18
18
  <img alt="GitHub Workflow Status" src="https://img.shields.io/github/actions/workflow/status/pengzhanbo/vite-plugin-mock-dev-server/lint.yml?style=flat-square">
19
19
  <a href="https://app.fossa.com/projects/git%2Bgithub.com%2Fpengzhanbo%2Fvite-plugin-mock-dev-server?ref=badge_shield"><img alt="fossa status" src="https://app.fossa.com/api/projects/git%2Bgithub.com%2Fpengzhanbo%2Fvite-plugin-mock-dev-server.svg?type=shield"></a>
@@ -37,13 +37,14 @@
37
37
  - 🎨 可选择你喜欢的任意用于生成mock数据库,如 `mockjs`,或者不使用其他库
38
38
  - 📥 路径规则匹配,请求参数匹配
39
39
  - ⚙️ 随意开启或关闭对某个接口的 mock配置
40
- - - 📀 支持多种响应体数据类型,包括 `text/json/buffer/stream`.
40
+ - 📀 支持多种响应体数据类型,包括 `text/json/buffer/stream`.
41
41
  - ⚖️ 使用 `server.proxy` 配置
42
42
  - 🍕 支持在 mock文件中使用 `viteConfig.define`配置字段
43
43
  - ⚓️ 支持在 mock文件中使用 `viteConfig.resolve.alias` 路径别名
44
44
  - 🌈 支持 `vite preview` 模式
45
45
  - 📤 支持 multipart 类型,模拟文件上传
46
46
  - 📥 支持模拟文件下载
47
+ - ⚜️ 支持模拟 `WebSocket`
47
48
  - 🗂 支持构建可独立部署的小型mock服务
48
49
 
49
50
 
@@ -140,12 +141,22 @@ export default defineConfig({
140
141
 
141
142
  **类型:** `string | string[]`
142
143
 
143
- 为mock服务器配置自定义匹配规则。任何请求路径以 `prefix` 值开头的请求将被代理到对应的目标。如果 `prefix` 值以 ^ 开头,将被识别为 RegExp。
144
+ 为mock服务器配置自定义匹配规则。任何请求路径以 `prefix` 值开头的请求将被代理到对应的目标。如果 `prefix` 值以 `^` 开头,将被识别为 RegExp。
144
145
 
145
146
  > 一般情况下, `server.proxy` 已经足够满足需求,添加此项是为了与某些场景兼容。
146
147
 
147
148
  **默认值:** `[]`
148
149
 
150
+ - `options.wsPrefix`
151
+
152
+ **类型:** `string | string[]`
153
+
154
+ 配置 webSocket 服务 匹配规则。任何请求路径以 `wsPrefix` 值开头的 `ws/wss` 协议请求,将被代理到对应的目标。
155
+ 如果`wsPrefix`值以 `^` 开头,将被识别为 RegExp。
156
+
157
+ > 与 http mock 默认使用 `viteConfig.server.proxy` 不同的是,`websocket mock` 不会使用 `viteConfig.server.proxy` 中的 ws 相关的配置,且配置在 `wsPrefix` 中的规则,不能同时配置在 `viteConfig.server.proxy`中,因为会导致在 vite 在启动服务时产生冲突,因为不能对同一个请求实现多个的 `WebSocketServer`实例。
158
+ > 该冲突既不是 `vite` 的问题,也不是插件的问题,这属于合理的错误类型。在进行 `WebSocket Mock`和 `WebSocket Proxy` 切换时,请注意配置不要出现重复导致冲突。
159
+
149
160
  - `option.include`
150
161
 
151
162
  **类型:** `string | string[]`
@@ -160,14 +171,7 @@ export default defineConfig({
160
171
 
161
172
  配置读取 mock文件时,需要排除的文件, 可以是一个 目录、glob、或者一个数组
162
173
 
163
- **默认值:**
164
- ```ts
165
- [
166
- '**/node_modules/**',
167
- '**/.vscode/**',
168
- '**/.git/**',
169
- ]
170
- ```
174
+ **默认值:** `['**/node_modules/**', '**/.vscode/**', '**/.git/**']`
171
175
 
172
176
  - `options.reload`
173
177
 
@@ -254,6 +258,7 @@ export default defineApiMock({
254
258
  ## Mock 配置
255
259
 
256
260
  ```ts
261
+ // 配置 http mock
257
262
  export default defineMock({
258
263
  /**
259
264
  * 请求地址,支持 `/api/user/:id` 格式
@@ -376,7 +381,38 @@ export default defineMock({
376
381
  res.end()
377
382
  }
378
383
  })
379
-
384
+ ```
385
+ ```ts
386
+ // 配置 WebSocket mock
387
+ export default defineMock({
388
+ /**
389
+ * 请求地址,支持 `/api/user/:id` 格式
390
+ * 插件通过 `path-to-regexp` 匹配路径
391
+ * @see https://github.com/pillarjs/path-to-regexp
392
+ */
393
+ url: '/api/test',
394
+ /**
395
+ * 必须显式的指定值为 `true`
396
+ * 插件内部需要根据此值进行判断
397
+ */
398
+ ws: true,
399
+ /**
400
+ * 配置 WebSocketServer
401
+ * @see https://github.com/websockets/ws/blob/master/doc/ws.md#class-websocketserver
402
+ * 如果在 setup 函数中有一些 额外的 自动执行任务或循环任务,
403
+ * 那么需要在 `onCleanup()` 传入一个回调,用于清除这些任务,
404
+ * 这是由于插件在热更新时,需要重新执行 setup,需要清除之前的任务,否则可能会导致重复任务产生冲突。
405
+ * `onCleanup()`可以在 setup 内部多次调用
406
+ * @type `(wss: WebSocketServer, context: SetupContext) => void`
407
+ */
408
+ setup(wss, { onCleanup }) {
409
+ wss.on('connection', (ws, request) => {
410
+ ws.on('message', (rawData) => {})
411
+ const timer = setInterval(() => ws.send('data'), 1000)
412
+ onCleanup(() => clearInterval(timer))
413
+ })
414
+ }
415
+ })
380
416
  ```
381
417
 
382
418
  ### Request/Response 增强
@@ -645,6 +681,76 @@ export default defineMock({
645
681
  })
646
682
  ```
647
683
 
684
+ **exp:** Graphql
685
+ ```ts
686
+ import { buildSchema, graphql } from 'graphql'
687
+ const schema = buildSchema(`
688
+ type Query {
689
+ hello: String
690
+ }
691
+ `)
692
+ const rootValue = { hello: () => 'Hello world!' }
693
+
694
+ export default defineMock({
695
+ url: '/api/graphql',
696
+ method: 'POST',
697
+ body: async (request) => {
698
+ const source = request.body.source
699
+ const { data } = await graphql({ schema, rootValue, source })
700
+ return data
701
+ },
702
+ })
703
+ ```
704
+
705
+ ```ts
706
+ fetch('/api/graphql', {
707
+ method: 'POST',
708
+ body: JSON.stringify({ source: '{ hello }' })
709
+ })
710
+ ```
711
+
712
+ **exp:** WebSocket Mock
713
+ ```ts
714
+ // ws.mock.ts
715
+ export default defineMock({
716
+ url: '/socket.io',
717
+ ws: true,
718
+ setup(wss, { onCleanup }) {
719
+ const wsMap = new Map()
720
+ wss.on('connection', (ws, req) => {
721
+ const token = req.getCookie('token')
722
+ wsMap.set(token, ws)
723
+ ws.on('message', (raw) => {
724
+ const data = JSON.parse(String(raw))
725
+ if (data.type === 'ping') return
726
+ // Broadcast
727
+ for (const [_token, _ws] of wsMap.entires()) {
728
+ if (_token !== token)
729
+ _ws.send(raw)
730
+ }
731
+ })
732
+ })
733
+ wss.on('error', (err) => {
734
+ console.error(err)
735
+ })
736
+ onCleanup(() => wsMap.clear())
737
+ }
738
+ })
739
+ ```
740
+ ```ts
741
+ // app.ts
742
+ const ws = new WebSocket('ws://localhost:5173/socket.io')
743
+ ws.addEventListener('open', () => {
744
+ setInterval(() => {
745
+ // heartbeat
746
+ ws.send(JSON.stringify({ type: 'ping' }))
747
+ }, 1000)
748
+ }, { once: true })
749
+ ws.addEventListener('message', (raw) => {
750
+ console.log(raw)
751
+ })
752
+ ```
753
+
648
754
  ## 独立部署的小型mock服务
649
755
 
650
756
  在一些场景中,可能会需要使用mock服务提供的数据支持,用于展示,但可能项目已完成打包构建部署,已脱离 `vite` 和本插件提供的 mock服务支持。由于本插件在设计之初,支持在mock文件中引入各种 `node` 模块,所以不能将 mock文件打包内联到客户端构建代码中。
package/dist/index.cjs CHANGED
@@ -1,32 +1,41 @@
1
- "use strict";var Ge=Object.create;var J=Object.defineProperty;var Qe=Object.getOwnPropertyDescriptor;var Xe=Object.getOwnPropertyNames;var Ke=Object.getPrototypeOf,Ve=Object.prototype.hasOwnProperty;var Ye=(t,o)=>{for(var e in o)J(t,e,{get:o[e],enumerable:!0})},le=(t,o,e,r)=>{if(o&&typeof o=="object"||typeof o=="function")for(let n of Xe(o))!Ve.call(t,n)&&n!==e&&J(t,n,{get:()=>o[n],enumerable:!(r=Qe(o,n))||r.enumerable});return t};var l=(t,o,e)=>(e=t!=null?Ge(Ke(t)):{},le(o||!t||!t.__esModule?J(e,"default",{value:t,enumerable:!0}):e,t)),Ze=t=>le(J({},"__esModule",{value:!0}),t);var xt={};Ye(xt,{baseMiddleware:()=>te,createDefineMock:()=>bt,default:()=>Mt,defineMock:()=>vt,mockDevServerPlugin:()=>ae,transformMockData:()=>oe});module.exports=Ze(xt);var et=()=>typeof document>"u"?new URL("file:"+__filename).href:document.currentScript&&document.currentScript.src||new URL("main.js",document.baseURI).href,f=et();var je=l(require("fs"),1),F=l(require("fs/promises"),1),w=l(require("path"),1),Re=require("esbuild"),Se=l(require("fast-glob"),1),Pe=l(require("is-core-module"),1),H=require("vite");var de="vite-plugin-mock-dev-server",me="1.1.5";var Q=l(require("fs/promises"),1),fe=l(require("path"),1),ge=l(require("json5"),1),U={name:"externalize-deps",setup(t){t.onResolve({filter:/.*/},({path:o})=>{if(o[0]!=="."&&!fe.default.isAbsolute(o))return{external:!0}})}},ye={name:"json5-loader",setup(t){t.onLoad({filter:/\.json5$/},async({path:o})=>{let e=await Q.default.readFile(o,"utf-8");return{contents:`export default ${JSON.stringify(ge.default.parse(e))}`,loader:"js"}})}},ke={name:"json-loader",setup(t){t.onLoad({filter:/\.json$/},async({path:o})=>({contents:`export default ${await Q.default.readFile(o,"utf-8")}`,loader:"js"}))}},A=t=>({name:"alias-plugin",setup(o){o.onResolve({filter:/.*/},async({path:e})=>{let r=t.find(({find:a})=>tt(a,e));if(!r)return null;let{find:n,replacement:s}=r;return{path:(await o.resolve(e.replace(n,s),{kind:"import-statement",resolveDir:s,namespace:"file"})).path,external:!1}})}});function tt(t,o){return t instanceof RegExp?t.test(o):o.length<t.length?!1:o===t?!0:o.startsWith(`${t}/`)}var _=l(require("fs"),1),q=l(require("path"),1),he=require("url"),ve=l(require("debug"),1),be=require("path-to-regexp"),X=l(require("picocolors"),1),v=t=>Array.isArray(t),b=t=>typeof t=="function",ot=t=>Object.prototype.toString.call(t)==="[object Object]",Me=t=>ot(t)&&Object.keys(t).length===0,rt=t=>t!==null&&typeof t=="object"&&typeof t.pipe=="function",xe=t=>rt(t)&&t.readable!==!1&&typeof t._read=="function"&&typeof t._readableState=="object";function we(t){return new Promise(o=>setTimeout(o,t))}function Oe(t){return q.default.dirname((0,he.fileURLToPath)(t))}var S=(0,ve.default)("vite:plugin-mock-dev-server"),M=t=>v(t)?t:t==null?[]:[t],P={info(...t){console.info(X.default.cyan("mock-dev-server: "),...t)},error(...t){console.error(`
2
- `,X.default.cyan("mock-dev-server: "),...t,`
3
- `)}};function E(t,o,e){for(let n of o){let s=q.default.join(t,n);if(_.default.existsSync(s)&&_.default.statSync(s).isFile()){let i=e!=null&&e.pathOnly?s:_.default.readFileSync(s,"utf-8");if(!(e!=null&&e.predicate)||e.predicate(i))return i}}let r=q.default.dirname(t);if(r!==t&&(!(e!=null&&e.rootDir)||r.startsWith(e==null?void 0:e.rootDir)))return E(r,o,e)}var z=(t={})=>Object.keys(t).map(e=>{var n,s;let r=t[e];return typeof r=="string"?e:r.ws||(n=r.target)!=null&&n.toString().startsWith("ws:")||(s=r.target)!=null&&s.toString().startsWith("wss:")?"":e}).filter(Boolean);function K(t,o){return((0,be.match)(t,{decode:decodeURIComponent})(o)||{params:{}}).params||{}}async function De(t,o,e){let r=M(e.include),n=M(e.exclude),s={};if(o.define)for(let g in o.define){let m=o.define[g];s[g]=typeof m=="string"?m:JSON.stringify(m)}let i=z(o.server.proxy||{}),a=M(e.prefix),c={};try{let g=E(o.root,["package.json"]);g&&(c=JSON.parse(g))}catch{}let p=e.build.dist,d=await at(process.cwd(),r,n),u=w.default.join(o.root,`mock-data-${Date.now()}.js`);await F.default.writeFile(u,d,"utf-8");let{code:W,deps:N}=await ct(u,s,o.resolve.alias),R=nt(N);await F.default.unlink(u);let C=[{filename:w.default.join(p,"mock-data.js"),source:W},{filename:w.default.join(p,"index.js"),source:it([...a,...i],e.cookiesOptions,e.build.serverPort)},{filename:w.default.join(p,"package.json"),source:st(c,R)}];try{if(w.default.isAbsolute(p)){await F.default.rm(p,{recursive:!0}),je.default.mkdirSync(p,{recursive:!0});for(let{filename:g,source:m}of C)await F.default.writeFile(g,m,"utf-8")}else for(let{filename:g,source:m}of C)t.emitFile({type:"asset",fileName:g,source:m})}catch{}}function nt(t){let o=new Set,e=[de,"connect","cors"];return Object.keys(t).forEach(r=>{t[r].imports.filter(s=>s.external).map(s=>s.path).forEach(s=>{!e.includes(s)&&!(0,Pe.default)(s)&&o.add(s)})}),Array.from(o)}function st(t,o){let{dependencies:e={},devDependencies:r={}}=t,n={...e,...r},s={name:"mock-server",type:"module",scripts:{start:"node index.js"},dependencies:{connect:"^3.7.0","vite-plugin-mock-dev-server":`^${me}`,cors:"^2.8.5"},pnpm:{peerDependencyRules:{ignoreMissing:["vite"]}}};return o.forEach(i=>{s.dependencies[i]=n[i]||"latest"}),JSON.stringify(s,null,2)}function it(t,o={},e=8080){return`import connect from 'connect';
1
+ "use strict";var Ye=Object.create;var A=Object.defineProperty;var Ze=Object.getOwnPropertyDescriptor;var et=Object.getOwnPropertyNames;var tt=Object.getPrototypeOf,ot=Object.prototype.hasOwnProperty;var rt=(e,o)=>{for(var t in o)A(e,t,{get:o[t],enumerable:!0})},ye=(e,o,t,r)=>{if(o&&typeof o=="object"||typeof o=="function")for(let n of et(o))!ot.call(e,n)&&n!==t&&A(e,n,{get:()=>o[n],enumerable:!(r=Ze(o,n))||r.enumerable});return e};var l=(e,o,t)=>(t=e!=null?Ye(tt(e)):{},ye(o||!e||!e.__esModule?A(t,"default",{value:e,enumerable:!0}):t,e)),nt=e=>ye(A({},"__esModule",{value:!0}),e);var jt={};rt(jt,{baseMiddleware:()=>ae,createDefineMock:()=>Ot,default:()=>St,defineMock:()=>wt,mockDevServerPlugin:()=>ge,mockWebSocket:()=>fe,transformMockData:()=>pe});module.exports=nt(jt);var st=()=>typeof document>"u"?new URL("file:"+__filename).href:document.currentScript&&document.currentScript.src||new URL("main.js",document.baseURI).href,x=st();var De=l(require("fs"),1),U=l(require("fs/promises"),1),I=l(require("path"),1),We=require("esbuild"),Ie=l(require("fast-glob"),1),Ee=l(require("is-core-module"),1),Y=require("vite");var ve="vite-plugin-mock-dev-server",Me="1.1.7";var oe=l(require("fs/promises"),1),be=l(require("path"),1),xe=l(require("json5"),1),B={name:"externalize-deps",setup(e){e.onResolve({filter:/.*/},({path:o})=>{if(o[0]!=="."&&!be.default.isAbsolute(o))return{external:!0}})}},J={name:"json5-loader",setup(e){e.onLoad({filter:/\.json5$/},async({path:o})=>{let t=await oe.default.readFile(o,"utf-8");return{contents:`export default ${JSON.stringify(xe.default.parse(t))}`,loader:"js"}})}},z={name:"json-loader",setup(e){e.onLoad({filter:/\.json$/},async({path:o})=>({contents:`export default ${await oe.default.readFile(o,"utf-8")}`,loader:"js"}))}},G=e=>({name:"alias-plugin",setup(o){o.onResolve({filter:/.*/},async({path:t})=>{let r=e.find(({find:c})=>it(c,t));if(!r)return null;let{find:n,replacement:s}=r;return{path:(await o.resolve(t.replace(n,s),{kind:"import-statement",resolveDir:s,namespace:"file"})).path,external:!1}})}});function it(e,o){return e instanceof RegExp?e.test(o):o.length<e.length?!1:o===e?!0:o.startsWith(`${e}/`)}var Q=l(require("fs"),1),X=l(require("path"),1),we=require("url"),Oe=l(require("debug"),1),Se=require("path-to-regexp"),re=l(require("picocolors"),1),S=e=>Array.isArray(e),C=e=>typeof e=="function",ct=e=>Object.prototype.toString.call(e)==="[object Object]",je=e=>ct(e)&&Object.keys(e).length===0,at=e=>e!==null&&typeof e=="object"&&typeof e.pipe=="function",Pe=e=>at(e)&&e.readable!==!1&&typeof e._read=="function"&&typeof e._readableState=="object";function Re(e){return new Promise(o=>setTimeout(o,e))}function Ce(e){return X.default.dirname((0,we.fileURLToPath)(e))}var D=(0,Oe.default)("vite:plugin-mock-dev-server"),j=e=>S(e)?e:e==null?[]:[e],T={info(...e){console.info(re.default.cyan("mock-dev-server: "),...e)},error(...e){console.error(`
2
+ `,re.default.cyan("mock-dev-server: "),...e,`
3
+ `)}};function H(e,o,t){for(let n of o){let s=X.default.join(e,n);if(Q.default.existsSync(s)&&Q.default.statSync(s).isFile()){let i=t!=null&&t.pathOnly?s:Q.default.readFileSync(s,"utf-8");if(!(t!=null&&t.predicate)||t.predicate(i))return i}}let r=X.default.dirname(e);if(r!==e&&(!(t!=null&&t.rootDir)||r.startsWith(t==null?void 0:t.rootDir)))return H(r,o,t)}var K=(e={})=>{let o=[],t=[];return Object.keys(e).forEach(r=>{var s,i;let n=e[r];typeof n=="string"||!n.ws&&!((s=n.target)!=null&&s.toString().startsWith("ws:"))&&!((i=n.target)!=null&&i.toString().startsWith("wss:"))?o.push(r):t.push(r)}),{httpProxies:o,wsProxies:t}};function V(e,o){return e[0]==="^"&&new RegExp(e).test(o)||o.startsWith(e)}function _(e,o){return((0,Se.match)(e,{decode:decodeURIComponent})(o)||{params:{}}).params||{}}async function Le(e,o,t){let r=j(t.include),n=j(t.exclude),s={};if(o.define)for(let k in o.define){let m=o.define[k];s[k]=typeof m=="string"?m:JSON.stringify(m)}let{httpProxies:i}=K(o.server.proxy||{});i.push(...j(t.prefix));let c=j(t.wsPrefix),a={};try{let k=H(o.root,["package.json"]);k&&(a=JSON.parse(k))}catch{}let p=t.build.dist,d=await mt(process.cwd(),r,n),u=I.default.join(o.root,`mock-data-${Date.now()}.js`);await U.default.writeFile(u,d,"utf-8");let{code:w,deps:v}=await dt(u,s,o.resolve.alias),g=pt(v);await U.default.unlink(u);let y=[{filename:I.default.join(p,"mock-data.js"),source:w},{filename:I.default.join(p,"index.js"),source:lt(i,c,t.cookiesOptions,t.build.serverPort)},{filename:I.default.join(p,"package.json"),source:ut(a,g)}];try{if(I.default.isAbsolute(p)){await U.default.rm(p,{recursive:!0}),De.default.mkdirSync(p,{recursive:!0});for(let{filename:k,source:m}of y)await U.default.writeFile(k,m,"utf-8")}else for(let{filename:k,source:m}of y)e.emitFile({type:"asset",fileName:k,source:m})}catch{}}function pt(e){let o=new Set,t=[ve,"connect","cors"];return Object.keys(e).forEach(r=>{e[r].imports.filter(s=>s.external).map(s=>s.path).forEach(s=>{!t.includes(s)&&!(0,Ee.default)(s)&&o.add(s)})}),Array.from(o)}function ut(e,o){let{dependencies:t={},devDependencies:r={}}=e,n={...t,...r},s={name:"mock-server",type:"module",scripts:{start:"node index.js"},dependencies:{connect:"^3.7.0","vite-plugin-mock-dev-server":`^${Me}`,cors:"^2.8.5"},pnpm:{peerDependencyRules:{ignoreMissing:["vite"]}}};return o.forEach(i=>{s.dependencies[i]=n[i]||"latest"}),JSON.stringify(s,null,2)}function lt(e,o,t={},r=8080){return`import { createServer } from 'node:http';
4
+ import connect from 'connect';
4
5
  import corsMiddleware from 'cors';
5
- import { baseMiddleware } from 'vite-plugin-mock-dev-server';
6
+ import { baseMiddleware, mockWebSocket } from 'vite-plugin-mock-dev-server';
6
7
  import mockData from './mock-data.js';
7
8
 
8
9
  const app = connect();
10
+ const server = createServer(app);
11
+ const httpProxies = ${JSON.stringify(e)};
12
+ const wxProxies = ${JSON.stringify(o)}
13
+ const cookiesOptions = ${JSON.stringify(t)};
14
+
15
+ mockWebSocket({ mockData }, server, wxProxies, cookiesOptions)
16
+
9
17
  app.use(corsMiddleware());
10
18
  app.use(baseMiddleware({ mockData }, {
11
19
  formidableOptions: { multiples: true },
12
- proxies: ${JSON.stringify(t)}
13
- cookiesOptions: ${JSON.stringify(o)}
20
+ proxies: httpProxies,
21
+ cookiesOptions,
14
22
  }));
15
- app.listen(${e});
16
23
 
17
- console.log('listen: http://localhost:${e}');
18
- `}async function at(t,o,e){let r=await(0,Se.default)(o,{cwd:t}),n=(0,H.createFilter)(o,e,{resolve:!1}),s=r.filter(n),i="",a="";return s.forEach((c,p)=>{let d=(0,H.normalizePath)(w.default.join(t,c));i+=`import * as m${p} from '${d}';
19
- `,a+=`m${p}, `}),`import { transformMockData } from 'vite-plugin-mock-dev-server';
24
+ server.listen(${r});
25
+
26
+ console.log('listen: http://localhost:${r}');
27
+ `}async function mt(e,o,t){let r=await(0,Ie.default)(o,{cwd:e}),n=(0,Y.createFilter)(o,t,{resolve:!1}),s=r.filter(n),i="",c="";return s.forEach((a,p)=>{let d=(0,Y.normalizePath)(I.default.join(e,a));i+=`import * as m${p} from '${d}';
28
+ `,c+=`m${p}, `}),`import { transformMockData } from 'vite-plugin-mock-dev-server';
20
29
  ${i}
21
- const exporters = [${a}];
30
+ const exporters = [${c}];
22
31
  const mockList = exporters.map((raw) => raw && raw.default
23
32
  ? raw.default
24
33
  : Object.keys(raw || {}).map((key) => raw[key])
25
34
  )
26
35
  export default transformMockData(mockList);
27
- `}async function ct(t,o,e){var r;try{let n=await(0,Re.build)({entryPoints:[t],outfile:"out.js",write:!1,target:["node14.18","node16"],platform:"node",bundle:!0,metafile:!0,format:"esm",define:o,plugins:[A(e),U,ye,ke]});return{code:n.outputFiles[0].text,deps:((r=n.metafile)==null?void 0:r.inputs)||{}}}catch(n){console.error(n)}return{code:"",deps:{}}}var Y=require("buffer"),Z=require("url"),$e=l(require("cookies"),1),Le=l(require("http-status"),1),T=l(require("mime-types"),1),ee=require("path-to-regexp"),D=l(require("picocolors"),1);var G=l(require("co-body"),1),Ce=l(require("formidable"),1);async function Ee(t,o){var n;let e=t.method.toUpperCase();if(["GET","DELETE","HEAD"].includes(e))return;let r=((n=t.headers["content-type"])==null?void 0:n.toLocaleLowerCase())||"";try{if(r.startsWith("application/json"))return await G.default.json(t);if(r.startsWith("application/x-www-form-urlencoded"))return await G.default.form(t);if(r.startsWith("text/plain"))return await G.default.text(t);if(r.startsWith("multipart/form-data"))return await pt(t,o)}catch(s){console.error(s)}}async function pt(t,o){let e=(0,Ce.default)(o);return new Promise((r,n)=>{e.parse(t,(s,i,a)=>{if(s){n(s);return}r({...i,...a})})})}function Fe(t,o){return O(t.headers,o.headers)&&O(t.body,o.body)&&O(t.params,o.params)&&O(t.query,o.query)&&O(t.refererQuery,o.refererQuery)}function O(t,o){if(!o)return!0;for(let e in o)if(o[e]!==t[e])return!1;return!0}function te(t,{formidableOptions:o={},proxies:e,cookiesOptions:r}){return async function(n,s,i){let a=Date.now(),{query:c,pathname:p}=(0,Z.parse)(n.url,!0);if(!p||e.length===0||!e.some(k=>ft(k,n.url)))return i();let d=t.mockData,u=Object.keys(d).find(k=>(0,ee.pathToRegexp)(k).test(p));if(!u)return i();let{query:W}=(0,Z.parse)(n.headers.referer||"",!0),N=await Ee(n,o),R=new $e.default(n,s,r),C=R.get.bind(R),g=n.method.toUpperCase(),m=lt(d[u],{pathname:p,method:g,request:{query:c,refererQuery:W,body:N,headers:n.headers,getCookie:C}});if(!m)return i();S("middleware: ",g,n.url);let y=n,h=s;y.body=N,y.query=c,y.refererQuery=W,y.params=K(m.url,p),y.getCookie=C,h.setCookie=R.set.bind(R);let{body:B,delay:ce,type:qe="json",response:pe,status:ze=200,statusText:He}=m;if(V(h,ze,He),await ut(y,h,m),await dt(y,h,m),B){try{let k=b(B)?await B(y):B;await Te(a,ce),mt(h,k,qe)}catch(k){P.error(`${D.default.red("[body error]")} ${n.url}
28
- `,k),V(h,500),s.end("")}return}if(pe){try{await Te(a,ce),await pe(y,h,i)}catch(k){P.error(`${D.default.red("[response error]")} ${n.url}
29
- `,k),V(h,500),s.end("")}return}s.end("")}}function lt(t,{pathname:o,method:e,request:r}){return t.find(n=>{if(!o||!n||!n.url||!(n.method?v(n.method)?n.method:[n.method]:["GET","POST"]).includes(e))return!1;let i=(0,ee.pathToRegexp)(n.url).test(o);if(i&&n.validator){let a=K(n.url,o);if(b(n.validator))return n.validator({params:a,...r});try{return Fe({params:a,...r},n.validator)}catch(c){return P.error(`${D.default.red("[validator error]")} ${o}
30
- `,c),!1}}return i})}function V(t,o=200,e){t.statusCode=o,t.statusMessage=e||gt(o)}async function ut(t,o,{headers:e,type:r="json"}){let n=T.contentType(r)||T.contentType(T.lookup(r)||"");if(n&&o.setHeader("Content-Type",n),o.setHeader("Cache-Control","no-cache,max-age=0"),o.setHeader("X-Mock","generate by vite:plugin-mock-dev-server"),!!e)try{let s=b(e)?await e(t):e;Object.keys(s).forEach(i=>{o.setHeader(i,s[i])})}catch(s){P.error(`${D.default.red("[headers error]")} ${t.url}
31
- `,s)}}async function dt(t,o,{cookies:e}){if(e)try{let r=b(e)?await e(t):e;Object.keys(r).forEach(n=>{let s=r[n];if(v(s)){let[i,a]=s;o.setCookie(n,i,a)}else o.setCookie(n,s)})}catch(r){P.error(`${D.default.red("[cookies error]")} ${t.url}
32
- `,r)}}function mt(t,o,e){if(xe(o))o.pipe(t);else if(Y.Buffer.isBuffer(o))t.end(e==="text"||e==="json"?o.toString("utf-8"):o);else{let r=typeof o=="string"?o:JSON.stringify(o);t.end(e==="buffer"?Y.Buffer.from(r):r)}}async function Te(t,o){if(!o||o<=0)return;let e=Date.now()-t,r=o-e;r>0&&await we(r)}function ft(t,o){return t[0]==="^"&&new RegExp(t).test(o)||o.startsWith(t)}function gt(t){return Le.default[t]||"Unknown"}var Ne=l(require("events"),1),L=l(require("fs"),1),Be=require("module"),re=l(require("path"),1),Je=require("url"),ne=l(require("chokidar"),1),Ue=require("esbuild"),Ae=l(require("fast-glob"),1),_e=l(require("json5"),1),x=require("vite");var Ie=require("url"),We=l(require("lodash.sortby"),1);function oe(t){let o=[];for(let[,r]of t.entries())r&&(v(r)?o.push(...r):o.push(r));let e={};return o.filter(r=>(r.enabled||typeof r.enabled>"u")&&r.url).forEach(r=>{let{pathname:n,query:s}=(0,Ie.parse)(r.url,!0),i=e[n]??(e[n]=[]),a={...r,url:n},c=a.validator;Me(s)||(b(c)?a.validator=function(p){return O(p.query,s)&&c(p)}:c?(a.validator={...c},a.validator.query=a.validator.query?{...s,...a.validator.query}:s):a.validator={query:s}),i.push(a)}),Object.keys(e).forEach(r=>{e[r]=(0,We.default)(e[r],({validator:n})=>{if(!n)return 2;if(b(n))return 0;let{query:s,params:i,headers:a,body:c,refererQuery:p}=n;return 1/($(s)+$(i)+$(a)+$(c)+$(p))})}),e}function $(t){return t?Object.keys(t).length:0}var yt=Oe(f),j=(0,Be.createRequire)(yt),se=class extends Ne.default{constructor(e){super();this.options=e;this.moduleCache=new Map;this.moduleDeps=new Map;this.moduleType="cjs";this._mockData={};this.cwd=e.cwd||process.cwd();try{let r=E(this.cwd,["package.json"]);this.moduleType=r&&JSON.parse(r).type==="module"?"esm":"cjs"}catch{}}get mockData(){return this._mockData}async load(){let{include:e,exclude:r}=this.options,n=await(0,Ae.default)(e,{cwd:this.cwd}),s=(0,x.createFilter)(e,r,{resolve:!1});this.watchMockEntry(),this.watchDeps();for(let i of n.filter(s))await this.loadMock(i);this.updateMockList(),this.on("mock:update",async i=>{s(i)&&(await this.loadMock(i),this.updateMockList(),this.emit("mock:update-end"))}),this.on("mock:unlink",async i=>{s(i)&&(this.moduleCache.delete(i),this.updateMockList(),this.emit("mock:update-end"))})}watchMockEntry(){let{include:e}=this.options,[r,...n]=e,s=ne.default.watch(r,{ignoreInitial:!0,cwd:this.cwd});n.length>0&&n.forEach(i=>s.add(i)),s.on("add",async i=>{i=(0,x.normalizePath)(i),this.emit("mock:update",i),S("watcher:add",i)}),s.on("change",async i=>{i=(0,x.normalizePath)(i),this.emit("mock:update",i),S("watcher:change",i)}),s.on("unlink",async i=>{i=(0,x.normalizePath)(i),this.emit("mock:unlink",i),S("watcher:unlink",i)}),this.mockWatcher=s}watchDeps(){let e=[];this.depsWatcher=ne.default.watch([],{ignoreInitial:!0,cwd:this.cwd}),this.depsWatcher.on("change",r=>{r=(0,x.normalizePath)(r);let n=this.moduleDeps.get(r);n&&n.forEach(s=>{this.emit("mock:update",s)})}),this.depsWatcher.on("unlink",r=>{r=(0,x.normalizePath)(r),this.moduleDeps.delete(r)}),this.on("update:deps",()=>{let r=[];for(let[s]of this.moduleDeps.entries())r.push(s);let n=r.filter(s=>!e.includes(s));n.length>0&&this.depsWatcher.add(n)})}close(){var e,r;(e=this.mockWatcher)==null||e.close(),(r=this.depsWatcher)==null||r.close()}updateMockList(){this._mockData=oe(this.moduleCache)}updateModuleDeps(e,r){Object.keys(r).forEach(n=>{r[n].imports.map(i=>i.path).forEach(i=>{this.moduleDeps.has(i)||this.moduleDeps.set(i,new Set),this.moduleDeps.get(i).add(e)})}),this.emit("update:deps")}async loadMock(e){e&&(se.EXT_JSON.test(e)?await this.loadJson(e):await this.loadModule(e))}async loadJson(e){let r=await L.default.promises.readFile(e,"utf-8");try{let n=_e.default.parse(r);this.moduleCache.set(e,n)}catch{}}async loadModule(e){if(!e)return;let r=!1;/\.m[jt]s$/.test(e)?r=!0:/\.c[jt]s$/.test(e)?r=!1:r=this.moduleType==="esm";let{code:n,deps:s}=await this.transformWithEsbuild(e,r);try{let i=await this.loadFromCode(e,n,r),a=i&&i.default?i.default:Object.keys(i||{}).map(c=>i[c]);this.moduleCache.set(e,a),this.updateModuleDeps(e,s)}catch(i){console.error(i)}}async loadFromCode(e,r,n){if(n){let s=`${e}.timestamp-${Date.now()}`,i=`${s}.mjs`,a=`${(0,Je.pathToFileURL)(s)}.mjs`;await L.default.promises.writeFile(i,r,"utf8");try{return await import(a)}finally{try{L.default.unlinkSync(i)}catch{}}}else{e=re.default.resolve(this.cwd,e);let s=re.default.extname(e),i=L.default.realpathSync(e),a=s in j.extensions?s:".js",c=j.extensions[a];j.extensions[a]=(d,u)=>{u===i?d._compile(r,u):c(d,u)},delete j.cache[j.resolve(e)];let p=j(e);return j.extensions[a]=c,p.__esModule?p:{default:p}}}async transformWithEsbuild(e,r){var n;try{let s=await(0,Ue.build)({entryPoints:[e],outfile:"out.js",write:!1,target:["node14.18","node16"],platform:"node",bundle:!0,metafile:!0,format:r?"esm":"cjs",define:this.options.define,plugins:[A(this.options.alias),U]});return{code:s.outputFiles[0].text,deps:((n=s.metafile)==null?void 0:n.inputs)||{}}}catch{}return{code:"",deps:{}}}},I=se;I.EXT_JSON=/\.json5?$/;async function ie(t,o,e,r){let n=M(o.include),s=M(o.exclude),i={};if(t.define)for(let d in t.define){let u=t.define[d];i[d]=typeof u=="string"?u:JSON.stringify(u)}let a=new I({include:n,exclude:s,define:i,alias:t.resolve.alias});await a.load(),e==null||e.on("close",()=>a.close()),a.on("mock:update-end",()=>{o.reload&&(r==null||r.send({type:"full-reload"}))});let c=z(t.server.proxy||{}),p=M(o.prefix);return te(a,{formidableOptions:o.formidableOptions,proxies:[...p,...c],cookiesOptions:o.cookiesOptions})}function ae({prefix:t=[],include:o=["mock/**/*.mock.{js,ts,cjs,mjs,json,json5}"],exclude:e=["**/node_modules/**","**/.vscode/**","**/.git/**"],reload:r=!1,formidableOptions:n={},build:s=!1,cookiesOptions:i={}}={}){let a={prefix:t,include:o,exclude:e,reload:r,cookiesOptions:i,formidableOptions:{multiples:!0,...n},build:s?Object.assign({serverPort:8080,dist:"mockServer"},typeof s=="object"?s:{}):!1},c=[ht(a)];return a.build&&c.push(kt(a)),c}function kt(t){let o={};return{name:"vite-plugin-mock-dev-server-generator",enforce:"post",apply:"build",configResolved(e){o=e,e.logger.warn("")},async buildEnd(e){e||o.command==="build"&&await De(this,o,t)}}}function ht(t){let o={};return{name:"vite-plugin-mock-dev-server",enforce:"pre",apply:"serve",configResolved(e){o=e,e.logger.warn("")},async configureServer({middlewares:e,config:r,httpServer:n,ws:s}){let i=await ie(r,t,n,s);e.use(i)},async configurePreviewServer({middlewares:e,httpServer:r}){let n=await ie(o,t,r);e.use(n)}}}function vt(t){return t}function bt(t){return e=>(v(e)?e=e.map(r=>t(r)||r):e=t(e)||e,e)}var Mt=ae;0&&(module.exports={baseMiddleware,createDefineMock,defineMock,mockDevServerPlugin,transformMockData});
36
+ `}async function dt(e,o,t){var r;try{let n=await(0,We.build)({entryPoints:[e],outfile:"out.js",write:!1,target:["node14.18","node16"],platform:"node",bundle:!0,metafile:!0,format:"esm",define:o,plugins:[G(t),B,J,z]});return{code:n.outputFiles[0].text,deps:((r=n.metafile)==null?void 0:r.inputs)||{}}}catch(n){console.error(n)}return{code:"",deps:{}}}var se=require("buffer"),ie=require("url"),_e=l(require("cookies"),1),Ue=l(require("http-status"),1),N=l(require("mime-types"),1),ce=require("path-to-regexp"),F=l(require("picocolors"),1);var Z=l(require("co-body"),1),Te=l(require("formidable"),1);async function Fe(e,o){var n;let t=e.method.toUpperCase();if(["GET","DELETE","HEAD"].includes(t))return;let r=((n=e.headers["content-type"])==null?void 0:n.toLocaleLowerCase())||"";try{if(r.startsWith("application/json"))return await Z.default.json(e);if(r.startsWith("application/x-www-form-urlencoded"))return await Z.default.form(e);if(r.startsWith("text/plain"))return await Z.default.text(e);if(r.startsWith("multipart/form-data"))return await ft(e,o)}catch(s){console.error(s)}}async function ft(e,o){let t=(0,Te.default)(o);return new Promise((r,n)=>{t.parse(e,(s,i,c)=>{if(s){n(s);return}r({...i,...c})})})}function $e(e,o){return E(e.headers,o.headers)&&E(e.body,o.body)&&E(e.params,o.params)&&E(e.query,o.query)&&E(e.refererQuery,o.refererQuery)}function E(e,o){if(!o)return!0;for(let t in o)if(o[t]!==e[t])return!1;return!0}function ae(e,{formidableOptions:o={},proxies:t,cookiesOptions:r}){return async function(n,s,i){let c=Date.now(),{query:a,pathname:p}=(0,ie.parse)(n.url,!0);if(!p||t.length===0||!t.some(P=>V(P,n.url)))return i();let d=e.mockData,u=Object.keys(d).find(P=>(0,ce.pathToRegexp)(P).test(p));if(!u)return i();let{query:w}=(0,ie.parse)(n.headers.referer||"",!0),v=await Fe(n,o),g=new _e.default(n,s,r),y=g.get.bind(g),k=n.method.toUpperCase(),m=kt(d[u],{pathname:p,method:k,request:{query:a,refererQuery:w,body:v,headers:n.headers,getCookie:y}});if(!m)return i();D("middleware: ",k,n.url);let M=n,h=s;M.body=v,M.query=a,M.refererQuery=w,M.params=_(m.url,p),M.getCookie=y,h.setCookie=g.set.bind(g);let{body:b,delay:f,type:O="json",response:R,status:$=200,statusText:Ve}=m;if(ne(h,$,Ve),await gt(M,h,m),await yt(M,h,m),b){try{let P=C(b)?await b(M):b;await He(c,f),ht(h,P,O)}catch(P){T.error(`${F.default.red("[body error]")} ${n.url}
37
+ `,P),ne(h,500),s.end("")}return}if(R){try{await He(c,f),await R(M,h,i)}catch(P){T.error(`${F.default.red("[response error]")} ${n.url}
38
+ `,P),ne(h,500),s.end("")}return}s.end("")}}function kt(e,{pathname:o,method:t,request:r}){return e.find(n=>{if(!o||!n||!n.url||n.ws===!0||!(n.method?S(n.method)?n.method:[n.method]:["GET","POST"]).includes(t))return!1;let i=(0,ce.pathToRegexp)(n.url).test(o);if(i&&n.validator){let c=_(n.url,o);if(C(n.validator))return n.validator({params:c,...r});try{return $e({params:c,...r},n.validator)}catch(a){return T.error(`${F.default.red("[validator error]")} ${o}
39
+ `,a),!1}}return i})}function ne(e,o=200,t){e.statusCode=o,e.statusMessage=t||vt(o)}async function gt(e,o,{headers:t,type:r="json"}){let n=N.contentType(r)||N.contentType(N.lookup(r)||"");if(n&&o.setHeader("Content-Type",n),o.setHeader("Cache-Control","no-cache,max-age=0"),o.setHeader("X-Mock","generate by vite:plugin-mock-dev-server"),!!t)try{let s=C(t)?await t(e):t;Object.keys(s).forEach(i=>{o.setHeader(i,s[i])})}catch(s){T.error(`${F.default.red("[headers error]")} ${e.url}
40
+ `,s)}}async function yt(e,o,{cookies:t}){if(t)try{let r=C(t)?await t(e):t;Object.keys(r).forEach(n=>{let s=r[n];if(S(s)){let[i,c]=s;o.setCookie(n,i,c)}else o.setCookie(n,s)})}catch(r){T.error(`${F.default.red("[cookies error]")} ${e.url}
41
+ `,r)}}function ht(e,o,t){if(Pe(o))o.pipe(e);else if(se.Buffer.isBuffer(o))e.end(t==="text"||t==="json"?o.toString("utf-8"):o);else{let r=typeof o=="string"?o:JSON.stringify(o);e.end(t==="buffer"?se.Buffer.from(r):r)}}async function He(e,o){if(!o||o<=0)return;let t=Date.now()-e,r=o-t;r>0&&await Re(r)}function vt(e){return Ue.default[e]||"Unknown"}var Ae=l(require("events"),1),ee=l(require("fs"),1),Be=require("module"),ue=l(require("path"),1),Je=require("url"),le=l(require("chokidar"),1),ze=require("esbuild"),Ge=l(require("fast-glob"),1),W=require("vite");var Ne=require("url"),qe=l(require("lodash.sortby"),1);function pe(e){let o=[];for(let[,r]of e.entries())r&&(S(r)?o.push(...r):o.push(r));let t={};return o.filter(r=>(r.enabled||typeof r.enabled>"u")&&r.url).forEach(r=>{let{pathname:n,query:s}=(0,Ne.parse)(r.url,!0),i=t[n]??(t[n]=[]),c={...r,url:n};if(c.ws!==!0){let a=c.validator;je(s)||(C(a)?c.validator=function(p){return E(p.query,s)&&a(p)}:a?(c.validator={...a},c.validator.query=c.validator.query?{...s,...c.validator.query}:s):c.validator={query:s})}i.push(c)}),Object.keys(t).forEach(r=>{t[r]=(0,qe.default)(t[r],n=>{if(n.ws===!0)return 0;let{validator:s}=n;if(!s)return 1;if(C(s))return 0;let{query:i,params:c,headers:a,body:p,refererQuery:d}=s;return 1/(q(i)+q(c)+q(a)+q(p)+q(d))})}),t}function q(e){return e?Object.keys(e).length:0}var Mt=Ce(x),L=(0,Be.createRequire)(Mt),te=class extends Ae.default{constructor(t){super();this.options=t;this.moduleCache=new Map;this.moduleDeps=new Map;this.moduleType="cjs";this._mockData={};this.cwd=t.cwd||process.cwd();try{let r=H(this.cwd,["package.json"]);this.moduleType=r&&JSON.parse(r).type==="module"?"esm":"cjs"}catch{}}get mockData(){return this._mockData}async load(){let{include:t,exclude:r}=this.options,n=await(0,Ge.default)(t,{cwd:this.cwd}),s=(0,W.createFilter)(t,r,{resolve:!1});this.watchMockEntry(),this.watchDeps();for(let c of n.filter(s))await this.loadMock(c);this.updateMockList();let i=null;this.on("mock:update",async c=>{s(c)&&(await this.loadMock(c),i&&clearTimeout(i),i=setTimeout(()=>{this.updateMockList(),this.emit("mock:update-end",c),i=null},0))}),this.on("mock:unlink",async c=>{s(c)&&(this.moduleCache.delete(c),this.updateMockList(),this.emit("mock:update-end",c))})}watchMockEntry(){let{include:t}=this.options,[r,...n]=t,s=le.default.watch(r,{ignoreInitial:!0,cwd:this.cwd});n.length>0&&n.forEach(i=>s.add(i)),s.on("add",async i=>{i=(0,W.normalizePath)(i),this.emit("mock:update",i),D("watcher:add",i)}),s.on("change",async i=>{i=(0,W.normalizePath)(i),this.emit("mock:update",i),D("watcher:change",i)}),s.on("unlink",async i=>{i=(0,W.normalizePath)(i),this.emit("mock:unlink",i),D("watcher:unlink",i)}),this.mockWatcher=s}watchDeps(){let t=[];this.depsWatcher=le.default.watch([],{ignoreInitial:!0,cwd:this.cwd}),this.depsWatcher.on("change",r=>{r=(0,W.normalizePath)(r);let n=this.moduleDeps.get(r);n&&n.forEach(s=>{this.emit("mock:update",s)})}),this.depsWatcher.on("unlink",r=>{r=(0,W.normalizePath)(r),this.moduleDeps.delete(r)}),this.on("update:deps",()=>{let r=[];for(let[s]of this.moduleDeps.entries())r.push(s);let n=r.filter(s=>!t.includes(s));n.length>0&&this.depsWatcher.add(n)})}close(){var t,r;(t=this.mockWatcher)==null||t.close(),(r=this.depsWatcher)==null||r.close()}updateMockList(){this._mockData=pe(this.moduleCache)}updateModuleDeps(t,r){Object.keys(r).forEach(n=>{r[n].imports.map(i=>i.path).forEach(i=>{this.moduleDeps.has(i)||this.moduleDeps.set(i,new Set),this.moduleDeps.get(i).add(t)})}),this.emit("update:deps")}async loadMock(t){if(!t)return;let r=!1;/\.m[jt]s$/.test(t)?r=!0:/\.c[jt]s$/.test(t)?r=!1:r=this.moduleType==="esm";let{code:n,deps:s}=await this.transformWithEsbuild(t,r);try{let i=await this.loadFromCode(t,n,r),c=i&&i.default?i.default:Object.keys(i||{}).map(a=>i[a]);S(c)?c.forEach(a=>a.__filepath__=t):c.__filepath__=t,this.moduleCache.set(t,c),this.updateModuleDeps(t,s)}catch(i){console.error(i)}}async loadFromCode(t,r,n){if(n){let s=`${t}.timestamp-${Date.now()}`,i=`${s}.mjs`,c=`${(0,Je.pathToFileURL)(s)}.mjs`;await ee.default.promises.writeFile(i,r,"utf8");try{return await import(c)}finally{try{ee.default.unlinkSync(i)}catch{}}}else{t=ue.default.resolve(this.cwd,t);let s=ue.default.extname(t),i=ee.default.realpathSync(t),c=s in L.extensions?s:".js",a=L.extensions[c];L.extensions[c]=(d,u)=>{u===i?d._compile(r,u):a(d,u)},delete L.cache[L.resolve(t)];let p=L(t);return L.extensions[c]=a,p.__esModule?p:{default:p}}}async transformWithEsbuild(t,r){var n;try{let s=await(0,ze.build)({entryPoints:[t],outfile:"out.js",write:!1,target:["node14.18","node16"],platform:"node",bundle:!0,metafile:!0,format:r?"esm":"cjs",define:this.options.define,plugins:[G(this.options.alias),B,z,J]});return{code:s.outputFiles[0].text,deps:((n=s.metafile)==null?void 0:n.inputs)||{}}}catch(s){console.error(s)}return{code:"",deps:{}}}};var me=require("url"),Xe=l(require("cookies"),1),de=require("path-to-regexp"),Ke=require("ws");function fe(e,o,t,r){var c;let n=new Set,s=new Map,i=new Map;(c=e.on)==null||c.call(e,"mock:update-end",a=>{if(!n.has(a))return;let p={};for(let[d,u]of i.entries())e.mockData[d].forEach(w=>{w.ws&&w.__filepath__===a&&u.forEach(({pathname:v,req:g,ws:y})=>{p[v]??(p[v]={mock:w,list:[],mockUrl:d}),p[v].list.push({req:g,ws:y})})});Object.keys(p).forEach(d=>{var m;let{wss:u,cleanupList:w,context:v}=s.get(d),{mock:g,list:y,mockUrl:k}=p[d];Qe(w),u.removeAllListeners(),(m=g.setup)==null||m.call(g,u,v),u.on("close",()=>s.delete(d)),y.forEach(({req:M,ws:h})=>{h.removeAllListeners(),u.emit("connection",h,M),h.on("close",()=>{let b=i.get(k),f=(b==null?void 0:b.findIndex(O=>O.ws===h))||-1;f!==-1&&(b==null||b.splice(f,1))})})})}),o==null||o.on("upgrade",(a,p,d)=>{var b;let{pathname:u,query:w}=(0,me.parse)(a.url,!0);if(!u||t.length===0||!t.some(f=>V(f,a.url)))return;let v=e.mockData,g=Object.keys(v).find(f=>(0,de.pathToRegexp)(f).test(u));if(!g)return;let y=v[g].find(f=>f.url&&f.ws&&(0,de.pathToRegexp)(f.url).test(u));if(!y)return;n.add(y.__filepath__);let k=s.get(u);if(!k){let f=new Ke.WebSocketServer({noServer:!0}),O=[],R={onCleanup:$=>O.push($)};(b=y.setup)==null||b.call(y,f,R),f.on("close",()=>s.delete(u)),s.set(u,k={wss:f,cleanupList:O,context:R})}let m=a,M=new Xe.default(a,a,r),{query:h}=(0,me.parse)(a.headers.referer||"",!0);m.query=w,m.refererQuery=h,m.params=_(g,u),m.getCookie=M.get.bind(M),k.wss.handleUpgrade(m,p,d,f=>{D(`websocket-mock: ${a.url} connected`),k.wss.emit("connection",f,m);let O=i.get(g);O||i.set(g,O=[]),O.push({req:m,ws:f,pathname:u}),f.on("close",()=>{let R=O.findIndex($=>$.ws===f);R!==-1&&O.splice(R,1)})})}),o==null||o.on("close",()=>{s.forEach(({wss:a,cleanupList:p})=>{Qe(p),a.close()}),s.clear(),i.clear(),n.clear()})}function Qe(e){let o;for(;o=e.shift();)o==null||o()}async function ke(e,o,t,r){let n=j(o.include),s=j(o.exclude),i={};if(e.define)for(let d in e.define){let u=e.define[d];i[d]=typeof u=="string"?u:JSON.stringify(u)}let c=new te({include:n,exclude:s,define:i,alias:e.resolve.alias});await c.load(),c.on("mock:update-end",()=>{o.reload&&(r==null||r.send({type:"full-reload"}))}),t==null||t.on("close",()=>c.close());let{httpProxies:a}=K(e.server.proxy||{}),p=j(o.prefix);return fe(c,t,j(o.wsPrefix),o.cookiesOptions),ae(c,{formidableOptions:o.formidableOptions,proxies:[...p,...a],cookiesOptions:o.cookiesOptions})}function ge({prefix:e=[],wsPrefix:o=[],include:t=["mock/**/*.mock.{js,ts,cjs,mjs,json,json5}"],exclude:r=["**/node_modules/**","**/.vscode/**","**/.git/**"],reload:n=!1,formidableOptions:s={},build:i=!1,cookiesOptions:c={}}={}){let a={prefix:e,wsPrefix:o,include:t,exclude:r,reload:n,cookiesOptions:c,formidableOptions:{multiples:!0,...s},build:i?Object.assign({serverPort:8080,dist:"mockServer"},typeof i=="object"?i:{}):!1},p=[xt(a)];return a.build&&p.push(bt(a)),p}function bt(e){let o={};return{name:"vite-plugin-mock-dev-server-generator",enforce:"post",apply:"build",configResolved(t){o=t,t.logger.warn("")},async buildEnd(t){t||o.command==="build"&&await Le(this,o,e)}}}function xt(e){let o={};return{name:"vite-plugin-mock-dev-server",enforce:"pre",apply:"serve",configResolved(t){o=t,t.logger.warn("")},async configureServer({middlewares:t,config:r,httpServer:n,ws:s}){let i=await ke(r,e,n,s);t.use(i)},async configurePreviewServer({middlewares:t,httpServer:r}){let n=await ke(o,e,r);t.use(n)}}}function wt(e){return e}function Ot(e){return t=>(S(t)?t=t.map(r=>e(r)||r):t=e(t)||t,t)}var St=ge;0&&(module.exports={baseMiddleware,createDefineMock,defineMock,mockDevServerPlugin,mockWebSocket,transformMockData});
package/dist/index.d.ts CHANGED
@@ -3,21 +3,35 @@ import http from 'node:http';
3
3
  import { Readable } from 'node:stream';
4
4
  import Cookies from 'cookies';
5
5
  import formidable from 'formidable';
6
+ import { WebSocketServer } from 'ws';
6
7
  import EventEmitter from 'node:events';
7
8
  import chokidar from 'chokidar';
8
9
 
9
10
  interface MockServerPluginOptions {
10
11
  /**
11
- * To configure the path matching rules for mock services,
12
+ * To configure the path matching rules for http mock services,
12
13
  * any request path starting with prefix will be intercepted and proxied.
13
14
  * If the prefix starts with `^`, it will be recognized as a `RegExp`.
14
15
  *
15
- * 为 mock 服务配置 路径匹配规则,任何请求路径以 prefix 开头的都将被拦截代理。
16
+ * 为 http mock 服务配置 路径匹配规则,任何请求路径以 prefix 开头的都将被拦截代理。
16
17
  * 如果 prefix 以 `^` 开头,将被识别为 `RegExp`。
17
18
  * @default []
18
19
  * @example ['^/api']
19
20
  */
20
21
  prefix?: string | string[];
22
+ /**
23
+ * Configure path matching rules for WebSocket mock service.
24
+ * Any ws/wss requests with a request path starting with wsPrefix
25
+ * will be intercepted by the proxy.
26
+ * If wsPrefix starts with `^`, it will be recognized as a `RegExp`.
27
+ *
28
+ * 为 websocket mock 服务配置 路径匹配规则, 任何请求路径以 wsPrefix 开头的 ws/wss请求,
29
+ * 都将被代理拦截。
30
+ * 如果 wsPrefix 以 `^` 开头,将被识别为 `RegExp`。
31
+ * @default []
32
+ * @example ['/socket.io']
33
+ */
34
+ wsPrefix?: string | string[];
21
35
  /**
22
36
  * glob string matching mock includes files
23
37
  *
@@ -128,7 +142,7 @@ type ResponseHeaderFn = (request: MockRequest) => Headers | Promise<Headers>;
128
142
  type CookieValue = string | [string, Cookies.SetOption];
129
143
  type ResponseCookies = Record<string, CookieValue>;
130
144
  type ResponseCookiesFn = (request: MockRequest) => ResponseCookies | Promise<ResponseCookies>;
131
- interface MockOptionsItem {
145
+ interface MockBaseItem {
132
146
  /**
133
147
  * The interface address that needs to be mocked,
134
148
  * supported by `path-to-regexp` for path matching.
@@ -144,23 +158,33 @@ interface MockOptionsItem {
144
158
  */
145
159
  url: string;
146
160
  /**
147
- * The interface allows request methods, and by default allows both GET and POST.
161
+ * Enable WebSocket interface simulation
148
162
  *
149
- * 该接口允许的 请求方法,默认同时支持 GET 和 POST
150
- * @default ['POST','GET']
163
+ * 开启 websocket 接口模拟
164
+ *
165
+ * @default false
151
166
  */
152
- method?: Method | Method[];
167
+ ws?: boolean;
153
168
  /**
154
169
  * Whether to enable mock for this interface.
155
170
  * In most scenarios, we only need to mock some interfaces instead of all requests that
156
171
  * have been configured with mock.
157
172
  * Therefore, it is important to be able to configure whether to enable it or not.
158
173
  *
159
- * 是否启动对该接口的mock,在多数场景下,我们进需要对部分接口进行 mock,
174
+ * 是否启动对该接口的mock,在多数场景下,我们仅需要对部分接口进行 mock,
160
175
  * 而不是对所有配置了mock的请求进行全量mock,所以是否能够配置是否启用很重要
161
176
  * @default true
162
177
  */
163
178
  enabled?: boolean;
179
+ }
180
+ interface MockHttpItem extends MockBaseItem {
181
+ /**
182
+ * The interface allows request methods, and by default allows both GET and POST.
183
+ *
184
+ * 该接口允许的 请求方法,默认同时支持 GET 和 POST
185
+ * @default ['POST','GET']
186
+ */
187
+ method?: Method | Method[];
164
188
  /**
165
189
  * Configure the response body headers
166
190
  *
@@ -330,11 +354,45 @@ interface MockOptionsItem {
330
354
  * ```
331
355
  */
332
356
  validator?: Partial<Omit<ExtraRequest, 'getCookie'>> | ((request: ExtraRequest) => boolean);
357
+ ws?: false;
358
+ }
359
+ interface MockWebsocketItem extends MockBaseItem {
360
+ ws: true;
361
+ /**
362
+ * Configure Websocket Server
363
+ *
364
+ * 配置 Websocket Server
365
+ * @example
366
+ * ```ts
367
+ * export default {
368
+ * ws: true
369
+ * setup: (wss, { onCleanup }) => {
370
+ * wss.on('connection', (ws,req) => {
371
+ * ws.on('message', (raw) => console.log(raw))
372
+ * const timer = setInterval(
373
+ * () => ws.send(JSON.stringify({ type: 'connected' })),
374
+ * 1000,
375
+ * )
376
+ * onCleanup(() => clearInterval(timer))
377
+ * })
378
+ * wss.on('error', (error) => console.error(error))
379
+ * }
380
+ * }
381
+ * ```
382
+ */
383
+ setup: (wss: WebSocketServer, context: WebSocketSetupContext) => void;
333
384
  }
334
- type MockOptions = MockOptionsItem[];
385
+ interface WebSocketSetupContext {
386
+ /**
387
+ * 当你在定义 WSS 时,可能会执行一些自动任务或循环任务,
388
+ * 但是当热更新时,插件内部会重新执行 setup() ,这可能导致出现
389
+ */
390
+ onCleanup: (cleanup: () => void) => void;
391
+ }
392
+ type MockOptions = (MockHttpItem | MockWebsocketItem)[];
335
393
  type FormidableFile = formidable.File | formidable.File[];
336
394
 
337
- declare function mockDevServerPlugin({ prefix, include, exclude, reload, formidableOptions, build, cookiesOptions, }?: MockServerPluginOptions): Plugin[];
395
+ declare function mockDevServerPlugin({ prefix, wsPrefix, include, exclude, reload, formidableOptions, build, cookiesOptions, }?: MockServerPluginOptions): Plugin[];
338
396
 
339
397
  /**
340
398
  * mock config helper
@@ -351,8 +409,9 @@ declare function mockDevServerPlugin({ prefix, include, exclude, reload, formida
351
409
  * })
352
410
  * ```
353
411
  */
354
- declare function defineMock(config: MockOptionsItem): MockOptionsItem;
412
+ declare function defineMock(config: MockHttpItem): MockHttpItem;
355
413
  declare function defineMock(config: MockOptions): MockOptions;
414
+ declare function defineMock(config: MockWebsocketItem): MockWebsocketItem;
356
415
  /**
357
416
  * 返回一个自定义的 defineMock 函数,用于支持对 mock config 的预处理。
358
417
  *
@@ -360,7 +419,7 @@ declare function defineMock(config: MockOptions): MockOptions;
360
419
  *
361
420
  * @param transformer preprocessing function
362
421
  */
363
- declare function createDefineMock(transformer: (mock: MockOptionsItem) => MockOptionsItem | void): typeof defineMock;
422
+ declare function createDefineMock(transformer: (mock: MockHttpItem | MockWebsocketItem) => MockHttpItem | MockWebsocketItem | void): typeof defineMock;
364
423
 
365
424
  interface MockLoaderOptions {
366
425
  cwd?: string;
@@ -374,8 +433,7 @@ interface MockLoaderOptions {
374
433
  */
375
434
  declare class MockLoader extends EventEmitter {
376
435
  options: MockLoaderOptions;
377
- static EXT_JSON: RegExp;
378
- moduleCache: Map<string, MockOptions | MockOptionsItem>;
436
+ moduleCache: Map<string, MockOptions | MockHttpItem | MockWebsocketItem>;
379
437
  moduleDeps: Map<string, Set<string>>;
380
438
  cwd: string;
381
439
  mockWatcher: chokidar.FSWatcher;
@@ -395,8 +453,6 @@ declare class MockLoader extends EventEmitter {
395
453
  private updateMockList;
396
454
  private updateModuleDeps;
397
455
  private loadMock;
398
- private loadJson;
399
- private loadModule;
400
456
  private loadFromCode;
401
457
  private transformWithEsbuild;
402
458
  }
@@ -408,6 +464,8 @@ interface BaseMiddlewareOptions {
408
464
  }
409
465
  declare function baseMiddleware(mockLoader: MockLoader, { formidableOptions, proxies, cookiesOptions }: BaseMiddlewareOptions): Connect.NextHandleFunction;
410
466
 
411
- declare function transformMockData(mockList: Map<string, MockOptionsItem | MockOptions> | (MockOptionsItem | MockOptions)[]): Record<string, MockOptions>;
467
+ declare function mockWebSocket(loader: MockLoader, httpServer: http.Server | null, proxies: string[], cookiesOptions: MockServerPluginOptions['cookiesOptions']): void;
468
+
469
+ declare function transformMockData(mockList: Map<string, MockHttpItem | MockWebsocketItem | MockOptions> | (MockHttpItem | MockWebsocketItem | MockOptions)[]): Record<string, MockOptions>;
412
470
 
413
- export { BaseMiddlewareOptions, FormidableFile, MockOptions, MockOptionsItem, MockServerPluginOptions, baseMiddleware, createDefineMock, mockDevServerPlugin as default, defineMock, mockDevServerPlugin, transformMockData };
471
+ export { BaseMiddlewareOptions, FormidableFile, MockHttpItem, MockOptions, MockRequest, MockServerPluginOptions, MockWebsocketItem, baseMiddleware, createDefineMock, mockDevServerPlugin as default, defineMock, mockDevServerPlugin, mockWebSocket, transformMockData };
package/dist/index.js CHANGED
@@ -1,32 +1,41 @@
1
- import Fe from"fs";import A from"fs/promises";import R from"path";import{build as Te}from"esbuild";import $e from"fast-glob";import Le from"is-core-module";import{createFilter as Ie,normalizePath as We}from"vite";var Z="vite-plugin-mock-dev-server",ee="1.1.5";import te from"fs/promises";import Oe from"path";import je from"json5";var N={name:"externalize-deps",setup(t){t.onResolve({filter:/.*/},({path:r})=>{if(r[0]!=="."&&!Oe.isAbsolute(r))return{external:!0}})}},oe={name:"json5-loader",setup(t){t.onLoad({filter:/\.json5$/},async({path:r})=>{let e=await te.readFile(r,"utf-8");return{contents:`export default ${JSON.stringify(je.parse(e))}`,loader:"js"}})}},re={name:"json-loader",setup(t){t.onLoad({filter:/\.json$/},async({path:r})=>({contents:`export default ${await te.readFile(r,"utf-8")}`,loader:"js"}))}},B=t=>({name:"alias-plugin",setup(r){r.onResolve({filter:/.*/},async({path:e})=>{let o=t.find(({find:a})=>Se(a,e));if(!o)return null;let{find:n,replacement:s}=o;return{path:(await r.resolve(e.replace(n,s),{kind:"import-statement",resolveDir:s,namespace:"file"})).path,external:!1}})}});function Se(t,r){return t instanceof RegExp?t.test(r):r.length<t.length?!1:r===t?!0:r.startsWith(`${t}/`)}import _ from"fs";import z from"path";import{fileURLToPath as Re}from"url";import Pe from"debug";import{match as De}from"path-to-regexp";import ne from"picocolors";var v=t=>Array.isArray(t),b=t=>typeof t=="function",Ce=t=>Object.prototype.toString.call(t)==="[object Object]",se=t=>Ce(t)&&Object.keys(t).length===0,Ee=t=>t!==null&&typeof t=="object"&&typeof t.pipe=="function",ie=t=>Ee(t)&&t.readable!==!1&&typeof t._read=="function"&&typeof t._readableState=="object";function ae(t){return new Promise(r=>setTimeout(r,t))}function ce(t){return z.dirname(Re(t))}var j=Pe("vite:plugin-mock-dev-server"),M=t=>v(t)?t:t==null?[]:[t],S={info(...t){console.info(ne.cyan("mock-dev-server: "),...t)},error(...t){console.error(`
2
- `,ne.cyan("mock-dev-server: "),...t,`
3
- `)}};function D(t,r,e){for(let n of r){let s=z.join(t,n);if(_.existsSync(s)&&_.statSync(s).isFile()){let i=e!=null&&e.pathOnly?s:_.readFileSync(s,"utf-8");if(!(e!=null&&e.predicate)||e.predicate(i))return i}}let o=z.dirname(t);if(o!==t&&(!(e!=null&&e.rootDir)||o.startsWith(e==null?void 0:e.rootDir)))return D(o,r,e)}var J=(t={})=>Object.keys(t).map(e=>{var n,s;let o=t[e];return typeof o=="string"?e:o.ws||(n=o.target)!=null&&n.toString().startsWith("ws:")||(s=o.target)!=null&&s.toString().startsWith("wss:")?"":e}).filter(Boolean);function U(t,r){return(De(t,{decode:decodeURIComponent})(r)||{params:{}}).params||{}}async function pe(t,r,e){let o=M(e.include),n=M(e.exclude),s={};if(r.define)for(let m in r.define){let d=r.define[m];s[m]=typeof d=="string"?d:JSON.stringify(d)}let i=J(r.server.proxy||{}),a=M(e.prefix),c={};try{let m=D(r.root,["package.json"]);m&&(c=JSON.parse(m))}catch{}let p=e.build.dist,u=await Ae(process.cwd(),o,n),l=R.join(r.root,`mock-data-${Date.now()}.js`);await A.writeFile(l,u,"utf-8");let{code:L,deps:I}=await qe(l,s,r.resolve.alias),O=Ne(I);await A.unlink(l);let P=[{filename:R.join(p,"mock-data.js"),source:L},{filename:R.join(p,"index.js"),source:Je([...a,...i],e.cookiesOptions,e.build.serverPort)},{filename:R.join(p,"package.json"),source:Be(c,O)}];try{if(R.isAbsolute(p)){await A.rm(p,{recursive:!0}),Fe.mkdirSync(p,{recursive:!0});for(let{filename:m,source:d}of P)await A.writeFile(m,d,"utf-8")}else for(let{filename:m,source:d}of P)t.emitFile({type:"asset",fileName:m,source:d})}catch{}}function Ne(t){let r=new Set,e=[Z,"connect","cors"];return Object.keys(t).forEach(o=>{t[o].imports.filter(s=>s.external).map(s=>s.path).forEach(s=>{!e.includes(s)&&!Le(s)&&r.add(s)})}),Array.from(r)}function Be(t,r){let{dependencies:e={},devDependencies:o={}}=t,n={...e,...o},s={name:"mock-server",type:"module",scripts:{start:"node index.js"},dependencies:{connect:"^3.7.0","vite-plugin-mock-dev-server":`^${ee}`,cors:"^2.8.5"},pnpm:{peerDependencyRules:{ignoreMissing:["vite"]}}};return r.forEach(i=>{s.dependencies[i]=n[i]||"latest"}),JSON.stringify(s,null,2)}function Je(t,r={},e=8080){return`import connect from 'connect';
1
+ import Fe from"fs";import Q from"fs/promises";import L from"path";import{build as $e}from"esbuild";import He from"fast-glob";import _e from"is-core-module";import{createFilter as Ue,normalizePath as Ne}from"vite";var re="vite-plugin-mock-dev-server",ne="1.1.7";import se from"fs/promises";import Re from"path";import Ce from"json5";var q={name:"externalize-deps",setup(t){t.onResolve({filter:/.*/},({path:o})=>{if(o[0]!=="."&&!Re.isAbsolute(o))return{external:!0}})}},A={name:"json5-loader",setup(t){t.onLoad({filter:/\.json5$/},async({path:o})=>{let e=await se.readFile(o,"utf-8");return{contents:`export default ${JSON.stringify(Ce.parse(e))}`,loader:"js"}})}},B={name:"json-loader",setup(t){t.onLoad({filter:/\.json$/},async({path:o})=>({contents:`export default ${await se.readFile(o,"utf-8")}`,loader:"js"}))}},J=t=>({name:"alias-plugin",setup(o){o.onResolve({filter:/.*/},async({path:e})=>{let r=t.find(({find:c})=>De(c,e));if(!r)return null;let{find:s,replacement:n}=r;return{path:(await o.resolve(e.replace(s,n),{kind:"import-statement",resolveDir:n,namespace:"file"})).path,external:!1}})}});function De(t,o){return t instanceof RegExp?t.test(o):o.length<t.length?!1:o===t?!0:o.startsWith(`${t}/`)}import K from"fs";import V from"path";import{fileURLToPath as We}from"url";import Ee from"debug";import{match as Ie}from"path-to-regexp";import ie from"picocolors";var S=t=>Array.isArray(t),C=t=>typeof t=="function",Le=t=>Object.prototype.toString.call(t)==="[object Object]",ce=t=>Le(t)&&Object.keys(t).length===0,Te=t=>t!==null&&typeof t=="object"&&typeof t.pipe=="function",ae=t=>Te(t)&&t.readable!==!1&&typeof t._read=="function"&&typeof t._readableState=="object";function pe(t){return new Promise(o=>setTimeout(o,t))}function ue(t){return V.dirname(We(t))}var D=Ee("vite:plugin-mock-dev-server"),P=t=>S(t)?t:t==null?[]:[t],I={info(...t){console.info(ie.cyan("mock-dev-server: "),...t)},error(...t){console.error(`
2
+ `,ie.cyan("mock-dev-server: "),...t,`
3
+ `)}};function F(t,o,e){for(let s of o){let n=V.join(t,s);if(K.existsSync(n)&&K.statSync(n).isFile()){let i=e!=null&&e.pathOnly?n:K.readFileSync(n,"utf-8");if(!(e!=null&&e.predicate)||e.predicate(i))return i}}let r=V.dirname(t);if(r!==t&&(!(e!=null&&e.rootDir)||r.startsWith(e==null?void 0:e.rootDir)))return F(r,o,e)}var z=(t={})=>{let o=[],e=[];return Object.keys(t).forEach(r=>{var n,i;let s=t[r];typeof s=="string"||!s.ws&&!((n=s.target)!=null&&n.toString().startsWith("ws:"))&&!((i=s.target)!=null&&i.toString().startsWith("wss:"))?o.push(r):e.push(r)}),{httpProxies:o,wsProxies:e}};function G(t,o){return t[0]==="^"&&new RegExp(t).test(o)||o.startsWith(t)}function $(t,o){return(Ie(t,{decode:decodeURIComponent})(o)||{params:{}}).params||{}}async function le(t,o,e){let r=P(e.include),s=P(e.exclude),n={};if(o.define)for(let f in o.define){let l=o.define[f];n[f]=typeof l=="string"?l:JSON.stringify(l)}let{httpProxies:i}=z(o.server.proxy||{});i.push(...P(e.prefix));let c=P(e.wsPrefix),a={};try{let f=F(o.root,["package.json"]);f&&(a=JSON.parse(f))}catch{}let p=e.build.dist,m=await Je(process.cwd(),r,s),u=L.join(o.root,`mock-data-${Date.now()}.js`);await Q.writeFile(u,m,"utf-8");let{code:b,deps:h}=await ze(u,n,o.resolve.alias),k=qe(h);await Q.unlink(u);let g=[{filename:L.join(p,"mock-data.js"),source:b},{filename:L.join(p,"index.js"),source:Be(i,c,e.cookiesOptions,e.build.serverPort)},{filename:L.join(p,"package.json"),source:Ae(a,k)}];try{if(L.isAbsolute(p)){await Q.rm(p,{recursive:!0}),Fe.mkdirSync(p,{recursive:!0});for(let{filename:f,source:l}of g)await Q.writeFile(f,l,"utf-8")}else for(let{filename:f,source:l}of g)t.emitFile({type:"asset",fileName:f,source:l})}catch{}}function qe(t){let o=new Set,e=[re,"connect","cors"];return Object.keys(t).forEach(r=>{t[r].imports.filter(n=>n.external).map(n=>n.path).forEach(n=>{!e.includes(n)&&!_e(n)&&o.add(n)})}),Array.from(o)}function Ae(t,o){let{dependencies:e={},devDependencies:r={}}=t,s={...e,...r},n={name:"mock-server",type:"module",scripts:{start:"node index.js"},dependencies:{connect:"^3.7.0","vite-plugin-mock-dev-server":`^${ne}`,cors:"^2.8.5"},pnpm:{peerDependencyRules:{ignoreMissing:["vite"]}}};return o.forEach(i=>{n.dependencies[i]=s[i]||"latest"}),JSON.stringify(n,null,2)}function Be(t,o,e={},r=8080){return`import { createServer } from 'node:http';
4
+ import connect from 'connect';
4
5
  import corsMiddleware from 'cors';
5
- import { baseMiddleware } from 'vite-plugin-mock-dev-server';
6
+ import { baseMiddleware, mockWebSocket } from 'vite-plugin-mock-dev-server';
6
7
  import mockData from './mock-data.js';
7
8
 
8
9
  const app = connect();
10
+ const server = createServer(app);
11
+ const httpProxies = ${JSON.stringify(t)};
12
+ const wxProxies = ${JSON.stringify(o)}
13
+ const cookiesOptions = ${JSON.stringify(e)};
14
+
15
+ mockWebSocket({ mockData }, server, wxProxies, cookiesOptions)
16
+
9
17
  app.use(corsMiddleware());
10
18
  app.use(baseMiddleware({ mockData }, {
11
19
  formidableOptions: { multiples: true },
12
- proxies: ${JSON.stringify(t)}
13
- cookiesOptions: ${JSON.stringify(r)}
20
+ proxies: httpProxies,
21
+ cookiesOptions,
14
22
  }));
15
- app.listen(${e});
16
23
 
17
- console.log('listen: http://localhost:${e}');
18
- `}async function Ae(t,r,e){let o=await $e(r,{cwd:t}),n=Ie(r,e,{resolve:!1}),s=o.filter(n),i="",a="";return s.forEach((c,p)=>{let u=We(R.join(t,c));i+=`import * as m${p} from '${u}';
19
- `,a+=`m${p}, `}),`import { transformMockData } from 'vite-plugin-mock-dev-server';
24
+ server.listen(${r});
25
+
26
+ console.log('listen: http://localhost:${r}');
27
+ `}async function Je(t,o,e){let r=await He(o,{cwd:t}),s=Ue(o,e,{resolve:!1}),n=r.filter(s),i="",c="";return n.forEach((a,p)=>{let m=Ne(L.join(t,a));i+=`import * as m${p} from '${m}';
28
+ `,c+=`m${p}, `}),`import { transformMockData } from 'vite-plugin-mock-dev-server';
20
29
  ${i}
21
- const exporters = [${a}];
30
+ const exporters = [${c}];
22
31
  const mockList = exporters.map((raw) => raw && raw.default
23
32
  ? raw.default
24
33
  : Object.keys(raw || {}).map((key) => raw[key])
25
34
  )
26
35
  export default transformMockData(mockList);
27
- `}async function qe(t,r,e){var o;try{let n=await Te({entryPoints:[t],outfile:"out.js",write:!1,target:["node14.18","node16"],platform:"node",bundle:!0,metafile:!0,format:"esm",define:r,plugins:[B(e),N,oe,re]});return{code:n.outputFiles[0].text,deps:((o=n.metafile)==null?void 0:o.inputs)||{}}}catch(n){console.error(n)}return{code:"",deps:{}}}import{Buffer as de}from"buffer";import{parse as me}from"url";import Ue from"cookies";import He from"http-status";import*as C from"mime-types";import{pathToRegexp as ge}from"path-to-regexp";import E from"picocolors";import H from"co-body";import _e from"formidable";async function le(t,r){var n;let e=t.method.toUpperCase();if(["GET","DELETE","HEAD"].includes(e))return;let o=((n=t.headers["content-type"])==null?void 0:n.toLocaleLowerCase())||"";try{if(o.startsWith("application/json"))return await H.json(t);if(o.startsWith("application/x-www-form-urlencoded"))return await H.form(t);if(o.startsWith("text/plain"))return await H.text(t);if(o.startsWith("multipart/form-data"))return await ze(t,r)}catch(s){console.error(s)}}async function ze(t,r){let e=_e(r);return new Promise((o,n)=>{e.parse(t,(s,i,a)=>{if(s){n(s);return}o({...i,...a})})})}function ue(t,r){return x(t.headers,r.headers)&&x(t.body,r.body)&&x(t.params,r.params)&&x(t.query,r.query)&&x(t.refererQuery,r.refererQuery)}function x(t,r){if(!r)return!0;for(let e in r)if(r[e]!==t[e])return!1;return!0}function ye(t,{formidableOptions:r={},proxies:e,cookiesOptions:o}){return async function(n,s,i){let a=Date.now(),{query:c,pathname:p}=me(n.url,!0);if(!p||e.length===0||!e.some(k=>Ve(k,n.url)))return i();let u=t.mockData,l=Object.keys(u).find(k=>ge(k).test(p));if(!l)return i();let{query:L}=me(n.headers.referer||"",!0),I=await le(n,r),O=new Ue(n,s,o),P=O.get.bind(O),m=n.method.toUpperCase(),d=Ge(u[l],{pathname:p,method:m,request:{query:c,refererQuery:L,body:I,headers:n.headers,getCookie:P}});if(!d)return i();j("middleware: ",m,n.url);let y=n,h=s;y.body=I,y.query=c,y.refererQuery=L,y.params=U(d.url,p),y.getCookie=P,h.setCookie=O.set.bind(O);let{body:W,delay:K,type:Me="json",response:V,status:xe=200,statusText:we}=d;if(G(h,xe,we),await Qe(y,h,d),await Xe(y,h,d),W){try{let k=b(W)?await W(y):W;await fe(a,K),Ke(h,k,Me)}catch(k){S.error(`${E.red("[body error]")} ${n.url}
28
- `,k),G(h,500),s.end("")}return}if(V){try{await fe(a,K),await V(y,h,i)}catch(k){S.error(`${E.red("[response error]")} ${n.url}
29
- `,k),G(h,500),s.end("")}return}s.end("")}}function Ge(t,{pathname:r,method:e,request:o}){return t.find(n=>{if(!r||!n||!n.url||!(n.method?v(n.method)?n.method:[n.method]:["GET","POST"]).includes(e))return!1;let i=ge(n.url).test(r);if(i&&n.validator){let a=U(n.url,r);if(b(n.validator))return n.validator({params:a,...o});try{return ue({params:a,...o},n.validator)}catch(c){return S.error(`${E.red("[validator error]")} ${r}
30
- `,c),!1}}return i})}function G(t,r=200,e){t.statusCode=r,t.statusMessage=e||Ye(r)}async function Qe(t,r,{headers:e,type:o="json"}){let n=C.contentType(o)||C.contentType(C.lookup(o)||"");if(n&&r.setHeader("Content-Type",n),r.setHeader("Cache-Control","no-cache,max-age=0"),r.setHeader("X-Mock","generate by vite:plugin-mock-dev-server"),!!e)try{let s=b(e)?await e(t):e;Object.keys(s).forEach(i=>{r.setHeader(i,s[i])})}catch(s){S.error(`${E.red("[headers error]")} ${t.url}
31
- `,s)}}async function Xe(t,r,{cookies:e}){if(e)try{let o=b(e)?await e(t):e;Object.keys(o).forEach(n=>{let s=o[n];if(v(s)){let[i,a]=s;r.setCookie(n,i,a)}else r.setCookie(n,s)})}catch(o){S.error(`${E.red("[cookies error]")} ${t.url}
32
- `,o)}}function Ke(t,r,e){if(ie(r))r.pipe(t);else if(de.isBuffer(r))t.end(e==="text"||e==="json"?r.toString("utf-8"):r);else{let o=typeof r=="string"?r:JSON.stringify(r);t.end(e==="buffer"?de.from(o):o)}}async function fe(t,r){if(!r||r<=0)return;let e=Date.now()-t,o=r-e;o>0&&await ae(o)}function Ve(t,r){return t[0]==="^"&&new RegExp(t).test(r)||r.startsWith(t)}function Ye(t){return He[t]||"Unknown"}import tt from"events";import q from"fs";import{createRequire as ot}from"module";import he from"path";import{pathToFileURL as rt}from"url";import ve from"chokidar";import{build as nt}from"esbuild";import st from"fast-glob";import it from"json5";import{createFilter as at,normalizePath as T}from"vite";import{parse as Ze}from"url";import et from"lodash.sortby";function ke(t){let r=[];for(let[,o]of t.entries())o&&(v(o)?r.push(...o):r.push(o));let e={};return r.filter(o=>(o.enabled||typeof o.enabled>"u")&&o.url).forEach(o=>{let{pathname:n,query:s}=Ze(o.url,!0),i=e[n]??(e[n]=[]),a={...o,url:n},c=a.validator;se(s)||(b(c)?a.validator=function(p){return x(p.query,s)&&c(p)}:c?(a.validator={...c},a.validator.query=a.validator.query?{...s,...a.validator.query}:s):a.validator={query:s}),i.push(a)}),Object.keys(e).forEach(o=>{e[o]=et(e[o],({validator:n})=>{if(!n)return 2;if(b(n))return 0;let{query:s,params:i,headers:a,body:c,refererQuery:p}=n;return 1/(F(s)+F(i)+F(a)+F(c)+F(p))})}),e}function F(t){return t?Object.keys(t).length:0}var ct=ce(import.meta.url),w=ot(ct),Q=class extends tt{constructor(e){super();this.options=e;this.moduleCache=new Map;this.moduleDeps=new Map;this.moduleType="cjs";this._mockData={};this.cwd=e.cwd||process.cwd();try{let o=D(this.cwd,["package.json"]);this.moduleType=o&&JSON.parse(o).type==="module"?"esm":"cjs"}catch{}}get mockData(){return this._mockData}async load(){let{include:e,exclude:o}=this.options,n=await st(e,{cwd:this.cwd}),s=at(e,o,{resolve:!1});this.watchMockEntry(),this.watchDeps();for(let i of n.filter(s))await this.loadMock(i);this.updateMockList(),this.on("mock:update",async i=>{s(i)&&(await this.loadMock(i),this.updateMockList(),this.emit("mock:update-end"))}),this.on("mock:unlink",async i=>{s(i)&&(this.moduleCache.delete(i),this.updateMockList(),this.emit("mock:update-end"))})}watchMockEntry(){let{include:e}=this.options,[o,...n]=e,s=ve.watch(o,{ignoreInitial:!0,cwd:this.cwd});n.length>0&&n.forEach(i=>s.add(i)),s.on("add",async i=>{i=T(i),this.emit("mock:update",i),j("watcher:add",i)}),s.on("change",async i=>{i=T(i),this.emit("mock:update",i),j("watcher:change",i)}),s.on("unlink",async i=>{i=T(i),this.emit("mock:unlink",i),j("watcher:unlink",i)}),this.mockWatcher=s}watchDeps(){let e=[];this.depsWatcher=ve.watch([],{ignoreInitial:!0,cwd:this.cwd}),this.depsWatcher.on("change",o=>{o=T(o);let n=this.moduleDeps.get(o);n&&n.forEach(s=>{this.emit("mock:update",s)})}),this.depsWatcher.on("unlink",o=>{o=T(o),this.moduleDeps.delete(o)}),this.on("update:deps",()=>{let o=[];for(let[s]of this.moduleDeps.entries())o.push(s);let n=o.filter(s=>!e.includes(s));n.length>0&&this.depsWatcher.add(n)})}close(){var e,o;(e=this.mockWatcher)==null||e.close(),(o=this.depsWatcher)==null||o.close()}updateMockList(){this._mockData=ke(this.moduleCache)}updateModuleDeps(e,o){Object.keys(o).forEach(n=>{o[n].imports.map(i=>i.path).forEach(i=>{this.moduleDeps.has(i)||this.moduleDeps.set(i,new Set),this.moduleDeps.get(i).add(e)})}),this.emit("update:deps")}async loadMock(e){e&&(Q.EXT_JSON.test(e)?await this.loadJson(e):await this.loadModule(e))}async loadJson(e){let o=await q.promises.readFile(e,"utf-8");try{let n=it.parse(o);this.moduleCache.set(e,n)}catch{}}async loadModule(e){if(!e)return;let o=!1;/\.m[jt]s$/.test(e)?o=!0:/\.c[jt]s$/.test(e)?o=!1:o=this.moduleType==="esm";let{code:n,deps:s}=await this.transformWithEsbuild(e,o);try{let i=await this.loadFromCode(e,n,o),a=i&&i.default?i.default:Object.keys(i||{}).map(c=>i[c]);this.moduleCache.set(e,a),this.updateModuleDeps(e,s)}catch(i){console.error(i)}}async loadFromCode(e,o,n){if(n){let s=`${e}.timestamp-${Date.now()}`,i=`${s}.mjs`,a=`${rt(s)}.mjs`;await q.promises.writeFile(i,o,"utf8");try{return await import(a)}finally{try{q.unlinkSync(i)}catch{}}}else{e=he.resolve(this.cwd,e);let s=he.extname(e),i=q.realpathSync(e),a=s in w.extensions?s:".js",c=w.extensions[a];w.extensions[a]=(u,l)=>{l===i?u._compile(o,l):c(u,l)},delete w.cache[w.resolve(e)];let p=w(e);return w.extensions[a]=c,p.__esModule?p:{default:p}}}async transformWithEsbuild(e,o){var n;try{let s=await nt({entryPoints:[e],outfile:"out.js",write:!1,target:["node14.18","node16"],platform:"node",bundle:!0,metafile:!0,format:o?"esm":"cjs",define:this.options.define,plugins:[B(this.options.alias),N]});return{code:s.outputFiles[0].text,deps:((n=s.metafile)==null?void 0:n.inputs)||{}}}catch{}return{code:"",deps:{}}}},$=Q;$.EXT_JSON=/\.json5?$/;async function X(t,r,e,o){let n=M(r.include),s=M(r.exclude),i={};if(t.define)for(let u in t.define){let l=t.define[u];i[u]=typeof l=="string"?l:JSON.stringify(l)}let a=new $({include:n,exclude:s,define:i,alias:t.resolve.alias});await a.load(),e==null||e.on("close",()=>a.close()),a.on("mock:update-end",()=>{r.reload&&(o==null||o.send({type:"full-reload"}))});let c=J(t.server.proxy||{}),p=M(r.prefix);return ye(a,{formidableOptions:r.formidableOptions,proxies:[...p,...c],cookiesOptions:r.cookiesOptions})}function be({prefix:t=[],include:r=["mock/**/*.mock.{js,ts,cjs,mjs,json,json5}"],exclude:e=["**/node_modules/**","**/.vscode/**","**/.git/**"],reload:o=!1,formidableOptions:n={},build:s=!1,cookiesOptions:i={}}={}){let a={prefix:t,include:r,exclude:e,reload:o,cookiesOptions:i,formidableOptions:{multiples:!0,...n},build:s?Object.assign({serverPort:8080,dist:"mockServer"},typeof s=="object"?s:{}):!1},c=[lt(a)];return a.build&&c.push(pt(a)),c}function pt(t){let r={};return{name:"vite-plugin-mock-dev-server-generator",enforce:"post",apply:"build",configResolved(e){r=e,e.logger.warn("")},async buildEnd(e){e||r.command==="build"&&await pe(this,r,t)}}}function lt(t){let r={};return{name:"vite-plugin-mock-dev-server",enforce:"pre",apply:"serve",configResolved(e){r=e,e.logger.warn("")},async configureServer({middlewares:e,config:o,httpServer:n,ws:s}){let i=await X(o,t,n,s);e.use(i)},async configurePreviewServer({middlewares:e,httpServer:o}){let n=await X(r,t,o);e.use(n)}}}function Fo(t){return t}function To(t){return e=>(v(e)?e=e.map(o=>t(o)||o):e=t(e)||e,e)}var Wo=be;export{ye as baseMiddleware,To as createDefineMock,Wo as default,Fo as defineMock,be as mockDevServerPlugin,ke as transformMockData};
36
+ `}async function ze(t,o,e){var r;try{let s=await $e({entryPoints:[t],outfile:"out.js",write:!1,target:["node14.18","node16"],platform:"node",bundle:!0,metafile:!0,format:"esm",define:o,plugins:[J(e),q,A,B]});return{code:s.outputFiles[0].text,deps:((r=s.metafile)==null?void 0:r.inputs)||{}}}catch(s){console.error(s)}return{code:"",deps:{}}}import{Buffer as fe}from"buffer";import{parse as ke}from"url";import Xe from"cookies";import Ke from"http-status";import*as H from"mime-types";import{pathToRegexp as ye}from"path-to-regexp";import _ from"picocolors";import Y from"co-body";import Ge from"formidable";async function me(t,o){var s;let e=t.method.toUpperCase();if(["GET","DELETE","HEAD"].includes(e))return;let r=((s=t.headers["content-type"])==null?void 0:s.toLocaleLowerCase())||"";try{if(r.startsWith("application/json"))return await Y.json(t);if(r.startsWith("application/x-www-form-urlencoded"))return await Y.form(t);if(r.startsWith("text/plain"))return await Y.text(t);if(r.startsWith("multipart/form-data"))return await Qe(t,o)}catch(n){console.error(n)}}async function Qe(t,o){let e=Ge(o);return new Promise((r,s)=>{e.parse(t,(n,i,c)=>{if(n){s(n);return}r({...i,...c})})})}function de(t,o){return W(t.headers,o.headers)&&W(t.body,o.body)&&W(t.params,o.params)&&W(t.query,o.query)&&W(t.refererQuery,o.refererQuery)}function W(t,o){if(!o)return!0;for(let e in o)if(o[e]!==t[e])return!1;return!0}function he(t,{formidableOptions:o={},proxies:e,cookiesOptions:r}){return async function(s,n,i){let c=Date.now(),{query:a,pathname:p}=ke(s.url,!0);if(!p||e.length===0||!e.some(j=>G(j,s.url)))return i();let m=t.mockData,u=Object.keys(m).find(j=>ye(j).test(p));if(!u)return i();let{query:b}=ke(s.headers.referer||"",!0),h=await me(s,o),k=new Xe(s,n,r),g=k.get.bind(k),f=s.method.toUpperCase(),l=Ve(m[u],{pathname:p,method:f,request:{query:a,refererQuery:b,body:h,headers:s.headers,getCookie:g}});if(!l)return i();D("middleware: ",f,s.url);let v=s,y=n;v.body=h,v.query=a,v.refererQuery=b,v.params=$(l.url,p),v.getCookie=g,y.setCookie=k.set.bind(k);let{body:M,delay:d,type:x="json",response:R,status:T=200,statusText:je}=l;if(Z(y,T,je),await Ye(v,y,l),await Ze(v,y,l),M){try{let j=C(M)?await M(v):M;await ge(c,d),et(y,j,x)}catch(j){I.error(`${_.red("[body error]")} ${s.url}
37
+ `,j),Z(y,500),n.end("")}return}if(R){try{await ge(c,d),await R(v,y,i)}catch(j){I.error(`${_.red("[response error]")} ${s.url}
38
+ `,j),Z(y,500),n.end("")}return}n.end("")}}function Ve(t,{pathname:o,method:e,request:r}){return t.find(s=>{if(!o||!s||!s.url||s.ws===!0||!(s.method?S(s.method)?s.method:[s.method]:["GET","POST"]).includes(e))return!1;let i=ye(s.url).test(o);if(i&&s.validator){let c=$(s.url,o);if(C(s.validator))return s.validator({params:c,...r});try{return de({params:c,...r},s.validator)}catch(a){return I.error(`${_.red("[validator error]")} ${o}
39
+ `,a),!1}}return i})}function Z(t,o=200,e){t.statusCode=o,t.statusMessage=e||tt(o)}async function Ye(t,o,{headers:e,type:r="json"}){let s=H.contentType(r)||H.contentType(H.lookup(r)||"");if(s&&o.setHeader("Content-Type",s),o.setHeader("Cache-Control","no-cache,max-age=0"),o.setHeader("X-Mock","generate by vite:plugin-mock-dev-server"),!!e)try{let n=C(e)?await e(t):e;Object.keys(n).forEach(i=>{o.setHeader(i,n[i])})}catch(n){I.error(`${_.red("[headers error]")} ${t.url}
40
+ `,n)}}async function Ze(t,o,{cookies:e}){if(e)try{let r=C(e)?await e(t):e;Object.keys(r).forEach(s=>{let n=r[s];if(S(n)){let[i,c]=n;o.setCookie(s,i,c)}else o.setCookie(s,n)})}catch(r){I.error(`${_.red("[cookies error]")} ${t.url}
41
+ `,r)}}function et(t,o,e){if(ae(o))o.pipe(t);else if(fe.isBuffer(o))t.end(e==="text"||e==="json"?o.toString("utf-8"):o);else{let r=typeof o=="string"?o:JSON.stringify(o);t.end(e==="buffer"?fe.from(r):r)}}async function ge(t,o){if(!o||o<=0)return;let e=Date.now()-t,r=o-e;r>0&&await pe(r)}function tt(t){return Ke[t]||"Unknown"}import nt from"events";import ee from"fs";import{createRequire as st}from"module";import Me from"path";import{pathToFileURL as it}from"url";import be from"chokidar";import{build as ct}from"esbuild";import at from"fast-glob";import{createFilter as pt,normalizePath as N}from"vite";import{parse as ot}from"url";import rt from"lodash.sortby";function ve(t){let o=[];for(let[,r]of t.entries())r&&(S(r)?o.push(...r):o.push(r));let e={};return o.filter(r=>(r.enabled||typeof r.enabled>"u")&&r.url).forEach(r=>{let{pathname:s,query:n}=ot(r.url,!0),i=e[s]??(e[s]=[]),c={...r,url:s};if(c.ws!==!0){let a=c.validator;ce(n)||(C(a)?c.validator=function(p){return W(p.query,n)&&a(p)}:a?(c.validator={...a},c.validator.query=c.validator.query?{...n,...c.validator.query}:n):c.validator={query:n})}i.push(c)}),Object.keys(e).forEach(r=>{e[r]=rt(e[r],s=>{if(s.ws===!0)return 0;let{validator:n}=s;if(!n)return 1;if(C(n))return 0;let{query:i,params:c,headers:a,body:p,refererQuery:m}=n;return 1/(U(i)+U(c)+U(a)+U(p)+U(m))})}),e}function U(t){return t?Object.keys(t).length:0}var ut=ue(import.meta.url),E=st(ut),X=class extends nt{constructor(e){super();this.options=e;this.moduleCache=new Map;this.moduleDeps=new Map;this.moduleType="cjs";this._mockData={};this.cwd=e.cwd||process.cwd();try{let r=F(this.cwd,["package.json"]);this.moduleType=r&&JSON.parse(r).type==="module"?"esm":"cjs"}catch{}}get mockData(){return this._mockData}async load(){let{include:e,exclude:r}=this.options,s=await at(e,{cwd:this.cwd}),n=pt(e,r,{resolve:!1});this.watchMockEntry(),this.watchDeps();for(let c of s.filter(n))await this.loadMock(c);this.updateMockList();let i=null;this.on("mock:update",async c=>{n(c)&&(await this.loadMock(c),i&&clearTimeout(i),i=setTimeout(()=>{this.updateMockList(),this.emit("mock:update-end",c),i=null},0))}),this.on("mock:unlink",async c=>{n(c)&&(this.moduleCache.delete(c),this.updateMockList(),this.emit("mock:update-end",c))})}watchMockEntry(){let{include:e}=this.options,[r,...s]=e,n=be.watch(r,{ignoreInitial:!0,cwd:this.cwd});s.length>0&&s.forEach(i=>n.add(i)),n.on("add",async i=>{i=N(i),this.emit("mock:update",i),D("watcher:add",i)}),n.on("change",async i=>{i=N(i),this.emit("mock:update",i),D("watcher:change",i)}),n.on("unlink",async i=>{i=N(i),this.emit("mock:unlink",i),D("watcher:unlink",i)}),this.mockWatcher=n}watchDeps(){let e=[];this.depsWatcher=be.watch([],{ignoreInitial:!0,cwd:this.cwd}),this.depsWatcher.on("change",r=>{r=N(r);let s=this.moduleDeps.get(r);s&&s.forEach(n=>{this.emit("mock:update",n)})}),this.depsWatcher.on("unlink",r=>{r=N(r),this.moduleDeps.delete(r)}),this.on("update:deps",()=>{let r=[];for(let[n]of this.moduleDeps.entries())r.push(n);let s=r.filter(n=>!e.includes(n));s.length>0&&this.depsWatcher.add(s)})}close(){var e,r;(e=this.mockWatcher)==null||e.close(),(r=this.depsWatcher)==null||r.close()}updateMockList(){this._mockData=ve(this.moduleCache)}updateModuleDeps(e,r){Object.keys(r).forEach(s=>{r[s].imports.map(i=>i.path).forEach(i=>{this.moduleDeps.has(i)||this.moduleDeps.set(i,new Set),this.moduleDeps.get(i).add(e)})}),this.emit("update:deps")}async loadMock(e){if(!e)return;let r=!1;/\.m[jt]s$/.test(e)?r=!0:/\.c[jt]s$/.test(e)?r=!1:r=this.moduleType==="esm";let{code:s,deps:n}=await this.transformWithEsbuild(e,r);try{let i=await this.loadFromCode(e,s,r),c=i&&i.default?i.default:Object.keys(i||{}).map(a=>i[a]);S(c)?c.forEach(a=>a.__filepath__=e):c.__filepath__=e,this.moduleCache.set(e,c),this.updateModuleDeps(e,n)}catch(i){console.error(i)}}async loadFromCode(e,r,s){if(s){let n=`${e}.timestamp-${Date.now()}`,i=`${n}.mjs`,c=`${it(n)}.mjs`;await ee.promises.writeFile(i,r,"utf8");try{return await import(c)}finally{try{ee.unlinkSync(i)}catch{}}}else{e=Me.resolve(this.cwd,e);let n=Me.extname(e),i=ee.realpathSync(e),c=n in E.extensions?n:".js",a=E.extensions[c];E.extensions[c]=(m,u)=>{u===i?m._compile(r,u):a(m,u)},delete E.cache[E.resolve(e)];let p=E(e);return E.extensions[c]=a,p.__esModule?p:{default:p}}}async transformWithEsbuild(e,r){var s;try{let n=await ct({entryPoints:[e],outfile:"out.js",write:!1,target:["node14.18","node16"],platform:"node",bundle:!0,metafile:!0,format:r?"esm":"cjs",define:this.options.define,plugins:[J(this.options.alias),q,B,A]});return{code:n.outputFiles[0].text,deps:((s=n.metafile)==null?void 0:s.inputs)||{}}}catch(n){console.error(n)}return{code:"",deps:{}}}};import{parse as xe}from"url";import lt from"cookies";import{pathToRegexp as we}from"path-to-regexp";import{WebSocketServer as mt}from"ws";function Se(t,o,e,r){var c;let s=new Set,n=new Map,i=new Map;(c=t.on)==null||c.call(t,"mock:update-end",a=>{if(!s.has(a))return;let p={};for(let[m,u]of i.entries())t.mockData[m].forEach(b=>{b.ws&&b.__filepath__===a&&u.forEach(({pathname:h,req:k,ws:g})=>{p[h]??(p[h]={mock:b,list:[],mockUrl:m}),p[h].list.push({req:k,ws:g})})});Object.keys(p).forEach(m=>{var l;let{wss:u,cleanupList:b,context:h}=n.get(m),{mock:k,list:g,mockUrl:f}=p[m];Oe(b),u.removeAllListeners(),(l=k.setup)==null||l.call(k,u,h),u.on("close",()=>n.delete(m)),g.forEach(({req:v,ws:y})=>{y.removeAllListeners(),u.emit("connection",y,v),y.on("close",()=>{let M=i.get(f),d=(M==null?void 0:M.findIndex(x=>x.ws===y))||-1;d!==-1&&(M==null||M.splice(d,1))})})})}),o==null||o.on("upgrade",(a,p,m)=>{var M;let{pathname:u,query:b}=xe(a.url,!0);if(!u||e.length===0||!e.some(d=>G(d,a.url)))return;let h=t.mockData,k=Object.keys(h).find(d=>we(d).test(u));if(!k)return;let g=h[k].find(d=>d.url&&d.ws&&we(d.url).test(u));if(!g)return;s.add(g.__filepath__);let f=n.get(u);if(!f){let d=new mt({noServer:!0}),x=[],R={onCleanup:T=>x.push(T)};(M=g.setup)==null||M.call(g,d,R),d.on("close",()=>n.delete(u)),n.set(u,f={wss:d,cleanupList:x,context:R})}let l=a,v=new lt(a,a,r),{query:y}=xe(a.headers.referer||"",!0);l.query=b,l.refererQuery=y,l.params=$(k,u),l.getCookie=v.get.bind(v),f.wss.handleUpgrade(l,p,m,d=>{D(`websocket-mock: ${a.url} connected`),f.wss.emit("connection",d,l);let x=i.get(k);x||i.set(k,x=[]),x.push({req:l,ws:d,pathname:u}),d.on("close",()=>{let R=x.findIndex(T=>T.ws===d);R!==-1&&x.splice(R,1)})})}),o==null||o.on("close",()=>{n.forEach(({wss:a,cleanupList:p})=>{Oe(p),a.close()}),n.clear(),i.clear(),s.clear()})}function Oe(t){let o;for(;o=t.shift();)o==null||o()}async function te(t,o,e,r){let s=P(o.include),n=P(o.exclude),i={};if(t.define)for(let m in t.define){let u=t.define[m];i[m]=typeof u=="string"?u:JSON.stringify(u)}let c=new X({include:s,exclude:n,define:i,alias:t.resolve.alias});await c.load(),c.on("mock:update-end",()=>{o.reload&&(r==null||r.send({type:"full-reload"}))}),e==null||e.on("close",()=>c.close());let{httpProxies:a}=z(t.server.proxy||{}),p=P(o.prefix);return Se(c,e,P(o.wsPrefix),o.cookiesOptions),he(c,{formidableOptions:o.formidableOptions,proxies:[...p,...a],cookiesOptions:o.cookiesOptions})}function Pe({prefix:t=[],wsPrefix:o=[],include:e=["mock/**/*.mock.{js,ts,cjs,mjs,json,json5}"],exclude:r=["**/node_modules/**","**/.vscode/**","**/.git/**"],reload:s=!1,formidableOptions:n={},build:i=!1,cookiesOptions:c={}}={}){let a={prefix:t,wsPrefix:o,include:e,exclude:r,reload:s,cookiesOptions:c,formidableOptions:{multiples:!0,...n},build:i?Object.assign({serverPort:8080,dist:"mockServer"},typeof i=="object"?i:{}):!1},p=[ft(a)];return a.build&&p.push(dt(a)),p}function dt(t){let o={};return{name:"vite-plugin-mock-dev-server-generator",enforce:"post",apply:"build",configResolved(e){o=e,e.logger.warn("")},async buildEnd(e){e||o.command==="build"&&await le(this,o,t)}}}function ft(t){let o={};return{name:"vite-plugin-mock-dev-server",enforce:"pre",apply:"serve",configResolved(e){o=e,e.logger.warn("")},async configureServer({middlewares:e,config:r,httpServer:s,ws:n}){let i=await te(r,t,s,n);e.use(i)},async configurePreviewServer({middlewares:e,httpServer:r}){let s=await te(o,t,r);e.use(s)}}}function Ao(t){return t}function Bo(t){return e=>(S(e)?e=e.map(r=>t(r)||r):e=t(e)||e,e)}var Qo=Pe;export{he as baseMiddleware,Bo as createDefineMock,Qo as default,Ao as defineMock,Pe as mockDevServerPlugin,Se as mockWebSocket,ve as transformMockData};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vite-plugin-mock-dev-server",
3
- "version": "1.1.5",
3
+ "version": "1.1.7",
4
4
  "keywords": [
5
5
  "vite",
6
6
  "plugin",
@@ -43,7 +43,8 @@
43
43
  "lodash.sortby": "^4.7.0",
44
44
  "mime-types": "^2.1.35",
45
45
  "path-to-regexp": "^6.2.1",
46
- "picocolors": "^1.0.0"
46
+ "picocolors": "^1.0.0",
47
+ "ws": "^8.13.0"
47
48
  },
48
49
  "devDependencies": {
49
50
  "@pengzhanbo/eslint-config-ts": "^0.3.4",
@@ -56,6 +57,7 @@
56
57
  "@types/lodash.sortby": "^4.7.7",
57
58
  "@types/mime-types": "^2.1.1",
58
59
  "@types/node": "^18.16.1",
60
+ "@types/ws": "^8.5.4",
59
61
  "bumpp": "^9.1.0",
60
62
  "conventional-changelog-cli": "^2.2.2",
61
63
  "eslint": "^8.39.0",