whistle.interceptors 0.0.2 → 0.0.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.
@@ -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-ZlpNVKm2.js"></script>
9
+ <link rel="stylesheet" crossorigin href="./assets/index-BWNZu5u4.css">
10
+ </head>
11
+ <body>
12
+ <div id="app"></div>
13
+ </body>
14
+ </html>
@@ -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,175 @@
1
+ import { LOCAL_PREFIX, PROXY_MODE } 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, req, options, extra}: {
30
+ conditions: Rule['config']['conditions'],
31
+ payload: Record<string, string>,
32
+ res: Whistle.PluginServerResponse,
33
+ req: Whistle.PluginServerRequest,
34
+ options: Whistle.PluginOptions,
35
+ extra: {
36
+ origin: string
37
+ }
38
+ }) {
39
+ const isMatch = conditions.every((condition) => {
40
+ const { key, value, enabled } = condition
41
+ return enabled && payload[key] && payload[key] === value
42
+ })
43
+
44
+ if (!isMatch) {
45
+ return true
46
+ }
47
+
48
+ res.setHeader('whistle-plugin', 'whistle.interceptors');
49
+ res.setHeader('Content-Type', 'application/json; charset=UTF-8');
50
+ res.setHeader('Access-Control-Allow-Origin', extra.origin);
51
+ res.setHeader('Access-Control-Allow-Credentials', 'true');
52
+ res.setHeader('Access-Control-Allow-Headers', 'Content-Type, Authorization, X-Requested-With')
53
+ res.setHeader('Access-Control-Allow-Methods', 'POST,GET,OPTIONS,PUT,DELETE,HEAD')
54
+ res.end(conditions[0].response)
55
+
56
+ }
57
+
58
+ function handleOrMode({conditions, payload, res, req, options, extra}: {
59
+ conditions: Rule['config']['conditions'],
60
+ payload: Record<string, string>,
61
+ res: Whistle.PluginServerResponse,
62
+ req: Whistle.PluginServerRequest,
63
+ options:Whistle.PluginOptions,
64
+ extra: {
65
+ origin: string
66
+ }
67
+ }) {
68
+ const matchingCondition = conditions.find(
69
+ ({ key, value, enabled }) => enabled && payload[key] === value
70
+ );
71
+ console.log('matchCondition', matchingCondition)
72
+ if (!matchingCondition) {
73
+ return true
74
+ }
75
+
76
+ if (matchingCondition.proxyMode === PROXY_MODE.NETWORK) {
77
+ req.getSession(session => {
78
+ // @ts-ignore
79
+ console.log('返回内容', session.res.body)
80
+ // @ts-ignore
81
+ options.localStorage.setProperty(`${LOCAL_PREFIX}_${matchingCondition.ruleId}_${matchingCondition.key}_${matchingCondition.value}`, session.res.body)
82
+ })
83
+ return true
84
+ } else {
85
+ res.setHeader('whistle-plugin', 'whistle.interceptors');
86
+ res.setHeader('Content-Type', 'application/json; charset=UTF-8');
87
+ res.setHeader('Access-Control-Allow-Origin', extra.origin);
88
+ res.setHeader('Access-Control-Allow-Credentials', 'true');
89
+ res.setHeader('Access-Control-Allow-Headers', 'Content-Type, Authorization, X-Requested-With')
90
+ res.setHeader('Access-Control-Allow-Methods', 'POST,GET,OPTIONS,PUT,DELETE,HEAD')
91
+ res.end(matchingCondition.response);
92
+ }
93
+ }
94
+
95
+ function handleMatchMode({matchType, conditions, payload, res, req, options}: {
96
+ matchType: 'and' | 'or',
97
+ conditions: Rule['config']['conditions'],
98
+ payload: Record<string, string>,
99
+ res: Whistle.PluginServerResponse,
100
+ req: Whistle.PluginServerRequest
101
+ options: Whistle.PluginOptions
102
+ }) {
103
+ const map = {
104
+ 'and': handleAndMode,
105
+ 'or': handleOrMode
106
+ }
107
+
108
+ const noMatch = map[matchType]({
109
+ conditions,
110
+ payload,
111
+ res,
112
+ req,
113
+ options,
114
+ extra: {
115
+ origin: req.headers.origin
116
+ }
117
+ })
118
+
119
+ if (noMatch) {
120
+ req.passThrough();
121
+ }
122
+ }
123
+
124
+
125
+ export default (server: Whistle.PluginServer, options: Whistle.PluginOptions) => {
126
+
127
+ server.on('request', async (req: Whistle.PluginServerRequest, res: Whistle.PluginServerResponse) => {
128
+
129
+ try {
130
+
131
+ const id = req.originalReq.ruleValue
132
+ const rules: Rule[] = JSON.parse(options.storage.getProperty(LOCAL_PREFIX)) || []
133
+ const targetRule = rules.filter((rule: Rule) => rule.id === id)[0]
134
+ const { matchType, method, conditions } = targetRule.config
135
+
136
+ if (req.method !== method) {
137
+ req.passThrough();
138
+ return
139
+ }
140
+
141
+ let payLoad: Record<string, string>
142
+ if (method === 'POST') {
143
+ payLoad = await getBody(req)
144
+ }
145
+
146
+ if (method === 'GET') {
147
+ // @ts-ignore
148
+ payLoad = parseQuery(options.parseUrl(req.fullUrl).query)
149
+ }
150
+
151
+ handleMatchMode({
152
+ matchType,
153
+ conditions,
154
+ res,
155
+ req,
156
+ options,
157
+ payload: payLoad
158
+ })
159
+ } catch (error) {
160
+ req.passThrough();
161
+ }
162
+ });
163
+
164
+ // handle websocket request
165
+ server.on('upgrade', (req: Whistle.PluginServerRequest, socket: Whistle.PluginServerSocket) => {
166
+ // do something
167
+ req.passThrough();
168
+ });
169
+
170
+ // handle tunnel request
171
+ server.on('connect', (req: Whistle.PluginServerRequest, socket: Whistle.PluginServerSocket) => {
172
+ // do something
173
+ req.passThrough();
174
+ });
175
+ };
@@ -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
+ }
@@ -0,0 +1,17 @@
1
+ export interface Rule {
2
+ id: string;
3
+ name: string;
4
+ config: {
5
+ method: 'GET' | 'POST' | 'PUT' | 'DELETE';
6
+ matchType: 'and' | 'or';
7
+ conditions: {
8
+ ruleId: string;
9
+ key: string;
10
+ value: string;
11
+ response: string;
12
+ enabled?: boolean;
13
+ remark?: string;
14
+ proxyMode?: 'network' | 'mock';
15
+ }[];
16
+ };
17
+ }
@@ -0,0 +1,19 @@
1
+
2
+ export const LOCAL_PREFIX = 'whistle.interceptors'
3
+
4
+ // export const LOCAL
5
+
6
+ export const PROXY_MODE = {
7
+ NETWORK: 'network',
8
+ MOCK: 'mock',
9
+ }
10
+
11
+ export const apis = {
12
+ get: '/collections/query',
13
+ add: '/collections/add',
14
+ delete: '/collections/delete',
15
+ sse: '/collections/sse',
16
+ }
17
+
18
+
19
+