@chaos-maker/core 0.5.0 → 0.6.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 +47 -8
- package/dist/chaos-maker.cjs +12 -5
- package/dist/chaos-maker.js +1394 -1178
- package/dist/chaos-maker.umd.js +11 -4
- package/dist/sw.js +1 -1
- package/dist/sw.mjs +457 -401
- package/dist/types/ChaosMaker.d.ts +5 -0
- package/dist/types/format-event.d.ts +13 -0
- package/dist/types/index.d.ts +4 -1
- package/dist/types/runtime-state.d.ts +6 -0
- package/dist/types/seed-reporting.d.ts +1 -0
- package/dist/types/session-errors.d.ts +18 -0
- package/dist/types/sw-bridge-source.d.ts +3 -2
- package/package.json +1 -1
package/dist/sw.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
var ChaosMakerSW=(function(x){"use strict";var Fe=Object.defineProperty;var Ue=(x,_,F)=>_ in x?Fe(x,_,{enumerable:!0,configurable:!0,writable:!0,value:F}):x[_]=F;var D=(x,_,F)=>Ue(x,typeof _!="symbol"?_+"":_,F);class _{constructor(e=2e3){D(this,"listeners",new Map);D(this,"log",[]);D(this,"logger");D(this,"ruleIds");this.maxLogEntries=e}on(e,t){this.listeners.has(e)||this.listeners.set(e,new Set),this.listeners.get(e).add(t)}off(e,t){var o;(o=this.listeners.get(e))==null||o.delete(t)}emit(e){this.log.push(e),this.log.length>this.maxLogEntries&&this.log.shift(),this.notify(this.listeners.get(e.type),e),this.notify(this.listeners.get("*"),e)}setLogger(e){this.logger=e}setRuleIds(e){this.ruleIds=e}debug(e,t,o){var p;if(!this.logger)return;const s=o?(p=this.ruleIds)==null?void 0:p.get(o):void 0,f=s?{...t,ruleType:s.ruleType,ruleId:s.ruleId}:t,l=this.logger.log(e,f);l&&this.emit(l)}getLog(){return[...this.log]}clearLog(){this.log=[]}notify(e,t){if(e)for(const o of e)try{o(t)}catch{}}}function F(n){let e=n|0;return()=>{e=e+1831565813|0;let t=Math.imul(e^e>>>15,1|e);return t=t+Math.imul(t^t>>>7,61|t)^t,((t^t>>>14)>>>0)/4294967296}}function pe(){return Math.random()*4294967296>>>0}function ee(n){const e=n??pe();return{random:F(e),seed:e}}const z="default";class ne{constructor(){D(this,"groups",new Map);D(this,"gatedEmitted",new Set)}ensure(e,t){const o=this.groups.get(e);if(o)return t!=null&&t.explicit&&(o.explicit=!0),(t==null?void 0:t.enabled)!==void 0&&(o.enabled=t.enabled),o;const s={name:e,enabled:(t==null?void 0:t.enabled)??!0,explicit:(t==null?void 0:t.explicit)??!1};return this.groups.set(e,s),s}setEnabled(e,t){this.ensure(e).enabled=t,this.gatedEmitted.clear()}isActive(e){return this.ensure(e??z).enabled}shouldEmitGated(e){return this.gatedEmitted.has(e)?!1:(this.gatedEmitted.add(e),!0)}has(e){return this.groups.has(e)}remove(e,t,o){if(e===z)return!1;if(!(o!=null&&o.force)&&t.has(e))throw new Error(`[chaos-maker] Cannot remove group '${e}': still referenced by one or more rules. Pass { force: true } to override.`);const s=this.groups.delete(e);return s&&this.gatedEmitted.delete(e),s}list(){return[...this.groups.values()].map(e=>({...e}))}getSnapshot(){const e={};for(const t of this.groups.values())e[t.name]=t.enabled;return e}}function q(n,e){return e()<n}function P(n,e){const t=(e.get(n)??0)+1;return e.set(n,t),t}function G(n,e){return n.onNth!==void 0?e===n.onNth:n.everyNth!==void 0?e%n.everyNth===0:n.afterN!==void 0?e>n.afterN:!0}function V(n,e){return e==="*"?!0:n.includes(e)}function ge(n,e){switch(e){case"truncate":return n.slice(0,Math.max(0,Math.floor(n.length/2)));case"malformed-json":return`${n}"}`;case"empty":return"";case"wrong-type":return"<html><body>Unexpected HTML</body></html>"}}function I(n,e,t,o){if(!e||e.isActive(n.group))return!0;const s=n.group??z;return e.shouldEmitGated(s)&&t&&t.emit({type:"rule-group:gated",timestamp:Date.now(),applied:!1,detail:{...o,groupName:s}}),t==null||t.debug("rule-skip-group",{...o,groupName:s},n),!1}function he(n,e){var o,s,f,l,p,u,a,S,A,M,L,N,T,d;const t=c=>{if(c)for(const i of c)e(i)};t((o=n.network)==null?void 0:o.failures),t((s=n.network)==null?void 0:s.latencies),t((f=n.network)==null?void 0:f.aborts),t((l=n.network)==null?void 0:l.corruptions),t((p=n.network)==null?void 0:p.cors),t((u=n.ui)==null?void 0:u.assaults),t((a=n.websocket)==null?void 0:a.drops),t((S=n.websocket)==null?void 0:S.delays),t((A=n.websocket)==null?void 0:A.corruptions),t((M=n.websocket)==null?void 0:M.closes),t((L=n.sse)==null?void 0:L.drops),t((N=n.sse)==null?void 0:N.delays),t((T=n.sse)==null?void 0:T.corruptions),t((d=n.sse)==null?void 0:d.closes)}function oe(n){const e=n.replace(/#[^\r\n]*/g," "),t=/\b(?:query|mutation|subscription)\s+([A-Za-z_][A-Za-z0-9_]*)/.exec(e);return(t==null?void 0:t[1])??null}function be(n){try{return JSON.parse(n)}catch{return}}function te(n){if(!n||typeof n!="object")return{isGraphQL:!1,operationName:null};if(Array.isArray(n))return n.length===0?{isGraphQL:!1,operationName:null}:te(n[0]);const e=n,t=typeof e.query=="string",o=typeof e.operationName=="string";return!t&&!o?{isGraphQL:!1,operationName:null}:o&&e.operationName.length>0?{isGraphQL:!0,operationName:e.operationName}:t?{isGraphQL:!0,operationName:oe(e.query)}:{isGraphQL:!0,operationName:null}}function ye(n){let e;try{e=new URL(n,"http://_chaos-maker.invalid")}catch{return{kind:"not-graphql"}}const t=e.searchParams.get("operationName"),o=e.searchParams.get("query");return t&&t.length>0?{kind:"extracted",operationName:t}:o&&o.length>0?{kind:"extracted",operationName:oe(o)}:{kind:"not-graphql"}}function ke(n,e,t,o){const s=n.toUpperCase();if(s==="POST"){if(t!==null){const f=be(t);if(f===void 0)return{kind:"not-graphql"};const{isGraphQL:l,operationName:p}=te(f);return l?{kind:"extracted",operationName:p}:{kind:"not-graphql"}}return o?{kind:"unparseable"}:{kind:"not-graphql"}}return s==="GET"?ye(e):{kind:"not-graphql"}}function we(n,e){return e===null?!1:typeof n=="string"?n===e:((n.global||n.sticky)&&(n.lastIndex=0),n.test(e))}function Me(n,e){return n?e.kind==="not-graphql"?{kind:"no-match"}:e.kind==="unparseable"?{kind:"unparseable"}:we(n,e.operationName)?{kind:"match",operationName:e.operationName}:{kind:"no-match"}:e.kind==="extracted"?{kind:"skip-no-constraint",operationName:e.operationName}:{kind:"skip-no-constraint",operationName:null}}function J(n){return typeof Request<"u"&&n instanceof Request}function ve(n){return J(n)?n.url:n.toString()}function Ce(n,e){return e!=null&&e.method?e.method.toUpperCase():J(n)?n.method.toUpperCase():"GET"}function Se(n,e){if(e!=null&&e.signal)return e.signal;if(J(n))return n.signal}function Te(){if(typeof DOMException<"u")return new DOMException("The user aborted a request.","AbortError");const n=new Error("The user aborted a request.");return n.name="AbortError",n}function Ee(n,e){if(!e)return n;const t=new AbortController,o=p=>{l(),t.signal.aborted||t.abort(p.reason)},s=()=>o(n),f=()=>o(e),l=()=>{n.removeEventListener("abort",s),e.removeEventListener("abort",f)};return n.aborted?(o(n),t.signal):e.aborted?(o(e),t.signal):(n.addEventListener("abort",s,{once:!0}),e.addEventListener("abort",f,{once:!0}),t.signal)}function Le(n,e){return e?{...n??{},signal:e}:n}async function Ae(n,e){const t=e==null?void 0:e.body;if(t!=null){if(typeof t=="string")return{text:t,unparseable:!1};if(typeof URLSearchParams<"u"&&t instanceof URLSearchParams)return{text:t.toString(),unparseable:!1};if(typeof Blob<"u"&&t instanceof Blob){if(!(t.type===""||/json|text|graphql/i.test(t.type)))return{text:null,unparseable:!0};try{return{text:await t.text(),unparseable:!1}}catch{return{text:null,unparseable:!0}}}return{text:null,unparseable:!0}}if(J(n)){if(n.body===null)return{text:null,unparseable:!1};try{return{text:await n.clone().text(),unparseable:!1}}catch{return{text:null,unparseable:!0}}}return{text:null,unparseable:!1}}function H(n,e,t,o,s){n==null||n.emit({type:e,timestamp:Date.now(),applied:!1,detail:{url:t,method:o,...s,reason:"graphql-body-unparseable"}})}function Q(n,e,t,o){if(!V(e,n.urlPattern))return{proceed:!1,outcome:null};if(n.methods&&!n.methods.includes(t))return{proceed:!1,outcome:null};const s=Me(n.graphqlOperation,o);return s.kind==="no-match"?{proceed:!1,outcome:s}:{proceed:!0,outcome:s}}function j(n){return n?n.kind==="match"||n.kind==="skip-no-constraint"?n.operationName?{operationName:n.operationName}:{}:{}:{}}function re(n,e,t,o,s,f){n==null||n.emit({type:"network:abort",timestamp:Date.now(),applied:s,detail:{url:t,method:o,timeoutMs:e.timeout,...j(f)}})}function Y(n,e,t,o,s,f){n==null||n.emit({type:"network:corruption",timestamp:Date.now(),applied:s,detail:{url:t,method:o,strategy:e.strategy,...j(f)}})}function Ne(n){return n.graphqlOperation!==void 0}function xe(n,e,t,o,s=new Map,f){return async(l,p)=>{var k,w,C,E,$;const u=ve(l),a=Ce(l,p),S=Se(l,p),A=(()=>{const r=[e.failures,e.latencies,e.aborts,e.corruptions,e.cors];for(const b of r)if(b!=null&&b.some(Ne))return!0;return!1})();let M={kind:"not-graphql"};if(A){const r=await Ae(l,p);M=ke(a,u,r.text,r.unparseable)}if(e.cors)for(const r of e.cors){o==null||o.debug("rule-evaluating",{url:u,method:a},r);const b=Q(r,u,a,M);if(!b.proceed){o==null||o.debug("rule-skip-match",{url:u,method:a},r);continue}o==null||o.debug("rule-matched",{url:u,method:a},r);const R=P(r,s);if(!G(r,R)){o==null||o.debug("rule-skip-counting",{url:u,method:a},r);continue}if(!I(r,f,o,{url:u,method:a}))continue;const v=q(r.probability,t);if(((k=b.outcome)==null?void 0:k.kind)==="unparseable"){v&&H(o,"network:cors",u,a,{});continue}if(o==null||o.emit({type:"network:cors",timestamp:Date.now(),applied:v,detail:{url:u,method:a,...j(b.outcome)}}),!v){o==null||o.debug("rule-skip-probability",{url:u,method:a},r);continue}o==null||o.debug("rule-applied",{url:u,method:a},r);const O=new TypeError("Failed to fetch");throw O.stack="",O}let L=null,N=null,T,d,c=!1;const i=r=>{!L||c||(c=!0,d&&(clearTimeout(d),d=void 0),re(o,L,u,a,r,N))};if(e.aborts)for(const r of e.aborts){o==null||o.debug("rule-evaluating",{url:u,method:a,timeoutMs:r.timeout},r);const b=Q(r,u,a,M);if(!b.proceed){o==null||o.debug("rule-skip-match",{url:u,method:a,timeoutMs:r.timeout},r);continue}o==null||o.debug("rule-matched",{url:u,method:a,timeoutMs:r.timeout},r);const R=P(r,s);if(!G(r,R)){o==null||o.debug("rule-skip-counting",{url:u,method:a,timeoutMs:r.timeout},r);continue}if(!I(r,f,o,{url:u,method:a,timeoutMs:r.timeout}))continue;const v=q(r.probability,t);if(((w=b.outcome)==null?void 0:w.kind)==="unparseable"){v&&H(o,"network:abort",u,a,{timeoutMs:r.timeout});continue}if(!v){o==null||o.debug("rule-skip-probability",{url:u,method:a,timeoutMs:r.timeout},r),re(o,r,u,a,!1,b.outcome);continue}o==null||o.debug("rule-applied",{url:u,method:a,timeoutMs:r.timeout},r),console.warn(`CHAOS: Aborting ${a} ${u} after ${r.timeout||0}ms`),L=r,N=b.outcome;const O=new AbortController;T=Ee(O.signal,S);const Z=()=>{c||(i(!0),O.abort(Te()))};r.timeout?d=setTimeout(Z,r.timeout):Z();break}if(L)try{const r=await n(l,Le(p,T));return i(!1),r}catch(r){throw i(!1),r}if(e.failures)for(const r of e.failures){o==null||o.debug("rule-evaluating",{url:u,method:a,statusCode:r.statusCode},r);const b=Q(r,u,a,M);if(!b.proceed){o==null||o.debug("rule-skip-match",{url:u,method:a,statusCode:r.statusCode},r);continue}o==null||o.debug("rule-matched",{url:u,method:a,statusCode:r.statusCode},r);const R=P(r,s);if(!G(r,R)){o==null||o.debug("rule-skip-counting",{url:u,method:a,statusCode:r.statusCode},r);continue}if(!I(r,f,o,{url:u,method:a,statusCode:r.statusCode}))continue;const v=q(r.probability,t);if(((C=b.outcome)==null?void 0:C.kind)==="unparseable"){v&&H(o,"network:failure",u,a,{statusCode:r.statusCode});continue}if(o==null||o.emit({type:"network:failure",timestamp:Date.now(),applied:v,detail:{url:u,method:a,statusCode:r.statusCode,...j(b.outcome)}}),!v){o==null||o.debug("rule-skip-probability",{url:u,method:a,statusCode:r.statusCode},r);continue}o==null||o.debug("rule-applied",{url:u,method:a,statusCode:r.statusCode},r),console.warn(`CHAOS: Forcing ${r.statusCode} for ${a} ${u}`);const O=r.body??JSON.stringify({error:"Chaos Maker Attack!"}),Z=r.headers??{};return new Response(O,{status:r.statusCode,statusText:r.statusText??"Service Unavailable (Chaos)",headers:Z})}if(e.latencies)for(const r of e.latencies){o==null||o.debug("rule-evaluating",{url:u,method:a,delayMs:r.delayMs},r);const b=Q(r,u,a,M);if(!b.proceed){o==null||o.debug("rule-skip-match",{url:u,method:a,delayMs:r.delayMs},r);continue}o==null||o.debug("rule-matched",{url:u,method:a,delayMs:r.delayMs},r);const R=P(r,s);if(!G(r,R)){o==null||o.debug("rule-skip-counting",{url:u,method:a,delayMs:r.delayMs},r);continue}if(!I(r,f,o,{url:u,method:a,delayMs:r.delayMs}))continue;const v=q(r.probability,t);if(((E=b.outcome)==null?void 0:E.kind)==="unparseable"){v&&H(o,"network:latency",u,a,{delayMs:r.delayMs});continue}if(o==null||o.emit({type:"network:latency",timestamp:Date.now(),applied:v,detail:{url:u,method:a,delayMs:r.delayMs,...j(b.outcome)}}),!v){o==null||o.debug("rule-skip-probability",{url:u,method:a,delayMs:r.delayMs},r);continue}o==null||o.debug("rule-applied",{url:u,method:a,delayMs:r.delayMs},r),console.warn(`CHAOS: Adding ${r.delayMs}ms latency to ${a} ${u}`),await new Promise(O=>setTimeout(O,r.delayMs))}let g=null,h=null;if(e.corruptions)for(const r of e.corruptions){o==null||o.debug("rule-evaluating",{url:u,method:a,strategy:r.strategy},r);const b=Q(r,u,a,M);if(!b.proceed){o==null||o.debug("rule-skip-match",{url:u,method:a,strategy:r.strategy},r);continue}o==null||o.debug("rule-matched",{url:u,method:a,strategy:r.strategy},r);const R=P(r,s);if(!G(r,R)){o==null||o.debug("rule-skip-counting",{url:u,method:a,strategy:r.strategy},r);continue}if(!I(r,f,o,{url:u,method:a,strategy:r.strategy}))continue;const v=q(r.probability,t);if((($=b.outcome)==null?void 0:$.kind)==="unparseable"){v&&H(o,"network:corruption",u,a,{strategy:r.strategy});continue}if(!v){o==null||o.debug("rule-skip-probability",{url:u,method:a,strategy:r.strategy},r),Y(o,r,u,a,!1,b.outcome);continue}o==null||o.debug("rule-applied",{url:u,method:a,strategy:r.strategy},r),g=r,h=b.outcome;break}let y;try{y=await n(l,p)}catch(r){throw g&&Y(o,g,u,a,!1,h),r}if(!g)return y;try{console.warn(`CHAOS: Corrupting response for ${a} ${u} with strategy: ${g.strategy}`);const r=await y.text(),b=ge(r,g.strategy);return Y(o,g,u,a,!0,h),new Response(b,{status:y.status,statusText:y.statusText,headers:y.headers})}catch(r){throw Y(o,g,u,a,!1,h),r}}}const se=Symbol.for("chaos-maker.websocket.intercepted");function _e(n,e){return n==="both"?!0:n===e}function ae(n){return typeof n=="string"?"text":"binary"}function ue(n,e){switch(e){case"truncate":return n.slice(0,Math.max(0,Math.floor(n.length/2)));case"malformed-json":return`${n}"}`;case"empty":return"";case"wrong-type":return"<html><body>Unexpected HTML</body></html>"}}function le(n,e){if(e==="malformed-json"||e==="wrong-type")return null;if(e==="empty")return typeof Blob<"u"&&n instanceof Blob?new Blob([]):n instanceof ArrayBuffer?new ArrayBuffer(0):new Uint8Array(0);if(typeof Blob<"u"&&n instanceof Blob)return n.slice(0,Math.max(0,Math.floor(n.size/2)));if(n instanceof ArrayBuffer)return n.slice(0,Math.max(0,Math.floor(n.byteLength/2)));const t=n,o=Math.max(0,Math.floor(t.byteLength/2));return new Uint8Array(t.buffer.slice(t.byteOffset,t.byteOffset+o))}function U(n,e,t,o,s,f,l){if(!n)return null;for(const p of n){if(l==null||l.debug("rule-evaluating",{url:e,direction:t},p),!V(e,p.urlPattern)){l==null||l.debug("rule-skip-match",{url:e,direction:t},p);continue}if(!_e(p.direction,t)){l==null||l.debug("rule-skip-match",{url:e,direction:t},p);continue}l==null||l.debug("rule-matched",{url:e,direction:t},p);const u=P(p,s);if(!G(p,u)){l==null||l.debug("rule-skip-counting",{url:e,direction:t},p);continue}if(I(p,f,l,{url:e,direction:t})){if(!q(p.probability,o)){l==null||l.debug("rule-skip-probability",{url:e,direction:t},p);continue}return l==null||l.debug("rule-applied",{url:e,direction:t},p),p}}return null}function K(n,e,t,o,s){n.emit({type:"websocket:drop",timestamp:Date.now(),applied:!0,detail:{url:e,direction:t,payloadType:o,...s?{reason:s}:{}}})}function ce(n,e,t,o,s){n.emit({type:"websocket:delay",timestamp:Date.now(),applied:!0,detail:{url:e,direction:t,payloadType:o,delayMs:s}})}function W(n,e,t,o,s,f,l){n.emit({type:"websocket:corrupt",timestamp:Date.now(),applied:f,detail:{url:e,direction:t,payloadType:o,strategy:s,...l?{reason:l}:{}}})}function Re(n,e,t,o){n.emit({type:"websocket:close",timestamp:Date.now(),applied:!0,detail:{url:e,closeCode:t,closeReason:o}})}function Oe(n,e,t,o,s,f){const l=new Map;let p=!0;const u=(d,c)=>{let i=l.get(d);i||(i=new Set,l.set(d,i)),i.add(c)},a=(d,c)=>{var i;(i=l.get(d))==null||i.delete(c)},S=(d,c)=>{const i=l.get(d);if(i){for(const g of i)clearTimeout(g.handle),g.kind==="delay"&&K(t,g.url,g.direction,g.payloadType,c);l.delete(d)}},A=(d,c,i)=>{const g=new MessageEvent("message",{data:i,origin:c.origin,lastEventId:c.lastEventId,source:c.source,ports:Array.from(c.ports??[])});g[se]=!0,d.dispatchEvent(g)},M=(d,c,i,g)=>{if(!p)return{handled:!1,data:i};const h="outbound",y=ae(i);if(U(e.drops,c,h,o,s,f,t))return K(t,c,h,y),{handled:!0,data:i};let k=i;const w=U(e.corruptions,c,h,o,s,f,t);if(w)if(y==="text")k=ue(k,w.strategy),W(t,c,h,y,w.strategy,!0);else{const E=le(k,w.strategy);E===null?W(t,c,h,y,w.strategy,!1,"incompatible-payload-type"):(k=E,W(t,c,h,y,w.strategy,!0))}const C=U(e.delays,c,h,o,s,f,t);if(C){ce(t,c,h,y,C.delayMs);const E={kind:"delay",handle:setTimeout(()=>{a(d,E);try{g(k)}catch{}},C.delayMs),url:c,direction:h,payloadType:y};return u(d,E),{handled:!0,data:k}}return{handled:!1,data:k}},L=(d,c)=>{d.addEventListener("message",i=>{const g=i;if(g[se]||!p)return;const h="inbound",y=ae(g.data);if(U(e.drops,c,h,o,s,f,t)){g.stopImmediatePropagation(),K(t,c,h,y);return}let k=g.data,w=!1;const C=U(e.corruptions,c,h,o,s,f,t);if(C)if(y==="text")k=ue(k,C.strategy),w=!0,W(t,c,h,y,C.strategy,!0);else{const $=le(k,C.strategy);$===null?W(t,c,h,y,C.strategy,!1,"incompatible-payload-type"):(k=$,w=!0,W(t,c,h,y,C.strategy,!0))}const E=U(e.delays,c,h,o,s,f,t);if(E){g.stopImmediatePropagation(),ce(t,c,h,y,E.delayMs);const $={kind:"delay",handle:setTimeout(()=>{a(d,$),A(d,g,k)},E.delayMs),url:c,direction:h,payloadType:y};u(d,$);return}w&&(g.stopImmediatePropagation(),A(d,g,k))})},N=(d,c)=>{if(e.closes)for(const i of e.closes){if(t.debug("rule-evaluating",{url:c},i),!V(c,i.urlPattern)){t.debug("rule-skip-match",{url:c},i);continue}t.debug("rule-matched",{url:c},i);const g=P(i,s);if(!G(i,g)){t.debug("rule-skip-counting",{url:c},i);continue}if(!I(i,f,t,{url:c}))continue;if(!q(i.probability,o)){t.debug("rule-skip-probability",{url:c},i);continue}t.debug("rule-applied",{url:c},i);const h=i.code??1e3,y=i.reason??"Chaos Maker close",k=i.afterMs??0,w=()=>{if(p){S(d,"close-interrupt"),Re(t,c,h,y);try{d.close(h,y)}catch{try{d.close()}catch{}}}};if(k<=0)d.readyState===d.OPEN?w():d.addEventListener("open",w,{once:!0});else{const C=()=>{const E={kind:"close",handle:setTimeout(w,k)};u(d,E)};d.readyState===d.OPEN?C():d.addEventListener("open",C,{once:!0})}return}};function T(d,c){const i=new n(d,c),g=typeof d=="string"?d:d.toString(),h=i.send.bind(i);return i.send=function(k){const w=M(i,g,k,h);w.handled||h(w.data)},L(i,g),N(i,g),i}Object.defineProperty(T,"prototype",{value:n.prototype,writable:!1});for(const d of["CONNECTING","OPEN","CLOSING","CLOSED"])T[d]=n[d];return{Wrapped:T,uninstall(){p=!1;for(const[,d]of l)for(const c of d)clearTimeout(c.handle),c.kind==="delay"&&K(t,c.url,c.direction,c.payloadType,"stop-during-delay");l.clear()}}}function $e(n){return n===void 0?{enabled:!1}:typeof n=="boolean"?{enabled:n}:{enabled:n.enabled}}const qe=[{pick:n=>{var e;return(e=n.network)==null?void 0:e.failures},ruleType:"failure"},{pick:n=>{var e;return(e=n.network)==null?void 0:e.latencies},ruleType:"latency"},{pick:n=>{var e;return(e=n.network)==null?void 0:e.aborts},ruleType:"abort"},{pick:n=>{var e;return(e=n.network)==null?void 0:e.corruptions},ruleType:"corruption"},{pick:n=>{var e;return(e=n.network)==null?void 0:e.cors},ruleType:"cors"},{pick:n=>{var e;return(e=n.ui)==null?void 0:e.assaults},ruleType:"ui-assault"},{pick:n=>{var e;return(e=n.websocket)==null?void 0:e.drops},ruleType:"ws-drop"},{pick:n=>{var e;return(e=n.websocket)==null?void 0:e.delays},ruleType:"ws-delay"},{pick:n=>{var e;return(e=n.websocket)==null?void 0:e.corruptions},ruleType:"ws-corrupt"},{pick:n=>{var e;return(e=n.websocket)==null?void 0:e.closes},ruleType:"ws-close"},{pick:n=>{var e;return(e=n.sse)==null?void 0:e.drops},ruleType:"sse-drop"},{pick:n=>{var e;return(e=n.sse)==null?void 0:e.delays},ruleType:"sse-delay"},{pick:n=>{var e;return(e=n.sse)==null?void 0:e.corruptions},ruleType:"sse-corrupt"},{pick:n=>{var e;return(e=n.sse)==null?void 0:e.closes},ruleType:"sse-close"}];function Pe(n){const e=new WeakMap;for(const{pick:t,ruleType:o}of qe){const s=t(n);s&&s.forEach((f,l)=>{e.set(f,{ruleType:o,ruleId:`${o}#${l}`})})}return e}function Ge(n,e){const t=[];return e.ruleId&&t.push(`rule=${e.ruleId}`),e.phase&&t.push(e.phase),e.method&&t.push(e.method),e.url&&t.push(e.url),e.statusCode!==void 0&&t.push(`-> ${e.statusCode}`),e.delayMs!==void 0&&t.push(`+${e.delayMs}ms`),e.direction&&t.push(e.direction),e.eventType&&t.push(`event=${e.eventType}`),e.selector&&t.push(`selector=${e.selector}`),e.action&&t.push(`action=${e.action}`),e.strategy&&t.push(`strategy=${e.strategy}`),e.groupName&&t.push(`group=${e.groupName}`),e.reason&&t.push(`reason=${e.reason}`),t.length===0?n:`${n}: ${t.join(" ")}`}class Ie{constructor(e,t="page"){this.opts=e,this.target=t}isEnabled(){return this.opts.enabled}log(e,t){if(!this.opts.enabled)return null;const o={...t,stage:e},s={type:"debug",timestamp:Date.now(),applied:!1,detail:o};if(typeof console<"u"&&typeof console.debug=="function"){const f=this.target==="sw"?"[Chaos SW]":"[Chaos]";try{console.debug(`${f} ${Ge(e,o)}`)}catch{}}return s}}const X=Symbol.for("chaos-maker.sw.installed");function De(){return typeof self<"u"?self:typeof globalThis<"u"?globalThis:null}function ie(n,e){const t=n.clients;!t||typeof t.matchAll!="function"||t.matchAll({includeUncontrolled:!0}).then(o=>{for(const s of o)try{s.postMessage(e)}catch{}}).catch(()=>{})}function de(n,e){n.running&&m(n);const t=ee(e.seed);n.seed=t.seed,n.random=t.random,n.requestCounters=new Map,n.groups=new ne;for(const s of e.groups??[])n.groups.ensure(s.name,{enabled:s.enabled??!0,explicit:!0});he(e,s=>{s.group&&n.groups.ensure(s.group)}),n.groups.ensure(z,{enabled:!0});const o=$e(e.debug);if(o.enabled?(n.emitter.setRuleIds(Pe(e)),n.emitter.setLogger(new Ie(o,"sw"))):(n.emitter.setRuleIds(void 0),n.emitter.setLogger(void 0)),n.emitter.debug("lifecycle",{phase:"sw:config-applied"}),e.network){const s=n.target;typeof s.fetch=="function"&&(n.originalFetch=s.fetch,s.fetch=xe(n.originalFetch.bind(s),e.network,n.random,n.emitter,n.requestCounters,n.groups))}return e.websocket&&typeof n.target.WebSocket<"u"&&(n.originalWebSocket=n.target.WebSocket,n.webSocketHandle=Oe(n.originalWebSocket,e.websocket,n.emitter,n.random,n.requestCounters,n.groups),n.target.WebSocket=n.webSocketHandle.Wrapped),n.running=!0,n.seed}function m(n){!n.running&&!n.originalFetch&&!n.originalWebSocket||(n.originalFetch&&(n.target.fetch=n.originalFetch,n.originalFetch=void 0),n.originalWebSocket&&(n.target.WebSocket=n.originalWebSocket,n.originalWebSocket=void 0),n.webSocketHandle&&(n.webSocketHandle.uninstall(),n.webSocketHandle=void 0),n.emitter.debug("lifecycle",{phase:"sw:config-stopped"}),n.emitter.setLogger(void 0),n.emitter.setRuleIds(void 0),n.running=!1)}function B(n,e,t){var s;const o=(s=e.ports)==null?void 0:s[0];if(o&&typeof o.postMessage=="function")try{o.postMessage(t);return}catch{}ie(n,t)}function fe(n={}){const e=De(),t={isRunning:()=>!1,getSeed:()=>null,getLog:()=>[],clearLog:()=>{},uninstall:()=>{}};if(!e||typeof e.fetch!="function"||typeof e.addEventListener!="function")return t;const o=e[X];if(o)return o;const s=new _(n.maxLogEntries??2e3),f=ee(0),l={target:e,emitter:s,running:!1,seed:null,random:f.random,requestCounters:new Map,groups:new ne};s.on("*",a=>{ie(e,{__chaosMakerSWEvent:!0,event:a})});const p=a=>{const S=a,A=S.data;if(!A||typeof A!="object")return;const M=A;if(M.__chaosMakerConfig){const L=de(l,M.__chaosMakerConfig);B(e,S,{__chaosMakerAck:!0,seed:L,running:l.running});return}if(M.__chaosMakerStop){m(l),B(e,S,{__chaosMakerAck:!0,running:!1});return}if(M.__chaosMakerToggleGroup){const{name:L,enabled:N}=M.__chaosMakerToggleGroup,T=L.trim();if(!T){B(e,S,{__chaosMakerAck:!0,running:l.running});return}l.groups.setEnabled(T,N),l.emitter.emit({type:N?"rule-group:enabled":"rule-group:disabled",timestamp:Date.now(),applied:!0,detail:{groupName:T}}),l.emitter.debug("lifecycle",{phase:"sw:group-toggled",groupName:T,enabled:N}),B(e,S,{__chaosMakerAck:!0,running:l.running});return}if(M.__chaosMakerGetLog){B(e,S,{__chaosMakerLog:!0,log:s.getLog()});return}if(M.__chaosMakerClearLog){s.clearLog(),B(e,S,{__chaosMakerAck:!0,running:l.running});return}};if(e.addEventListener("message",p),(n.source??"message")==="self-global"){const a=e.__CHAOS_CONFIG__;a&&typeof a=="object"&&de(l,a)}const u={isRunning:()=>l.running,getSeed:()=>l.seed,getLog:()=>s.getLog(),clearLog:()=>s.clearLog(),uninstall:()=>{e.removeEventListener("message",p),m(l),delete e[X]}};return e[X]=u,u}return typeof self<"u"&&typeof importScripts=="function"&&fe({source:"message"}),x.installChaosSW=fe,Object.defineProperty(x,Symbol.toStringTag,{value:"Module"}),x})({});
|
|
1
|
+
var ChaosMakerSW=(function(x){"use strict";var Je=Object.defineProperty;var Ke=(x,_,W)=>_ in x?Je(x,_,{enumerable:!0,configurable:!0,writable:!0,value:W}):x[_]=W;var G=(x,_,W)=>Ke(x,typeof _!="symbol"?_+"":_,W);class _{constructor(e=2e3){G(this,"listeners",new Map);G(this,"log",[]);G(this,"logger");G(this,"ruleIds");this.maxLogEntries=e}on(e,t){this.listeners.has(e)||this.listeners.set(e,new Set),this.listeners.get(e).add(t)}off(e,t){var o;(o=this.listeners.get(e))==null||o.delete(t)}emit(e){this.log.push(e),this.log.length>this.maxLogEntries&&this.log.shift(),this.notify(this.listeners.get(e.type),e),this.notify(this.listeners.get("*"),e)}setLogger(e){this.logger=e}setRuleIds(e){this.ruleIds=e}debug(e,t,o){var p;if(!this.logger)return;const s=o?(p=this.ruleIds)==null?void 0:p.get(o):void 0,i=s?{...t,ruleType:s.ruleType,ruleId:s.ruleId}:t,l=this.logger.log(e,i);l&&this.emit(l)}getLog(){return[...this.log]}clearLog(){this.log=[]}notify(e,t){if(e)for(const o of e)try{o(t)}catch{}}}function W(n){let e=n|0;return()=>{e=e+1831565813|0;let t=Math.imul(e^e>>>15,1|e);return t=t+Math.imul(t^t>>>7,61|t)^t,((t^t>>>14)>>>0)/4294967296}}function ye(){return Math.random()*4294967296>>>0}function ne(n){const e=n??ye();return{random:W(e),seed:e}}const J="default";class oe{constructor(){G(this,"groups",new Map);G(this,"gatedEmitted",new Set)}ensure(e,t){const o=this.groups.get(e);if(o)return t!=null&&t.explicit&&(o.explicit=!0),(t==null?void 0:t.enabled)!==void 0&&(o.enabled=t.enabled),o;const s={name:e,enabled:(t==null?void 0:t.enabled)??!0,explicit:(t==null?void 0:t.explicit)??!1};return this.groups.set(e,s),s}setEnabled(e,t){this.ensure(e).enabled=t,this.gatedEmitted.clear()}isActive(e){return this.ensure(e??J).enabled}shouldEmitGated(e){return this.gatedEmitted.has(e)?!1:(this.gatedEmitted.add(e),!0)}has(e){return this.groups.has(e)}remove(e,t,o){if(e===J)return!1;if(!(o!=null&&o.force)&&t.has(e))throw new Error(`[chaos-maker] Cannot remove group '${e}': still referenced by one or more rules. Pass { force: true } to override.`);const s=this.groups.delete(e);return s&&this.gatedEmitted.delete(e),s}list(){return[...this.groups.values()].map(e=>({...e}))}getSnapshot(){const e={};for(const t of this.groups.values())e[t.name]=t.enabled;return e}}function I(n,e){return e()<n}function $(n,e){const t=(e.get(n)??0)+1;return e.set(n,t),t}function q(n,e){return n.onNth!==void 0?e===n.onNth:n.everyNth!==void 0?e%n.everyNth===0:n.afterN!==void 0?e>n.afterN:!0}function Z(n,e){return e==="*"?!0:n.includes(e)}function ke(n,e){switch(e){case"truncate":return n.slice(0,Math.max(0,Math.floor(n.length/2)));case"malformed-json":return`${n}"}`;case"empty":return"";case"wrong-type":return"<html><body>Unexpected HTML</body></html>"}}function D(n,e,t,o){if(!e||e.isActive(n.group))return!0;const s=n.group??J;return e.shouldEmitGated(s)&&t&&t.emit({type:"rule-group:gated",timestamp:Date.now(),applied:!1,detail:{...o,groupName:s}}),t==null||t.debug("rule-skip-group",{...o,groupName:s},n),!1}function we(n,e){var o,s,i,l,p,u,a,S,A,M,L,N,T,f;const t=c=>{if(c)for(const d of c)e(d)};t((o=n.network)==null?void 0:o.failures),t((s=n.network)==null?void 0:s.latencies),t((i=n.network)==null?void 0:i.aborts),t((l=n.network)==null?void 0:l.corruptions),t((p=n.network)==null?void 0:p.cors),t((u=n.ui)==null?void 0:u.assaults),t((a=n.websocket)==null?void 0:a.drops),t((S=n.websocket)==null?void 0:S.delays),t((A=n.websocket)==null?void 0:A.corruptions),t((M=n.websocket)==null?void 0:M.closes),t((L=n.sse)==null?void 0:L.drops),t((N=n.sse)==null?void 0:N.delays),t((T=n.sse)==null?void 0:T.corruptions),t((f=n.sse)==null?void 0:f.closes)}function te(n){const e=n.replace(/#[^\r\n]*/g," "),t=/\b(?:query|mutation|subscription)\s+([A-Za-z_][A-Za-z0-9_]*)/.exec(e);return(t==null?void 0:t[1])??null}function Me(n){try{return JSON.parse(n)}catch{return}}function re(n){if(!n||typeof n!="object")return{isGraphQL:!1,operationName:null};if(Array.isArray(n))return n.length===0?{isGraphQL:!1,operationName:null}:re(n[0]);const e=n,t=typeof e.query=="string",o=typeof e.operationName=="string";return!t&&!o?{isGraphQL:!1,operationName:null}:o&&e.operationName.length>0?{isGraphQL:!0,operationName:e.operationName}:t?{isGraphQL:!0,operationName:te(e.query)}:{isGraphQL:!0,operationName:null}}function ve(n){let e;try{e=new URL(n,"http://_chaos-maker.invalid")}catch{return{kind:"not-graphql"}}const t=e.searchParams.get("operationName"),o=e.searchParams.get("query");return t&&t.length>0?{kind:"extracted",operationName:t}:o&&o.length>0?{kind:"extracted",operationName:te(o)}:{kind:"not-graphql"}}function Ce(n,e,t,o){const s=n.toUpperCase();if(s==="POST"){if(t!==null){const i=Me(t);if(i===void 0)return{kind:"not-graphql"};const{isGraphQL:l,operationName:p}=re(i);return l?{kind:"extracted",operationName:p}:{kind:"not-graphql"}}return o?{kind:"unparseable"}:{kind:"not-graphql"}}return s==="GET"?ve(e):{kind:"not-graphql"}}function Se(n,e){return e===null?!1:typeof n=="string"?n===e:((n.global||n.sticky)&&(n.lastIndex=0),n.test(e))}function Te(n,e){return n?e.kind==="not-graphql"?{kind:"no-match"}:e.kind==="unparseable"?{kind:"unparseable"}:Se(n,e.operationName)?{kind:"match",operationName:e.operationName}:{kind:"no-match"}:e.kind==="extracted"?{kind:"skip-no-constraint",operationName:e.operationName}:{kind:"skip-no-constraint",operationName:null}}function K(n){return typeof Request<"u"&&n instanceof Request}function Ee(n){return K(n)?n.url:n.toString()}function Le(n,e){return e!=null&&e.method?e.method.toUpperCase():K(n)?n.method.toUpperCase():"GET"}function Ae(n,e){if(e!=null&&e.signal)return e.signal;if(K(n))return n.signal}function Ne(){if(typeof DOMException<"u")return new DOMException("The user aborted a request.","AbortError");const n=new Error("The user aborted a request.");return n.name="AbortError",n}function xe(n,e){if(!e)return n;const t=new AbortController,o=p=>{l(),t.signal.aborted||t.abort(p.reason)},s=()=>o(n),i=()=>o(e),l=()=>{n.removeEventListener("abort",s),e.removeEventListener("abort",i)};return n.aborted?(o(n),t.signal):e.aborted?(o(e),t.signal):(n.addEventListener("abort",s,{once:!0}),e.addEventListener("abort",i,{once:!0}),t.signal)}function _e(n,e){return e?{...n??{},signal:e}:n}async function Re(n,e){const t=e==null?void 0:e.body;if(t!=null){if(typeof t=="string")return{text:t,unparseable:!1};if(typeof URLSearchParams<"u"&&t instanceof URLSearchParams)return{text:t.toString(),unparseable:!1};if(typeof Blob<"u"&&t instanceof Blob){if(!(t.type===""||/json|text|graphql/i.test(t.type)))return{text:null,unparseable:!0};try{return{text:await t.text(),unparseable:!1}}catch{return{text:null,unparseable:!0}}}return{text:null,unparseable:!0}}if(K(n)){if(n.body===null)return{text:null,unparseable:!1};try{return{text:await n.clone().text(),unparseable:!1}}catch{return{text:null,unparseable:!0}}}return{text:null,unparseable:!1}}function j(n,e,t,o,s){n==null||n.emit({type:e,timestamp:Date.now(),applied:!1,detail:{url:t,method:o,...s,reason:"graphql-body-unparseable"}})}function H(n,e,t,o){if(!Z(e,n.urlPattern))return{proceed:!1,outcome:null};if(n.methods&&!n.methods.includes(t))return{proceed:!1,outcome:null};const s=Te(n.graphqlOperation,o);return s.kind==="no-match"?{proceed:!1,outcome:s}:{proceed:!0,outcome:s}}function Q(n){return n?n.kind==="match"||n.kind==="skip-no-constraint"?n.operationName?{operationName:n.operationName}:{}:{}:{}}function se(n,e,t,o,s,i){n==null||n.emit({type:"network:abort",timestamp:Date.now(),applied:s,detail:{url:t,method:o,timeoutMs:e.timeout,...Q(i)}})}function Y(n,e,t,o,s,i){n==null||n.emit({type:"network:corruption",timestamp:Date.now(),applied:s,detail:{url:t,method:o,strategy:e.strategy,...Q(i)}})}function Oe(n){return n.graphqlOperation!==void 0}function Pe(n,e,t,o,s=new Map,i){return async(l,p)=>{var k,w,C,E,P;const u=Ee(l),a=Le(l,p),S=Ae(l,p),A=(()=>{const r=[e.failures,e.latencies,e.aborts,e.corruptions,e.cors];for(const b of r)if(b!=null&&b.some(Oe))return!0;return!1})();let M={kind:"not-graphql"};if(A){const r=await Re(l,p);M=Ce(a,u,r.text,r.unparseable)}if(e.cors)for(const r of e.cors){o==null||o.debug("rule-evaluating",{url:u,method:a},r);const b=H(r,u,a,M);if(!b.proceed){o==null||o.debug("rule-skip-match",{url:u,method:a},r);continue}o==null||o.debug("rule-matched",{url:u,method:a},r);const R=$(r,s);if(!q(r,R)){o==null||o.debug("rule-skip-counting",{url:u,method:a},r);continue}if(!D(r,i,o,{url:u,method:a}))continue;const v=I(r.probability,t);if(((k=b.outcome)==null?void 0:k.kind)==="unparseable"){v&&j(o,"network:cors",u,a,{});continue}if(o==null||o.emit({type:"network:cors",timestamp:Date.now(),applied:v,detail:{url:u,method:a,...Q(b.outcome)}}),!v){o==null||o.debug("rule-skip-probability",{url:u,method:a},r);continue}o==null||o.debug("rule-applied",{url:u,method:a},r);const O=new TypeError("Failed to fetch");throw O.stack="",O}let L=null,N=null,T,f,c=!1;const d=r=>{!L||c||(c=!0,f&&(clearTimeout(f),f=void 0),se(o,L,u,a,r,N))};if(e.aborts)for(const r of e.aborts){o==null||o.debug("rule-evaluating",{url:u,method:a,timeoutMs:r.timeout},r);const b=H(r,u,a,M);if(!b.proceed){o==null||o.debug("rule-skip-match",{url:u,method:a,timeoutMs:r.timeout},r);continue}o==null||o.debug("rule-matched",{url:u,method:a,timeoutMs:r.timeout},r);const R=$(r,s);if(!q(r,R)){o==null||o.debug("rule-skip-counting",{url:u,method:a,timeoutMs:r.timeout},r);continue}if(!D(r,i,o,{url:u,method:a,timeoutMs:r.timeout}))continue;const v=I(r.probability,t);if(((w=b.outcome)==null?void 0:w.kind)==="unparseable"){v&&j(o,"network:abort",u,a,{timeoutMs:r.timeout});continue}if(!v){o==null||o.debug("rule-skip-probability",{url:u,method:a,timeoutMs:r.timeout},r),se(o,r,u,a,!1,b.outcome);continue}o==null||o.debug("rule-applied",{url:u,method:a,timeoutMs:r.timeout},r),console.warn(`CHAOS: Aborting ${a} ${u} after ${r.timeout||0}ms`),L=r,N=b.outcome;const O=new AbortController;T=xe(O.signal,S);const V=()=>{c||(d(!0),O.abort(Ne()))};r.timeout?f=setTimeout(V,r.timeout):V();break}if(L)try{const r=await n(l,_e(p,T));return d(!1),r}catch(r){throw d(!1),r}if(e.failures)for(const r of e.failures){o==null||o.debug("rule-evaluating",{url:u,method:a,statusCode:r.statusCode},r);const b=H(r,u,a,M);if(!b.proceed){o==null||o.debug("rule-skip-match",{url:u,method:a,statusCode:r.statusCode},r);continue}o==null||o.debug("rule-matched",{url:u,method:a,statusCode:r.statusCode},r);const R=$(r,s);if(!q(r,R)){o==null||o.debug("rule-skip-counting",{url:u,method:a,statusCode:r.statusCode},r);continue}if(!D(r,i,o,{url:u,method:a,statusCode:r.statusCode}))continue;const v=I(r.probability,t);if(((C=b.outcome)==null?void 0:C.kind)==="unparseable"){v&&j(o,"network:failure",u,a,{statusCode:r.statusCode});continue}if(o==null||o.emit({type:"network:failure",timestamp:Date.now(),applied:v,detail:{url:u,method:a,statusCode:r.statusCode,...Q(b.outcome)}}),!v){o==null||o.debug("rule-skip-probability",{url:u,method:a,statusCode:r.statusCode},r);continue}o==null||o.debug("rule-applied",{url:u,method:a,statusCode:r.statusCode},r),console.warn(`CHAOS: Forcing ${r.statusCode} for ${a} ${u}`);const O=r.body??JSON.stringify({error:"Chaos Maker Attack!"}),V=r.headers??{};return new Response(O,{status:r.statusCode,statusText:r.statusText??"Service Unavailable (Chaos)",headers:V})}if(e.latencies)for(const r of e.latencies){o==null||o.debug("rule-evaluating",{url:u,method:a,delayMs:r.delayMs},r);const b=H(r,u,a,M);if(!b.proceed){o==null||o.debug("rule-skip-match",{url:u,method:a,delayMs:r.delayMs},r);continue}o==null||o.debug("rule-matched",{url:u,method:a,delayMs:r.delayMs},r);const R=$(r,s);if(!q(r,R)){o==null||o.debug("rule-skip-counting",{url:u,method:a,delayMs:r.delayMs},r);continue}if(!D(r,i,o,{url:u,method:a,delayMs:r.delayMs}))continue;const v=I(r.probability,t);if(((E=b.outcome)==null?void 0:E.kind)==="unparseable"){v&&j(o,"network:latency",u,a,{delayMs:r.delayMs});continue}if(o==null||o.emit({type:"network:latency",timestamp:Date.now(),applied:v,detail:{url:u,method:a,delayMs:r.delayMs,...Q(b.outcome)}}),!v){o==null||o.debug("rule-skip-probability",{url:u,method:a,delayMs:r.delayMs},r);continue}o==null||o.debug("rule-applied",{url:u,method:a,delayMs:r.delayMs},r),console.warn(`CHAOS: Adding ${r.delayMs}ms latency to ${a} ${u}`),await new Promise(O=>setTimeout(O,r.delayMs))}let g=null,h=null;if(e.corruptions)for(const r of e.corruptions){o==null||o.debug("rule-evaluating",{url:u,method:a,strategy:r.strategy},r);const b=H(r,u,a,M);if(!b.proceed){o==null||o.debug("rule-skip-match",{url:u,method:a,strategy:r.strategy},r);continue}o==null||o.debug("rule-matched",{url:u,method:a,strategy:r.strategy},r);const R=$(r,s);if(!q(r,R)){o==null||o.debug("rule-skip-counting",{url:u,method:a,strategy:r.strategy},r);continue}if(!D(r,i,o,{url:u,method:a,strategy:r.strategy}))continue;const v=I(r.probability,t);if(((P=b.outcome)==null?void 0:P.kind)==="unparseable"){v&&j(o,"network:corruption",u,a,{strategy:r.strategy});continue}if(!v){o==null||o.debug("rule-skip-probability",{url:u,method:a,strategy:r.strategy},r),Y(o,r,u,a,!1,b.outcome);continue}o==null||o.debug("rule-applied",{url:u,method:a,strategy:r.strategy},r),g=r,h=b.outcome;break}let y;try{y=await n(l,p)}catch(r){throw g&&Y(o,g,u,a,!1,h),r}if(!g)return y;try{console.warn(`CHAOS: Corrupting response for ${a} ${u} with strategy: ${g.strategy}`);const r=await y.text(),b=ke(r,g.strategy);return Y(o,g,u,a,!0,h),new Response(b,{status:y.status,statusText:y.statusText,headers:y.headers})}catch(r){throw Y(o,g,u,a,!1,h),r}}}const ae=Symbol.for("chaos-maker.websocket.intercepted");function Ie(n,e){return n==="both"?!0:n===e}function ue(n){return typeof n=="string"?"text":"binary"}function le(n,e){switch(e){case"truncate":return n.slice(0,Math.max(0,Math.floor(n.length/2)));case"malformed-json":return`${n}"}`;case"empty":return"";case"wrong-type":return"<html><body>Unexpected HTML</body></html>"}}function ce(n,e){if(e==="malformed-json"||e==="wrong-type")return null;if(e==="empty")return typeof Blob<"u"&&n instanceof Blob?new Blob([]):n instanceof ArrayBuffer?new ArrayBuffer(0):new Uint8Array(0);if(typeof Blob<"u"&&n instanceof Blob)return n.slice(0,Math.max(0,Math.floor(n.size/2)));if(n instanceof ArrayBuffer)return n.slice(0,Math.max(0,Math.floor(n.byteLength/2)));const t=n,o=Math.max(0,Math.floor(t.byteLength/2));return new Uint8Array(t.buffer.slice(t.byteOffset,t.byteOffset+o))}function F(n,e,t,o,s,i,l){if(!n)return null;for(const p of n){if(l==null||l.debug("rule-evaluating",{url:e,direction:t},p),!Z(e,p.urlPattern)){l==null||l.debug("rule-skip-match",{url:e,direction:t},p);continue}if(!Ie(p.direction,t)){l==null||l.debug("rule-skip-match",{url:e,direction:t},p);continue}l==null||l.debug("rule-matched",{url:e,direction:t},p);const u=$(p,s);if(!q(p,u)){l==null||l.debug("rule-skip-counting",{url:e,direction:t},p);continue}if(D(p,i,l,{url:e,direction:t})){if(!I(p.probability,o)){l==null||l.debug("rule-skip-probability",{url:e,direction:t},p);continue}return l==null||l.debug("rule-applied",{url:e,direction:t},p),p}}return null}function m(n,e,t,o,s){n.emit({type:"websocket:drop",timestamp:Date.now(),applied:!0,detail:{url:e,direction:t,payloadType:o,...s?{reason:s}:{}}})}function ie(n,e,t,o,s){n.emit({type:"websocket:delay",timestamp:Date.now(),applied:!0,detail:{url:e,direction:t,payloadType:o,delayMs:s}})}function U(n,e,t,o,s,i,l){n.emit({type:"websocket:corrupt",timestamp:Date.now(),applied:i,detail:{url:e,direction:t,payloadType:o,strategy:s,...l?{reason:l}:{}}})}function $e(n,e,t,o){n.emit({type:"websocket:close",timestamp:Date.now(),applied:!0,detail:{url:e,closeCode:t,closeReason:o}})}function qe(n,e,t,o,s,i){const l=new Map;let p=!0;const u=(f,c)=>{let d=l.get(f);d||(d=new Set,l.set(f,d)),d.add(c)},a=(f,c)=>{var d;(d=l.get(f))==null||d.delete(c)},S=(f,c)=>{const d=l.get(f);if(d){for(const g of d)clearTimeout(g.handle),g.kind==="delay"&&m(t,g.url,g.direction,g.payloadType,c);l.delete(f)}},A=(f,c,d)=>{const g=new MessageEvent("message",{data:d,origin:c.origin,lastEventId:c.lastEventId,source:c.source,ports:Array.from(c.ports??[])});g[ae]=!0,f.dispatchEvent(g)},M=(f,c,d,g)=>{if(!p)return{handled:!1,data:d};const h="outbound",y=ue(d);if(F(e.drops,c,h,o,s,i,t))return m(t,c,h,y),{handled:!0,data:d};let k=d;const w=F(e.corruptions,c,h,o,s,i,t);if(w)if(y==="text")k=le(k,w.strategy),U(t,c,h,y,w.strategy,!0);else{const E=ce(k,w.strategy);E===null?U(t,c,h,y,w.strategy,!1,"incompatible-payload-type"):(k=E,U(t,c,h,y,w.strategy,!0))}const C=F(e.delays,c,h,o,s,i,t);if(C){ie(t,c,h,y,C.delayMs);const E={kind:"delay",handle:setTimeout(()=>{if(a(f,E),!!p)try{g(k)}catch{}},C.delayMs),url:c,direction:h,payloadType:y};return u(f,E),{handled:!0,data:k}}return{handled:!1,data:k}},L=(f,c)=>{f.addEventListener("message",d=>{const g=d;if(g[ae]||!p)return;const h="inbound",y=ue(g.data);if(F(e.drops,c,h,o,s,i,t)){g.stopImmediatePropagation(),m(t,c,h,y);return}let k=g.data,w=!1;const C=F(e.corruptions,c,h,o,s,i,t);if(C)if(y==="text")k=le(k,C.strategy),w=!0,U(t,c,h,y,C.strategy,!0);else{const P=ce(k,C.strategy);P===null?U(t,c,h,y,C.strategy,!1,"incompatible-payload-type"):(k=P,w=!0,U(t,c,h,y,C.strategy,!0))}const E=F(e.delays,c,h,o,s,i,t);if(E){g.stopImmediatePropagation(),ie(t,c,h,y,E.delayMs);const P={kind:"delay",handle:setTimeout(()=>{a(f,P),p&&A(f,g,k)},E.delayMs),url:c,direction:h,payloadType:y};u(f,P);return}w&&(g.stopImmediatePropagation(),A(f,g,k))})},N=(f,c)=>{if(e.closes)for(const d of e.closes){if(t.debug("rule-evaluating",{url:c},d),!Z(c,d.urlPattern)){t.debug("rule-skip-match",{url:c},d);continue}t.debug("rule-matched",{url:c},d);const g=$(d,s);if(!q(d,g)){t.debug("rule-skip-counting",{url:c},d);continue}if(!D(d,i,t,{url:c}))continue;if(!I(d.probability,o)){t.debug("rule-skip-probability",{url:c},d);continue}t.debug("rule-applied",{url:c},d);const h=d.code??1e3,y=d.reason??"Chaos Maker close",k=d.afterMs??0,w=()=>{if(p){S(f,"close-interrupt"),$e(t,c,h,y);try{f.close(h,y)}catch{try{f.close()}catch{}}}};if(k<=0)f.readyState===f.OPEN?w():f.addEventListener("open",w,{once:!0});else{const C=()=>{const E={kind:"close",handle:setTimeout(w,k)};u(f,E)};f.readyState===f.OPEN?C():f.addEventListener("open",C,{once:!0})}return}};function T(f,c){const d=new n(f,c),g=typeof f=="string"?f:f.toString(),h=d.send.bind(d);return d.send=function(k){const w=M(d,g,k,h);w.handled||h(w.data)},L(d,g),N(d,g),d}Object.defineProperty(T,"prototype",{value:n.prototype,writable:!1});for(const f of["CONNECTING","OPEN","CLOSING","CLOSED"])T[f]=n[f];return{Wrapped:T,uninstall(){p=!1;for(const[,f]of l)for(const c of f)clearTimeout(c.handle),c.kind==="delay"&&m(t,c.url,c.direction,c.payloadType,"stop-during-delay");l.clear()}}}function De(n){return n===void 0?{enabled:!1}:typeof n=="boolean"?{enabled:n}:{enabled:n.enabled}}const Ge=[{pick:n=>{var e;return(e=n.network)==null?void 0:e.failures},ruleType:"failure"},{pick:n=>{var e;return(e=n.network)==null?void 0:e.latencies},ruleType:"latency"},{pick:n=>{var e;return(e=n.network)==null?void 0:e.aborts},ruleType:"abort"},{pick:n=>{var e;return(e=n.network)==null?void 0:e.corruptions},ruleType:"corruption"},{pick:n=>{var e;return(e=n.network)==null?void 0:e.cors},ruleType:"cors"},{pick:n=>{var e;return(e=n.ui)==null?void 0:e.assaults},ruleType:"ui-assault"},{pick:n=>{var e;return(e=n.websocket)==null?void 0:e.drops},ruleType:"ws-drop"},{pick:n=>{var e;return(e=n.websocket)==null?void 0:e.delays},ruleType:"ws-delay"},{pick:n=>{var e;return(e=n.websocket)==null?void 0:e.corruptions},ruleType:"ws-corrupt"},{pick:n=>{var e;return(e=n.websocket)==null?void 0:e.closes},ruleType:"ws-close"},{pick:n=>{var e;return(e=n.sse)==null?void 0:e.drops},ruleType:"sse-drop"},{pick:n=>{var e;return(e=n.sse)==null?void 0:e.delays},ruleType:"sse-delay"},{pick:n=>{var e;return(e=n.sse)==null?void 0:e.corruptions},ruleType:"sse-corrupt"},{pick:n=>{var e;return(e=n.sse)==null?void 0:e.closes},ruleType:"sse-close"}];function We(n){const e=new WeakMap;for(const{pick:t,ruleType:o}of Ge){const s=t(n);s&&s.forEach((i,l)=>{e.set(i,{ruleType:o,ruleId:`${o}#${l}`})})}return e}function Fe(n,e){const t=[];return e.ruleId&&t.push(`rule=${e.ruleId}`),e.phase&&t.push(e.phase),e.method&&t.push(e.method),e.url&&t.push(e.url),e.statusCode!==void 0&&t.push(`-> ${e.statusCode}`),e.delayMs!==void 0&&t.push(`+${e.delayMs}ms`),e.direction&&t.push(e.direction),e.eventType&&t.push(`event=${e.eventType}`),e.selector&&t.push(`selector=${e.selector}`),e.action&&t.push(`action=${e.action}`),e.strategy&&t.push(`strategy=${e.strategy}`),e.groupName&&t.push(`group=${e.groupName}`),e.reason&&t.push(`reason=${e.reason}`),t.length===0?n:`${n}: ${t.join(" ")}`}class Ue{constructor(e,t="page"){this.opts=e,this.target=t}isEnabled(){return this.opts.enabled}log(e,t){if(!this.opts.enabled)return null;const o={...t,stage:e},s={type:"debug",timestamp:Date.now(),applied:!1,detail:o};if(typeof console<"u"&&typeof console.debug=="function"){const i=this.target==="sw"?"[Chaos SW]":"[Chaos]";try{console.debug(`${i} ${Fe(e,o)}`)}catch{}}return s}}const de=Symbol.for("chaos-maker.runtime.patch-kind"),z=Symbol.for("chaos-maker.runtime.active-instance");function Be(n){return typeof n=="object"&&n!==null||typeof n=="function"}function fe(n,e){try{Object.defineProperty(n,de,{value:e,configurable:!0})}catch{}return n}function pe(n){if(Be(n))return n[de]}function je(n){return n[z]}function He(n,e){try{Object.defineProperty(n,z,{value:e,configurable:!0})}catch{}}function Qe(n,e){const t=n;if(t[z]===e)try{delete t[z]}catch{try{t[z]=void 0}catch{}}}const X=Symbol.for("chaos-maker.sw.installed");function ze(){return typeof self<"u"?self:typeof globalThis<"u"?globalThis:null}function ge(n,e){const t=n.clients;!t||typeof t.matchAll!="function"||t.matchAll({includeUncontrolled:!0}).then(o=>{for(const s of o)try{s.postMessage(e)}catch{}}).catch(()=>{})}function he(n,e){n.running&&ee(n);const t=ne(e.seed);n.seed=t.seed,n.random=t.random,n.requestCounters=new Map,n.groups=new oe;for(const i of e.groups??[])n.groups.ensure(i.name,{enabled:i.enabled??!0,explicit:!0});we(e,i=>{i.group&&n.groups.ensure(i.group)}),n.groups.ensure(J,{enabled:!0});const o=De(e.debug);o.enabled?(n.emitter.setRuleIds(We(e)),n.emitter.setLogger(new Ue(o,"sw"))):(n.emitter.setRuleIds(void 0),n.emitter.setLogger(void 0));const s=je(n.target);if(s&&s!==n&&n.emitter.debug("lifecycle",{phase:"sw:config-applied",reason:"active-instance-conflict"}),pe(n.target.fetch)==="fetch"&&n.emitter.debug("lifecycle",{phase:"sw:config-applied",reason:"target-fetch-already-patched"}),typeof n.target.WebSocket<"u"&&pe(n.target.WebSocket)==="websocket"&&n.emitter.debug("lifecycle",{phase:"sw:config-applied",reason:"target-websocket-already-patched"}),n.emitter.debug("lifecycle",{phase:"sw:config-applied"}),e.network){const i=n.target;typeof i.fetch=="function"&&(n.originalFetch=i.fetch,i.fetch=fe(Pe(n.originalFetch.bind(i),e.network,n.random,n.emitter,n.requestCounters,n.groups),"fetch"))}return e.websocket&&typeof n.target.WebSocket<"u"&&(n.originalWebSocket=n.target.WebSocket,n.webSocketHandle=qe(n.originalWebSocket,e.websocket,n.emitter,n.random,n.requestCounters,n.groups),n.target.WebSocket=fe(n.webSocketHandle.Wrapped,"websocket")),n.running=!0,He(n.target,n),n.seed}function ee(n){!n.running&&!n.originalFetch&&!n.originalWebSocket||(n.originalFetch&&(n.target.fetch=n.originalFetch,n.originalFetch=void 0),n.originalWebSocket&&(n.target.WebSocket=n.originalWebSocket,n.originalWebSocket=void 0),n.webSocketHandle&&(n.webSocketHandle.uninstall(),n.webSocketHandle=void 0),n.emitter.debug("lifecycle",{phase:"sw:config-stopped"}),n.emitter.setLogger(void 0),n.emitter.setRuleIds(void 0),n.seed=null,n.requestCounters.clear(),Qe(n.target,n),n.running=!1)}function B(n,e,t){var s;const o=(s=e.ports)==null?void 0:s[0];if(o&&typeof o.postMessage=="function")try{o.postMessage(t);return}catch{}ge(n,t)}function be(n={}){const e=ze(),t={isRunning:()=>!1,getSeed:()=>null,getLog:()=>[],clearLog:()=>{},uninstall:()=>{}};if(!e||typeof e.fetch!="function"||typeof e.addEventListener!="function")return t;const o=e[X];if(o)return o;const s=new _(n.maxLogEntries??2e3),i=ne(0),l={target:e,emitter:s,running:!1,seed:null,random:i.random,requestCounters:new Map,groups:new oe};s.on("*",a=>{ge(e,{__chaosMakerSWEvent:!0,event:a})});const p=a=>{const S=a,A=S.data;if(!A||typeof A!="object")return;const M=A;if(M.__chaosMakerConfig){const L=he(l,M.__chaosMakerConfig);B(e,S,{__chaosMakerAck:!0,seed:L,running:l.running});return}if(M.__chaosMakerStop){ee(l),B(e,S,{__chaosMakerAck:!0,running:!1});return}if(M.__chaosMakerToggleGroup){const{name:L,enabled:N}=M.__chaosMakerToggleGroup,T=L.trim();if(!T){B(e,S,{__chaosMakerAck:!0,running:l.running});return}l.groups.setEnabled(T,N),l.emitter.emit({type:N?"rule-group:enabled":"rule-group:disabled",timestamp:Date.now(),applied:!0,detail:{groupName:T}}),l.emitter.debug("lifecycle",{phase:"sw:group-toggled",groupName:T,enabled:N}),B(e,S,{__chaosMakerAck:!0,running:l.running});return}if(M.__chaosMakerGetLog){B(e,S,{__chaosMakerLog:!0,log:s.getLog()});return}if(M.__chaosMakerClearLog){s.clearLog(),B(e,S,{__chaosMakerAck:!0,running:l.running});return}};if(e.addEventListener("message",p),(n.source??"message")==="self-global"){const a=e.__CHAOS_CONFIG__;a&&typeof a=="object"&&he(l,a)}const u={isRunning:()=>l.running,getSeed:()=>l.seed,getLog:()=>s.getLog(),clearLog:()=>s.clearLog(),uninstall:()=>{e.removeEventListener("message",p),ee(l),delete e[X]}};return e[X]=u,u}return typeof self<"u"&&typeof importScripts=="function"&&be({source:"message"}),x.installChaosSW=be,Object.defineProperty(x,Symbol.toStringTag,{value:"Module"}),x})({});
|