vite-plugin-mock-dev-server 1.1.2 → 1.1.4

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
@@ -30,18 +30,19 @@
30
30
  - 🧲 Not injection-based, non-intrusive to client code.
31
31
  - 💡 ESModule/commonjs.
32
32
  - 🦾 Typescript.
33
+ - 🔥 HMR
33
34
  - 🏷 Support `json` / `json5`.
34
35
  - 📦 Auto import mock file.
35
36
  - 🎨 Support any lib,like `mockjs`,or not use it.
36
37
  - 📥 Path rule matching, request parameter matching.
37
38
  - ⚙️ Support Enabled/Disabled any one of api mock
38
- - 🔥 HMR
39
+ - 📀 Supports response body content type such as `text/json/buffer/stream`.
39
40
  - ⚖️ Use `server.proxy`
40
41
  - 🍕 Support `viteConfig.define` in mock file.
41
- - ⚓️ Support `resolve.alias` in mock file.
42
+ - ⚓️ Support `viteConfig.resolve.alias` in mock file.
43
+ - 🌈 Support `vite preview` mode.
42
44
  - 📤 Support `multipart` content-type,mock upload file.
43
- - 🍪 Support cookies
44
- - 🌈 Support `vite preview` mode
45
+ - 📥 Support mock download file.
45
46
  - 🗂 Support building small independent deployable mock services.
46
47
 
47
48
 
@@ -260,11 +261,12 @@ export default defineApiMock({
260
261
  export default defineMock({
261
262
  /**
262
263
  * Request address, supports the `/api/user/:id` format.
264
+ * The plugin matches the path through `path-to-regexp`.
265
+ * @see https://github.com/pillarjs/path-to-regexp
263
266
  */
264
267
  url: '/api/test',
265
268
  /**
266
269
  * Supported request methods of the interface.
267
- *
268
270
  * @type string | string[]
269
271
  * @default ['POST','GET']
270
272
  *
@@ -282,13 +284,11 @@ export default defineMock({
282
284
  enable: true,
283
285
  /**
284
286
  * Set interface response delay, unit: ms.
285
- *
286
287
  * @default 0
287
288
  */
288
289
  delay: 1000,
289
290
  /**
290
291
  * response status
291
- *
292
292
  * @default 200
293
293
  */
294
294
  status: 200,
@@ -309,8 +309,8 @@ export default defineMock({
309
309
  * then the validation method is to strictly compare whether the `value`
310
310
  * of each `key` in headers/body/query/params in the request interface is exactly equal.
311
311
  * If they are all equal, then the validation passes.
312
- *
313
312
  * @type ({ headers: object; body: object; query: object; params: object; refererQuery: object }) => boolean
313
+ *
314
314
  * If the validator passed in is a function,
315
315
  * then the data related to the requested interface will be provided as input parameters
316
316
  * for users to perform custom validation and return a boolean.
@@ -329,11 +329,8 @@ export default defineMock({
329
329
  refererQuery: {}
330
330
  },
331
331
  /**
332
- *
333
332
  * response headers
334
- *
335
333
  * @type Record<string, any>
336
- *
337
334
  * @type (({ query, body, params, headers }) => Record<string, any>)
338
335
  */
339
336
  headers: {
@@ -349,17 +346,28 @@ export default defineMock({
349
346
  'your-cookie': 'your cookie value',
350
347
  'cookie&option': ['cookie value', { path: '/', httpOnly: true }]
351
348
  },
349
+ /**
350
+ * Response body data type, optional values include `text, json, buffer`.
351
+ * And also support types included in `mime-db`.
352
+ * When the response body returns a file and you are not sure which type to use,
353
+ * you can pass the file name as the value. The plugin will internally search for matching
354
+ * `content-type` based on the file name suffix.
355
+ * However, if it is a TypeScript file such as `a.ts`, it may not be correctly matched
356
+ * as a JavaScript script. You need to modify `a.ts` to `a.js` as the value passed
357
+ * in order to recognize it correctly.
358
+ * @see https://github.com/jshttp/mime-db
359
+ * @default 'json'
360
+ */
361
+ type: 'json',
352
362
 
353
363
  /**
354
364
  * Response Body
355
- * Support `string/number/array/object`
365
+ * Support `string/number/array/object/buffer/ReadableStream`
356
366
  * You can also use libraries such as' mockjs' to generate data content
357
- *
358
- * @type string | number | array | object
359
- *
367
+ * @type string | number | array | object | ReadableStream | buffer
360
368
  * @type (request: { headers, query, body, params, refererQuery, getCookie }) => any | Promise<any>
361
369
  */
362
- body: {},
370
+ body: '',
363
371
 
364
372
  /**
365
373
  * If the mock requirement cannot be solved through `body` configuration,
@@ -408,37 +416,35 @@ type Response = http.ServerResponse<http.IncomingMessage> & {
408
416
  ```
409
417
 
410
418
 
411
- > Tips
419
+ > **Tips:**
412
420
  >
413
421
  > If you write mock files using json/json5,
414
422
  > the 'response' method is not supported,
415
423
  > as is the function form that uses other fields.
416
424
 
425
+ ## Example
426
+
417
427
  `mock/**/*.mock.{ts,js,mjs,cjs,json,json5}`
418
428
 
419
429
  See more examples: [example](/example/)
420
430
 
421
- #### Example 1:
422
- Match `/api/test`,And returns a response body content with empty data
431
+ **exp:** Match `/api/test`,And returns a response body content with empty data
423
432
  ```ts
424
433
  export default defineMock({
425
434
  url: '/api/test',
426
435
  })
427
436
  ```
428
437
 
429
- #### Example 2:
430
- Match `/api/test` ,And returns a static content data
438
+ **exp:** Match `/api/test` ,And returns a static content data
431
439
  ```ts
432
440
  export default defineMock({
433
441
  url: '/api/test',
434
- body: {
435
- a: 1
436
- }
442
+ body: { a: 1 },
437
443
  })
438
444
  ```
439
445
 
440
- #### Example 3:
441
- Only Support `GET` Method
446
+
447
+ **exp:** Only Support `GET` Method
442
448
  ```ts
443
449
  export default defineMock({
444
450
  url: '/api/test',
@@ -446,69 +452,56 @@ export default defineMock({
446
452
  })
447
453
  ```
448
454
 
449
- #### Example 4:
450
- In the response header, add a custom header
455
+ **exp:** In the response header, add a custom header and cookie
451
456
  ```ts
452
457
  export default defineMock({
453
458
  url: '/api/test',
454
- headers: {
455
- 'X-Custom': '12345678'
456
- }
459
+ headers: { 'X-Custom': '12345678' },
460
+ cookies: { 'my-cookie': '123456789' },
457
461
  })
458
462
  ```
459
463
  ```ts
460
464
  export default defineMock({
461
465
  url: '/api/test',
462
466
  headers({ query, body, params, headers }) {
463
- return {
464
- 'X-Custom': query.custom
465
- }
467
+ return { 'X-Custom': query.custom }
468
+ },
469
+ cookies() {
470
+ return { 'my-cookie': '123456789' }
466
471
  }
467
472
  })
468
473
  ```
469
474
 
470
- #### Example 5:
471
- Define multiple mock requests for the same url and match valid rules with validators
475
+
476
+ **exp:** Define multiple mock requests for the same url and match valid rules with validators
472
477
  ```ts
473
478
  export default defineMock([
474
479
  // Match /api/test?a=1
475
480
  {
476
481
  url: '/api/test',
477
482
  validator: {
478
- query: {
479
- a: 1
480
- }
483
+ query: { a: 1 },
481
484
  },
482
- body: {
483
- message: 'query.a == 1'
484
- }
485
+ body: { message: 'query.a == 1' },
485
486
  },
486
487
  // Match /api/test?a=2
487
488
  {
488
489
  url: '/api/test',
489
490
  validator: {
490
- query: {
491
- a: 2
492
- }
491
+ query: { a: 2 },
493
492
  },
494
- body: {
495
- message: 'query.a == 2'
496
- }
493
+ body: { message: 'query.a == 2' },
497
494
  },
498
495
  {
499
- /**
500
- * `?a=3` will resolve to `validator.query`
501
- */
496
+ // `?a=3` will resolve to `validator.query`
502
497
  url: '/api/test?a=3',
503
- body: {
504
- message: 'query.a == 3'
505
- }
498
+ body: { message: 'query.a == 3' }
506
499
  }
507
500
  ])
508
501
  ```
509
502
 
510
- #### Example 6:
511
- Response Delay
503
+
504
+ **exp:** Response Delay
512
505
  ```ts
513
506
  export default defineMock({
514
507
  url: '/api/test',
@@ -516,33 +509,67 @@ export default defineMock({
516
509
  })
517
510
  ```
518
511
 
519
- #### Example 7:
520
- The interface request failed
512
+
513
+ **exp:** The interface request failed
521
514
  ```ts
522
515
  export default defineMock({
523
516
  url: '/api/test',
524
- status: 504,
517
+ status: 502,
525
518
  statusText: 'Bad Gateway'
526
519
  })
527
520
  ```
528
521
 
529
- #### Example 8:
530
- Dynamic route matching
522
+
523
+ **exp:** Dynamic route matching
531
524
  ```ts
532
525
  export default defineMock({
533
526
  url: '/api/user/:userId',
534
527
  body({ params }) {
535
- return {
536
- userId: params.userId,
537
- }
528
+ return { userId: params.userId }
538
529
  }
539
530
  })
540
531
  ```
541
532
 
542
533
  The `userId` in the route will be resolved into the `request.params` object.
543
534
 
544
- #### Example 9:
545
- Use `mockjs`:
535
+ **exp:** Use buffer to respond data
536
+ ```ts
537
+ // Since the default value of type is json,
538
+ // although buffer is used for body during transmission,
539
+ // the content-type is still json.
540
+ export default defineMock({
541
+ url: 'api/buffer',
542
+ body: Buffer.from(JSON.stringify({ a: 1 }))
543
+ })
544
+ ```
545
+ ```ts
546
+ // When the type is buffer, the content-type is application/octet-stream.
547
+ // The data passed in through body will be converted to a buffer.
548
+ export default defineMock({
549
+ url: 'api/buffer',
550
+ type: 'buffer',
551
+ // Convert using Buffer.from(body) for internal use
552
+ body: { a: 1 }
553
+ })
554
+ ```
555
+
556
+ **exp:** Response file type
557
+
558
+ Simulate file download, pass in the file reading stream.
559
+ ```ts
560
+ import { createReadStream } from 'node:fs'
561
+ export default defineMock({
562
+ url: '/api/download',
563
+ // When you are unsure of the type, you can pass in the file name for internal parsing by the plugin.
564
+ type: 'my-app.dmg',
565
+ body: () => createReadStream('./my-app.dmg')
566
+ })
567
+ ```
568
+ ```html
569
+ <a href="/api/download" download="my-app.dmg">Download File</a>
570
+ ```
571
+
572
+ **exp:** Use `mockjs`:
546
573
  ```ts
547
574
  import Mock from 'mockjs'
548
575
  export default defineMock({
@@ -556,8 +583,8 @@ export default defineMock({
556
583
  ```
557
584
  You need installed `mockjs`
558
585
 
559
- ### Example 10:
560
- Use `response` to customize the response
586
+
587
+ **exp:** Use `response` to customize the response
561
588
  ```ts
562
589
  export default defineMock({
563
590
  url: '/api/test',
@@ -576,11 +603,10 @@ export default defineMock({
576
603
  })
577
604
  ```
578
605
 
579
- ### Example 11:
580
- Use json / json5
606
+
607
+ **exp:** Use json / json5
581
608
  ```json
582
609
  {
583
- // Support comment
584
610
  "url": "/api/test",
585
611
  "body": {
586
612
  "a": 1
@@ -588,9 +614,9 @@ Use json / json5
588
614
  }
589
615
  ```
590
616
 
591
- ### Example 12:
592
617
 
593
- multipart, upload file.
618
+
619
+ **exp:** multipart, upload file.
594
620
 
595
621
  use [`formidable`](https://www.npmjs.com/package/formidable#readme) to supported.
596
622
  ``` html
package/README.zh-CN.md CHANGED
@@ -31,18 +31,19 @@
31
31
  - 🧲 非注入式,对客户端代码无侵入
32
32
  - 💡 ESModule/commonjs
33
33
  - 🦾 Typescript
34
+ - 🔥 热更新
34
35
  - 🏷 支持 `json` / `json5` 编写 mock 数据
35
36
  - 📦 自动加载 mock 文件
36
37
  - 🎨 可选择你喜欢的任意用于生成mock数据库,如 `mockjs`,或者不使用其他库
37
38
  - 📥 路径规则匹配,请求参数匹配
38
39
  - ⚙️ 随意开启或关闭对某个接口的 mock配置
39
- - 🔥 热更新
40
+ - - 📀 支持多种响应体数据类型,包括 `text/json/buffer/stream`.
40
41
  - ⚖️ 使用 `server.proxy` 配置
41
42
  - 🍕 支持在 mock文件中使用 `viteConfig.define`配置字段
42
- - ⚓️ 支持 `resolve.alias`
43
- - 📤 支持 multipart 类型,模拟文件上传
44
- - 🍪 支持 cookies
43
+ - ⚓️ 支持在 mock文件中使用 `viteConfig.resolve.alias` 路径别名
45
44
  - 🌈 支持 `vite preview` 模式
45
+ - 📤 支持 multipart 类型,模拟文件上传
46
+ - 📥 支持模拟文件下载
46
47
  - 🗂 支持构建可独立部署的小型mock服务
47
48
 
48
49
 
@@ -255,12 +256,13 @@ export default defineApiMock({
255
256
  ```ts
256
257
  export default defineMock({
257
258
  /**
258
- * 请求地址,支持 `/api/user/:id` 格式
259
+ * 请求地址,支持 `/api/user/:id` 格式
260
+ * 插件通过 `path-to-regexp` 匹配路径
261
+ * @see https://github.com/pillarjs/path-to-regexp
259
262
  */
260
263
  url: '/api/test',
261
264
  /**
262
265
  * 接口支持的请求方法
263
- *
264
266
  * @type string | string[]
265
267
  * @default ['POST','GET']
266
268
  *
@@ -268,23 +270,19 @@ export default defineMock({
268
270
  method: ['GET', 'POST'],
269
271
  /**
270
272
  * 是否启用当前 mock请求
271
- *
272
273
  * 在实际场景中,我们一般只需要某几个mock接口生效,
273
274
  * 而不是所以mock接口都启用。
274
275
  * 对当前不需要mock的接口,可设置为 false
275
- *
276
276
  * @default true
277
277
  */
278
278
  enable: true,
279
279
  /**
280
280
  * 设置接口响应延迟, 单位:ms
281
- *
282
281
  * @default 0
283
282
  */
284
283
  delay: 1000,
285
284
  /**
286
285
  * 响应状态码
287
- *
288
286
  * @default 200
289
287
  */
290
288
  status: 200,
@@ -320,11 +318,8 @@ export default defineMock({
320
318
  refererQuery: {}
321
319
  },
322
320
  /**
323
- *
324
321
  * 响应状态 headers
325
- *
326
322
  * @type Record<string, any>
327
- *
328
323
  * @type (({ query, body, params, headers }) => Record<string, any>)
329
324
  * 入参部分为 请求相关信息
330
325
  */
@@ -342,6 +337,18 @@ export default defineMock({
342
337
  'cookie&option': ['cookie value', { path: '/', httpOnly: true }]
343
338
  },
344
339
 
340
+ /**
341
+ * 响应体数据类型, 可选值包括 `text, json, buffer`,
342
+ * 还支持`mime-db`中的包含的类型。
343
+ * 当响应体返回的是一个文件,而你不确定应该使用哪个类型时,可以将文件名作为值传入,
344
+ * 插件内部会根据文件名后缀查找匹配的`content-type`。
345
+ * 但如果是 `typescript`文件如 `a.ts`,可能不会被正确匹配为 `javascript`脚本,
346
+ * 你需要将 `a.ts` 修改为 `a.js`作为值传入才能正确识别。
347
+ * @see https://github.com/jshttp/mime-db
348
+ * @default 'json'
349
+ */
350
+ type: 'json',
351
+
345
352
  /**
346
353
  * 响应体数据
347
354
  * 定义返回的响应体数据内容。
@@ -360,10 +367,8 @@ export default defineMock({
360
367
  * 如果通过 body 配置不能解决mock需求,
361
368
  * 那么可以通过 配置 response,暴露http server 的接口,
362
369
  * 实现完全可控的自定义配置
363
- *
364
370
  * 在 req参数中,已内置了 query、body、params 的解析,
365
- * 你可以直接使用它们
366
- *
371
+ * 你可以直接使用它们。
367
372
  * 别忘了,需要通过 `res.end()` 返回响应体数据,
368
373
  * 或者需要跳过mock,那么别忘了调用 `next()`
369
374
  */
@@ -407,35 +412,38 @@ type Response = http.ServerResponse<http.IncomingMessage> & {
407
412
  ```
408
413
 
409
414
 
410
- > 注意:
415
+ > **注意:**
411
416
  >
412
417
  > 如果使用 json/json5 编写 mock文件,则不支持使用 `response` 方法,以及不支持使用其他字段的函数形式。
413
418
 
419
+ ## Example
420
+
414
421
  `mock/**/*.mock.{ts,js,mjs,cjs,json,json5}`
415
422
 
416
423
  查看更多示例: [example](/example/)
417
424
 
418
- #### 示例1:
419
- 命中 `/api/test` 请求,并返回一个 数据为空的响应体内容
425
+ **exp:** 命中 `/api/test` 请求,并返回一个 数据为空的响应体内容
420
426
  ```ts
421
427
  export default defineMock({
422
428
  url: '/api/test',
423
429
  })
424
430
  ```
425
431
 
426
- #### 示例2:
427
- 命中 `/api/test` 请求,并返回一个固定内容数据
432
+ **exp:** 命中 `/api/test` 请求,并返回一个固定内容数据
428
433
  ```ts
429
434
  export default defineMock({
430
435
  url: '/api/test',
431
- body: {
432
- a: 1
433
- }
436
+ body: { a: 1 },
437
+ })
438
+ ```
439
+ ```ts
440
+ export default defineMock({
441
+ url: '/api/test',
442
+ body: () => ({ a: 1 })
434
443
  })
435
444
  ```
436
445
 
437
- #### 示例3:
438
- 限定只允许 `GET` 请求
446
+ **exp:** 限定只允许 `GET` 请求
439
447
  ```ts
440
448
  export default defineMock({
441
449
  url: '/api/test',
@@ -443,69 +451,56 @@ export default defineMock({
443
451
  })
444
452
  ```
445
453
 
446
- #### 示例4:
447
- 在返回的响应头中,添加自定义header
454
+
455
+ **exp:** 在返回的响应头中,添加自定义 header 和 cookie
448
456
  ```ts
449
457
  export default defineMock({
450
458
  url: '/api/test',
451
- headers: {
452
- 'X-Custom': '12345678'
453
- }
459
+ headers: { 'X-Custom': '12345678' },
460
+ cookies: { 'my-cookie': '123456789' },
454
461
  })
455
462
  ```
456
463
  ```ts
457
464
  export default defineMock({
458
465
  url: '/api/test',
459
466
  headers({ query, body, params, headers }) {
460
- return {
461
- 'X-Custom': query.custom
462
- }
467
+ return { 'X-Custom': query.custom }
468
+ },
469
+ cookies() {
470
+ return { 'my-cookie': '123456789' }
463
471
  }
464
472
  })
465
473
  ```
466
474
 
467
- #### 示例5:
468
- 定义多个相同url请求mock,并使用验证器匹配生效规则
475
+ **exp:** 定义多个相同url请求mock,并使用验证器匹配生效规则
469
476
  ```ts
470
477
  export default defineMock([
471
478
  // 命中 /api/test?a=1
472
479
  {
473
480
  url: '/api/test',
474
481
  validator: {
475
- query: {
476
- a: 1
477
- }
482
+ query: { a: 1 },
478
483
  },
479
- body: {
480
- message: 'query.a === 1'
481
- }
484
+ body: { message: 'query.a === 1' },
482
485
  },
483
486
  // 命中 /api/test?a=2
484
487
  {
485
488
  url: '/api/test',
486
489
  validator: {
487
- query: {
488
- a: 2
489
- }
490
+ query: { a: 2 },
490
491
  },
491
- body: {
492
- message: 'query.a === 2'
493
- }
492
+ body: { message: 'query.a === 2' },
494
493
  },
495
494
  {
496
- /**
497
- * `?a=3` 将会解析到 `validator.query`
498
- */
495
+ // `?a=3` 将会解析到 `validator.query`
499
496
  url: '/api/test?a=3',
500
- body: {
501
- message: 'query.a == 3'
502
- }
497
+ body: { message: 'query.a == 3' },
503
498
  }
504
499
  ])
505
500
  ```
506
501
 
507
- #### 示例6:
508
- 延迟接口响应:
502
+
503
+ **exp:** 延迟接口响应:
509
504
  ```ts
510
505
  export default defineMock({
511
506
  url: '/api/test',
@@ -513,33 +508,64 @@ export default defineMock({
513
508
  })
514
509
  ```
515
510
 
516
- #### 示例7:
517
- 使接口请求失败
511
+ **exp:** 使接口请求失败
518
512
  ```ts
519
513
  export default defineMock({
520
514
  url: '/api/test',
521
- status: 504,
515
+ status: 502,
522
516
  statusText: 'Bad Gateway'
523
517
  })
524
518
  ```
525
519
 
526
- #### 示例8:
527
- 动态路由匹配
520
+ **exp:** 动态路由匹配
528
521
  ```ts
529
522
  export default defineMock({
530
523
  url: '/api/user/:userId',
531
524
  body({ params }) {
532
- return {
533
- userId: params.userId,
534
- }
525
+ return { userId: params.userId }
535
526
  }
536
527
  })
537
528
  ```
538
529
 
539
530
  路由中的 `userId`将会解析到 `request.params` 对象中.
540
531
 
541
- #### 示例9:
542
- 使用 `mockjs` 生成响应数据:
532
+ **exp:** 使用 buffer 响应数据
533
+ ```ts
534
+ // 由于 type 默认值是 json,虽然在传输过程中body使用buffer,
535
+ // 但是 content-type 还是为 json
536
+ export default defineMock({
537
+ url: 'api/buffer',
538
+ body: Buffer.from(JSON.stringify({ a: 1 }))
539
+ })
540
+ ```
541
+ ```ts
542
+ // 当 type 为 buffer 时,content-type 为 application/octet-stream,
543
+ // body 传入的数据会被转为 buffer
544
+ export default defineMock({
545
+ url: 'api/buffer',
546
+ type: 'buffer',
547
+ // 内部使用 Buffer.from(body) 进行转换
548
+ body: { a: 1 }
549
+ })
550
+ ```
551
+
552
+ **exp:** 响应文件类型
553
+
554
+ 模拟文件下载,传入文件读取流
555
+ ```ts
556
+ import { createReadStream } from 'node:fs'
557
+ export default defineMock({
558
+ url: '/api/download',
559
+ // 当你不确定类型,可传入文件名由插件内部进行解析
560
+ type: 'my-app.dmg',
561
+ body: () => createReadStream('./my-app.dmg')
562
+ })
563
+ ```
564
+ ```html
565
+ <a href="/api/download" download="my-app.dmg">下载文件</a>
566
+ ```
567
+
568
+ **exp:** 使用 `mockjs` 生成响应数据:
543
569
  ```ts
544
570
  import Mock from 'mockjs'
545
571
  export default defineMock({
@@ -553,8 +579,8 @@ export default defineMock({
553
579
  ```
554
580
  请先安装 `mockjs`
555
581
 
556
- ### 示例10:
557
- 使用 `response` 自定义响应
582
+
583
+ **exp:** 使用 `response` 自定义响应
558
584
  ```ts
559
585
  export default defineMock({
560
586
  url: '/api/test',
@@ -573,11 +599,10 @@ export default defineMock({
573
599
  })
574
600
  ```
575
601
 
576
- ### 示例11:
577
- 使用 json / json5
602
+
603
+ **exp:** 使用 json / json5
578
604
  ```json
579
605
  {
580
- // 支持 comment
581
606
  "url": "/api/test",
582
607
  "body": {
583
608
  "a": 1
@@ -585,9 +610,8 @@ export default defineMock({
585
610
  }
586
611
  ```
587
612
 
588
- ### Example 12:
589
613
 
590
- multipart, 文件上传.
614
+ **exp:** multipart, 文件上传.
591
615
 
592
616
  通过 [`formidable`](https://www.npmjs.com/package/formidable#readme) 支持。
593
617
  ``` html
package/dist/index.cjs CHANGED
@@ -54,7 +54,7 @@ var import_vite = require("vite");
54
54
 
55
55
  // package.json
56
56
  var name = "vite-plugin-mock-dev-server";
57
- var version = "1.1.2";
57
+ var version = "1.1.4";
58
58
 
59
59
  // src/esbuildPlugin.ts
60
60
  var import_promises = __toESM(require("fs/promises"), 1);
@@ -141,6 +141,8 @@ var import_path_to_regexp = require("path-to-regexp");
141
141
  var import_picocolors = __toESM(require("picocolors"), 1);
142
142
  var isArray = (val) => Array.isArray(val);
143
143
  var isFunction = (val) => typeof val === "function";
144
+ var isStream = (stream) => stream !== null && typeof stream === "object" && typeof stream.pipe === "function";
145
+ var isReadableStream = (stream) => isStream(stream) && stream.readable !== false && typeof stream._read === "function" && typeof stream._readableState === "object";
144
146
  function sleep(timeout) {
145
147
  return new Promise((resolve) => setTimeout(resolve, timeout));
146
148
  }
@@ -180,8 +182,9 @@ function lookupFile(dir, formats, options) {
180
182
  }
181
183
  var ensureProxies = (serverProxy = {}) => {
182
184
  const proxies = Object.keys(serverProxy).map((key) => {
185
+ var _a, _b;
183
186
  const value = serverProxy[key];
184
- return typeof value === "string" ? key : value.ws === true ? "" : key;
187
+ return typeof value === "string" ? key : value.ws || ((_a = value.target) == null ? void 0 : _a.toString().startsWith("ws:")) || ((_b = value.target) == null ? void 0 : _b.toString().startsWith("wss:")) ? "" : key;
185
188
  }).filter(Boolean);
186
189
  return proxies;
187
190
  };
@@ -363,9 +366,11 @@ async function buildMockEntry(inputFile, define, alias) {
363
366
  }
364
367
 
365
368
  // src/baseMiddleware.ts
369
+ var import_node_buffer = require("buffer");
366
370
  var import_node_url2 = require("url");
367
371
  var import_cookies = __toESM(require("cookies"), 1);
368
372
  var import_http_status = __toESM(require("http-status"), 1);
373
+ var mime = __toESM(require("mime-types"), 1);
369
374
  var import_path_to_regexp2 = require("path-to-regexp");
370
375
  var import_picocolors2 = __toESM(require("picocolors"), 1);
371
376
 
@@ -428,7 +433,6 @@ function baseMiddleware(mockLoader, { formidableOptions = {}, proxies, cookiesOp
428
433
  return async function(req, res, next) {
429
434
  const startTime = Date.now();
430
435
  const { query, pathname } = (0, import_node_url2.parse)(req.url, true);
431
- const { query: refererQuery } = (0, import_node_url2.parse)(req.headers.referer || "", true);
432
436
  if (!pathname || proxies.length === 0 || !proxies.some((context) => doesProxyContextMatchUrl(context, req.url))) {
433
437
  return next();
434
438
  }
@@ -438,35 +442,49 @@ function baseMiddleware(mockLoader, { formidableOptions = {}, proxies, cookiesOp
438
442
  });
439
443
  if (!mockUrl)
440
444
  return next();
445
+ const { query: refererQuery } = (0, import_node_url2.parse)(req.headers.referer || "", true);
441
446
  const reqBody = await parseReqBody(req, formidableOptions);
447
+ const cookies = new import_cookies.default(req, res, cookiesOptions);
448
+ const getCookie = cookies.get.bind(cookies);
442
449
  const method = req.method.toUpperCase();
443
- const mock = fineMock(mockData[mockUrl], pathname, method, {
444
- query,
445
- refererQuery,
446
- body: reqBody,
447
- headers: req.headers
450
+ const mock = fineMock(mockData[mockUrl], {
451
+ pathname,
452
+ method,
453
+ request: {
454
+ query,
455
+ refererQuery,
456
+ body: reqBody,
457
+ headers: req.headers,
458
+ getCookie
459
+ }
448
460
  });
449
461
  if (!mock)
450
462
  return next();
451
463
  debug("middleware: ", method, pathname);
452
- const cookies = new import_cookies.default(req, res, cookiesOptions);
453
464
  const request = req;
454
465
  const response = res;
455
466
  request.body = reqBody;
456
467
  request.query = query;
457
468
  request.refererQuery = refererQuery;
458
469
  request.params = parseParams(mock.url, pathname);
459
- request.getCookie = cookies.get.bind(cookies);
470
+ request.getCookie = getCookie;
460
471
  response.setCookie = cookies.set.bind(cookies);
461
- responseStatus(response, mock.status, mock.statusText);
462
- await provideHeaders(request, response, mock.headers);
463
- await provideCookies(request, response, mock.cookies);
464
- const { body, delay, response: responseFn } = mock;
472
+ const {
473
+ body,
474
+ delay,
475
+ type = "json",
476
+ response: responseFn,
477
+ status = 200,
478
+ statusText
479
+ } = mock;
480
+ responseStatus(response, status, statusText);
481
+ await provideHeaders(request, response, mock);
482
+ await provideCookies(request, response, mock);
465
483
  if (body) {
466
484
  try {
467
- const result = isFunction(body) ? await body(request) : mock.body;
485
+ const content = isFunction(body) ? await body(request) : body;
468
486
  await realDelay(startTime, delay);
469
- res.end(JSON.stringify(result));
487
+ sendData(response, content, type);
470
488
  } catch (e) {
471
489
  log.error(`${import_picocolors2.default.red("[body error]")} ${req.url}
472
490
  `, e);
@@ -490,7 +508,11 @@ function baseMiddleware(mockLoader, { formidableOptions = {}, proxies, cookiesOp
490
508
  res.end("");
491
509
  };
492
510
  }
493
- function fineMock(mockList, pathname, method, request) {
511
+ function fineMock(mockList, {
512
+ pathname,
513
+ method,
514
+ request
515
+ }) {
494
516
  return mockList.find((mock) => {
495
517
  if (!pathname || !mock || !mock.url)
496
518
  return false;
@@ -500,11 +522,10 @@ function fineMock(mockList, pathname, method, request) {
500
522
  const hasMock = (0, import_path_to_regexp2.pathToRegexp)(mock.url).test(pathname);
501
523
  if (hasMock && mock.validator) {
502
524
  const params = parseParams(mock.url, pathname);
503
- const extraRequest = { params, ...request };
504
525
  if (isFunction(mock.validator)) {
505
- return mock.validator(extraRequest);
526
+ return mock.validator({ params, ...request });
506
527
  } else {
507
- return validate(extraRequest, mock.validator);
528
+ return validate({ params, ...request }, mock.validator);
508
529
  }
509
530
  }
510
531
  return hasMock;
@@ -514,34 +535,35 @@ function responseStatus(response, status = 200, statusText) {
514
535
  response.statusCode = status;
515
536
  response.statusMessage = statusText || getHTTPStatusText(status);
516
537
  }
517
- async function provideHeaders(req, res, headersOption) {
518
- res.setHeader("Content-Type", "application/json");
538
+ async function provideHeaders(req, res, { headers, type = "json" }) {
539
+ const contentType2 = mime.contentType(type) || mime.contentType(mime.lookup(type) || "");
540
+ contentType2 && res.setHeader("Content-Type", contentType2);
519
541
  res.setHeader("Cache-Control", "no-cache,max-age=0");
520
542
  res.setHeader("X-Mock", "generate by vite:plugin-mock-dev-server");
521
- if (!headersOption)
543
+ if (!headers)
522
544
  return;
523
545
  try {
524
- const headers = isFunction(headersOption) ? await headersOption(req) : headersOption;
525
- Object.keys(headers).forEach((key) => {
526
- res.setHeader(key, headers[key]);
546
+ const raw = isFunction(headers) ? await headers(req) : headers;
547
+ Object.keys(raw).forEach((key) => {
548
+ res.setHeader(key, raw[key]);
527
549
  });
528
550
  } catch (e) {
529
551
  log.error(`${import_picocolors2.default.red("[headers error]")} ${req.url}
530
552
  `, e);
531
553
  }
532
554
  }
533
- async function provideCookies(req, res, cookiesOption) {
534
- if (!cookiesOption)
555
+ async function provideCookies(req, res, { cookies }) {
556
+ if (!cookies)
535
557
  return;
536
558
  try {
537
- const cookies = isFunction(cookiesOption) ? await cookiesOption(req) : cookiesOption;
538
- Object.keys(cookies).forEach((key) => {
539
- const optional = cookies[key];
540
- if (isArray(optional)) {
541
- const [value, options] = optional;
559
+ const raw = isFunction(cookies) ? await cookies(req) : cookies;
560
+ Object.keys(raw).forEach((key) => {
561
+ const cookie = raw[key];
562
+ if (isArray(cookie)) {
563
+ const [value, options] = cookie;
542
564
  res.setCookie(key, value, options);
543
565
  } else {
544
- res.setCookie(key, optional);
566
+ res.setCookie(key, cookie);
545
567
  }
546
568
  });
547
569
  } catch (e) {
@@ -549,6 +571,16 @@ async function provideCookies(req, res, cookiesOption) {
549
571
  `, e);
550
572
  }
551
573
  }
574
+ function sendData(res, raw, type) {
575
+ if (isReadableStream(raw)) {
576
+ raw.pipe(res);
577
+ } else if (import_node_buffer.Buffer.isBuffer(raw)) {
578
+ res.end(type === "text" || type === "json" ? raw.toString("utf-8") : raw);
579
+ } else {
580
+ const content = typeof raw === "string" ? raw : JSON.stringify(raw);
581
+ res.end(type === "buffer" ? import_node_buffer.Buffer.from(content) : content);
582
+ }
583
+ }
552
584
  async function realDelay(startTime, delay) {
553
585
  if (!delay || delay <= 0)
554
586
  return;
package/dist/index.d.ts CHANGED
@@ -1,5 +1,6 @@
1
1
  import { Connect, Plugin, ResolvedConfig } from 'vite';
2
2
  import http from 'node:http';
3
+ import { Readable } from 'node:stream';
3
4
  import Cookies from 'cookies';
4
5
  import formidable from 'formidable';
5
6
  import EventEmitter from 'node:events';
@@ -79,7 +80,7 @@ interface ServerBuildOption {
79
80
  }
80
81
  type Method = 'GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH' | 'HEAD' | 'TRACE' | 'OPTIONS';
81
82
  type Headers = http.IncomingHttpHeaders;
82
- type ResponseBody = Record<string, any> | any[] | string | number | null;
83
+ type ResponseBody = Record<string, any> | any[] | string | number | Readable | Buffer | null;
83
84
  interface ExtraRequest {
84
85
  /**
85
86
  * The query string located after `?` in the request address has been parsed into JSON.
@@ -110,13 +111,12 @@ interface ExtraRequest {
110
111
  * 请求体中 headers
111
112
  */
112
113
  headers: Headers;
113
- }
114
- type MockRequest = Connect.IncomingMessage & ExtraRequest & {
115
114
  /**
116
115
  * @see [cookies](https://github.com/pillarjs/cookies#cookiesgetname--options)
117
116
  */
118
117
  getCookie: (name: string, option?: Cookies.GetOption) => string | undefined;
119
- };
118
+ }
119
+ type MockRequest = Connect.IncomingMessage & ExtraRequest;
120
120
  type MockResponse = http.ServerResponse<http.IncomingMessage> & {
121
121
  /**
122
122
  * @see [cookies](https://github.com/pillarjs/cookies#cookiessetname--values--options)
@@ -218,6 +218,37 @@ interface MockOptionsItem {
218
218
  * ```
219
219
  */
220
220
  cookies?: ResponseCookies | ResponseCookiesFn;
221
+ /**
222
+ * Response body data type, optional values include `text, json, buffer`.
223
+ *
224
+ * And also support types included in `mime-db`.
225
+ * When the response body returns a file and you are not sure which type to use,
226
+ * you can pass the file name as the value. The plugin will internally search for matching
227
+ * `content-type` based on the file name suffix.
228
+ *
229
+ * However, if it is a TypeScript file such as `a.ts`, it may not be correctly matched
230
+ * as a JavaScript script. You need to modify `a.ts` to `a.js` as the value passed
231
+ * in order to recognize it correctly.
232
+ *
233
+ * 响应体数据类型, 可选值包括 `text, json, buffer`,
234
+ *
235
+ * 还支持`mime-db`中的包含的类型。
236
+ * 当响应体返回的是一个文件,而你不确定应该使用哪个类型时,可以将文件名作为值传入,
237
+ * 插件内部会根据文件名后缀查找匹配的`content-type`。
238
+ *
239
+ * 但如果是 `typescript`文件如 `a.ts`,可能不会被正确匹配为 `javascript`脚本,
240
+ * 你需要将 `a.ts` 修改为 `a.js`作为值传入才能正确识别。
241
+ * @see [mime-db](https://github.com/jshttp/mime-db)
242
+ * @default 'json'
243
+ * @example
244
+ * ```txt
245
+ * json
246
+ * buffer
247
+ * my-app.dmg
248
+ * music.mp4
249
+ * ```
250
+ */
251
+ type?: 'text' | 'json' | 'buffer' | string;
221
252
  /**
222
253
  * Configure response body data content
223
254
  *
@@ -298,7 +329,7 @@ interface MockOptionsItem {
298
329
  * }
299
330
  * ```
300
331
  */
301
- validator?: Partial<ExtraRequest> | ((request: ExtraRequest) => boolean);
332
+ validator?: Partial<Omit<ExtraRequest, 'getCookie'>> | ((request: ExtraRequest) => boolean);
302
333
  }
303
334
  type MockOptions = MockOptionsItem[];
304
335
  type FormidableFile = formidable.File | formidable.File[];
package/dist/index.js CHANGED
@@ -9,7 +9,7 @@ import { createFilter, normalizePath } from "vite";
9
9
 
10
10
  // package.json
11
11
  var name = "vite-plugin-mock-dev-server";
12
- var version = "1.1.2";
12
+ var version = "1.1.4";
13
13
 
14
14
  // src/esbuildPlugin.ts
15
15
  import fsp from "fs/promises";
@@ -96,6 +96,8 @@ import { match } from "path-to-regexp";
96
96
  import colors from "picocolors";
97
97
  var isArray = (val) => Array.isArray(val);
98
98
  var isFunction = (val) => typeof val === "function";
99
+ var isStream = (stream) => stream !== null && typeof stream === "object" && typeof stream.pipe === "function";
100
+ var isReadableStream = (stream) => isStream(stream) && stream.readable !== false && typeof stream._read === "function" && typeof stream._readableState === "object";
99
101
  function sleep(timeout) {
100
102
  return new Promise((resolve) => setTimeout(resolve, timeout));
101
103
  }
@@ -135,8 +137,9 @@ function lookupFile(dir, formats, options) {
135
137
  }
136
138
  var ensureProxies = (serverProxy = {}) => {
137
139
  const proxies = Object.keys(serverProxy).map((key) => {
140
+ var _a, _b;
138
141
  const value = serverProxy[key];
139
- return typeof value === "string" ? key : value.ws === true ? "" : key;
142
+ return typeof value === "string" ? key : value.ws || ((_a = value.target) == null ? void 0 : _a.toString().startsWith("ws:")) || ((_b = value.target) == null ? void 0 : _b.toString().startsWith("wss:")) ? "" : key;
140
143
  }).filter(Boolean);
141
144
  return proxies;
142
145
  };
@@ -318,9 +321,11 @@ async function buildMockEntry(inputFile, define, alias) {
318
321
  }
319
322
 
320
323
  // src/baseMiddleware.ts
324
+ import { Buffer } from "buffer";
321
325
  import { parse as urlParse } from "url";
322
326
  import Cookies from "cookies";
323
327
  import HTTP_STATUS from "http-status";
328
+ import * as mime from "mime-types";
324
329
  import { pathToRegexp } from "path-to-regexp";
325
330
  import colors2 from "picocolors";
326
331
 
@@ -383,7 +388,6 @@ function baseMiddleware(mockLoader, { formidableOptions = {}, proxies, cookiesOp
383
388
  return async function(req, res, next) {
384
389
  const startTime = Date.now();
385
390
  const { query, pathname } = urlParse(req.url, true);
386
- const { query: refererQuery } = urlParse(req.headers.referer || "", true);
387
391
  if (!pathname || proxies.length === 0 || !proxies.some((context) => doesProxyContextMatchUrl(context, req.url))) {
388
392
  return next();
389
393
  }
@@ -393,35 +397,49 @@ function baseMiddleware(mockLoader, { formidableOptions = {}, proxies, cookiesOp
393
397
  });
394
398
  if (!mockUrl)
395
399
  return next();
400
+ const { query: refererQuery } = urlParse(req.headers.referer || "", true);
396
401
  const reqBody = await parseReqBody(req, formidableOptions);
402
+ const cookies = new Cookies(req, res, cookiesOptions);
403
+ const getCookie = cookies.get.bind(cookies);
397
404
  const method = req.method.toUpperCase();
398
- const mock = fineMock(mockData[mockUrl], pathname, method, {
399
- query,
400
- refererQuery,
401
- body: reqBody,
402
- headers: req.headers
405
+ const mock = fineMock(mockData[mockUrl], {
406
+ pathname,
407
+ method,
408
+ request: {
409
+ query,
410
+ refererQuery,
411
+ body: reqBody,
412
+ headers: req.headers,
413
+ getCookie
414
+ }
403
415
  });
404
416
  if (!mock)
405
417
  return next();
406
418
  debug("middleware: ", method, pathname);
407
- const cookies = new Cookies(req, res, cookiesOptions);
408
419
  const request = req;
409
420
  const response = res;
410
421
  request.body = reqBody;
411
422
  request.query = query;
412
423
  request.refererQuery = refererQuery;
413
424
  request.params = parseParams(mock.url, pathname);
414
- request.getCookie = cookies.get.bind(cookies);
425
+ request.getCookie = getCookie;
415
426
  response.setCookie = cookies.set.bind(cookies);
416
- responseStatus(response, mock.status, mock.statusText);
417
- await provideHeaders(request, response, mock.headers);
418
- await provideCookies(request, response, mock.cookies);
419
- const { body, delay, response: responseFn } = mock;
427
+ const {
428
+ body,
429
+ delay,
430
+ type = "json",
431
+ response: responseFn,
432
+ status = 200,
433
+ statusText
434
+ } = mock;
435
+ responseStatus(response, status, statusText);
436
+ await provideHeaders(request, response, mock);
437
+ await provideCookies(request, response, mock);
420
438
  if (body) {
421
439
  try {
422
- const result = isFunction(body) ? await body(request) : mock.body;
440
+ const content = isFunction(body) ? await body(request) : body;
423
441
  await realDelay(startTime, delay);
424
- res.end(JSON.stringify(result));
442
+ sendData(response, content, type);
425
443
  } catch (e) {
426
444
  log.error(`${colors2.red("[body error]")} ${req.url}
427
445
  `, e);
@@ -445,7 +463,11 @@ function baseMiddleware(mockLoader, { formidableOptions = {}, proxies, cookiesOp
445
463
  res.end("");
446
464
  };
447
465
  }
448
- function fineMock(mockList, pathname, method, request) {
466
+ function fineMock(mockList, {
467
+ pathname,
468
+ method,
469
+ request
470
+ }) {
449
471
  return mockList.find((mock) => {
450
472
  if (!pathname || !mock || !mock.url)
451
473
  return false;
@@ -455,11 +477,10 @@ function fineMock(mockList, pathname, method, request) {
455
477
  const hasMock = pathToRegexp(mock.url).test(pathname);
456
478
  if (hasMock && mock.validator) {
457
479
  const params = parseParams(mock.url, pathname);
458
- const extraRequest = { params, ...request };
459
480
  if (isFunction(mock.validator)) {
460
- return mock.validator(extraRequest);
481
+ return mock.validator({ params, ...request });
461
482
  } else {
462
- return validate(extraRequest, mock.validator);
483
+ return validate({ params, ...request }, mock.validator);
463
484
  }
464
485
  }
465
486
  return hasMock;
@@ -469,34 +490,35 @@ function responseStatus(response, status = 200, statusText) {
469
490
  response.statusCode = status;
470
491
  response.statusMessage = statusText || getHTTPStatusText(status);
471
492
  }
472
- async function provideHeaders(req, res, headersOption) {
473
- res.setHeader("Content-Type", "application/json");
493
+ async function provideHeaders(req, res, { headers, type = "json" }) {
494
+ const contentType2 = mime.contentType(type) || mime.contentType(mime.lookup(type) || "");
495
+ contentType2 && res.setHeader("Content-Type", contentType2);
474
496
  res.setHeader("Cache-Control", "no-cache,max-age=0");
475
497
  res.setHeader("X-Mock", "generate by vite:plugin-mock-dev-server");
476
- if (!headersOption)
498
+ if (!headers)
477
499
  return;
478
500
  try {
479
- const headers = isFunction(headersOption) ? await headersOption(req) : headersOption;
480
- Object.keys(headers).forEach((key) => {
481
- res.setHeader(key, headers[key]);
501
+ const raw = isFunction(headers) ? await headers(req) : headers;
502
+ Object.keys(raw).forEach((key) => {
503
+ res.setHeader(key, raw[key]);
482
504
  });
483
505
  } catch (e) {
484
506
  log.error(`${colors2.red("[headers error]")} ${req.url}
485
507
  `, e);
486
508
  }
487
509
  }
488
- async function provideCookies(req, res, cookiesOption) {
489
- if (!cookiesOption)
510
+ async function provideCookies(req, res, { cookies }) {
511
+ if (!cookies)
490
512
  return;
491
513
  try {
492
- const cookies = isFunction(cookiesOption) ? await cookiesOption(req) : cookiesOption;
493
- Object.keys(cookies).forEach((key) => {
494
- const optional = cookies[key];
495
- if (isArray(optional)) {
496
- const [value, options] = optional;
514
+ const raw = isFunction(cookies) ? await cookies(req) : cookies;
515
+ Object.keys(raw).forEach((key) => {
516
+ const cookie = raw[key];
517
+ if (isArray(cookie)) {
518
+ const [value, options] = cookie;
497
519
  res.setCookie(key, value, options);
498
520
  } else {
499
- res.setCookie(key, optional);
521
+ res.setCookie(key, cookie);
500
522
  }
501
523
  });
502
524
  } catch (e) {
@@ -504,6 +526,16 @@ async function provideCookies(req, res, cookiesOption) {
504
526
  `, e);
505
527
  }
506
528
  }
529
+ function sendData(res, raw, type) {
530
+ if (isReadableStream(raw)) {
531
+ raw.pipe(res);
532
+ } else if (Buffer.isBuffer(raw)) {
533
+ res.end(type === "text" || type === "json" ? raw.toString("utf-8") : raw);
534
+ } else {
535
+ const content = typeof raw === "string" ? raw : JSON.stringify(raw);
536
+ res.end(type === "buffer" ? Buffer.from(content) : content);
537
+ }
538
+ }
507
539
  async function realDelay(startTime, delay) {
508
540
  if (!delay || delay <= 0)
509
541
  return;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vite-plugin-mock-dev-server",
3
- "version": "1.1.2",
3
+ "version": "1.1.4",
4
4
  "keywords": [
5
5
  "vite",
6
6
  "plugin",
@@ -34,12 +34,13 @@
34
34
  "co-body": "^6.1.0",
35
35
  "cookies": "^0.8.0",
36
36
  "debug": "^4.3.4",
37
- "esbuild": "^0.17.17",
37
+ "esbuild": "^0.17.18",
38
38
  "fast-glob": "^3.2.12",
39
39
  "formidable": "^2.1.1",
40
40
  "http-status": "^1.6.2",
41
41
  "is-core-module": "^2.12.0",
42
42
  "json5": "^2.2.3",
43
+ "mime-types": "^2.1.35",
43
44
  "path-to-regexp": "^6.2.1",
44
45
  "picocolors": "^1.0.0"
45
46
  },
@@ -51,17 +52,16 @@
51
52
  "@types/debug": "^4.1.7",
52
53
  "@types/formidable": "^2.0.5",
53
54
  "@types/is-core-module": "^2.2.0",
54
- "@types/node": "^18.15.12",
55
+ "@types/mime-types": "^2.1.1",
56
+ "@types/node": "^18.16.0",
55
57
  "bumpp": "^9.1.0",
56
58
  "conventional-changelog-cli": "^2.2.2",
57
- "eslint": "^8.38.0",
59
+ "eslint": "^8.39.0",
58
60
  "mockjs": "^1.1.0",
59
- "prettier": "^2.8.7",
61
+ "prettier": "^2.8.8",
60
62
  "tsup": "^6.7.0",
61
63
  "typescript": "^5.0.4",
62
- "vite": "^4.3.0",
63
- "vitepress": "1.0.0-alpha.73",
64
- "vue": "^3.2.47"
64
+ "vitepress": "1.0.0-alpha.74"
65
65
  },
66
66
  "peerDependencies": {
67
67
  "vite": ">=3.0.0"