@chaos-maker/core 0.3.0 → 0.5.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 +151 -11
- package/dist/chaos-config.schema.json +1314 -0
- package/dist/chaos-config.schema.notes.md +32 -0
- package/dist/chaos-maker.cjs +128 -4
- package/dist/chaos-maker.js +3839 -2017
- package/dist/chaos-maker.umd.js +128 -4
- package/dist/sw.js +1 -0
- package/dist/sw.mjs +1074 -0
- package/dist/types/ChaosMaker.d.ts +60 -1
- package/dist/types/builder.d.ts +37 -1
- package/dist/types/config.d.ts +141 -18
- package/dist/types/debug.d.ts +58 -0
- package/dist/types/errors.d.ts +14 -2
- package/dist/types/events.d.ts +65 -1
- package/dist/types/graphql.d.ts +54 -0
- package/dist/types/groups.d.ts +71 -0
- package/dist/types/index.d.ts +34 -5
- package/dist/types/interceptors/domAssailant.d.ts +2 -1
- package/dist/types/interceptors/eventSource.d.ts +42 -0
- package/dist/types/interceptors/networkFetch.d.ts +2 -1
- package/dist/types/interceptors/networkXHR.d.ts +2 -1
- package/dist/types/interceptors/websocket.d.ts +4 -3
- package/dist/types/presets.d.ts +63 -2
- package/dist/types/sw-bridge-source.d.ts +20 -0
- package/dist/types/sw.d.ts +104 -0
- package/dist/types/transport.d.ts +21 -0
- package/dist/types/utils.d.ts +46 -1
- package/dist/types/validation-deprecation.d.ts +7 -0
- package/dist/types/validation-format.d.ts +10 -0
- package/dist/types/validation-strip.d.ts +11 -0
- package/dist/types/validation-types.d.ts +34 -0
- package/dist/types/validation.d.ts +52 -0
- package/package.json +13 -6
package/dist/sw.js
ADDED
|
@@ -0,0 +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})({});
|