whistle.interceptors 0.0.2 → 0.0.3
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/.console.log +2 -0
- package/dist/server.js +1 -1
- package/dist/uiServer/index.js +1 -58
- package/index.js +1 -0
- package/package.json +16 -4
- package/public/assets/index-Bn3cFRn4.css +1 -0
- package/public/assets/index-yFos5qg5.js +83 -0
- package/public/assets/vanilla-picker-B6E6ObS_.js +8 -0
- package/public/index.html +14 -0
- package/public/vite.svg +1 -0
- package/src/server.ts +166 -0
- package/src/types/base.d.ts +17 -0
- package/src/types/global.d.ts +378 -0
- package/src/types/rule.ts +13 -0
- package/src/uiServer/constant.ts +11 -0
- package/src/uiServer/index.ts +41 -0
- package/src/uiServer/router.ts +40 -0
- package/tsup.config.ts +11 -0
- package/README.md +0 -29
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/*!
|
|
2
|
+
* vanilla-picker v2.12.3
|
|
3
|
+
* https://vanilla-picker.js.org
|
|
4
|
+
*
|
|
5
|
+
* Copyright 2017-2024 Andreas Borgen (https://github.com/Sphinxxxx), Adam Brooks (https://github.com/dissimulate)
|
|
6
|
+
* Released under the ISC license.
|
|
7
|
+
*/var O=function(l,n){if(!(l instanceof n))throw new TypeError("Cannot call a class as a function")},R=function(){function l(n,e){for(var t=0;t<e.length;t++){var r=e[t];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(n,r.key,r)}}return function(n,e,t){return e&&l(n.prototype,e),t&&l(n,t),n}}(),y=function(){function l(n,e){var t=[],r=!0,i=!1,o=void 0;try{for(var c=n[Symbol.iterator](),a;!(r=(a=c.next()).done)&&(t.push(a.value),!(e&&t.length===e));r=!0);}catch(s){i=!0,o=s}finally{try{!r&&c.return&&c.return()}finally{if(i)throw o}}return t}return function(n,e){if(Array.isArray(n))return n;if(Symbol.iterator in Object(n))return l(n,e);throw new TypeError("Invalid attempt to destructure non-iterable instance")}}();String.prototype.startsWith=String.prototype.startsWith||function(l){return this.indexOf(l)===0};String.prototype.padStart=String.prototype.padStart||function(l,n){for(var e=this;e.length<l;)e=n+e;return e};var I={cb:"0f8ff",tqw:"aebd7",q:"-ffff",qmrn:"7fffd4",zr:"0ffff",bg:"5f5dc",bsq:"e4c4",bck:"---",nch:"ebcd",b:"--ff",bvt:"8a2be2",brwn:"a52a2a",brw:"deb887",ctb:"5f9ea0",hrt:"7fff-",chcT:"d2691e",cr:"7f50",rnw:"6495ed",crns:"8dc",crms:"dc143c",cn:"-ffff",Db:"--8b",Dcn:"-8b8b",Dgnr:"b8860b",Dgr:"a9a9a9",Dgrn:"-64-",Dkhk:"bdb76b",Dmgn:"8b-8b",Dvgr:"556b2f",Drng:"8c-",Drch:"9932cc",Dr:"8b--",Dsmn:"e9967a",Dsgr:"8fbc8f",DsTb:"483d8b",DsTg:"2f4f4f",Dtrq:"-ced1",Dvt:"94-d3",ppnk:"1493",pskb:"-bfff",mgr:"696969",grb:"1e90ff",rbrc:"b22222",rwht:"af0",stg:"228b22",chs:"-ff",gnsb:"dcdcdc",st:"8f8ff",g:"d7-",gnr:"daa520",gr:"808080",grn:"-8-0",grnw:"adff2f",hnw:"0fff0",htpn:"69b4",nnr:"cd5c5c",ng:"4b-82",vr:"0",khk:"0e68c",vnr:"e6e6fa",nrb:"0f5",wngr:"7cfc-",mnch:"acd",Lb:"add8e6",Lcr:"08080",Lcn:"e0ffff",Lgnr:"afad2",Lgr:"d3d3d3",Lgrn:"90ee90",Lpnk:"b6c1",Lsmn:"a07a",Lsgr:"20b2aa",Lskb:"87cefa",LsTg:"778899",Lstb:"b0c4de",Lw:"e0",m:"-ff-",mgrn:"32cd32",nn:"af0e6",mgnt:"-ff",mrn:"8--0",mqm:"66cdaa",mmb:"--cd",mmrc:"ba55d3",mmpr:"9370db",msg:"3cb371",mmsT:"7b68ee","":"-fa9a",mtr:"48d1cc",mmvt:"c71585",mnLb:"191970",ntc:"5fffa",mstr:"e4e1",mccs:"e4b5",vjw:"dead",nv:"--80",c:"df5e6",v:"808-0",vrb:"6b8e23",rng:"a5-",rngr:"45-",rch:"da70d6",pgnr:"eee8aa",pgrn:"98fb98",ptrq:"afeeee",pvtr:"db7093",ppwh:"efd5",pchp:"dab9",pr:"cd853f",pnk:"c0cb",pm:"dda0dd",pwrb:"b0e0e6",prp:"8-080",cc:"663399",r:"--",sbr:"bc8f8f",rb:"4169e1",sbrw:"8b4513",smn:"a8072",nbr:"4a460",sgrn:"2e8b57",ssh:"5ee",snn:"a0522d",svr:"c0c0c0",skb:"87ceeb",sTb:"6a5acd",sTgr:"708090",snw:"afa",n:"-ff7f",stb:"4682b4",tn:"d2b48c",t:"-8080",thst:"d8bfd8",tmT:"6347",trqs:"40e0d0",vt:"ee82ee",whT:"5deb3",wht:"",hts:"5f5f5",w:"-",wgrn:"9acd32"};function A(l){var n=arguments.length>1&&arguments[1]!==void 0?arguments[1]:1,e=n>0?l.toFixed(n).replace(/0+$/,"").replace(/\.$/,""):l.toString();return e||"0"}var N=function(){function l(n,e,t,r){O(this,l);var i=this;function o(a){if(a.startsWith("hsl")){var s=a.match(/([\-\d\.e]+)/g).map(Number),p=y(s,4),f=p[0],u=p[1],d=p[2],b=p[3];b===void 0&&(b=1),f/=360,u/=100,d/=100,i.hsla=[f,u,d,b]}else if(a.startsWith("rgb")){var m=a.match(/([\-\d\.e]+)/g).map(Number),h=y(m,4),v=h[0],g=h[1],E=h[2],k=h[3];k===void 0&&(k=1),i.rgba=[v,g,E,k]}else a.startsWith("#")?i.rgba=l.hexToRgb(a):i.rgba=l.nameToRgb(a)||l.hexToRgb(a)}if(n!==void 0)if(Array.isArray(n))this.rgba=n;else if(t===void 0){var c=n&&""+n;c&&o(c.toLowerCase())}else this.rgba=[n,e,t,r===void 0?1:r]}return R(l,[{key:"printRGB",value:function(e){var t=e?this.rgba:this.rgba.slice(0,3),r=t.map(function(i,o){return A(i,o===3?3:0)});return e?"rgba("+r+")":"rgb("+r+")"}},{key:"printHSL",value:function(e){var t=[360,100,100,1],r=["","%","%",""],i=e?this.hsla:this.hsla.slice(0,3),o=i.map(function(c,a){return A(c*t[a],a===3?3:1)+r[a]});return e?"hsla("+o+")":"hsl("+o+")"}},{key:"printHex",value:function(e){var t=this.hex;return e?t:t.substring(0,7)}},{key:"rgba",get:function(){if(this._rgba)return this._rgba;if(!this._hsla)throw new Error("No color is set");return this._rgba=l.hslToRgb(this._hsla)},set:function(e){e.length===3&&(e[3]=1),this._rgba=e,this._hsla=null}},{key:"rgbString",get:function(){return this.printRGB()}},{key:"rgbaString",get:function(){return this.printRGB(!0)}},{key:"hsla",get:function(){if(this._hsla)return this._hsla;if(!this._rgba)throw new Error("No color is set");return this._hsla=l.rgbToHsl(this._rgba)},set:function(e){e.length===3&&(e[3]=1),this._hsla=e,this._rgba=null}},{key:"hslString",get:function(){return this.printHSL()}},{key:"hslaString",get:function(){return this.printHSL(!0)}},{key:"hex",get:function(){var e=this.rgba,t=e.map(function(r,i){return i<3?r.toString(16):Math.round(r*255).toString(16)});return"#"+t.map(function(r){return r.padStart(2,"0")}).join("")},set:function(e){this.rgba=l.hexToRgb(e)}}],[{key:"hexToRgb",value:function(e){var t=(e.startsWith("#")?e.slice(1):e).replace(/^(\w{3})$/,"$1F").replace(/^(\w)(\w)(\w)(\w)$/,"$1$1$2$2$3$3$4$4").replace(/^(\w{6})$/,"$1FF");if(!t.match(/^([0-9a-fA-F]{8})$/))throw new Error("Unknown hex color; "+e);var r=t.match(/^(\w\w)(\w\w)(\w\w)(\w\w)$/).slice(1).map(function(i){return parseInt(i,16)});return r[3]=r[3]/255,r}},{key:"nameToRgb",value:function(e){var t=e.toLowerCase().replace("at","T").replace(/[aeiouyldf]/g,"").replace("ght","L").replace("rk","D").slice(-5,4),r=I[t];return r===void 0?r:l.hexToRgb(r.replace(/\-/g,"00").padStart(6,"f"))}},{key:"rgbToHsl",value:function(e){var t=y(e,4),r=t[0],i=t[1],o=t[2],c=t[3];r/=255,i/=255,o/=255;var a=Math.max(r,i,o),s=Math.min(r,i,o),p=void 0,f=void 0,u=(a+s)/2;if(a===s)p=f=0;else{var d=a-s;switch(f=u>.5?d/(2-a-s):d/(a+s),a){case r:p=(i-o)/d+(i<o?6:0);break;case i:p=(o-r)/d+2;break;case o:p=(r-i)/d+4;break}p/=6}return[p,f,u,c]}},{key:"hslToRgb",value:function(e){var t=y(e,4),r=t[0],i=t[1],o=t[2],c=t[3],a=void 0,s=void 0,p=void 0;if(i===0)a=s=p=o;else{var f=function(h,v,g){return g<0&&(g+=1),g>1&&(g-=1),g<.16666666666666666?h+(v-h)*6*g:g<.5?v:g<.6666666666666666?h+(v-h)*(.6666666666666666-g)*6:h},u=o<.5?o*(1+i):o+i-o*i,d=2*o-u;a=f(d,u,r+1/3),s=f(d,u,r),p=f(d,u,r-1/3)}var b=[a*255,s*255,p*255].map(Math.round);return b[3]=c,b}}]),l}(),z=function(){function l(){O(this,l),this._events=[]}return R(l,[{key:"add",value:function(e,t,r){e.addEventListener(t,r,!1),this._events.push({target:e,type:t,handler:r})}},{key:"remove",value:function(e,t,r){this._events=this._events.filter(function(i){var o=!0;return e&&e!==i.target&&(o=!1),t&&t!==i.type&&(o=!1),r&&r!==i.handler&&(o=!1),o&&l._doRemove(i.target,i.type,i.handler),!o})}},{key:"destroy",value:function(){this._events.forEach(function(e){return l._doRemove(e.target,e.type,e.handler)}),this._events=[]}}],[{key:"_doRemove",value:function(e,t,r){e.removeEventListener(t,r,!1)}}]),l}();function F(l){var n=document.createElement("div");return n.innerHTML=l,n.firstElementChild}function L(l,n,e){var t=!1;function r(a,s,p){return Math.max(s,Math.min(a,p))}function i(a,s,p){if(p&&(t=!0),!!t){a.preventDefault();var f=n.getBoundingClientRect(),u=f.width,d=f.height,b=s.clientX,m=s.clientY,h=r(b-f.left,0,u),v=r(m-f.top,0,d);e(h/u,v/d)}}function o(a,s){var p=a.buttons===void 0?a.which:a.buttons;p===1?i(a,a,s):t=!1}function c(a,s){a.touches.length===1?i(a,a.touches[0],s):t=!1}l.add(n,"mousedown",function(a){o(a,!0)}),l.add(n,"touchstart",function(a){c(a,!0)}),l.add(window,"mousemove",o),l.add(n,"touchmove",c),l.add(window,"mouseup",function(a){t=!1}),l.add(n,"touchend",function(a){t=!1}),l.add(n,"touchcancel",function(a){t=!1})}var U=`linear-gradient(45deg, lightgrey 25%, transparent 25%, transparent 75%, lightgrey 75%) 0 0 / 2em 2em,
|
|
8
|
+
linear-gradient(45deg, lightgrey 25%, white 25%, white 75%, lightgrey 75%) 1em 1em / 2em 2em`,B=360,P="keydown",x="mousedown",T="focusin";function _(l,n){return(n||document).querySelector(l)}function G(l){l.preventDefault(),l.stopPropagation()}function H(l,n,e,t,r){l.add(n,P,function(i){e.indexOf(i.key)>=0&&t(i)})}var K=function(){function l(n){O(this,l),this.settings={popup:"right",layout:"default",alpha:!0,editor:!0,editorFormat:"hex",cancelButton:!1,defaultColor:"#0cf"},this._events=new z,this.onChange=null,this.onDone=null,this.onOpen=null,this.onClose=null,this.setOptions(n)}return R(l,[{key:"setOptions",value:function(e){var t=this;if(!e)return;var r=this.settings;function i(s,p,f){for(var u in s)p[u]=s[u]}if(e instanceof HTMLElement)r.parent=e;else{r.parent&&e.parent&&r.parent!==e.parent&&(this._events.remove(r.parent),this._popupInited=!1),i(e,r),e.onChange&&(this.onChange=e.onChange),e.onDone&&(this.onDone=e.onDone),e.onOpen&&(this.onOpen=e.onOpen),e.onClose&&(this.onClose=e.onClose);var o=e.color||e.colour;o&&this._setColor(o)}var c=r.parent;if(c&&r.popup&&!this._popupInited){var a=function(p){return t.openHandler(p)};this._events.add(c,"click",a),H(this._events,c,[" ","Spacebar","Enter"],a),this._popupInited=!0}else e.parent&&!r.popup&&this.show()}},{key:"openHandler",value:function(e){if(this.show()){e&&e.preventDefault(),this.settings.parent.style.pointerEvents="none";var t=e&&e.type===P?this._domEdit:this.domElement;setTimeout(function(){return t.focus()},100),this.onOpen&&this.onOpen(this.colour)}}},{key:"closeHandler",value:function(e){var t=e&&e.type,r=!1;if(!e)r=!0;else if(t===x||t===T){var i=(this.__containedEvent||0)+100;e.timeStamp>i&&(r=!0)}else G(e),r=!0;r&&this.hide()&&(this.settings.parent.style.pointerEvents="",t!==x&&this.settings.parent.focus(),this.onClose&&this.onClose(this.colour))}},{key:"movePopup",value:function(e,t){this.closeHandler(),this.setOptions(e),t&&this.openHandler()}},{key:"setColor",value:function(e,t){this._setColor(e,{silent:t})}},{key:"_setColor",value:function(e,t){if(typeof e=="string"&&(e=e.trim()),!!e){t=t||{};var r=void 0;try{r=new N(e)}catch(o){if(t.failSilently)return;throw o}if(!this.settings.alpha){var i=r.hsla;i[3]=1,r.hsla=i}this.colour=this.color=r,this._setHSLA(null,null,null,null,t)}}},{key:"setColour",value:function(e,t){this.setColor(e,t)}},{key:"show",value:function(){var e=this.settings.parent;if(!e)return!1;if(this.domElement){var t=this._toggleDOM(!0);return this._setPosition(),t}var r=this.settings.template||'<div class="picker_wrapper" tabindex="-1"><div class="picker_arrow"></div><div class="picker_hue picker_slider"><div class="picker_selector"></div></div><div class="picker_sl"><div class="picker_selector"></div></div><div class="picker_alpha picker_slider"><div class="picker_selector"></div></div><div class="picker_editor"><input aria-label="Type a color name or hex value"/></div><div class="picker_sample"></div><div class="picker_done"><button>Ok</button></div><div class="picker_cancel"><button>Cancel</button></div></div>',i=F(r);return this.domElement=i,this._domH=_(".picker_hue",i),this._domSL=_(".picker_sl",i),this._domA=_(".picker_alpha",i),this._domEdit=_(".picker_editor input",i),this._domSample=_(".picker_sample",i),this._domOkay=_(".picker_done button",i),this._domCancel=_(".picker_cancel button",i),i.classList.add("layout_"+this.settings.layout),this.settings.alpha||i.classList.add("no_alpha"),this.settings.editor||i.classList.add("no_editor"),this.settings.cancelButton||i.classList.add("no_cancel"),this._ifPopup(function(){return i.classList.add("popup")}),this._setPosition(),this.colour?this._updateUI():this._setColor(this.settings.defaultColor),this._bindEvents(),!0}},{key:"hide",value:function(){return this._toggleDOM(!1)}},{key:"destroy",value:function(){this._events.destroy(),this.domElement&&this.settings.parent.removeChild(this.domElement)}},{key:"_bindEvents",value:function(){var e=this,t=this,r=this.domElement,i=this._events;function o(s,p,f){i.add(s,p,f)}o(r,"click",function(s){return s.preventDefault()}),L(i,this._domH,function(s,p){return t._setHSLA(s)}),L(i,this._domSL,function(s,p){return t._setHSLA(null,s,1-p)}),this.settings.alpha&&L(i,this._domA,function(s,p){return t._setHSLA(null,null,null,1-p)});var c=this._domEdit;o(c,"input",function(s){t._setColor(this.value,{fromEditor:!0,failSilently:!0})}),o(c,"focus",function(s){var p=this;p.selectionStart===p.selectionEnd&&p.select()}),this._ifPopup(function(){var s=function(u){return e.closeHandler(u)};o(window,x,s),o(window,T,s),H(i,r,["Esc","Escape"],s);var p=function(u){e.__containedEvent=u.timeStamp};o(r,x,p),o(r,T,p),o(e._domCancel,"click",s)});var a=function(p){e._ifPopup(function(){return e.closeHandler(p)}),e.onDone&&e.onDone(e.colour)};o(this._domOkay,"click",a),H(i,r,["Enter"],a)}},{key:"_setPosition",value:function(){var e=this.settings.parent,t=this.domElement;e!==t.parentNode&&e.appendChild(t),this._ifPopup(function(r){getComputedStyle(e).position==="static"&&(e.style.position="relative");var i=r===!0?"popup_right":"popup_"+r;["popup_top","popup_bottom","popup_left","popup_right"].forEach(function(o){o===i?t.classList.add(o):t.classList.remove(o)}),t.classList.add(i)})}},{key:"_setHSLA",value:function(e,t,r,i,o){o=o||{};var c=this.colour,a=c.hsla;[e,t,r,i].forEach(function(s,p){(s||s===0)&&(a[p]=s)}),c.hsla=a,this._updateUI(o),this.onChange&&!o.silent&&this.onChange(c)}},{key:"_updateUI",value:function(e){if(!this.domElement)return;e=e||{};var t=this.colour,r=t.hsla,i="hsl("+r[0]*B+", 100%, 50%)",o=t.hslString,c=t.hslaString,a=this._domH,s=this._domSL,p=this._domA,f=_(".picker_selector",a),u=_(".picker_selector",s),d=_(".picker_selector",p);function b(M,S,C){S.style.left=C*100+"%"}function m(M,S,C){S.style.top=C*100+"%"}b(a,f,r[0]),this._domSL.style.backgroundColor=this._domH.style.color=i,b(s,u,r[1]),m(s,u,1-r[2]),s.style.color=o,m(p,d,1-r[3]);var h=o,v=h.replace("hsl","hsla").replace(")",", 0)"),g="linear-gradient("+[h,v]+")";if(this._domA.style.background=g+", "+U,!e.fromEditor){var E=this.settings.editorFormat,k=this.settings.alpha,w=void 0;switch(E){case"rgb":w=t.printRGB(k);break;case"hsl":w=t.printHSL(k);break;default:w=t.printHex(k)}this._domEdit.value=w}this._domSample.style.color=c}},{key:"_ifPopup",value:function(e,t){this.settings.parent&&this.settings.popup?e&&e(this.settings.popup):t&&t()}},{key:"_toggleDOM",value:function(e){var t=this.domElement;if(!t)return!1;var r=e?"":"none",i=t.style.display!==r;return i&&(t.style.display=r),i}}]),l}();{var D=document.createElement("style");D.textContent='.picker_wrapper.no_alpha .picker_alpha{display:none}.picker_wrapper.no_editor .picker_editor{position:absolute;z-index:-1;opacity:0}.picker_wrapper.no_cancel .picker_cancel{display:none}.layout_default.picker_wrapper{display:flex;flex-flow:row wrap;justify-content:space-between;align-items:stretch;font-size:10px;width:25em;padding:.5em}.layout_default.picker_wrapper input,.layout_default.picker_wrapper button{font-size:1rem}.layout_default.picker_wrapper>*{margin:.5em}.layout_default.picker_wrapper::before{content:"";display:block;width:100%;height:0;order:1}.layout_default .picker_slider,.layout_default .picker_selector{padding:1em}.layout_default .picker_hue{width:100%}.layout_default .picker_sl{flex:1 1 auto}.layout_default .picker_sl::before{content:"";display:block;padding-bottom:100%}.layout_default .picker_editor{order:1;width:6.5rem}.layout_default .picker_editor input{width:100%;height:100%}.layout_default .picker_sample{order:1;flex:1 1 auto}.layout_default .picker_done,.layout_default .picker_cancel{order:1}.picker_wrapper{box-sizing:border-box;background:#f2f2f2;box-shadow:0 0 0 1px silver;cursor:default;font-family:sans-serif;color:#444;pointer-events:auto}.picker_wrapper:focus{outline:none}.picker_wrapper button,.picker_wrapper input{box-sizing:border-box;border:none;box-shadow:0 0 0 1px silver;outline:none}.picker_wrapper button:focus,.picker_wrapper button:active,.picker_wrapper input:focus,.picker_wrapper input:active{box-shadow:0 0 2px 1px #1e90ff}.picker_wrapper button{padding:.4em .6em;cursor:pointer;background-color:#f5f5f5;background-image:linear-gradient(0deg, gainsboro, transparent)}.picker_wrapper button:active{background-image:linear-gradient(0deg, transparent, gainsboro)}.picker_wrapper button:hover{background-color:#fff}.picker_selector{position:absolute;z-index:1;display:block;-webkit-transform:translate(-50%, -50%);transform:translate(-50%, -50%);border:2px solid #fff;border-radius:100%;box-shadow:0 0 3px 1px #67b9ff;background:currentColor;cursor:pointer}.picker_slider .picker_selector{border-radius:2px}.picker_hue{position:relative;background-image:linear-gradient(90deg, red, yellow, lime, cyan, blue, magenta, red);box-shadow:0 0 0 1px silver}.picker_sl{position:relative;box-shadow:0 0 0 1px silver;background-image:linear-gradient(180deg, white, rgba(255, 255, 255, 0) 50%),linear-gradient(0deg, black, rgba(0, 0, 0, 0) 50%),linear-gradient(90deg, #808080, rgba(128, 128, 128, 0))}.picker_alpha,.picker_sample{position:relative;background:linear-gradient(45deg, lightgrey 25%, transparent 25%, transparent 75%, lightgrey 75%) 0 0/2em 2em,linear-gradient(45deg, lightgrey 25%, white 25%, white 75%, lightgrey 75%) 1em 1em/2em 2em;box-shadow:0 0 0 1px silver}.picker_alpha .picker_selector,.picker_sample .picker_selector{background:none}.picker_editor input{font-family:monospace;padding:.2em .4em}.picker_sample::before{content:"";position:absolute;display:block;width:100%;height:100%;background:currentColor}.picker_arrow{position:absolute;z-index:-1}.picker_wrapper.popup{position:absolute;z-index:2;margin:1.5em}.picker_wrapper.popup,.picker_wrapper.popup .picker_arrow::before,.picker_wrapper.popup .picker_arrow::after{background:#f2f2f2;box-shadow:0 0 10px 1px rgba(0,0,0,.4)}.picker_wrapper.popup .picker_arrow{width:3em;height:3em;margin:0}.picker_wrapper.popup .picker_arrow::before,.picker_wrapper.popup .picker_arrow::after{content:"";display:block;position:absolute;top:0;left:0;z-index:-99}.picker_wrapper.popup .picker_arrow::before{width:100%;height:100%;-webkit-transform:skew(45deg);transform:skew(45deg);-webkit-transform-origin:0 100%;transform-origin:0 100%}.picker_wrapper.popup .picker_arrow::after{width:150%;height:150%;box-shadow:none}.popup.popup_top{bottom:100%;left:0}.popup.popup_top .picker_arrow{bottom:0;left:0;-webkit-transform:rotate(-90deg);transform:rotate(-90deg)}.popup.popup_bottom{top:100%;left:0}.popup.popup_bottom .picker_arrow{top:0;left:0;-webkit-transform:rotate(90deg) scale(1, -1);transform:rotate(90deg) scale(1, -1)}.popup.popup_left{top:0;right:100%}.popup.popup_left .picker_arrow{top:0;right:0;-webkit-transform:scale(-1, 1);transform:scale(-1, 1)}.popup.popup_right{top:0;left:100%}.popup.popup_right .picker_arrow{top:0;left:0}',document.documentElement.firstElementChild.appendChild(D),K.StyleElement=D}export{K as default};
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
<!doctype html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="UTF-8" />
|
|
5
|
+
<link rel="icon" type="image/svg+xml" href="./vite.svg" />
|
|
6
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
7
|
+
<title>Vite + Svelte + TS</title>
|
|
8
|
+
<script type="module" crossorigin src="./assets/index-yFos5qg5.js"></script>
|
|
9
|
+
<link rel="stylesheet" crossorigin href="./assets/index-Bn3cFRn4.css">
|
|
10
|
+
</head>
|
|
11
|
+
<body>
|
|
12
|
+
<div id="app"></div>
|
|
13
|
+
</body>
|
|
14
|
+
</html>
|
package/public/vite.svg
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" class="iconify iconify--logos" width="31.88" height="32" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 257"><defs><linearGradient id="IconifyId1813088fe1fbc01fb466" x1="-.828%" x2="57.636%" y1="7.652%" y2="78.411%"><stop offset="0%" stop-color="#41D1FF"></stop><stop offset="100%" stop-color="#BD34FE"></stop></linearGradient><linearGradient id="IconifyId1813088fe1fbc01fb467" x1="43.376%" x2="50.316%" y1="2.242%" y2="89.03%"><stop offset="0%" stop-color="#FFEA83"></stop><stop offset="8.333%" stop-color="#FFDD35"></stop><stop offset="100%" stop-color="#FFA800"></stop></linearGradient></defs><path fill="url(#IconifyId1813088fe1fbc01fb466)" d="M255.153 37.938L134.897 252.976c-2.483 4.44-8.862 4.466-11.382.048L.875 37.958c-2.746-4.814 1.371-10.646 6.827-9.67l120.385 21.517a6.537 6.537 0 0 0 2.322-.004l117.867-21.483c5.438-.991 9.574 4.796 6.877 9.62Z"></path><path fill="url(#IconifyId1813088fe1fbc01fb467)" d="M185.432.063L96.44 17.501a3.268 3.268 0 0 0-2.634 3.014l-5.474 92.456a3.268 3.268 0 0 0 3.997 3.378l24.777-5.718c2.318-.535 4.413 1.507 3.936 3.838l-7.361 36.047c-.495 2.426 1.782 4.5 4.151 3.78l15.304-4.649c2.372-.72 4.652 1.36 4.15 3.788l-11.698 56.621c-.732 3.542 3.979 5.473 5.943 2.437l1.313-2.028l72.516-144.72c1.215-2.423-.88-5.186-3.54-4.672l-25.505 4.922c-2.396.462-4.435-1.77-3.759-4.114l16.646-57.705c.677-2.35-1.37-4.583-3.769-4.113Z"></path></svg>
|
package/src/server.ts
ADDED
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
import { LOCAL_PREFIX } from "./uiServer/constant"
|
|
2
|
+
import { Rule } from "./types/rule"
|
|
3
|
+
|
|
4
|
+
function parseQuery(queryString: string): Record<string, string> {
|
|
5
|
+
const params: Record<string, string> = {};
|
|
6
|
+
// 移除开头的 ? 号(如果存在)
|
|
7
|
+
const query = queryString.startsWith('?') ? queryString.substring(1) : queryString;
|
|
8
|
+
|
|
9
|
+
// 分割参数对并解析
|
|
10
|
+
query.split('&').forEach(item => {
|
|
11
|
+
const [key, value] = item.split('=');
|
|
12
|
+
if (key && value) {
|
|
13
|
+
params[decodeURIComponent(key)] = decodeURIComponent(value);
|
|
14
|
+
}
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
return params;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
function getBody(req: Whistle.PluginServerRequest): Promise<Record<string, string>> {
|
|
21
|
+
return new Promise((resolve) => {
|
|
22
|
+
req.getReqSession((session) => {
|
|
23
|
+
// @ts-ignore
|
|
24
|
+
resolve(JSON.parse(session.req.body))
|
|
25
|
+
});
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
function handleAndMode({conditions, payload, res}: {
|
|
30
|
+
conditions: Rule['config']['conditions'],
|
|
31
|
+
payload: Record<string, string>,
|
|
32
|
+
res: Whistle.PluginServerResponse
|
|
33
|
+
}) {
|
|
34
|
+
const isMatch = conditions.every((condition) => {
|
|
35
|
+
const { key, value } = condition
|
|
36
|
+
return payload[key] && payload[key] === value
|
|
37
|
+
})
|
|
38
|
+
|
|
39
|
+
if (!isMatch) {
|
|
40
|
+
return true
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
res.setHeader('whistle-plugin', 'whistle.interceptors');
|
|
44
|
+
res.setHeader('Content-Type', 'application/json; charset=UTF-8');
|
|
45
|
+
res.end(conditions[0].response)
|
|
46
|
+
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
function handleOrMode({conditions, payload, res}: {
|
|
50
|
+
conditions: Rule['config']['conditions'],
|
|
51
|
+
payload: Record<string, string>,
|
|
52
|
+
res: Whistle.PluginServerResponse
|
|
53
|
+
}) {
|
|
54
|
+
const matchingCondition = conditions.find(
|
|
55
|
+
({ key, value }) => payload[key] === value
|
|
56
|
+
);
|
|
57
|
+
|
|
58
|
+
if (!matchingCondition) {
|
|
59
|
+
return true
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
res.setHeader('whistle-plugin', 'whistle.interceptors');
|
|
63
|
+
res.setHeader('Content-Type', 'application/json; charset=UTF-8');
|
|
64
|
+
res.end(matchingCondition.response);
|
|
65
|
+
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
function handleMatchMode({matchType, conditions, payload, res, req}: {
|
|
69
|
+
matchType: 'and' | 'or',
|
|
70
|
+
conditions: Rule['config']['conditions'],
|
|
71
|
+
payload: Record<string, string>,
|
|
72
|
+
res: Whistle.PluginServerResponse,
|
|
73
|
+
req: Whistle.PluginServerRequest
|
|
74
|
+
}) {
|
|
75
|
+
const map = {
|
|
76
|
+
'and': handleAndMode,
|
|
77
|
+
'or': handleOrMode
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
const noMatch = map[matchType]({
|
|
81
|
+
conditions,
|
|
82
|
+
payload,
|
|
83
|
+
res
|
|
84
|
+
})
|
|
85
|
+
|
|
86
|
+
if (noMatch) {
|
|
87
|
+
req.passThrough();
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
export default (server: Whistle.PluginServer, options: Whistle.PluginOptions) => {
|
|
93
|
+
server.on('request', async (req: Whistle.PluginServerRequest, res: Whistle.PluginServerResponse) => {
|
|
94
|
+
|
|
95
|
+
try {
|
|
96
|
+
|
|
97
|
+
const id = req.originalReq.ruleValue
|
|
98
|
+
const rules: Rule[] = JSON.parse(options.storage.getProperty(LOCAL_PREFIX)) || []
|
|
99
|
+
const targetRule = rules.filter((rule: Rule) => rule.id === id)[0]
|
|
100
|
+
const { matchType, method, conditions } = targetRule.config
|
|
101
|
+
|
|
102
|
+
if (req.method !== method) {
|
|
103
|
+
req.passThrough();
|
|
104
|
+
return
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
let payLoad: Record<string, string>
|
|
108
|
+
if (method === 'POST') {
|
|
109
|
+
payLoad = await getBody(req)
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
if (method === 'GET') {
|
|
113
|
+
// @ts-ignore
|
|
114
|
+
payLoad = parseQuery(options.parseUrl(req.fullUrl).query)
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
handleMatchMode({
|
|
118
|
+
matchType,
|
|
119
|
+
conditions,
|
|
120
|
+
res,
|
|
121
|
+
req,
|
|
122
|
+
payload: payLoad
|
|
123
|
+
})
|
|
124
|
+
} catch (error) {
|
|
125
|
+
req.passThrough();
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
|
|
129
|
+
// if (matchType === "or") {
|
|
130
|
+
// const matchingCondition = conditions.find(
|
|
131
|
+
// ({ key, value }) => payLoad[key] === value
|
|
132
|
+
// );
|
|
133
|
+
// if (matchingCondition) {
|
|
134
|
+
// res.setHeader('whistle-plugin', 'whistle.interceptors');
|
|
135
|
+
// res.setHeader('Content-Type', 'application/json; charset=UTF-8');
|
|
136
|
+
// res.end(matchingCondition.response);
|
|
137
|
+
// return;
|
|
138
|
+
// }
|
|
139
|
+
// }
|
|
140
|
+
// if (matchType === 'and') {
|
|
141
|
+
// const isMatch = conditions.every((condition) => {
|
|
142
|
+
// const { key, value } = condition
|
|
143
|
+
// return payLoad[key] && payLoad[key] === value
|
|
144
|
+
// })
|
|
145
|
+
// if (isMatch) {
|
|
146
|
+
// res.setHeader('whistle-plugin', 'whistle.interceptors');
|
|
147
|
+
// res.setHeader('Content-Type', 'application/json; charset=UTF-8');
|
|
148
|
+
// res.end(conditions[0].response)
|
|
149
|
+
// return
|
|
150
|
+
// }
|
|
151
|
+
// }
|
|
152
|
+
|
|
153
|
+
});
|
|
154
|
+
|
|
155
|
+
// handle websocket request
|
|
156
|
+
server.on('upgrade', (req: Whistle.PluginServerRequest, socket: Whistle.PluginServerSocket) => {
|
|
157
|
+
// do something
|
|
158
|
+
req.passThrough();
|
|
159
|
+
});
|
|
160
|
+
|
|
161
|
+
// handle tunnel request
|
|
162
|
+
server.on('connect', (req: Whistle.PluginServerRequest, socket: Whistle.PluginServerSocket) => {
|
|
163
|
+
// do something
|
|
164
|
+
req.passThrough();
|
|
165
|
+
});
|
|
166
|
+
};
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/// <reference types="node" />
|
|
2
|
+
|
|
3
|
+
import { IncomingMessage, ServerResponse, Server } from 'http';
|
|
4
|
+
import { ParsedUrlQuery } from 'querystring';
|
|
5
|
+
import { Socket } from 'net';
|
|
6
|
+
|
|
7
|
+
declare global {
|
|
8
|
+
namespace WhistleBase {
|
|
9
|
+
class Request extends IncomingMessage {}
|
|
10
|
+
class Response extends ServerResponse {}
|
|
11
|
+
class HttpServer extends Server {}
|
|
12
|
+
class Socks extends Socket {}
|
|
13
|
+
type UrlQuery = ParsedUrlQuery;
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
|
|
@@ -0,0 +1,378 @@
|
|
|
1
|
+
/* eslint-disable @typescript-eslint/triple-slash-reference, @typescript-eslint/naming-convention */
|
|
2
|
+
|
|
3
|
+
/// <reference path="base.d.ts" />
|
|
4
|
+
|
|
5
|
+
declare module 'koa-onerror';
|
|
6
|
+
|
|
7
|
+
declare namespace Whistle {
|
|
8
|
+
type Body = string | false;
|
|
9
|
+
|
|
10
|
+
interface LRUOptions<K = any, V = any> {
|
|
11
|
+
max?: number;
|
|
12
|
+
maxAge?: number;
|
|
13
|
+
length?(value: V, key?: K): number;
|
|
14
|
+
dispose?(key: K, value: V): void;
|
|
15
|
+
stale?: boolean;
|
|
16
|
+
noDisposeOnSet?: boolean;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
interface LRUEntry<K, V> {
|
|
20
|
+
k: K;
|
|
21
|
+
v: V;
|
|
22
|
+
e: number;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
interface LRUCache<K = any, V = any> {
|
|
26
|
+
new (options?: LRUOptions<K, V>): this;
|
|
27
|
+
readonly length: number;
|
|
28
|
+
readonly itemCount: number;
|
|
29
|
+
allowStale: boolean;
|
|
30
|
+
lengthCalculator(value: V): number;
|
|
31
|
+
max: number;
|
|
32
|
+
maxAge: number;
|
|
33
|
+
set(key: K, value: V, maxAge?: number): boolean;
|
|
34
|
+
get(key: K): V;
|
|
35
|
+
peek(key: K): V;
|
|
36
|
+
has(key: K): boolean;
|
|
37
|
+
del(key: K): void;
|
|
38
|
+
reset(): void;
|
|
39
|
+
prune(): void;
|
|
40
|
+
forEach<T = this>(callbackFn: (this: T, value: V, key: K, cache: this) => void, thisArg?: T): void;
|
|
41
|
+
rforEach<T = this>(callbackFn: (this: T, value: V, key: K, cache: this) => void, thisArg?: T): void;
|
|
42
|
+
keys(): K[];
|
|
43
|
+
values(): V[];
|
|
44
|
+
dump(): Array<LRUEntry<K, V>>;
|
|
45
|
+
load(cacheEntries: ReadonlyArray<LRUEntry<K, V>>): void;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
interface Frame {
|
|
49
|
+
reqId: string;
|
|
50
|
+
frameId: string;
|
|
51
|
+
base64?: string;
|
|
52
|
+
bin?: '' | Buffer;
|
|
53
|
+
text?: string;
|
|
54
|
+
mask?: boolean;
|
|
55
|
+
compressed?: boolean;
|
|
56
|
+
length?: number;
|
|
57
|
+
opcode?: number;
|
|
58
|
+
isClient?: boolean;
|
|
59
|
+
err?: string;
|
|
60
|
+
closed?: true;
|
|
61
|
+
code?: string | number;
|
|
62
|
+
[propName: string]: any;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
interface Session {
|
|
66
|
+
id: string;
|
|
67
|
+
url: string;
|
|
68
|
+
useH2?: boolean;
|
|
69
|
+
isHttps?: boolean;
|
|
70
|
+
startTime: number;
|
|
71
|
+
dnsTime?: number;
|
|
72
|
+
requestTime: number;
|
|
73
|
+
responseTime: number;
|
|
74
|
+
endTime?: number;
|
|
75
|
+
req: {
|
|
76
|
+
method?: string;
|
|
77
|
+
httpVersion?: string;
|
|
78
|
+
ip?: string;
|
|
79
|
+
port?: string | number;
|
|
80
|
+
rawHeaderNames?: object;
|
|
81
|
+
headers: object;
|
|
82
|
+
size?: number;
|
|
83
|
+
body?: Body;
|
|
84
|
+
base64?: Body;
|
|
85
|
+
rawHeaders?: object;
|
|
86
|
+
[propName: string]: any;
|
|
87
|
+
};
|
|
88
|
+
res: {
|
|
89
|
+
ip?: string;
|
|
90
|
+
port?: string | number;
|
|
91
|
+
rawHeaderNames?: object;
|
|
92
|
+
statusCode?: number | string;
|
|
93
|
+
statusMessage?: string;
|
|
94
|
+
headers?: object;
|
|
95
|
+
size?: number;
|
|
96
|
+
body?: Body;
|
|
97
|
+
base64?: Body;
|
|
98
|
+
rawHeaders?: object;
|
|
99
|
+
[propName: string]: any;
|
|
100
|
+
};
|
|
101
|
+
rules: object;
|
|
102
|
+
rulesHeaders?: object;
|
|
103
|
+
frames?: Frame[];
|
|
104
|
+
[propName: string]: any;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
interface File {
|
|
108
|
+
index: number;
|
|
109
|
+
name: string;
|
|
110
|
+
data: string;
|
|
111
|
+
selected: boolean;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
interface Storage {
|
|
115
|
+
new (dir: string, filters?: object, disabled?: boolean): this;
|
|
116
|
+
count(): number;
|
|
117
|
+
existsFile(file: string): false | File;
|
|
118
|
+
getFileList(origin: boolean): File[];
|
|
119
|
+
writeFile(file: string, data: string): boolean;
|
|
120
|
+
updateFile(file: string, data: string): boolean;
|
|
121
|
+
readFile(file: string): string;
|
|
122
|
+
removeFile(file: string): boolean;
|
|
123
|
+
renameFile(file: string, newFile: string): boolean;
|
|
124
|
+
moveTo(fromName: string, toName: string): boolean;
|
|
125
|
+
setProperty(name: string, value: string): void;
|
|
126
|
+
hasProperty(file: string): boolean;
|
|
127
|
+
setProperties(obj: object): boolean;
|
|
128
|
+
getProperty(name: string): any;
|
|
129
|
+
removeProperty(name: string): void;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
interface SharedStorage {
|
|
133
|
+
getAll: () => Promise<any>;
|
|
134
|
+
setItem: (key: any, value?: any) => Promise<any>;
|
|
135
|
+
getItem: (key: string) => any;
|
|
136
|
+
removeItem: (key: string) => any;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
interface PluginOptions {
|
|
140
|
+
name: string;
|
|
141
|
+
version: string;
|
|
142
|
+
debugMode?: boolean;
|
|
143
|
+
CUSTOM_CERT_HEADER: string;
|
|
144
|
+
ENABLE_CAPTURE_HEADER: string;
|
|
145
|
+
RULE_VALUE_HEADER: string;
|
|
146
|
+
RULE_PROTO_HEADER: string;
|
|
147
|
+
SNI_VALUE_HEADER: string;
|
|
148
|
+
RULE_URL_HEADER: string;
|
|
149
|
+
MAX_AGE_HEADER: string;
|
|
150
|
+
ETAG_HEADER: string;
|
|
151
|
+
FULL_URL_HEADER: string;
|
|
152
|
+
REAL_URL_HEADER: string;
|
|
153
|
+
RELATIVE_URL_HEADER: string;
|
|
154
|
+
REQ_ID_HEADER: string;
|
|
155
|
+
PIPE_VALUE_HEADER: string;
|
|
156
|
+
CUSTOM_PARSER_HEADER: string;
|
|
157
|
+
STATUS_CODE_HEADER: string;
|
|
158
|
+
PLUGIN_REQUEST_HEADER: string;
|
|
159
|
+
LOCAL_HOST_HEADER: string;
|
|
160
|
+
HOST_VALUE_HEADER: string;
|
|
161
|
+
PROXY_VALUE_HEADER: string;
|
|
162
|
+
PAC_VALUE_HEADER: string;
|
|
163
|
+
METHOD_HEADER: string;
|
|
164
|
+
CLIENT_IP_HEADER: string;
|
|
165
|
+
CLIENT_PORT_HEAD: string;
|
|
166
|
+
UI_REQUEST_HEADER: string;
|
|
167
|
+
GLOBAL_VALUE_HEAD: string;
|
|
168
|
+
SERVER_NAME_HEAD: string;
|
|
169
|
+
COMMON_NAME_HEAD: string;
|
|
170
|
+
CERT_CACHE_INFO: string;
|
|
171
|
+
HOST_IP_HEADER: string;
|
|
172
|
+
REQ_FROM_HEADER: string;
|
|
173
|
+
config: {
|
|
174
|
+
name: string;
|
|
175
|
+
version: string;
|
|
176
|
+
localUIHost: string;
|
|
177
|
+
port: number;
|
|
178
|
+
sockets: number;
|
|
179
|
+
timeout: number;
|
|
180
|
+
baseDir: string;
|
|
181
|
+
uiport: number;
|
|
182
|
+
clientId: string;
|
|
183
|
+
uiHostList: string[];
|
|
184
|
+
pluginHosts: object;
|
|
185
|
+
host: string;
|
|
186
|
+
[propName: string]: any;
|
|
187
|
+
};
|
|
188
|
+
parseUrl(url: string): WhistleBase.UrlQuery;
|
|
189
|
+
wsParser: {
|
|
190
|
+
getExtensions(res: any, isServer?: boolean): any;
|
|
191
|
+
getSender(socket: any, toServer?: boolean): any;
|
|
192
|
+
getReceiver(res: any, fromServer?: boolean, maxPayload?: number): any;
|
|
193
|
+
};
|
|
194
|
+
wrapWsReader(socket?: any, maxPayload?: number): any;
|
|
195
|
+
wrapWsWriter(socket?: any): any;
|
|
196
|
+
shortName: string;
|
|
197
|
+
Storage: Storage;
|
|
198
|
+
localStorage: Storage;
|
|
199
|
+
storage: Storage;
|
|
200
|
+
sharedStorage: SharedStorage;
|
|
201
|
+
baseUrl: string;
|
|
202
|
+
LRU: LRUCache;
|
|
203
|
+
getValue(key: string, cb: (value: string) => void): void;
|
|
204
|
+
getCert(domain: string, cb: (cert: any) => void): void;
|
|
205
|
+
getRootCA(cb: (cert: any) => void): void;
|
|
206
|
+
getHttpsStatus(cb: (status: any) => void): void;
|
|
207
|
+
getRuntimeInfo(cb: (info: any) => void): void;
|
|
208
|
+
updateRules(): void;
|
|
209
|
+
compose(options: any, cb: (err: any, data?: any) => void): void;
|
|
210
|
+
getRules(cb: (rules: any, outputArray?: boolean) => void): void;
|
|
211
|
+
getValues(cb: (values: any, outputArray?: boolean) => void): void;
|
|
212
|
+
getPlugins(cb: (plugins: any) => void): void;
|
|
213
|
+
getCustomCertsInfo(cb: (certs: any) => void): void;
|
|
214
|
+
isActive(cb: (active: boolean) => void): void;
|
|
215
|
+
ctx: any;
|
|
216
|
+
connect(opts: any, cb?: Function): any;
|
|
217
|
+
request(opts: any, cb?: Function): any;
|
|
218
|
+
generateSaz(sessions: Session[]): Buffer;
|
|
219
|
+
extractSaz(saz: Buffer, cb: (sessions: Session[]) => void): void;
|
|
220
|
+
getTempFilePath(ruleValue: string): string | undefined;
|
|
221
|
+
[propName: string]: any;
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
type GetSession = (cb: (session: Session | '') => void) => void;
|
|
225
|
+
type GetFrame = (cb: (Frames: Frame[] | '') => void) => void;
|
|
226
|
+
type SetRules = (rules: string) => boolean;
|
|
227
|
+
interface PluginDecoder {
|
|
228
|
+
getBuffer: (cb: (err: any, buf?: Buffer | null) => void) => void;
|
|
229
|
+
getText: (cb: (err: any, text?: string) => void, encoding?: string) => void;
|
|
230
|
+
getJson: (cb: (err: any, json?: any) => void, encoding?: string) => void;
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
type PluginReqCtx = PluginDecoder & PluginRequest;
|
|
234
|
+
type PluginResCtx = PluginDecoder & WhistleBase.Request;
|
|
235
|
+
type PluginNextResult = {
|
|
236
|
+
rules?: string | null | undefined;
|
|
237
|
+
body?: any;
|
|
238
|
+
};
|
|
239
|
+
type PluginReqHandler = (buffer: Buffer | null, next: (result?: PluginNextResult) => void, ctx?: PluginReqCtx) => void;
|
|
240
|
+
type PluginResHandler = (buffer: Buffer | null, next: (result?: PluginNextResult) => void, ctx?: PluginResCtx) => void;
|
|
241
|
+
type PassThroughReq = PluginReqHandler | { [key: string]: any } | string | null | undefined;
|
|
242
|
+
type PassThroughRes = PluginResHandler | { [key: string]: any } | null | undefined;
|
|
243
|
+
type PassThrough = (uri?: PassThroughReq, trailers?: PassThroughRes) => void;
|
|
244
|
+
|
|
245
|
+
interface WriteHead {
|
|
246
|
+
(code: string | number, msg?: string, headers?: any): void;
|
|
247
|
+
(code: string | number, headers?: any): void;
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
interface RequestFn {
|
|
251
|
+
(uri: any, cb?: (res: any) => void, opts?: any): any;
|
|
252
|
+
(uri: any, opts?: any, cb?: (res: any) => void): any;
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
class PluginRequest extends WhistleBase.Request {
|
|
256
|
+
clientIp: string;
|
|
257
|
+
fullUrl: string;
|
|
258
|
+
isHttps: boolean;
|
|
259
|
+
fromTunnel: boolean;
|
|
260
|
+
fromComposer: boolean;
|
|
261
|
+
isHttpsServer?: boolean;
|
|
262
|
+
getReqSession: GetSession;
|
|
263
|
+
getSession: GetSession;
|
|
264
|
+
getFrames: GetFrame;
|
|
265
|
+
Storage: Storage;
|
|
266
|
+
localStorage: Storage;
|
|
267
|
+
sharedStorage: SharedStorage;
|
|
268
|
+
sessionStorage: {
|
|
269
|
+
set(key: string, value: any): any;
|
|
270
|
+
get(key: string): any;
|
|
271
|
+
remove(key: string): any;
|
|
272
|
+
};
|
|
273
|
+
originalReq: {
|
|
274
|
+
id: string;
|
|
275
|
+
clientIp: string;
|
|
276
|
+
isH2: boolean;
|
|
277
|
+
existsCustomCert: boolean;
|
|
278
|
+
isUIRequest: boolean;
|
|
279
|
+
enableCapture: boolean;
|
|
280
|
+
isFromPlugin: boolean;
|
|
281
|
+
ruleValue: string;
|
|
282
|
+
ruleUrl: string;
|
|
283
|
+
pipeValue: string;
|
|
284
|
+
sniValue: string;
|
|
285
|
+
hostValue: string;
|
|
286
|
+
fullUrl: string;
|
|
287
|
+
url: string;
|
|
288
|
+
isHttps: boolean;
|
|
289
|
+
remoteAddress: string;
|
|
290
|
+
remotePort: number;
|
|
291
|
+
fromTunnel: boolean;
|
|
292
|
+
fromComposer: boolean;
|
|
293
|
+
servername: string;
|
|
294
|
+
certCacheName: string;
|
|
295
|
+
certCacheTime: number;
|
|
296
|
+
isSNI: boolean;
|
|
297
|
+
commonName: string;
|
|
298
|
+
realUrl: string;
|
|
299
|
+
relativeUrl: string;
|
|
300
|
+
extraUrl: string;
|
|
301
|
+
method: string;
|
|
302
|
+
clientPort: string;
|
|
303
|
+
globalValue: string;
|
|
304
|
+
proxyValue: string;
|
|
305
|
+
pacValue: string;
|
|
306
|
+
pluginVars: string[];
|
|
307
|
+
globalPluginVars: string[];
|
|
308
|
+
headers: any;
|
|
309
|
+
isRexExp?: boolean;
|
|
310
|
+
pattern?: string;
|
|
311
|
+
customParser?: boolean | '';
|
|
312
|
+
};
|
|
313
|
+
originalRes: {
|
|
314
|
+
serverIp: string;
|
|
315
|
+
statusCode: string;
|
|
316
|
+
};
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
type PluginResponse = WhistleBase.Response;
|
|
320
|
+
type PluginSocket = WhistleBase.Socks;
|
|
321
|
+
type PluginServer = WhistleBase.HttpServer;
|
|
322
|
+
class PluginServerRequest extends PluginRequest {
|
|
323
|
+
setReqRules: SetRules;
|
|
324
|
+
setResRules: SetRules;
|
|
325
|
+
writeHead: WriteHead;
|
|
326
|
+
request: RequestFn;
|
|
327
|
+
connect: RequestFn;
|
|
328
|
+
passThrough: PassThrough;
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
class PluginServerResponse extends WhistleBase.Response {
|
|
332
|
+
setReqRules: SetRules;
|
|
333
|
+
setResRules: SetRules;
|
|
334
|
+
disableTrailers?: boolean;
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
class PluginServerSocket extends WhistleBase.Socks {
|
|
338
|
+
setReqRules: SetRules;
|
|
339
|
+
setResRules: SetRules;
|
|
340
|
+
disableTrailers?: boolean;
|
|
341
|
+
}
|
|
342
|
+
class PluginUIRequest extends WhistleBase.Request {
|
|
343
|
+
clientIp: string;
|
|
344
|
+
Storage: Storage;
|
|
345
|
+
localStorage: Storage;
|
|
346
|
+
sharedStorage: SharedStorage;
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
type PluginUIResponse = WhistleBase.Response;
|
|
350
|
+
|
|
351
|
+
class PluginAuthRequest extends PluginRequest {
|
|
352
|
+
isUIRequest: boolean;
|
|
353
|
+
setHtml(html: string): void;
|
|
354
|
+
setUrl(url: string): void;
|
|
355
|
+
setFile(url: string): void;
|
|
356
|
+
setHeader(key: string, value: string): void;
|
|
357
|
+
set(key: string, value: string): void;
|
|
358
|
+
setRedirect(url: string): void;
|
|
359
|
+
setLogin(login: boolean): void;
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
class PluginSNIRequest extends PluginRequest {
|
|
363
|
+
isSNI: boolean;
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
type PluginSNIResult = boolean | {
|
|
367
|
+
key: string;
|
|
368
|
+
cert: string;
|
|
369
|
+
mtime?: number;
|
|
370
|
+
};
|
|
371
|
+
|
|
372
|
+
type Result<T> = T | Promise<T>;
|
|
373
|
+
|
|
374
|
+
type PluginAuthHook = (req: PluginAuthRequest, options?: PluginOptions) => Result<boolean>;
|
|
375
|
+
type PluginSNIHook = (req: PluginSNIRequest, options?: PluginOptions) => Result<PluginSNIResult>;
|
|
376
|
+
type PluginHook = (server: PluginServer, options?: PluginOptions) => Result<void>;
|
|
377
|
+
type PluginUIHook = (server: PluginServer, options?: PluginOptions) => Result<void>;
|
|
378
|
+
}
|