rspack-plugin-mock 1.2.0 → 1.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +10 -2
- package/README.zh-CN.md +13 -5
- package/dist/{helper.d.cts → helper.d.mts} +60 -44
- package/dist/helper.mjs +4 -0
- package/dist/index.d.mts +13 -0
- package/dist/index.mjs +1 -0
- package/dist/json5-loader.cjs +1 -32
- package/dist/options-BUfaThYe.mjs +43 -0
- package/dist/rsbuild.d.mts +7 -0
- package/dist/rsbuild.mjs +1 -0
- package/dist/{mockWebsocket-DkVHpZCx.d.cts → server-4ETytB7L.d.mts} +44 -40
- package/dist/server.d.mts +3 -0
- package/dist/server.mjs +1 -0
- package/dist/{types-6lajtJPx.d.cts → types-Bt_OTa7I.d.mts} +139 -10
- package/dist/ws-BM06pHhL.mjs +1 -0
- package/package.json +40 -51
- package/dist/chunk-CUT6urMc.cjs +0 -30
- package/dist/helper.cjs +0 -140
- package/dist/helper.d.ts +0 -110
- package/dist/helper.js +0 -136
- package/dist/index.cjs +0 -86
- package/dist/index.d.cts +0 -13
- package/dist/index.d.ts +0 -13
- package/dist/index.js +0 -80
- package/dist/logger-C0V8Cvvd.cjs +0 -800
- package/dist/logger-C48_LmdS.js +0 -710
- package/dist/mockWebsocket-qLVAe-RI.d.ts +0 -85
- package/dist/resolvePluginOptions-Da5uqlBx.cjs +0 -506
- package/dist/resolvePluginOptions-DlkIkykz.js +0 -476
- package/dist/rsbuild.cjs +0 -176
- package/dist/rsbuild.d.cts +0 -7
- package/dist/rsbuild.d.ts +0 -7
- package/dist/rsbuild.js +0 -175
- package/dist/server.cjs +0 -9
- package/dist/server.d.cts +0 -27
- package/dist/server.d.ts +0 -27
- package/dist/server.js +0 -3
- package/dist/types-DPzh7nJq.d.ts +0 -572
|
@@ -1,14 +1,135 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import Cookies from "cookies";
|
|
1
|
+
import { Readable } from "node:stream";
|
|
3
2
|
import { CorsOptions } from "cors";
|
|
3
|
+
import { Options } from "co-body";
|
|
4
4
|
import formidable from "formidable";
|
|
5
|
+
import http, { IncomingMessage, ServerResponse } from "node:http";
|
|
6
|
+
import crypto from "node:crypto";
|
|
5
7
|
import { Buffer } from "node:buffer";
|
|
6
|
-
import http from "node:http";
|
|
7
|
-
import { Readable } from "node:stream";
|
|
8
8
|
import { WebSocketServer } from "ws";
|
|
9
9
|
|
|
10
|
+
//#region src/cookies/Keygrip.d.ts
|
|
11
|
+
declare class Keygrip {
|
|
12
|
+
private algorithm;
|
|
13
|
+
private encoding;
|
|
14
|
+
private keys;
|
|
15
|
+
constructor(keys: string[], algorithm?: string, encoding?: crypto.BinaryToTextEncoding);
|
|
16
|
+
sign(data: string, key?: string): string;
|
|
17
|
+
index(data: string, digest: string): number;
|
|
18
|
+
verify(data: string, digest: string): boolean;
|
|
19
|
+
}
|
|
20
|
+
//#endregion
|
|
21
|
+
//#region src/cookies/types.d.ts
|
|
22
|
+
interface CookiesOption {
|
|
23
|
+
keys?: string[] | Keygrip;
|
|
24
|
+
secure?: boolean;
|
|
25
|
+
}
|
|
26
|
+
interface SetCookieOption {
|
|
27
|
+
/**
|
|
28
|
+
* a number representing the milliseconds from `Date.now()` for expiry
|
|
29
|
+
*
|
|
30
|
+
* 表示从 `Date.now()` 起至过期的毫秒数
|
|
31
|
+
*/
|
|
32
|
+
maxAge?: number;
|
|
33
|
+
/**
|
|
34
|
+
* a Date object indicating the cookie's expiration
|
|
35
|
+
* date (expires at the end of session by default).
|
|
36
|
+
*
|
|
37
|
+
* 一个指示cookie过期时间的 Date 对象(默认在会话结束时过期)。
|
|
38
|
+
*/
|
|
39
|
+
expires?: Date;
|
|
40
|
+
/**
|
|
41
|
+
* a string indicating the path of the cookie (`/` by default).
|
|
42
|
+
*
|
|
43
|
+
* 一个指示cookie路径的字符串(默认为 `/`)。
|
|
44
|
+
*/
|
|
45
|
+
path?: string;
|
|
46
|
+
/**
|
|
47
|
+
* a string indicating the domain of the cookie (no default).
|
|
48
|
+
*
|
|
49
|
+
* 表示 Cookie 域的字符串(无默认值)。
|
|
50
|
+
*/
|
|
51
|
+
domain?: string;
|
|
52
|
+
/**
|
|
53
|
+
* a boolean indicating whether the cookie is only to be sent
|
|
54
|
+
* over HTTPS (false by default for HTTP, true by default for HTTPS).
|
|
55
|
+
*
|
|
56
|
+
* 一个布尔值,指示该 Cookie 是否仅通过 HTTPS 发送(HTTP 默认为 false,HTTPS 默认为 true)。
|
|
57
|
+
*/
|
|
58
|
+
secure?: boolean;
|
|
59
|
+
/**
|
|
60
|
+
* a boolean indicating whether the cookie is only to be sent over HTTP(S),
|
|
61
|
+
* and not made available to client JavaScript (true by default).
|
|
62
|
+
*
|
|
63
|
+
* 一个布尔值,指示该 cookie 是否仅通过HTTP(S)发送,而不对客户端JavaScript开放(默认为true)。
|
|
64
|
+
*/
|
|
65
|
+
httpOnly?: boolean;
|
|
66
|
+
/**
|
|
67
|
+
* a boolean or string indicating whether the cookie is a "same site" cookie (false by default).
|
|
68
|
+
* This can be set to 'strict', 'lax', or true (which maps to 'strict').
|
|
69
|
+
*
|
|
70
|
+
* 一个布尔值或字符串,用于指示该cookie是否为“同站”cookie(默认为false)。
|
|
71
|
+
* 可将其设置为'strict'、'lax'或true(true会映射为'strict')。
|
|
72
|
+
*/
|
|
73
|
+
sameSite?: "strict" | "lax" | "none" | boolean;
|
|
74
|
+
/**
|
|
75
|
+
* a boolean indicating whether the cookie is to be signed (false by default).
|
|
76
|
+
* If this is true, another cookie of the same name with the .sig suffix
|
|
77
|
+
* appended will also be sent, with a 27-byte url-safe base64 SHA1 value
|
|
78
|
+
* representing the hash of cookie-name=cookie-value against the first Keygrip key.
|
|
79
|
+
* This signature key is used to detect tampering the next time a cookie is received.
|
|
80
|
+
*
|
|
81
|
+
* 一个布尔值,指示cookie是否需签名(默认为false)。
|
|
82
|
+
* 若设为true,将同时发送另一个同名但附加 `.sig` 后缀的 cookie,其值为 27 字节的URL安全型 base64 SHA1哈希值,
|
|
83
|
+
* 该哈希由cookie名称=cookie值的字符串与首个 Keygrip 密钥计算生成。
|
|
84
|
+
* 此签名密钥用于在下次接收cookie时检测数据是否被篡改。
|
|
85
|
+
*/
|
|
86
|
+
signed?: boolean;
|
|
87
|
+
/**
|
|
88
|
+
* a boolean indicating whether to overwrite previously set
|
|
89
|
+
* cookies of the same name (false by default). If this is true,
|
|
90
|
+
* all cookies set during the same request with the same
|
|
91
|
+
* name (regardless of path or domain) are filtered out of
|
|
92
|
+
* the Set-Cookie header when setting this cookie.
|
|
93
|
+
*
|
|
94
|
+
* 一个布尔值,指示是否覆盖先前设置的同名Cookie(默认为false)。
|
|
95
|
+
* 若设为true,当设置此Cookie时,在同一请求期间设置的所有同名Cookie(无论路径或域)
|
|
96
|
+
* 都将从Set-Cookie标头中过滤掉。
|
|
97
|
+
*/
|
|
98
|
+
overwrite?: boolean;
|
|
99
|
+
/**
|
|
100
|
+
* a string indicating the cookie priority.
|
|
101
|
+
* This can be set to 'low', 'medium', or 'high'.
|
|
102
|
+
*
|
|
103
|
+
* 表示Cookie优先级的字符串。可设置为'low'、'medium'或'high'。
|
|
104
|
+
*/
|
|
105
|
+
priority?: "low" | "medium" | "high";
|
|
106
|
+
/**
|
|
107
|
+
* a boolean indicating whether to partition the cookie in Chrome
|
|
108
|
+
* for the CHIPS Update (false by default). If this is true,
|
|
109
|
+
* Cookies from embedded sites will be partitioned
|
|
110
|
+
* and only readable from the same top level site from which it was created.
|
|
111
|
+
*
|
|
112
|
+
* 一个布尔值,指示是否在Chrome中为CHIPS更新对Cookie进行分区(默认为false)。
|
|
113
|
+
* 若设为true,来自嵌入式站点的Cookie将被分区,且仅可从创建它的同一顶级站点读取。
|
|
114
|
+
*/
|
|
115
|
+
partitioned?: boolean;
|
|
116
|
+
}
|
|
117
|
+
interface GetCookieOption {
|
|
118
|
+
signed: boolean;
|
|
119
|
+
}
|
|
120
|
+
//#endregion
|
|
121
|
+
//#region src/cookies/Cookies.d.ts
|
|
122
|
+
declare class Cookies {
|
|
123
|
+
request: IncomingMessage;
|
|
124
|
+
response: ServerResponse<IncomingMessage>;
|
|
125
|
+
secure: boolean | undefined;
|
|
126
|
+
keys: Keygrip | undefined;
|
|
127
|
+
constructor(req: IncomingMessage, res: ServerResponse<IncomingMessage>, options?: CookiesOption);
|
|
128
|
+
set(name: string, value?: string | null, options?: SetCookieOption): this;
|
|
129
|
+
get(name: string, options?: GetCookieOption): string | void;
|
|
130
|
+
}
|
|
131
|
+
//#endregion
|
|
10
132
|
//#region src/types.d.ts
|
|
11
|
-
|
|
12
133
|
/**
|
|
13
134
|
* Configure plugin
|
|
14
135
|
*
|
|
@@ -48,6 +169,14 @@ interface MockServerPluginOptions {
|
|
|
48
169
|
*/
|
|
49
170
|
cwd?: string;
|
|
50
171
|
/**
|
|
172
|
+
* The directory to store mock files
|
|
173
|
+
*
|
|
174
|
+
* 存储 mock 文件的目录
|
|
175
|
+
*
|
|
176
|
+
* @default 'mock'
|
|
177
|
+
*/
|
|
178
|
+
dir?: string;
|
|
179
|
+
/**
|
|
51
180
|
* glob string matching mock includes files
|
|
52
181
|
*
|
|
53
182
|
* glob 字符串匹配 mock 包含的文件
|
|
@@ -97,7 +226,7 @@ interface MockServerPluginOptions {
|
|
|
97
226
|
* cookies options
|
|
98
227
|
* @see [cookies](https://github.com/pillarjs/cookies#new-cookiesrequest-response--options)
|
|
99
228
|
*/
|
|
100
|
-
cookiesOptions?:
|
|
229
|
+
cookiesOptions?: CookiesOption;
|
|
101
230
|
/**
|
|
102
231
|
* Configure to `co-body`
|
|
103
232
|
*
|
|
@@ -278,7 +407,7 @@ interface ExtraRequest {
|
|
|
278
407
|
* 获取 请求中携带的 cookie
|
|
279
408
|
* @see [cookies](https://github.com/pillarjs/cookies#cookiesgetname--options)
|
|
280
409
|
*/
|
|
281
|
-
getCookie:
|
|
410
|
+
getCookie: Cookies["get"];
|
|
282
411
|
}
|
|
283
412
|
type MockRequest = http.IncomingMessage & ExtraRequest;
|
|
284
413
|
type MockResponse = http.ServerResponse<http.IncomingMessage> & {
|
|
@@ -288,11 +417,11 @@ type MockResponse = http.ServerResponse<http.IncomingMessage> & {
|
|
|
288
417
|
* 向请求响应中设置 cookie
|
|
289
418
|
* @see [cookies](https://github.com/pillarjs/cookies#cookiessetname--values--options)
|
|
290
419
|
*/
|
|
291
|
-
setCookie:
|
|
420
|
+
setCookie: Cookies["set"];
|
|
292
421
|
};
|
|
293
422
|
type ResponseBodyFn = (request: MockRequest) => ResponseBody | Promise<ResponseBody>;
|
|
294
423
|
type ResponseHeaderFn = (request: MockRequest) => Headers | Promise<Headers>;
|
|
295
|
-
type CookieValue = string | [string,
|
|
424
|
+
type CookieValue = string | [string, SetCookieOption];
|
|
296
425
|
type ResponseCookies = Record<string, CookieValue>;
|
|
297
426
|
type ResponseCookiesFn = (request: MockRequest) => ResponseCookies | Promise<ResponseCookies>;
|
|
298
427
|
interface MockBaseItem {
|
|
@@ -569,4 +698,4 @@ type FormidableFile = formidable.File | formidable.File[];
|
|
|
569
698
|
type LogType = "info" | "warn" | "error" | "debug";
|
|
570
699
|
type LogLevel = LogType | "silent";
|
|
571
700
|
//#endregion
|
|
572
|
-
export {
|
|
701
|
+
export { WebSocketSetupContext as _, LogType as a, MockMatchPriority as c, MockRequest as d, MockResponse as f, ServerBuildOption as g, ResponseBody as h, LogLevel as i, MockMatchSpecialPriority as l, MockWebsocketItem as m, ExtraRequest as n, Method as o, MockServerPluginOptions as p, FormidableFile as r, MockHttpItem as s, BodyParserOptions as t, MockOptions as u };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{isArray as e,isBoolean as t,isEmptyObject as n,isFunction as r,isPlainObject as i,random as a,sleep as o,sortBy as s,timestamp as c,toArray as l,uniq as u}from"@pengzhanbo/utils";import d from"node:path";import f from"ansis";import p from"picomatch";import{loadPackageJSONSync as m}from"local-pkg";import{match as h,parse as g,pathToRegexp as _}from"path-to-regexp";import v from"node:os";import{fileURLToPath as y}from"node:url";import b from"debug";import{Volume as x,createFsFromVolume as S}from"memfs";import{parse as C}from"node:querystring";import w from"co-body";import T from"formidable";import E from"node:http";import D from"node:crypto";import{Buffer as O}from"node:buffer";import k from"http-status";import*as A from"mime-types";import{WebSocketServer as j}from"ws";function ee(e,t){let n=[],r=[`**/node_modules/**`,...l(t)];return l(e).forEach(e=>{e[0]===`!`?r.push(e.slice(1)):n.push(e)}),{pattern:n,ignore:r,isMatch:p(n,{ignore:r})}}function M(e,t,n){return typeof e==`function`?e(t,n):e[0]===`^`&&new RegExp(e).test(t)||t.startsWith(e)}function N(e){let{dependencies:t,devDependencies:n,peerDependencies:r,optionalDependencies:i}=m(e)||{};return{...t,...n,...r,...i}}function P(e){let t=N(e);return u(Object.keys(t))}function te(e){return typeof e==`object`&&!!e&&typeof e.pipe==`function`}function ne(e){return te(e)&&e.readable!==!1&&typeof e._read==`function`&&typeof e._readableState==`object`}function F(e,t){if(!t)return!0;for(let n in t)if(!I(e[n],t[n]))return!1;return!0}function I(t,n){if(e(t)&&e(n)){let e=new Set;return n.every(n=>t.some((t,r)=>{if(e.has(r))return!1;let i=I(t,n);return i&&e.add(r),i}))}return i(t)&&i(n)?F(t,n):Object.is(t,n)}const L=new Map;function R(e,t){let n=L.get(e);return n||(n=_(e).regexp,L.set(e,n)),n.test(t)}const z={silent:0,error:1,warn:2,info:3,debug:4};function re(e,n=`info`){e=`[${e}]`;function r(r,i,a){if(a=t(a)?a?n:`error`:a,z[a]>=z[r]){let t=r===`info`||r===`debug`?`log`:r,n=r===`debug`?f.magenta.bold(e):r===`info`?f.cyan.bold(e):r===`warn`?f.yellow.bold(e):f.red.bold(e),a=`${f.dim(new Date().toLocaleTimeString())} ${n} ${i}`;console[t](a)}}return{debug(e,t=n){r(`debug`,e,t)},info(e,t=n){r(`info`,e,t)},warn(e,t=n){r(`warn`,e,t)},error(e,t=n){r(`error`,e,t)}}}ae(import.meta.url);const ie=S(new x);function ae(e){return d.dirname(y(e))}b(`vite:mock-dev-server`);const oe=/\\/g,se=v.platform()===`win32`;function ce(e){return e.replace(oe,`/`)}function le(e){return d.posix.normalize(se?ce(e):e)}function B(e){let t=new URL(e,`http://example.com`);return{pathname:decodeURIComponent(t.pathname),query:C(t.search.replace(/^\?/,``))}}function ue(e,t=5){return function n(r,i=0){let a=r();a?e(a):i<t&&setTimeout(()=>n(r,i+1),100)}}function de(e){return e.filter(e=>e[0]).map(([e,t])=>{let n;return e.default?n=Array.isArray(e.default)?e.default.map(e=>({...e,__filepath__:t})):{...e.default,__filepath__:t}:`url`in e?n={...e,__filepath__:t}:(n=[],Object.keys(e||{}).forEach(r=>{Array.isArray(e[r])?n.push(...e[r].map(e=>({...e,__filepath__:t}))):n.push({...e[r],__filepath__:t})})),n})}function fe(e){let t=[];for(let[,n]of e.entries())n&&t.push(...l(n));let a={};return t.filter(e=>i(e)&&e.enabled!==!1&&e.url).forEach(e=>{let{pathname:t,query:i}=B(e.url),o=a[t]??=[],s={...e,url:t};if(s.ws!==!0){let e=s.validator;n(i)||(r(e)?s.validator=function(t){return F(t.query,i)&&e(t)}:e?(s.validator={...e},s.validator.query=s.validator.query?{...i,...s.validator.query}:i):s.validator={query:i})}o.push(s)}),Object.keys(a).forEach(e=>{a[e]=V(a[e])}),a}function V(e){return s(e,e=>{if(e.ws===!0)return 0;let{validator:t}=e;return!t||n(t)?2:r(t)?0:1/Object.keys(t).reduce((e,n)=>e+pe(t[n]),0)})}function pe(e){return e?Object.keys(e).length:0}async function me(e,t,n={}){let r=e.method.toUpperCase();if([`HEAD`,`OPTIONS`].includes(r))return;let i=e.headers[`content-type`]?.toLocaleLowerCase()||``,{limit:a,formLimit:o,jsonLimit:s,textLimit:c,...l}=n;try{if(i.startsWith(`application/json`))return await w.json(e,{limit:s||a,...l});if(i.startsWith(`application/x-www-form-urlencoded`))return await w.form(e,{limit:o||a,...l});if(i.startsWith(`text/plain`))return await w.text(e,{limit:c||a,...l});if(i.startsWith(`multipart/form-data`))return await ge(e,t)}catch(e){console.error(e)}}const he={keepExtensions:!0,filename(e,t,n){return n?.originalFilename||`${e}.${Date.now()}${t?`.${t}`:``}`}};async function ge(e,t){let n=T({...he,...t});return new Promise((t,r)=>{n.parse(e,(e,n,i)=>{if(e){r(e);return}t({...n,...i})})})}const H=new Map;function U(e,t){let n=H.get(e);n||(n=h(e,{decode:decodeURIComponent}),H.set(e,n));let r=n(t);return r?r.params:{}}function _e(e,t){return F(e.headers,t.headers)&&F(e.body,t.body)&&F(e.params,t.params)&&F(e.query,t.query)&&F(e.refererQuery,t.refererQuery)}function W(e,t){return!t||n(t)?``:` ${f.gray(`${e}:`)}${JSON.stringify(t)}`}function ve(e,t){let{url:n,method:r,query:i,params:a,body:o}=e,{pathname:s}=new URL(n,`http://example.com`);s=f.green(decodeURIComponent(s));let c=f.magenta.bold(r),l=W(`query`,i),u=W(`params`,a),d=W(`body`,o),p=` ${f.dim.underline(`(${t})`)}`;return`${c} ${s}${l}${u}${d}${p}`}function ye(t,n,{pathname:i,method:a,request:o}){return t.find(t=>{if(!i||!t||!t.url||t.ws||!(t.method?e(t.method)?t.method:[t.method]:[`GET`,`POST`]).includes(a))return!1;let s=R(t.url,i);if(s&&t.validator){let e=U(t.url,i);if(r(t.validator))return t.validator({params:e,...o});try{return _e({params:e,...o},t.validator)}catch(e){let r=t.__filepath__;return n.error(`${f.red(`mock error at ${i}`)}\n${e}\n at validator (${f.underline(r)})`,t.log),!1}}return s})}const G=/^[\t\u0020-\u007E\u0080-\u00FF]+$/,be=/^(?:low|medium|high)$/i,K=Object.create(null),xe=/[\^$\\.*+?()[\]{}|]/g,Se=/[;=]/,Ce=/;/,we=/^(?:lax|none|strict)$/i;var Te=class{name;value;maxAge;expires;path=`/`;domain;secure=!1;httpOnly=!0;sameSite=!1;overwrite=!1;priority;partitioned;constructor(e,t,n={}){if(!G.test(e)||Se.test(e))throw TypeError(`argument name is invalid`);if(t&&(!G.test(t)||Ce.test(t)))throw TypeError(`argument value is invalid`);if(this.name=e,this.value=t,Object.assign(this,n),this.value||(this.expires=new Date(0),this.maxAge=void 0),this.path&&!G.test(this.path))throw TypeError(`[Cookie] option path is invalid`);if(this.domain&&!G.test(this.domain))throw TypeError(`[Cookie] option domain is invalid`);if(typeof this.maxAge==`number`?Number.isNaN(this.maxAge)||!Number.isFinite(this.maxAge):this.maxAge)throw TypeError(`[Cookie] option maxAge is invalid`);if(this.priority&&!be.test(this.priority))throw TypeError(`[Cookie] option priority is invalid`);if(this.sameSite&&this.sameSite!==!0&&!we.test(this.sameSite))throw TypeError(`[Cookie] option sameSite is invalid`)}toString(){return`${this.name}=${this.value}`}toHeader(){let e=this.toString();return this.maxAge&&(this.expires=new Date(Date.now()+this.maxAge)),this.path&&(e+=`; path=${this.path}`),this.expires&&(e+=`; expires=${this.expires.toUTCString()}`),this.domain&&(e+=`; domain=${this.domain}`),this.priority&&(e+=`; priority=${this.priority.toLowerCase()}`),this.sameSite&&(e+=`; samesite=${this.sameSite===!0?`strict`:this.sameSite.toLowerCase()}`),this.secure&&(e+=`; secure`),this.httpOnly&&(e+=`; httponly`),this.partitioned&&(e+=`; partitioned`),e}};function Ee(e,t){if(e.length!==t.length)return!1;if(D.timingSafeEqual)return D.timingSafeEqual(e,t);for(let n=0;n<e.length;n++)if(e[n]!==t[n])return!1;return!0}function q(e,t){return D.createHmac(`sha256`,e).update(t).digest()}function De(e,t){let n=String(e),r=String(t),i=D.randomBytes(32);return Ee(q(i,n),q(i,r))&&e===t}const Oe=/[/+=]/g,ke={"/":`_`,"+":`-`,"=":``};var J=class{algorithm;encoding;keys=[];constructor(e,t,n){this.keys=e,this.algorithm=t||`sha256`,this.encoding=n||`base64`}sign(e,t=this.keys[0]){return D.createHmac(this.algorithm,t).update(e).digest(this.encoding).replace(Oe,e=>ke[e])}index(e,t){for(let n=0,r=this.keys.length;n<r;n++)if(De(t,this.sign(e,this.keys[n])))return n;return-1}verify(e,t){return this.index(e,t)>-1}},Y=class{request;response;secure;keys;constructor(t,n,r={}){this.request=t,this.response=n,this.secure=r.secure,r.keys instanceof J?this.keys=r.keys:e(r.keys)&&(this.keys=new J(r.keys))}set(e,t,n){let r=this.request,i=this.response,a=l(i.getHeader(`Set-Cookie`)),o=new Te(e,t,n),s=n?.signed??!!this.keys,c=this.secure===void 0?r.protocol===`https`||je(r):!!this.secure;if(!c&&n?.secure)throw Error(`Cannot send secure cookie over unencrypted connection`);if(o.secure=n?.secure??c,Me(a,o),s&&n){if(!this.keys)throw Error(`.keys required for signed cookies`);o.value=this.keys.sign(o.toString()),o.name+=`.sig`,Me(a,o)}return(i.set?E.OutgoingMessage.prototype.setHeader:i.setHeader).call(i,`Set-Cookie`,a),this}get(e,t){let n=`${e}.sig`,r=t?.signed??!!this.keys,i=this.request.headers.cookie;if(!i)return;let a=i.match(Ae(e));if(!a)return;let o=a[1];if(o[0]===`"`&&(o=o.slice(1,-1)),!t||!r)return o;let s=this.get(n);if(!s)return;let c=`${e}=${o}`;if(!this.keys)throw Error(`.keys required for signed cookies`);let l=this.keys.index(c,s);if(l<0)this.set(n,null,{path:`/`,signed:!1});else return l&&this.set(n,this.keys.sign(c),{signed:!1}),o}};function Ae(e){return K[e]||(K[e]=RegExp(`(?:^|;) *${e.replace(xe,`\\$&`)}=([^;]*)`)),K[e]}function je(e){return!!(e.socket?e.socket.encrypted:e.connection.encrypted)}function Me(e,t){if(t.overwrite)for(let n=e.length-1;n>=0;n--)e[n].indexOf(`${t.name}=`)===0&&e.splice(n,1);e.push(t.toHeader())}const X={};function Z(e){if(X[e])return X[e];let t=[],n=(e,r=!1)=>{for(let i of e)if(i.type===`text`){let e=i.value.split(`/`).filter(Boolean);e.length&&t.push(...e.map(e=>({type:`text`,value:e})))}else i.type===`group`?n(i.tokens,!0):(r&&(i.optional=!0),t.push(i))};return n(g(e).tokens),X[e]=t,t}function Ne(e){let t=e.map(e=>Z(e).length);return t=t.length===0?[1]:t,Math.max(...t)+2}function Pe(e){let t=Z(e),n=0;for(let e=0;e<t.length;e++)t[e].type!==`text`&&(n+=10**(e+1)),n+=10**(e+1);return n}function Fe(e){let t=[],n=[];for(let t of e){let e=Z(t).filter(e=>e.type!==`text`).length;n[e]||(n[e]=[]),n[e].push(t)}for(let e of n.filter(e=>e&&e.length>0))t=[...t,...s(e,Pe).reverse()];return t}function Ie(e){let t=Ne(e);return s(e,e=>{let n=Z(e),r=n.filter(e=>e.type!==`text`);if(r.length===0)return 0;let i=r.length,a=0;for(let e=0;e<n.length;e++){let r=n[e],o=r.type!==`text`,s=r.type===`wildcard`,c=!!r.optional;a+=o?1:0,e===n.length-1&&s?i+=(c?5:4)*10**(n.length===1?t+1:t):(s?i+=3*10**(t-1):i+=2*10**a,c&&(i+=10**a))}return i})}function Le(t,r,i){let a=Ie(Fe(t.filter(e=>R(e,r)))),{global:o=[],special:s={}}=i;if(o.length===0&&n(s)||a.length===0)return a;let[c,l]=Re(a),d=o.filter(e=>l.includes(e));if(d.length>0&&(a=u([...c,...d,...l])),n(s))return a;let f=Object.keys(s).filter(e=>a.includes(e))[0];if(!f)return a;let p=s[f],{rules:m,when:h}=e(p)?{rules:p,when:[]}:p;return m.includes(a[0])&&(h.length===0||h.some(e=>_(e).regexp.test(r)))&&(a=u([f,...a])),a}function Re(e){let t=[],n=[];for(let r of e)Z(r).filter(e=>e.type!==`text`).length>0?n.push(r):t.push(r);return[t,n]}const Q=new WeakMap;function ze(e){let t=[];e.addListener(`data`,e=>{t.push(O.from(e))}),e.addListener(`end`,()=>{t.length&&Q.set(e,O.concat(t))})}function Be(e,t){let n=Q.get(t);n&&(Q.delete(t),e.headersSent||e.setHeader(`Content-Length`,n.byteLength),e.writableEnded||e.write(n))}function Ve(e){return k[e]||`Unknown`}function $(e,t=200,n){e.statusCode=t,e.statusMessage=n||Ve(t)}async function He(e,t,n,i){let{headers:a,type:o=`json`}=n,s=n.__filepath__,c=A.contentType(o)||A.contentType(A.lookup(o)||``);if(c&&t.setHeader(`Content-Type`,c),t.setHeader(`Cache-Control`,`no-cache,max-age=0`),t.setHeader(`X-Mock-Power-By`,`vite-plugin-mock-dev-server`),s&&t.setHeader(`X-File-Path`,s),a)try{let n=r(a)?await a(e):a;Object.keys(n).forEach(e=>{t.setHeader(e,n[e])})}catch(t){i.error(`${f.red(`mock error at ${e.url.split(`?`)[0]}`)}\n${t}\n at headers (${f.underline(s)})`,n.log)}}async function Ue(t,n,i,a){let{cookies:o}=i,s=i.__filepath__;if(o)try{let i=r(o)?await o(t):o;Object.keys(i).forEach(t=>{let r=i[t];if(e(r)){let[e,i]=r;n.setCookie(t,e,i)}else n.setCookie(t,r)})}catch(e){a.error(`${f.red(`mock error at ${t.url.split(`?`)[0]}`)}\n${e}\n at cookies (${f.underline(s)})`,i.log)}}function We(e,t,n){if(ne(t))t.pipe(e);else if(O.isBuffer(t))e.end(n===`text`||n===`json`?t.toString(`utf-8`):t);else{let r=typeof t==`string`?t:JSON.stringify(t);e.end(n===`buffer`?O.from(r):r)}}async function Ge(t,n){if(!n||typeof n==`number`&&n<=0||e(n)&&n.length!==2)return;let r=0;if(e(n)){let[e,t]=n;r=a(e,t)}else r=n-(c()-t);r>0&&await o(r)}function Ke(e,{formidableOptions:t={},bodyParserOptions:n={},proxies:i,cookiesOptions:a,logger:o,priority:s={}}){return async function(l,u,d){let p=c(),{query:m,pathname:h}=B(l.url);if(!h||i.length===0||!i.some(e=>M(e,l.url,l)))return d();let g=e.mockData,_=Le(Object.keys(g),h,s);if(_.length===0)return d();ze(l);let{query:v}=B(l.headers.referer||``),y=await me(l,t,n),b=new Y(l,u,a),x=b.get.bind(b),S=l.method.toUpperCase(),C,w;for(let e of _)if(C=ye(g[e],o,{pathname:h,method:S,request:{query:m,refererQuery:v,body:y,headers:l.headers,getCookie:x}}),C){w=e;break}if(!C){let e=_.map(e=>e===w?f.underline.bold(e):f.dim(e)).join(`, `);return o.warn(`${f.green(h)} matches ${e} , but mock data is not found.`),d()}let T=l,E=u;T.body=y,T.query=m,T.refererQuery=v,T.params=U(C.url,h),T.getCookie=x,E.setCookie=b.set.bind(b);let{body:D,delay:O,type:k=`json`,response:A,status:j=200,statusText:ee,log:N,__filepath__:P}=C;if($(E,j,ee),await He(T,E,C,o),await Ue(T,E,C,o),o.info(ve(T,P),N),o.debug(`${f.magenta(`DEBUG`)} ${f.underline(h)} matches: [ ${_.map(e=>e===w?f.underline.bold(e):f.dim(e)).join(`, `)} ]\n`),D){try{let e=r(D)?await D(T):D;await Ge(p,O),We(E,e,k)}catch(e){o.error(`${f.red(`mock error at ${h}`)}\n${e}\n at body (${f.underline(P)})`,N),$(E,500),u.end(``)}return}if(A){try{await Ge(p,O),await A(T,E,d)}catch(e){o.error(`${f.red(`mock error at ${h}`)}\n${e}\n at response (${f.underline(P)})`,N),$(E,500),u.end(``)}return}u.end(``)}}function qe(e,t,{wsProxies:n,cookiesOptions:r,logger:i}){let a=new Map,o=new Map,s=new WeakMap,c=e=>{let t=o.get(e);return t||o.set(e,t=new Map),t},l=(e,t)=>{let n=a.get(e);n||a.set(e,n=new Set),n.add(t)},u=(e,t,n,r,a,o)=>{try{n.setup?.(t,r),t.on(`close`,()=>e.delete(a)),t.on(`error`,e=>{i.error(`${f.red(`WebSocket mock error at ${t.path}`)}\n${e}\n at setup (${o})`,n.log)})}catch(e){i.error(`${f.red(`WebSocket mock error at ${t.path}`)}\n${e}\n at setup (${o})`,n.log)}},d=(e,t,n,r,i)=>{let{cleanupList:a,connectionList:o,context:c}=s.get(t);Xe(a),o.forEach(({ws:e})=>e.removeAllListeners()),t.removeAllListeners(),u(e,t,n,c,r,i),o.forEach(({ws:e,req:n})=>Ye(t,e,n,o))};e.on(`update`,({filepath:t})=>{if(!a.has(t))return;let n=a.get(t);if(n)for(let r of n.values())for(let n of e.mockData[r]){if(!n.ws||n.__filepath__!==t)return;let e=c(r);for(let[r,i]of e.entries())d(e,i,n,r,t)}}),t?.on(`upgrade`,(t,a,o)=>{let{pathname:d,query:p}=B(t.url);if(!d||n.length===0||!n.some(e=>M(e,t.url,t)))return;let m=e.mockData,h=Object.keys(m).find(e=>R(e,d));if(!h)return;let g=m[h].find(e=>e.url&&e.ws&&R(e.url,d));if(!g)return;let _=g.__filepath__;l(_,h);let v=c(h),y=Je(v,d),b=s.get(y);if(!b){let e=[],t={onCleanup:t=>e.push(t)};b={cleanupList:e,context:t,connectionList:[]},s.set(y,b),u(v,y,g,t,d,_)}let x=t,S=new Y(t,t,r),{query:C}=B(t.headers.referer||``);x.query=p,x.refererQuery=C,x.params=U(h,d),x.getCookie=S.get.bind(S),y.handleUpgrade(x,a,o,e=>{i.info(`${f.magenta(f.bold(`WebSocket`))} ${f.green(t.url)} connected ${f.dim(`(${_})`)}`,g.log),b.connectionList.push({req:x,ws:e}),Ye(y,e,x,b.connectionList)})}),t?.on(`close`,()=>{for(let e of o.values()){for(let t of e.values())Xe(s.get(t).cleanupList),t.close();e.clear()}o.clear(),a.clear()})}function Je(e,t){let n=e.get(t);return n||e.set(t,n=new j({noServer:!0})),n}function Ye(e,t,n,r){e.emit(`connection`,t,n),t.on(`close`,()=>{let e=r.findIndex(e=>e.ws===t);e!==-1&&r.splice(e,1)})}function Xe(e){let t;for(;t=e.shift();)t?.()}export{ee as _,de as a,B as c,re as d,z as f,M as g,N as h,fe as i,le as l,P as m,Ke as n,V as o,R as p,Be as r,ue as s,qe as t,ie as u};
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "rspack-plugin-mock",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "1.
|
|
4
|
+
"version": "1.3.0",
|
|
5
5
|
"description": "inject api mock server to development server",
|
|
6
6
|
"author": "pengzhanbo <q942450674@outlook.com> (https://github.com/pengzhanbo)",
|
|
7
7
|
"license": "MIT",
|
|
@@ -24,53 +24,37 @@
|
|
|
24
24
|
"exports": {
|
|
25
25
|
".": {
|
|
26
26
|
"import": {
|
|
27
|
-
"types": "./dist/index.d.
|
|
28
|
-
"default": "./dist/index.
|
|
29
|
-
},
|
|
30
|
-
"require": {
|
|
31
|
-
"types": "./dist/index.d.cts",
|
|
32
|
-
"default": "./dist/index.cjs"
|
|
27
|
+
"types": "./dist/index.d.mts",
|
|
28
|
+
"default": "./dist/index.mjs"
|
|
33
29
|
}
|
|
34
30
|
},
|
|
35
31
|
"./server": {
|
|
36
32
|
"import": {
|
|
37
|
-
"types": "./dist/server.d.
|
|
38
|
-
"default": "./dist/server.
|
|
39
|
-
},
|
|
40
|
-
"require": {
|
|
41
|
-
"types": "./dist/server.d.cts",
|
|
42
|
-
"default": "./dist/server.cjs"
|
|
33
|
+
"types": "./dist/server.d.mts",
|
|
34
|
+
"default": "./dist/server.mjs"
|
|
43
35
|
}
|
|
44
36
|
},
|
|
45
37
|
"./rsbuild": {
|
|
46
38
|
"import": {
|
|
47
|
-
"types": "./dist/rsbuild.d.
|
|
48
|
-
"default": "./dist/rsbuild.
|
|
49
|
-
},
|
|
50
|
-
"require": {
|
|
51
|
-
"types": "./dist/rsbuild.d.cts",
|
|
52
|
-
"default": "./dist/rsbuild.cjs"
|
|
39
|
+
"types": "./dist/rsbuild.d.mts",
|
|
40
|
+
"default": "./dist/rsbuild.mjs"
|
|
53
41
|
}
|
|
54
42
|
},
|
|
55
43
|
"./helper": {
|
|
56
44
|
"import": {
|
|
57
|
-
"types": "./dist/helper.d.
|
|
58
|
-
"default": "./dist/helper.
|
|
59
|
-
},
|
|
60
|
-
"require": {
|
|
61
|
-
"types": "./dist/helper.d.cts",
|
|
62
|
-
"default": "./dist/helper.cjs"
|
|
45
|
+
"types": "./dist/helper.d.mts",
|
|
46
|
+
"default": "./dist/helper.mjs"
|
|
63
47
|
}
|
|
64
48
|
},
|
|
65
49
|
"./package.json": "./package.json"
|
|
66
50
|
},
|
|
67
|
-
"main": "dist/index.
|
|
68
|
-
"types": "dist/index.d.
|
|
51
|
+
"main": "dist/index.mjs",
|
|
52
|
+
"types": "dist/index.d.mts",
|
|
69
53
|
"files": [
|
|
70
54
|
"dist"
|
|
71
55
|
],
|
|
72
56
|
"engines": {
|
|
73
|
-
"node": ">=
|
|
57
|
+
"node": ">=20.19.0",
|
|
74
58
|
"pnpm": ">=9"
|
|
75
59
|
},
|
|
76
60
|
"peerDependencies": {
|
|
@@ -86,54 +70,59 @@
|
|
|
86
70
|
}
|
|
87
71
|
},
|
|
88
72
|
"dependencies": {
|
|
89
|
-
"@pengzhanbo/utils": "^2.1.
|
|
90
|
-
"
|
|
91
|
-
"chokidar": "
|
|
73
|
+
"@pengzhanbo/utils": "^2.1.2",
|
|
74
|
+
"ansis": "^4.2.0",
|
|
75
|
+
"chokidar": "^5.0.0",
|
|
92
76
|
"co-body": "^6.2.0",
|
|
93
|
-
"cookies": "^0.9.1",
|
|
94
77
|
"cors": "^2.8.5",
|
|
95
|
-
"debug": "^4.4.
|
|
96
|
-
"fast-glob": "^3.3.3",
|
|
78
|
+
"debug": "^4.4.3",
|
|
97
79
|
"formidable": "^3.5.4",
|
|
98
80
|
"http-status": "^2.1.0",
|
|
99
81
|
"is-core-module": "^2.16.1",
|
|
100
82
|
"json5": "^2.2.3",
|
|
101
|
-
"
|
|
102
|
-
"
|
|
103
|
-
"
|
|
104
|
-
"
|
|
105
|
-
"
|
|
83
|
+
"local-pkg": "^1.1.2",
|
|
84
|
+
"memfs": "^4.51.1",
|
|
85
|
+
"mime-types": "^3.0.2",
|
|
86
|
+
"path-to-regexp": "^8.3.0",
|
|
87
|
+
"picomatch": "^4.0.3",
|
|
88
|
+
"portfinder": "^1.0.38",
|
|
89
|
+
"tinyglobby": "^0.2.15",
|
|
106
90
|
"ws": "^8.18.3"
|
|
107
91
|
},
|
|
108
92
|
"devDependencies": {
|
|
109
|
-
"@pengzhanbo/eslint-config": "^1.
|
|
110
|
-
"@rsbuild/core": "^1.
|
|
111
|
-
"@rspack/core": "^1.
|
|
93
|
+
"@pengzhanbo/eslint-config": "^1.45.0",
|
|
94
|
+
"@rsbuild/core": "^1.6.15",
|
|
95
|
+
"@rspack/core": "^1.6.8",
|
|
112
96
|
"@types/co-body": "^6.1.3",
|
|
113
|
-
"@types/cookies": "^0.9.1",
|
|
114
97
|
"@types/cors": "^2.8.19",
|
|
115
98
|
"@types/debug": "^4.1.12",
|
|
116
|
-
"@types/formidable": "^3.4.
|
|
99
|
+
"@types/formidable": "^3.4.6",
|
|
117
100
|
"@types/is-core-module": "^2.2.2",
|
|
118
101
|
"@types/mime-types": "^3.0.1",
|
|
119
|
-
"@types/node": "^
|
|
102
|
+
"@types/node": "^25.0.3",
|
|
103
|
+
"@types/picomatch": "^4.0.2",
|
|
120
104
|
"@types/ws": "^8.18.1",
|
|
121
|
-
"bumpp": "^10.2
|
|
105
|
+
"bumpp": "^10.3.2",
|
|
122
106
|
"conventional-changelog-cli": "^5.0.0",
|
|
123
|
-
"eslint": "^9.
|
|
107
|
+
"eslint": "^9.39.2",
|
|
124
108
|
"husky": "^9.1.7",
|
|
125
|
-
"lint-staged": "^16.
|
|
126
|
-
"tsdown": "^0.
|
|
127
|
-
"typescript": "^5.
|
|
109
|
+
"lint-staged": "^16.2.7",
|
|
110
|
+
"tsdown": "^0.18.3",
|
|
111
|
+
"typescript": "^5.9.3"
|
|
128
112
|
},
|
|
129
113
|
"lint-staged": {
|
|
130
114
|
"*": "eslint --fix"
|
|
131
115
|
},
|
|
116
|
+
"publishConfig": {
|
|
117
|
+
"access": "public",
|
|
118
|
+
"provenance": true
|
|
119
|
+
},
|
|
132
120
|
"scripts": {
|
|
133
121
|
"dev": "tsdown src --watch",
|
|
134
122
|
"build": "tsdown",
|
|
135
123
|
"lint": "eslint .",
|
|
124
|
+
"release:publish": "pnpm -r publish",
|
|
136
125
|
"release:changelog": "conventional-changelog -p angular -i CHANGELOG.md -s",
|
|
137
|
-
"release": "bumpp package.json --execute=\"pnpm release:changelog\" --commit --all --push --tag
|
|
126
|
+
"release": "bumpp package.json --execute=\"pnpm release:changelog\" --commit --all --push --tag"
|
|
138
127
|
}
|
|
139
128
|
}
|
package/dist/chunk-CUT6urMc.cjs
DELETED
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
//#region rolldown:runtime
|
|
2
|
-
var __create = Object.create;
|
|
3
|
-
var __defProp = Object.defineProperty;
|
|
4
|
-
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
-
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
-
var __getProtoOf = Object.getPrototypeOf;
|
|
7
|
-
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
-
var __copyProps = (to, from, except, desc) => {
|
|
9
|
-
if (from && typeof from === "object" || typeof from === "function") for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
|
|
10
|
-
key = keys[i];
|
|
11
|
-
if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
|
|
12
|
-
get: ((k) => from[k]).bind(null, key),
|
|
13
|
-
enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
|
|
14
|
-
});
|
|
15
|
-
}
|
|
16
|
-
return to;
|
|
17
|
-
};
|
|
18
|
-
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
|
|
19
|
-
value: mod,
|
|
20
|
-
enumerable: true
|
|
21
|
-
}) : target, mod));
|
|
22
|
-
|
|
23
|
-
//#endregion
|
|
24
|
-
|
|
25
|
-
Object.defineProperty(exports, '__toESM', {
|
|
26
|
-
enumerable: true,
|
|
27
|
-
get: function () {
|
|
28
|
-
return __toESM;
|
|
29
|
-
}
|
|
30
|
-
});
|
package/dist/helper.cjs
DELETED
|
@@ -1,140 +0,0 @@
|
|
|
1
|
-
const require_chunk = require('./chunk-CUT6urMc.cjs');
|
|
2
|
-
const __pengzhanbo_utils = require_chunk.__toESM(require("@pengzhanbo/utils"));
|
|
3
|
-
const node_stream = require_chunk.__toESM(require("node:stream"));
|
|
4
|
-
|
|
5
|
-
//#region src/core/defineMock.ts
|
|
6
|
-
function defineMock(config) {
|
|
7
|
-
return config;
|
|
8
|
-
}
|
|
9
|
-
/**
|
|
10
|
-
* Return a custom defineMock function to support preprocessing of mock config.
|
|
11
|
-
*
|
|
12
|
-
* 返回一个自定义的 defineMock 函数,用于支持对 mock config 的预处理。
|
|
13
|
-
* @param transformer preprocessing function
|
|
14
|
-
* @example
|
|
15
|
-
* ```ts
|
|
16
|
-
* const definePostMock = createDefineMock((mock) => {
|
|
17
|
-
* mock.url = '/api/post/' + mock.url
|
|
18
|
-
* })
|
|
19
|
-
* export default definePostMock({
|
|
20
|
-
* url: 'list',
|
|
21
|
-
* body: [{ title: '1' }, { title: '2' }],
|
|
22
|
-
* })
|
|
23
|
-
* ```
|
|
24
|
-
*/
|
|
25
|
-
function createDefineMock(transformer) {
|
|
26
|
-
const define = (config) => {
|
|
27
|
-
if ((0, __pengzhanbo_utils.isArray)(config)) config = config.map((item) => transformer(item) || item);
|
|
28
|
-
else config = transformer(config) || config;
|
|
29
|
-
return config;
|
|
30
|
-
};
|
|
31
|
-
return define;
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
//#endregion
|
|
35
|
-
//#region src/core/defineMockData.ts
|
|
36
|
-
const mockDataCache = /* @__PURE__ */ new Map();
|
|
37
|
-
const responseCache = /* @__PURE__ */ new WeakMap();
|
|
38
|
-
const staleInterval = 70;
|
|
39
|
-
var CacheImpl = class {
|
|
40
|
-
value;
|
|
41
|
-
#initialValue;
|
|
42
|
-
#lastUpdate;
|
|
43
|
-
constructor(value) {
|
|
44
|
-
this.value = value;
|
|
45
|
-
this.#initialValue = (0, __pengzhanbo_utils.deepClone)(value);
|
|
46
|
-
this.#lastUpdate = Date.now();
|
|
47
|
-
}
|
|
48
|
-
hotUpdate(value) {
|
|
49
|
-
if (Date.now() - this.#lastUpdate < staleInterval) return;
|
|
50
|
-
if (!(0, __pengzhanbo_utils.deepEqual)(value, this.#initialValue)) {
|
|
51
|
-
this.value = value;
|
|
52
|
-
this.#initialValue = (0, __pengzhanbo_utils.deepClone)(value);
|
|
53
|
-
this.#lastUpdate = Date.now();
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
};
|
|
57
|
-
function defineMockData(key, initialData) {
|
|
58
|
-
if (!mockDataCache.has(key)) mockDataCache.set(key, new CacheImpl(initialData));
|
|
59
|
-
const cache = mockDataCache.get(key);
|
|
60
|
-
cache.hotUpdate(initialData);
|
|
61
|
-
if (responseCache.has(cache)) return responseCache.get(cache);
|
|
62
|
-
const res = [() => cache.value, (val) => {
|
|
63
|
-
if ((0, __pengzhanbo_utils.isFunction)(val)) val = val(cache.value) ?? cache.value;
|
|
64
|
-
cache.value = val;
|
|
65
|
-
}];
|
|
66
|
-
Object.defineProperty(res, "value", {
|
|
67
|
-
get() {
|
|
68
|
-
return cache.value;
|
|
69
|
-
},
|
|
70
|
-
set(val) {
|
|
71
|
-
cache.value = val;
|
|
72
|
-
}
|
|
73
|
-
});
|
|
74
|
-
responseCache.set(cache, res);
|
|
75
|
-
return res;
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
//#endregion
|
|
79
|
-
//#region src/core/sse.ts
|
|
80
|
-
/**
|
|
81
|
-
* Transforms "messages" to W3C event stream content.
|
|
82
|
-
* See https://html.spec.whatwg.org/multipage/server-sent-events.html
|
|
83
|
-
* A message is an object with one or more of the following properties:
|
|
84
|
-
* - data (String or object, which gets turned into JSON)
|
|
85
|
-
* - event
|
|
86
|
-
* - id
|
|
87
|
-
* - retry
|
|
88
|
-
* - comment
|
|
89
|
-
*
|
|
90
|
-
* If constructed with a HTTP Request, it will optimise the socket for streaming.
|
|
91
|
-
* If this stream is piped to an HTTP Response, it will set appropriate headers.
|
|
92
|
-
*/
|
|
93
|
-
var SSEStream = class extends node_stream.Transform {
|
|
94
|
-
constructor(req) {
|
|
95
|
-
super({ objectMode: true });
|
|
96
|
-
req.socket.setKeepAlive(true);
|
|
97
|
-
req.socket.setNoDelay(true);
|
|
98
|
-
req.socket.setTimeout(0);
|
|
99
|
-
}
|
|
100
|
-
pipe(destination, options) {
|
|
101
|
-
if (destination.writeHead) {
|
|
102
|
-
destination.writeHead(200, {
|
|
103
|
-
"Content-Type": "text/event-stream; charset=utf-8",
|
|
104
|
-
"Transfer-Encoding": "identity",
|
|
105
|
-
"Cache-Control": "no-cache",
|
|
106
|
-
"Connection": "keep-alive"
|
|
107
|
-
});
|
|
108
|
-
destination.flushHeaders?.();
|
|
109
|
-
}
|
|
110
|
-
destination.write(":ok\n\n");
|
|
111
|
-
return super.pipe(destination, options);
|
|
112
|
-
}
|
|
113
|
-
_transform(message, encoding, callback) {
|
|
114
|
-
if (message.comment) this.push(`: ${message.comment}\n`);
|
|
115
|
-
if (message.event) this.push(`event: ${message.event}\n`);
|
|
116
|
-
if (message.id) this.push(`id: ${message.id}\n`);
|
|
117
|
-
if (message.retry) this.push(`retry: ${message.retry}\n`);
|
|
118
|
-
if (message.data) this.push(dataString(message.data));
|
|
119
|
-
this.push("\n");
|
|
120
|
-
callback();
|
|
121
|
-
}
|
|
122
|
-
write(message, ...args) {
|
|
123
|
-
return super.write(message, ...args);
|
|
124
|
-
}
|
|
125
|
-
};
|
|
126
|
-
function dataString(data) {
|
|
127
|
-
if (typeof data === "object") return dataString(JSON.stringify(data));
|
|
128
|
-
return data.split(/\r\n|\r|\n/).map((line) => `data: ${line}\n`).join("");
|
|
129
|
-
}
|
|
130
|
-
function createSSEStream(req, res) {
|
|
131
|
-
const sse = new SSEStream(req);
|
|
132
|
-
sse.pipe(res);
|
|
133
|
-
return sse;
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
//#endregion
|
|
137
|
-
exports.createDefineMock = createDefineMock;
|
|
138
|
-
exports.createSSEStream = createSSEStream;
|
|
139
|
-
exports.defineMock = defineMock;
|
|
140
|
-
exports.defineMockData = defineMockData;
|
package/dist/helper.d.ts
DELETED
|
@@ -1,110 +0,0 @@
|
|
|
1
|
-
import { BodyParserOptions, ExtraRequest, FormidableFile, LogLevel, LogType, Method, MockHttpItem, MockMatchPriority, MockMatchSpecialPriority, MockOptions, MockRequest, MockResponse, MockServerPluginOptions, MockWebsocketItem, ResponseBody, ServerBuildOption, WebSocketSetupContext } from "./types-DPzh7nJq.js";
|
|
2
|
-
import { Transform } from "node:stream";
|
|
3
|
-
import { IncomingMessage, OutgoingHttpHeaders, ServerResponse } from "node:http";
|
|
4
|
-
|
|
5
|
-
//#region src/core/defineMock.d.ts
|
|
6
|
-
|
|
7
|
-
/**
|
|
8
|
-
* mock config Type helper
|
|
9
|
-
*
|
|
10
|
-
* mock配置 类型帮助函数
|
|
11
|
-
* @param config see config docs:
|
|
12
|
-
* {@link https://vite-plugin-mock-dev-server.netlify.app/en/guide/mock-config en-US DOC} |
|
|
13
|
-
* {@link https://vite-plugin-mock-dev-server.netlify.app/guide/mock-config zh-CN DOC}
|
|
14
|
-
*
|
|
15
|
-
* @example
|
|
16
|
-
* Mock Http Request
|
|
17
|
-
* ```ts
|
|
18
|
-
* export default defineMock({
|
|
19
|
-
* url: '/api/example',
|
|
20
|
-
* method: ['GET', 'POST'],
|
|
21
|
-
* body: { a: 1 },
|
|
22
|
-
* })
|
|
23
|
-
* ```
|
|
24
|
-
* ```ts
|
|
25
|
-
* export default defineMock({
|
|
26
|
-
* url: '/api/example',
|
|
27
|
-
* method: 'GET',
|
|
28
|
-
* body: ({ query }) => ({ a: 1, b: query.b }),
|
|
29
|
-
* })
|
|
30
|
-
* ```
|
|
31
|
-
* @example
|
|
32
|
-
* Mock WebSocket
|
|
33
|
-
* ```ts
|
|
34
|
-
* export default defineMock({
|
|
35
|
-
* url: '/socket.io',
|
|
36
|
-
* ws: true,
|
|
37
|
-
* setup(wss) {
|
|
38
|
-
* wss.on('connection', (ws) => {
|
|
39
|
-
* ws.on('message', (rawData) => console.log(rawData))
|
|
40
|
-
* ws.send('data')
|
|
41
|
-
* })
|
|
42
|
-
* },
|
|
43
|
-
* })
|
|
44
|
-
* ```
|
|
45
|
-
*/
|
|
46
|
-
declare function defineMock(config: MockHttpItem): MockHttpItem;
|
|
47
|
-
declare function defineMock(config: MockWebsocketItem): MockWebsocketItem;
|
|
48
|
-
declare function defineMock(config: MockOptions): MockOptions;
|
|
49
|
-
/**
|
|
50
|
-
* Return a custom defineMock function to support preprocessing of mock config.
|
|
51
|
-
*
|
|
52
|
-
* 返回一个自定义的 defineMock 函数,用于支持对 mock config 的预处理。
|
|
53
|
-
* @param transformer preprocessing function
|
|
54
|
-
* @example
|
|
55
|
-
* ```ts
|
|
56
|
-
* const definePostMock = createDefineMock((mock) => {
|
|
57
|
-
* mock.url = '/api/post/' + mock.url
|
|
58
|
-
* })
|
|
59
|
-
* export default definePostMock({
|
|
60
|
-
* url: 'list',
|
|
61
|
-
* body: [{ title: '1' }, { title: '2' }],
|
|
62
|
-
* })
|
|
63
|
-
* ```
|
|
64
|
-
*/
|
|
65
|
-
declare function createDefineMock(transformer: (mock: MockHttpItem | MockWebsocketItem) => MockHttpItem | MockWebsocketItem | void): typeof defineMock;
|
|
66
|
-
//#endregion
|
|
67
|
-
//#region src/core/defineMockData.d.ts
|
|
68
|
-
type MockData<T = any> = readonly [() => T, (val: T | ((val: T) => T | void)) => void] & {
|
|
69
|
-
value: T;
|
|
70
|
-
};
|
|
71
|
-
declare function defineMockData<T = any>(key: string, initialData: T): MockData<T>;
|
|
72
|
-
//#endregion
|
|
73
|
-
//#region src/core/sse.d.ts
|
|
74
|
-
interface SSEMessage {
|
|
75
|
-
data?: string | object;
|
|
76
|
-
comment?: string;
|
|
77
|
-
event?: string;
|
|
78
|
-
id?: string;
|
|
79
|
-
retry?: number;
|
|
80
|
-
}
|
|
81
|
-
interface WriteHeaders {
|
|
82
|
-
writeHead?: (statusCode: number, headers?: OutgoingHttpHeaders) => WriteHeaders;
|
|
83
|
-
flushHeaders?: () => void;
|
|
84
|
-
}
|
|
85
|
-
type HeaderStream = NodeJS.WritableStream & WriteHeaders;
|
|
86
|
-
/**
|
|
87
|
-
* Transforms "messages" to W3C event stream content.
|
|
88
|
-
* See https://html.spec.whatwg.org/multipage/server-sent-events.html
|
|
89
|
-
* A message is an object with one or more of the following properties:
|
|
90
|
-
* - data (String or object, which gets turned into JSON)
|
|
91
|
-
* - event
|
|
92
|
-
* - id
|
|
93
|
-
* - retry
|
|
94
|
-
* - comment
|
|
95
|
-
*
|
|
96
|
-
* If constructed with a HTTP Request, it will optimise the socket for streaming.
|
|
97
|
-
* If this stream is piped to an HTTP Response, it will set appropriate headers.
|
|
98
|
-
*/
|
|
99
|
-
declare class SSEStream extends Transform {
|
|
100
|
-
constructor(req: IncomingMessage);
|
|
101
|
-
pipe<T extends HeaderStream>(destination: T, options?: {
|
|
102
|
-
end?: boolean;
|
|
103
|
-
}): T;
|
|
104
|
-
_transform(message: SSEMessage, encoding: string, callback: (error?: (Error | null), data?: any) => void): void;
|
|
105
|
-
write(message: SSEMessage, encoding?: BufferEncoding, cb?: (error: Error | null | undefined) => void): boolean;
|
|
106
|
-
write(message: SSEMessage, cb?: (error: Error | null | undefined) => void): boolean;
|
|
107
|
-
}
|
|
108
|
-
declare function createSSEStream(req: IncomingMessage, res: ServerResponse): SSEStream;
|
|
109
|
-
//#endregion
|
|
110
|
-
export { BodyParserOptions, ExtraRequest, FormidableFile, HeaderStream, LogLevel, LogType, Method, MockData, MockHttpItem, MockMatchPriority, MockMatchSpecialPriority, MockOptions, MockRequest, MockResponse, MockServerPluginOptions, MockWebsocketItem, ResponseBody, SSEMessage, ServerBuildOption, WebSocketSetupContext, createDefineMock, createSSEStream, defineMock, defineMockData };
|