@replay-kit/core 0.0.1
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/LICENSE +21 -0
- package/README.md +2 -0
- package/dist/app_event.cjs +4 -0
- package/dist/app_event.d.cts +7 -0
- package/dist/app_event.d.ts +7 -0
- package/dist/app_event.js +4 -0
- package/dist/cli.cjs +46 -0
- package/dist/cli.d.cts +1 -0
- package/dist/cli.d.ts +1 -0
- package/dist/cli.js +46 -0
- package/dist/enum/index.cjs +1 -0
- package/dist/enum/index.d.cts +1 -0
- package/dist/enum/index.d.ts +1 -0
- package/dist/enum/index.js +1 -0
- package/dist/enum/log_level.enum.cjs +1 -0
- package/dist/enum/log_level.enum.d.cts +7 -0
- package/dist/enum/log_level.enum.d.ts +7 -0
- package/dist/enum/log_level.enum.js +1 -0
- package/dist/error_handle.helper-CQsPSbuz.d.cts +75 -0
- package/dist/error_handle.helper-CQsPSbuz.d.ts +75 -0
- package/dist/helper/crypto.helper.cjs +1 -0
- package/dist/helper/crypto.helper.d.cts +3 -0
- package/dist/helper/crypto.helper.d.ts +3 -0
- package/dist/helper/crypto.helper.js +1 -0
- package/dist/helper/error_handle.helper.cjs +3 -0
- package/dist/helper/error_handle.helper.d.cts +2 -0
- package/dist/helper/error_handle.helper.d.ts +2 -0
- package/dist/helper/error_handle.helper.js +3 -0
- package/dist/helper/index.cjs +4 -0
- package/dist/helper/index.d.cts +4 -0
- package/dist/helper/index.d.ts +4 -0
- package/dist/helper/index.js +4 -0
- package/dist/helper/stack.helper.cjs +2 -0
- package/dist/helper/stack.helper.d.cts +9 -0
- package/dist/helper/stack.helper.d.ts +9 -0
- package/dist/helper/stack.helper.js +2 -0
- package/dist/index-8u1_ya-u.d.ts +36 -0
- package/dist/index-MBKv_hsI.d.cts +36 -0
- package/dist/index.cjs +4 -0
- package/dist/index.d.cts +7 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.js +4 -0
- package/dist/logger/actions/index.cjs +3 -0
- package/dist/logger/actions/index.d.cts +4 -0
- package/dist/logger/actions/index.d.ts +4 -0
- package/dist/logger/actions/index.js +3 -0
- package/dist/logger/actions/record.action.cjs +2 -0
- package/dist/logger/actions/record.action.d.cts +4 -0
- package/dist/logger/actions/record.action.d.ts +4 -0
- package/dist/logger/actions/record.action.js +2 -0
- package/dist/logger/actions/view_many.action.cjs +2 -0
- package/dist/logger/actions/view_many.action.d.cts +4 -0
- package/dist/logger/actions/view_many.action.d.ts +4 -0
- package/dist/logger/actions/view_many.action.js +2 -0
- package/dist/logger/handler.cjs +3 -0
- package/dist/logger/handler.d.cts +4 -0
- package/dist/logger/handler.d.ts +4 -0
- package/dist/logger/handler.js +3 -0
- package/dist/logger/index.cjs +3 -0
- package/dist/logger/index.d.cts +4 -0
- package/dist/logger/index.d.ts +4 -0
- package/dist/logger/index.js +3 -0
- package/dist/replay/base.cjs +1 -0
- package/dist/replay/base.d.cts +18 -0
- package/dist/replay/base.d.ts +18 -0
- package/dist/replay/base.js +1 -0
- package/dist/replay/handler.cjs +25 -0
- package/dist/replay/handler.d.cts +24 -0
- package/dist/replay/handler.d.ts +24 -0
- package/dist/replay/handler.js +25 -0
- package/dist/replay/helper.cjs +1 -0
- package/dist/replay/helper.d.cts +34 -0
- package/dist/replay/helper.d.ts +34 -0
- package/dist/replay/helper.js +1 -0
- package/dist/replay/index.cjs +25 -0
- package/dist/replay/index.d.cts +6 -0
- package/dist/replay/index.d.ts +6 -0
- package/dist/replay/index.js +25 -0
- package/dist/replay/mode/advance/index.cjs +22 -0
- package/dist/replay/mode/advance/index.d.cts +11 -0
- package/dist/replay/mode/advance/index.d.ts +11 -0
- package/dist/replay/mode/advance/index.js +22 -0
- package/dist/replay/mode/advance/reasons/assigner_cases/base.cjs +14 -0
- package/dist/replay/mode/advance/reasons/assigner_cases/base.d.cts +137 -0
- package/dist/replay/mode/advance/reasons/assigner_cases/base.d.ts +137 -0
- package/dist/replay/mode/advance/reasons/assigner_cases/base.js +14 -0
- package/dist/replay/mode/advance/reasons/assigner_cases/business_logic_rejection_case/index.cjs +14 -0
- package/dist/replay/mode/advance/reasons/assigner_cases/business_logic_rejection_case/index.d.cts +19 -0
- package/dist/replay/mode/advance/reasons/assigner_cases/business_logic_rejection_case/index.d.ts +19 -0
- package/dist/replay/mode/advance/reasons/assigner_cases/business_logic_rejection_case/index.js +14 -0
- package/dist/replay/mode/advance/reasons/assigner_cases/index.cjs +14 -0
- package/dist/replay/mode/advance/reasons/assigner_cases/index.d.cts +15 -0
- package/dist/replay/mode/advance/reasons/assigner_cases/index.d.ts +15 -0
- package/dist/replay/mode/advance/reasons/assigner_cases/index.js +14 -0
- package/dist/replay/mode/advance/reasons/assigner_cases/post_trace_response_mutation_case/index.cjs +14 -0
- package/dist/replay/mode/advance/reasons/assigner_cases/post_trace_response_mutation_case/index.d.cts +18 -0
- package/dist/replay/mode/advance/reasons/assigner_cases/post_trace_response_mutation_case/index.d.ts +18 -0
- package/dist/replay/mode/advance/reasons/assigner_cases/post_trace_response_mutation_case/index.js +14 -0
- package/dist/replay/mode/advance/reasons/assigner_cases/trace_divergence_case/index.cjs +14 -0
- package/dist/replay/mode/advance/reasons/assigner_cases/trace_divergence_case/index.d.cts +18 -0
- package/dist/replay/mode/advance/reasons/assigner_cases/trace_divergence_case/index.d.ts +18 -0
- package/dist/replay/mode/advance/reasons/assigner_cases/trace_divergence_case/index.js +14 -0
- package/dist/replay/mode/advance/reasons/index.cjs +21 -0
- package/dist/replay/mode/advance/reasons/index.d.cts +17 -0
- package/dist/replay/mode/advance/reasons/index.d.ts +17 -0
- package/dist/replay/mode/advance/reasons/index.js +21 -0
- package/dist/replay/mode/advance/reasons/reason_assigner.cjs +14 -0
- package/dist/replay/mode/advance/reasons/reason_assigner.d.cts +25 -0
- package/dist/replay/mode/advance/reasons/reason_assigner.d.ts +25 -0
- package/dist/replay/mode/advance/reasons/reason_assigner.js +14 -0
- package/dist/replay/mode/advance/reasons/reason_printer.cjs +8 -0
- package/dist/replay/mode/advance/reasons/reason_printer.d.cts +25 -0
- package/dist/replay/mode/advance/reasons/reason_printer.d.ts +25 -0
- package/dist/replay/mode/advance/reasons/reason_printer.js +8 -0
- package/dist/replay/mode/advance/reasons/reason_signal.cjs +1 -0
- package/dist/replay/mode/advance/reasons/reason_signal.d.cts +87 -0
- package/dist/replay/mode/advance/reasons/reason_signal.d.ts +87 -0
- package/dist/replay/mode/advance/reasons/reason_signal.js +1 -0
- package/dist/replay/mode/advance/replay.cjs +22 -0
- package/dist/replay/mode/advance/replay.d.cts +57 -0
- package/dist/replay/mode/advance/replay.d.ts +57 -0
- package/dist/replay/mode/advance/replay.js +22 -0
- package/dist/replay/mode/index.cjs +25 -0
- package/dist/replay/mode/index.d.cts +12 -0
- package/dist/replay/mode/index.d.ts +12 -0
- package/dist/replay/mode/index.js +25 -0
- package/dist/replay/mode/smart.replay.cjs +4 -0
- package/dist/replay/mode/smart.replay.d.cts +18 -0
- package/dist/replay/mode/smart.replay.d.ts +18 -0
- package/dist/replay/mode/smart.replay.js +4 -0
- package/dist/setup.cjs +7 -0
- package/dist/setup.d.cts +27 -0
- package/dist/setup.d.ts +27 -0
- package/dist/setup.js +7 -0
- package/dist/trace/builder.cjs +1 -0
- package/dist/trace/builder.d.cts +6 -0
- package/dist/trace/builder.d.ts +6 -0
- package/dist/trace/builder.js +1 -0
- package/dist/trace/context.cjs +2 -0
- package/dist/trace/context.d.cts +2 -0
- package/dist/trace/context.d.ts +2 -0
- package/dist/trace/context.js +2 -0
- package/dist/trace/filter.cjs +1 -0
- package/dist/trace/filter.d.cts +21 -0
- package/dist/trace/filter.d.ts +21 -0
- package/dist/trace/filter.js +1 -0
- package/dist/trace/index.cjs +2 -0
- package/dist/trace/index.d.cts +7 -0
- package/dist/trace/index.d.ts +7 -0
- package/dist/trace/index.js +2 -0
- package/package.json +81 -0
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
"use strict";var Y=Object.create;var w=Object.defineProperty;var Q=Object.getOwnPropertyDescriptor;var X=Object.getOwnPropertyNames;var Z=Object.getPrototypeOf,ee=Object.prototype.hasOwnProperty;var a=(s,e)=>w(s,"name",{value:e,configurable:!0});var te=(s,e)=>{for(var t in e)w(s,t,{get:e[t],enumerable:!0})},B=(s,e,t,r)=>{if(e&&typeof e=="object"||typeof e=="function")for(let n of X(e))!ee.call(s,n)&&n!==t&&w(s,n,{get:()=>e[n],enumerable:!(r=Q(e,n))||r.enumerable});return s};var m=(s,e,t)=>(t=s!=null?Y(Z(s)):{},B(e||!s||!s.__esModule?w(t,"default",{value:s,enumerable:!0}):t,s)),re=s=>B(w({},"__esModule",{value:!0}),s);var fe={};te(fe,{ReplayHandler:()=>A});module.exports=re(fe);var ir=require("dotenv/config");var ot=require("dotenv/config.js");var ce=require("ulid"),H=require("async_hooks");var se=m(require("fs"),1),ne=m(require("chalk"),1),ae=m(require("path"),1),oe=require("bundle-require");var _e=new H.AsyncLocalStorage;var q=m(require("crypto"),1);function J(s){try{return q.default.createHash("md5").update(s).digest("hex")}catch(e){throw e}}a(J,"cryptoHash");var I="__root__";function le(s){let e=new Map;for(let t of s){let r=t.parentId||I;e.has(r)||e.set(r,[]),e.get(r).push(t)}return e}a(le,"buildTraceTree");function pe(s,e,t){return`${t}->${s.name}#${e}`}a(pe,"buildSignature");function S(s){try{let n=function(o,l){(t.get(o)||[]).sort((c,p)=>c.start-p.start).forEach((c,p)=>{let f=pe(c,p,l),d=J(f);r.push({...c,signature:d,rawSignature:f}),n(c.id,d)})};var e=n;a(n,"walk");let t=le(s),r=[];return n(I,I),r}catch(t){throw t}}a(S,"flattenTrace");var _=class{constructor(e){this.config=e}config;static{a(this,"ReplayFilterManager")}matchPattern(e,t){try{return e instanceof RegExp?e.test(t):e.includes("*")?new RegExp("^"+e.replace(/\*/g,".*")+"$").test(t):e===t}catch(r){throw r}}async filterTrace(e){try{if(!this.config.filters||!e||e.length===0)return e;let t=this.config.filters;return e.filter(r=>{let n=r.name;return!t.ignoreSteps?.some(l=>this.matchPattern(l,n))})}catch(t){throw t}}async filterNonOptionalTrace(e){try{if(!this.config.filters||!e||e.length===0)return e;let t=this.config.filters;return e.filter(r=>{let n=r.name;return!t.optionalSteps?.some(l=>this.matchPattern(l,n))})}catch(t){throw t}}isOptionalStep(e){try{return this.config.filters?.optionalSteps?.some(t=>this.matchPattern(t,e))}catch(t){throw t}}async filterResponse(e){try{if(!this.config.filters||!e)return e;let t=Object.keys(e.error);if(t.length===0)return e;let r=this.config.filters;for(let n of t)r.ignoreFields?.includes(n)&&delete e.error[n];return{...e,error:e.error}}catch(t){throw t}}};var v=class{constructor(e){this.config=e}config;static{a(this,"ReplayHelper")}get filterManager(){return new _(this.config)}setConfig(e){this.config=e}normalize(e){if(!e)return e;if(typeof e=="string")try{return JSON.parse(e)}catch{return e}return e}stableStringify(e){return JSON.stringify(this.sortKeys(e))}sortKeys(e){return Array.isArray(e)?e.map(t=>this.sortKeys(t)):e&&typeof e=="object"?Object.keys(e).sort().reduce((t,r)=>(t[r]=this.sortKeys(e[r]),t),{}):e}compareTrace(e,t){try{let r=[],n=new Map(e.map(i=>[i.signature,i])),o=new Map(t.map(i=>[i.signature,i])),l={};for(let[i,c]of n)l[c.name]={id:c.id,parentId:c.parentId,original:c.returnData,replay:null},o.has(c.signature)||this.filterManager.isOptionalStep(c.name)||r.push({type:"missing_step",name:c.name,message:`Missing step: ${i}`});for(let[i,c]of o)l[c.name].replay=c.returnData,n.has(c.signature)||i&&this.filterManager.isOptionalStep(c.name)||r.push({type:"extra_step",name:c.name,message:`Extra step: ${i}`});for(let i in l){let c=l[i].original,p=l[i].replay;c!==p&&r.push({type:"trace_return_data_mismatch",name:i,message:"Trace return data mismatch",not_matched:{original:c,replay:p}})}return{isDifferent:r.length>0,issues:r}}catch(r){throw r}}compareResponse(e,t){try{let r=[];e.status!==t.status&&r.push({type:"status_mismatch",message:"Status code mismatch",not_matched:{original:e.status,replay:t.status}});let n=this.normalize(e.error),o=this.normalize(t.error),l=this.stableStringify(n),i=this.stableStringify(o);return l!==i&&r.push({type:"body_mismatch",message:"Response mismatch",not_matched:{original:n,replay:o}}),{isDifferent:r.length>0,issues:r}}catch(r){throw r}}fullUrl(e){return`${process.env.SERVER_URL}${e}`}async sendRequest(e){try{return await fetch(this.fullUrl(e.request.url),{method:e.request.method,headers:{"Content-Type":"application/json","x-is-replay":"true"},body:JSON.stringify(e.request.body)})}catch(t){throw t}}};var P=m(require("chalk"),1);var D=class{constructor(e){this.config=e}config;static{a(this,"BaseReplay")}get filterManager(){return new _(this.config)}get replayHelper(){return new v(this.config)}};var b=class extends D{constructor(t){super(t);this.config=t}config;static{a(this,"SmartReplay")}print(t){try{let{log:r,replay:n,responseDiff:o,traceDiff:l}=t;if(console.log(P.default.yellow.bold(`\u25B6 ${r.request.method} ${r.request.url}`)),!o.isDifferent&&!l.isDifferent){console.log(P.default.green(`[OK] Reponse & Trace match
|
|
2
|
+
`));return}if(o.isDifferent&&console.log(P.default.red(`[!] Response DIFF
|
|
3
|
+
`)),l.isDifferent){console.log(P.default.red(`[!] Trace DIFF
|
|
4
|
+
`));for(let i of l.issues)console.log(` - [${i.type}] ${i.name}`)}}catch(r){throw r}}async replay(t){try{t.request.headers["x-replay-id"]=t.meta.id;let r=await this.replayHelper.sendRequest(t),n=await r.json(),o=n.__replay;delete n.__replay;let l=this.replayHelper.compareResponse({error:t.response.error,status:t.response.status},{error:n,status:r.status}),i=S(t.trace||[]),c=S(o.trace||[]),p=this.replayHelper.compareTrace(i,c);this.print({log:t,replay:r,responseDiff:l,traceDiff:p})}catch(r){throw r}}};var y=m(require("chalk"),1);var z=m(require("http"),1);var N={trace_step_match:a((s=.1)=>({weight:s,serverity:h(s),message:`trace_match (+${s}) \u2192 trace fully matches replay`}),"trace_step_match"),trace_step_not_match:a((s=.25)=>({weight:s,serverity:h(s),message:`trace_step_not_match (+${s}) \u2192 trace partially matches replay`}),"trace_step_not_match"),trace_return_data_match:a((s=.1)=>({weight:s,serverity:h(s),message:`trace_return_data_match (+${s}) \u2192 trace return data is consistent`}),"trace_return_data_match"),trace_return_data_not_match:a((s=.25)=>({weight:s,serverity:h(s),message:`trace_return_data_not_match (+${s}) \u2192 trace return data is inconsistent`}),"trace_return_data_not_match"),response_match:a((s=.1)=>({weight:s,serverity:h(s),message:`response_match (+${s}) \u2192 response is consistent`}),"response_match"),response_not_match:a((s=.25)=>({weight:s,serverity:h(s),message:`response_not_match (+${s}) \u2192 response is inconsistent`}),"response_not_match"),response_status_match:a((s=.1)=>({weight:s,serverity:h(s),message:`response_status_match (+${s}) \u2192 response status is consistent`}),"response_status_match"),response_status_not_match:a((s=.25)=>({weight:s,serverity:h(s),message:`response_status_not_match (+${s}) \u2192 response status is inconsistent`}),"response_status_not_match"),logic_error_indicator:a((s=.6)=>({weight:s,serverity:h(s),message:`logic_error_indicator (+${s}) \u2192 original response status >= 400 triggered logic flag`}),"logic_error_indicator")},j={trace_match:{value:!0,message:"flow is clean"},trace_not_match:{value:!1,message:"flow is not clean"},trace_step_match:{value:!0,message:"no mismatch"},trace_step_not_match:{value:!1,message:"mismatch"},trace_return_data_match:{value:!0,message:"no mismatch"},trace_return_data_not_match:{value:!1,message:"mismatch"},response_match:{value:!0,message:"no mismatch"},response_not_match:{value:!1,message:"mismatch"}};function h(s){return s>.75?"high":s>.55?"medium":"low"}a(h,"getSignalLevel");var C=class{static{a(this,"ReasonSignalCls")}findSignalByType(e){try{return N[e]}catch(t){throw t}}sumSignalWeights(e){try{return Object.values(e).reduce((t,r)=>t+r.weight,0)}catch(t){throw t}}};var u=m(require("chalk"),1);var R=class{static{a(this,"BaseAssignerCase")}get evidenceSource(){return j}get signalSource(){return N}getTraceDivergenceSection(e){let t=e.traceDiff.issues;if(t.length===0)return"No divergence";let r=`
|
|
5
|
+
`;for(let n of t)n.type==="missing_step"&&(r+=u.default.yellow(`
|
|
6
|
+
* ${n.name}(missing_step):
|
|
7
|
+
`),r+=u.default.green(` \u2192 original: exists
|
|
8
|
+
`),r+=u.default.red(" \u2192 replay: missing"),r+=`
|
|
9
|
+
`),n.type==="extra_step"&&(r+=u.default.yellow(`
|
|
10
|
+
* ${n.name}(extra_step):
|
|
11
|
+
`),r+=u.default.green(` \u2192 original: none
|
|
12
|
+
`),r+=u.default.red(" \u2192 replay: exists"),r+=`
|
|
13
|
+
`);return r.trim()}getMessageEdvidence(e){return`${this.evidenceSource[e].value} (${this.evidenceSource[e].message})`}getStatusEdvidence(e){let t=z.default.STATUS_CODES[e]||"Unknown";return`${e} (${t})`}isTraceMatch(e){return!e.traceDiff.isDifferent}isTraceStepMatch(e){return e.traceDiff.issues.length>0?!e.traceDiff.issues.some(t=>t.type==="missing_step"||t.type==="extra_step"):!0}isTraceReturnDataMatch(e){return e.traceDiff.issues.length>0?!e.traceDiff.issues.some(t=>t.type==="trace_return_data_mismatch"):!0}isResponseMatch(e){return!e.responseDiff.isDifferent}isResponseStatusMatch(e){let{originalStatus:t,replayStatus:r}=this.resolveStatus(e);return t===r}resolveStatus(e){return{originalStatus:Number(e.log.response.status),replayStatus:e.replayResultStatus}}getResponseDiffSection(e){let t=e.responseDiff.issues;if(t.length===0)return"No diff";let r=t.length>1?1:0,n=e.responseDiff.issues[r].not_matched;if(!n)return"No diff";let o=n.original||{},l=n.replay||{},i=new Set([...Object.keys(o),...Object.keys(l)]),c=`
|
|
14
|
+
`;for(let p of i){let f=o[p],d=l[p];f!==d&&(c+=u.default.yellow(` * ${p}:
|
|
15
|
+
`),c+=u.default.green(` \u2192 original: ${JSON.stringify(f)}
|
|
16
|
+
`),c+=u.default.red(` \u2192 replay: ${JSON.stringify(d)}
|
|
17
|
+
`))}return c}};var k=class extends R{static{a(this,"BusinessLogicRejectionCase")}condition(e,t){return this.isTraceMatch(e)&&this.isResponseMatch(e)&&t.originalStatus>=400&&t.replayStatus>=400}assign(e){try{let t=this.resolveStatus(e);if(this.condition(e,t)){let r=e.log.trace?.find(o=>o.parentId===null);return{type:"Business Logic Rejection Case (logic_suspicious)",message:"Response indicates error, but execution original and replay result match expected behavior",possibleCauses:["Business rule might not align with actual execution flow","Or validation logic is too strict / misaligned"],evidence:{traceMatch:this.getMessageEdvidence("trace_match"),responseMatch:this.getMessageEdvidence("response_match"),originalStatus:this.getStatusEdvidence(t.originalStatus),finalResponse:typeof r?.returnData=="object"?JSON.stringify(r.returnData,null,2):r?.returnData},confidence:{signals:{trace_match:this.signalSource.trace_step_match(.3),response_match:this.signalSource.response_match(.3),logic_error_indicator:this.signalSource.logic_error_indicator(.2)},result:0},finalMessage:["This is NOT a runtime bug","This is likely a business logic issue"],references:e.log.stack}}}catch(t){throw t}}};var K=class extends R{static{a(this,"PostTraceResponseMutationCase")}assign(e){try{let t=this.resolveStatus(e);if(this.isTraceStepMatch(e)&&!this.isResponseMatch(e)&&this.isTraceReturnDataMatch(e))return{type:"Response Mismatch Case (post_processing_suspicious)",message:"Execution flow is identical, but response output differs",possibleCauses:["Post-processing logic may be inconsistent","Response mapping or transformation may be incorrect","Data changes may affect the final result.","Non-deterministic behavior (e.g. random, time-based, shared state)"],evidence:{traceMatch:this.getMessageEdvidence("trace_match"),responseMatch:this.getMessageEdvidence("response_not_match"),originalStatus:this.getStatusEdvidence(t.originalStatus),responseDiff:this.getResponseDiffSection(e)},confidence:{signals:{trace_step_match:this.signalSource.trace_step_match(.3),response_mismatch:this.signalSource.response_not_match(.2),trace_return_data_match:this.signalSource.trace_return_data_match(.3)},result:0},finalMessage:["Execution logic is stable, but output is inconsistent","This may indicate issues in response transformation or side effects","This may occur after the business logic is execute complete."],references:e.log.stack}}catch(t){throw t}}};var L=class extends R{static{a(this,"TraceDivergenceCase")}assign(e){try{let t=this.resolveStatus(e);if(!this.isTraceStepMatch(e)&&!this.isResponseMatch(e)&&!this.isTraceReturnDataMatch(e)&&!this.isResponseStatusMatch(e))return{type:"Trace Divergence Case (execution_path_mismatch)",message:"Execution path diverged between original and replay",possibleCauses:["Conditional branch logic may behave differently","Environment or shared state may affect execution flow","Request context may not be deterministic","Replay execution may enter different logic branches","Hidden dependencies or side effects may exist"],evidence:{traceMatch:this.getMessageEdvidence("trace_not_match"),originalStatus:this.getStatusEdvidence(t.originalStatus),traceDivergence:this.getTraceDivergenceSection(e),responseDiff:this.getResponseDiffSection(e)},confidence:{signals:{trace_step_not_match:this.signalSource.trace_step_not_match(.45),trace_return_data_not_match:this.signalSource.trace_return_data_not_match(.25),response_not_match:this.signalSource.response_not_match(.15),response_status_not_match:this.signalSource.response_status_not_match(.1)},result:0},finalMessage:["Replay execution diverged from the original execution flow","This may indicate unstable conditions or branch inconsistency","Root cause likely exists before response generation"],references:e.log.stack}}catch(t){throw t}}};var E=class{static{a(this,"ReasonAssigner")}get case(){return{business_logic_rejection:new k,post_trace_response_mutation:new K,trace_divergence:new L}}};var g=m(require("chalk"),1);var M=class{static{a(this,"ReasonPrinter")}get reasonSignal(){return new C}title(e){console.log(g.default.yellowBright("** Reason Title:")),console.log(`[!] ${e}`)}description(e){console.log(g.default.yellowBright("** Description:")),console.log(e)}possibleCauses(e){console.log(g.default.yellowBright("** What I think happened:")),e.forEach(t=>{console.log(` \u2192 ${t}`)})}evidence(e){let t=Object.keys(e);console.log(g.default.yellowBright("** Evidence I saw:")),t.forEach(r=>{console.log(` \u2192 ${r}: ${e[r]}`)})}confidence(e){console.log(g.default.yellowBright("** Confidence Reason (why I think this): ")),e.signals&&Object.keys(e.signals).forEach(n=>{console.log(` \u2192 ${e.signals[n].message}`)}),e.result=this.reasonSignal.sumSignalWeights(e.signals);let t=Math.round(e.result*100);console.log(`
|
|
18
|
+
`),console.log(g.default.yellowBright("** Confidence Result: ")),console.log(g.default.green.italic.bold(` * score: ${e.result.toFixed(2)} / 1 `)),console.log(g.default.green.italic.bold(` * percent: ${t} / 100 (%) `))}finalMessage(e){e.length!=0&&(console.log(g.default.yellowBright("** Final Call:")),e.forEach(t=>{console.log(` \u2192 ${t}`)}))}referencePosition(e){if(e&&(console.log(g.default.yellowBright("* Reference Position: ")),console.log(" \u2192 Suspected position:",g.default.red.underline(e.primary?.full_path)),e.context&&e.context.length>0)){let t=e.context.length-1;e.context.forEach((r,n)=>{console.log(` \u2192 (Context ${t-n}): ${r.full_path}`)})}}printReason(e){try{if(!e)return;console.log(g.default.red.italic.bold(`
|
|
19
|
+
Aeeaeae yohh BUT...`)),this.title(e.type),console.log(`
|
|
20
|
+
`),this.description(e.message),console.log(`
|
|
21
|
+
`),this.possibleCauses(e.possibleCauses),console.log(`
|
|
22
|
+
`),this.evidence(e.evidence),console.log(`
|
|
23
|
+
`),this.confidence(e.confidence),console.log(`
|
|
24
|
+
`),this.finalMessage(e.finalMessage||[]),this.referencePosition(e.references)}catch(t){throw t}}};var $=class extends D{constructor(t){super(t);this.config=t}config;static{a(this,"AdvanceReplay")}get reasonPrinter(){return new M}get reasonAssigner(){return new E}printResponseDiff(t){if(t.isDifferent){console.log(y.default.red("[!] Response DIFF"));for(let r of t.issues)console.log(` - [${r.type}] ${r.message}`)}else console.log(y.default.green("[OK] Response MATCH"))}printTraceDiff(t){if(t.isDifferent){console.log(y.default.red("[!] Trace DIFF"));for(let r of t.issues)console.log(` - [${r.type}] ${r.name}`)}else console.log(y.default.green("[OK] Trace MATCH"))}printRootCauseIssue(t){if(t.length>0){let r=["performance_issue","performance_warning","performance_regression"];if(!t.every(o=>r.includes(o.type))){console.log(y.default.red("\u26A0 Root Cause Analysis"));for(let o of t)console.log(` - [${o.type}] ${o.message}`)}}else console.log(y.default.green("[OK] No root cause issues detected"))}printPerformanceIssue(t){let r=t.filter(n=>n.type==="performance_regression");if(r.length>0){console.log(y.default.yellow(`
|
|
25
|
+
\u26A0 Performance Regression Detected`));for(let n of r)console.log(`- ${n.step}: ${n.message}`)}}print(t){try{let{log:r,responseDiff:n,traceDiff:o,analysis:l}=t;console.log(y.default.bgYellowBright.bold(` \u25B6 ${r.request.method} ${r.request.url} `)),this.printResponseDiff(n),this.printTraceDiff(o),this.printRootCauseIssue(l),this.printPerformanceIssue(l),this.printReason(t)}catch(r){throw r}}printReason(t){try{let r=this.reasonAssigner.case.business_logic_rejection.assign(t);this.reasonPrinter.printReason(r);let n=this.reasonAssigner.case.post_trace_response_mutation.assign(t);this.reasonPrinter.printReason(n);let o=this.reasonAssigner.case.trace_divergence.assign(t);this.reasonPrinter.printReason(o)}catch(r){throw r}}analyzeRootCause(t){try{let{responseDiff:r,traceDiff:n,logTrace:o,replayData:l}=t,i=[],c=this.config.filters;r.isDifferent&&n.isDifferent&&i.push({type:"flow_break",message:"Response mismatch caused by trace difference"});let p=c?.expectedPerformance;if(!p)return i;for(let f of o){let d=l?.trace?.find(V=>V.name===f.name);if(!d)continue;let x=(d.duration_ms||0)-(f.duration_ms||0),U=Math.max(f.duration_ms||1,20),W=x/U*100,O=f.name.split("."),F=f.name;O.length==2?F=O[1]:F=O[0];let T=p.steps?.[F]??0;if(T===0)continue;let G=T/2;x>T?i.push({type:"performance_regression",step:f.name,severity:"high",message:`Slow step: +${x}ms > ${T}ms (+${W.toFixed(1)}%)`}):x>G&&i.push({type:"performance_warning",step:f.name,severity:"low",message:`Slight delay: +${x}ms`})}return i}catch(r){throw r}}async getTraceResult(t,r){try{let n=S(t.trace||[]),o=S(r.trace||[]),l=await this.filterManager.filterTrace(n),i=await this.filterManager.filterTrace(o),c=this.replayHelper.compareTrace(l,i);return{logTraceFiltered:l,replayTraceFiltered:i,traceDiff:c}}catch(n){throw n}}async getResponseResult(t,r,n){try{let o=await this.filterManager.filterResponse({error:JSON.parse(t.response.error),status:t.response.status}),l=await this.filterManager.filterResponse({error:r,status:n.status});return{responseDiff:this.replayHelper.compareResponse(o,l)}}catch(o){throw o}}async replay(t){try{let r=await this.replayHelper.sendRequest(t),n=await r.json(),o=n.__replay;delete n.__replay;let l=await this.getResponseResult(t,n,r),i=await this.getTraceResult(t,o),c=this.analyzeRootCause({replayData:o,traceDiff:i.traceDiff,logTrace:i.logTraceFiltered,responseDiff:l.responseDiff});r.status<=400&&c.length==0?this.print({log:t,replayResultStatus:r.status,analysis:[],traceDiff:{isDifferent:!1,issues:[]},responseDiff:{isDifferent:!1,issues:[]}}):this.print({log:t,replayResultStatus:r.status,analysis:c,traceDiff:i.traceDiff,responseDiff:l.responseDiff})}catch(r){throw r}}};var A=class{constructor(e){this.config=e}config;static{a(this,"ReplayHandler")}get replayHelper(){return new v(this.config)}async simpleReplay(e){try{console.log("Replaying log data : ",e);let r=await(await this.replayHelper.sendRequest(e)).json();console.log("Replayed response data : ",r)}catch(t){throw t}}async smartReplay(e){try{return new b(this.config).replay(e)}catch(t){throw t}}async advancedReplay(e){try{return new $(this.config).replay(e)}catch(t){throw t}}};0&&(module.exports={ReplayHandler});
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
var j=Object.defineProperty;var a=(s,e)=>j(s,"name",{value:e,configurable:!0});import"dotenv/config";import"dotenv/config.js";import{ulid as ge}from"ulid";import{AsyncLocalStorage as U}from"async_hooks";import Z from"fs";import te from"chalk";import se from"path";import{bundleRequire as ae}from"bundle-require";var ye=new U;import W from"crypto";function I(s){try{return W.createHash("md5").update(s).digest("hex")}catch(e){throw e}}a(I,"cryptoHash");var O="__root__";function G(s){let e=new Map;for(let t of s){let r=t.parentId||O;e.has(r)||e.set(r,[]),e.get(r).push(t)}return e}a(G,"buildTraceTree");function V(s,e,t){return`${t}->${s.name}#${e}`}a(V,"buildSignature");function R(s){try{let n=function(o,l){(t.get(o)||[]).sort((c,p)=>c.start-p.start).forEach((c,p)=>{let f=V(c,p,l),h=I(f);r.push({...c,signature:h,rawSignature:f}),n(c.id,h)})};var e=n;a(n,"walk");let t=G(s),r=[];return n(O,O),r}catch(t){throw t}}a(R,"flattenTrace");var S=class{constructor(e){this.config=e}config;static{a(this,"ReplayFilterManager")}matchPattern(e,t){try{return e instanceof RegExp?e.test(t):e.includes("*")?new RegExp("^"+e.replace(/\*/g,".*")+"$").test(t):e===t}catch(r){throw r}}async filterTrace(e){try{if(!this.config.filters||!e||e.length===0)return e;let t=this.config.filters;return e.filter(r=>{let n=r.name;return!t.ignoreSteps?.some(l=>this.matchPattern(l,n))})}catch(t){throw t}}async filterNonOptionalTrace(e){try{if(!this.config.filters||!e||e.length===0)return e;let t=this.config.filters;return e.filter(r=>{let n=r.name;return!t.optionalSteps?.some(l=>this.matchPattern(l,n))})}catch(t){throw t}}isOptionalStep(e){try{return this.config.filters?.optionalSteps?.some(t=>this.matchPattern(t,e))}catch(t){throw t}}async filterResponse(e){try{if(!this.config.filters||!e)return e;let t=Object.keys(e.error);if(t.length===0)return e;let r=this.config.filters;for(let n of t)r.ignoreFields?.includes(n)&&delete e.error[n];return{...e,error:e.error}}catch(t){throw t}}};var _=class{constructor(e){this.config=e}config;static{a(this,"ReplayHelper")}get filterManager(){return new S(this.config)}setConfig(e){this.config=e}normalize(e){if(!e)return e;if(typeof e=="string")try{return JSON.parse(e)}catch{return e}return e}stableStringify(e){return JSON.stringify(this.sortKeys(e))}sortKeys(e){return Array.isArray(e)?e.map(t=>this.sortKeys(t)):e&&typeof e=="object"?Object.keys(e).sort().reduce((t,r)=>(t[r]=this.sortKeys(e[r]),t),{}):e}compareTrace(e,t){try{let r=[],n=new Map(e.map(i=>[i.signature,i])),o=new Map(t.map(i=>[i.signature,i])),l={};for(let[i,c]of n)l[c.name]={id:c.id,parentId:c.parentId,original:c.returnData,replay:null},o.has(c.signature)||this.filterManager.isOptionalStep(c.name)||r.push({type:"missing_step",name:c.name,message:`Missing step: ${i}`});for(let[i,c]of o)l[c.name].replay=c.returnData,n.has(c.signature)||i&&this.filterManager.isOptionalStep(c.name)||r.push({type:"extra_step",name:c.name,message:`Extra step: ${i}`});for(let i in l){let c=l[i].original,p=l[i].replay;c!==p&&r.push({type:"trace_return_data_mismatch",name:i,message:"Trace return data mismatch",not_matched:{original:c,replay:p}})}return{isDifferent:r.length>0,issues:r}}catch(r){throw r}}compareResponse(e,t){try{let r=[];e.status!==t.status&&r.push({type:"status_mismatch",message:"Status code mismatch",not_matched:{original:e.status,replay:t.status}});let n=this.normalize(e.error),o=this.normalize(t.error),l=this.stableStringify(n),i=this.stableStringify(o);return l!==i&&r.push({type:"body_mismatch",message:"Response mismatch",not_matched:{original:n,replay:o}}),{isDifferent:r.length>0,issues:r}}catch(r){throw r}}fullUrl(e){return`${process.env.SERVER_URL}${e}`}async sendRequest(e){try{return await fetch(this.fullUrl(e.request.url),{method:e.request.method,headers:{"Content-Type":"application/json","x-is-replay":"true"},body:JSON.stringify(e.request.body)})}catch(t){throw t}}};import w from"chalk";var v=class{constructor(e){this.config=e}config;static{a(this,"BaseReplay")}get filterManager(){return new S(this.config)}get replayHelper(){return new _(this.config)}};var P=class extends v{constructor(t){super(t);this.config=t}config;static{a(this,"SmartReplay")}print(t){try{let{log:r,replay:n,responseDiff:o,traceDiff:l}=t;if(console.log(w.yellow.bold(`\u25B6 ${r.request.method} ${r.request.url}`)),!o.isDifferent&&!l.isDifferent){console.log(w.green(`[OK] Reponse & Trace match
|
|
2
|
+
`));return}if(o.isDifferent&&console.log(w.red(`[!] Response DIFF
|
|
3
|
+
`)),l.isDifferent){console.log(w.red(`[!] Trace DIFF
|
|
4
|
+
`));for(let i of l.issues)console.log(` - [${i.type}] ${i.name}`)}}catch(r){throw r}}async replay(t){try{t.request.headers["x-replay-id"]=t.meta.id;let r=await this.replayHelper.sendRequest(t),n=await r.json(),o=n.__replay;delete n.__replay;let l=this.replayHelper.compareResponse({error:t.response.error,status:t.response.status},{error:n,status:r.status}),i=R(t.trace||[]),c=R(o.trace||[]),p=this.replayHelper.compareTrace(i,c);this.print({log:t,replay:r,responseDiff:l,traceDiff:p})}catch(r){throw r}}};import d from"chalk";import Y from"http";var F={trace_step_match:a((s=.1)=>({weight:s,serverity:u(s),message:`trace_match (+${s}) \u2192 trace fully matches replay`}),"trace_step_match"),trace_step_not_match:a((s=.25)=>({weight:s,serverity:u(s),message:`trace_step_not_match (+${s}) \u2192 trace partially matches replay`}),"trace_step_not_match"),trace_return_data_match:a((s=.1)=>({weight:s,serverity:u(s),message:`trace_return_data_match (+${s}) \u2192 trace return data is consistent`}),"trace_return_data_match"),trace_return_data_not_match:a((s=.25)=>({weight:s,serverity:u(s),message:`trace_return_data_not_match (+${s}) \u2192 trace return data is inconsistent`}),"trace_return_data_not_match"),response_match:a((s=.1)=>({weight:s,serverity:u(s),message:`response_match (+${s}) \u2192 response is consistent`}),"response_match"),response_not_match:a((s=.25)=>({weight:s,serverity:u(s),message:`response_not_match (+${s}) \u2192 response is inconsistent`}),"response_not_match"),response_status_match:a((s=.1)=>({weight:s,serverity:u(s),message:`response_status_match (+${s}) \u2192 response status is consistent`}),"response_status_match"),response_status_not_match:a((s=.25)=>({weight:s,serverity:u(s),message:`response_status_not_match (+${s}) \u2192 response status is inconsistent`}),"response_status_not_match"),logic_error_indicator:a((s=.6)=>({weight:s,serverity:u(s),message:`logic_error_indicator (+${s}) \u2192 original response status >= 400 triggered logic flag`}),"logic_error_indicator")},N={trace_match:{value:!0,message:"flow is clean"},trace_not_match:{value:!1,message:"flow is not clean"},trace_step_match:{value:!0,message:"no mismatch"},trace_step_not_match:{value:!1,message:"mismatch"},trace_return_data_match:{value:!0,message:"no mismatch"},trace_return_data_not_match:{value:!1,message:"mismatch"},response_match:{value:!0,message:"no mismatch"},response_not_match:{value:!1,message:"mismatch"}};function u(s){return s>.75?"high":s>.55?"medium":"low"}a(u,"getSignalLevel");var T=class{static{a(this,"ReasonSignalCls")}findSignalByType(e){try{return F[e]}catch(t){throw t}}sumSignalWeights(e){try{return Object.values(e).reduce((t,r)=>t+r.weight,0)}catch(t){throw t}}};import m from"chalk";var y=class{static{a(this,"BaseAssignerCase")}get evidenceSource(){return N}get signalSource(){return F}getTraceDivergenceSection(e){let t=e.traceDiff.issues;if(t.length===0)return"No divergence";let r=`
|
|
5
|
+
`;for(let n of t)n.type==="missing_step"&&(r+=m.yellow(`
|
|
6
|
+
* ${n.name}(missing_step):
|
|
7
|
+
`),r+=m.green(` \u2192 original: exists
|
|
8
|
+
`),r+=m.red(" \u2192 replay: missing"),r+=`
|
|
9
|
+
`),n.type==="extra_step"&&(r+=m.yellow(`
|
|
10
|
+
* ${n.name}(extra_step):
|
|
11
|
+
`),r+=m.green(` \u2192 original: none
|
|
12
|
+
`),r+=m.red(" \u2192 replay: exists"),r+=`
|
|
13
|
+
`);return r.trim()}getMessageEdvidence(e){return`${this.evidenceSource[e].value} (${this.evidenceSource[e].message})`}getStatusEdvidence(e){let t=Y.STATUS_CODES[e]||"Unknown";return`${e} (${t})`}isTraceMatch(e){return!e.traceDiff.isDifferent}isTraceStepMatch(e){return e.traceDiff.issues.length>0?!e.traceDiff.issues.some(t=>t.type==="missing_step"||t.type==="extra_step"):!0}isTraceReturnDataMatch(e){return e.traceDiff.issues.length>0?!e.traceDiff.issues.some(t=>t.type==="trace_return_data_mismatch"):!0}isResponseMatch(e){return!e.responseDiff.isDifferent}isResponseStatusMatch(e){let{originalStatus:t,replayStatus:r}=this.resolveStatus(e);return t===r}resolveStatus(e){return{originalStatus:Number(e.log.response.status),replayStatus:e.replayResultStatus}}getResponseDiffSection(e){let t=e.responseDiff.issues;if(t.length===0)return"No diff";let r=t.length>1?1:0,n=e.responseDiff.issues[r].not_matched;if(!n)return"No diff";let o=n.original||{},l=n.replay||{},i=new Set([...Object.keys(o),...Object.keys(l)]),c=`
|
|
14
|
+
`;for(let p of i){let f=o[p],h=l[p];f!==h&&(c+=m.yellow(` * ${p}:
|
|
15
|
+
`),c+=m.green(` \u2192 original: ${JSON.stringify(f)}
|
|
16
|
+
`),c+=m.red(` \u2192 replay: ${JSON.stringify(h)}
|
|
17
|
+
`))}return c}};var b=class extends y{static{a(this,"BusinessLogicRejectionCase")}condition(e,t){return this.isTraceMatch(e)&&this.isResponseMatch(e)&&t.originalStatus>=400&&t.replayStatus>=400}assign(e){try{let t=this.resolveStatus(e);if(this.condition(e,t)){let r=e.log.trace?.find(o=>o.parentId===null);return{type:"Business Logic Rejection Case (logic_suspicious)",message:"Response indicates error, but execution original and replay result match expected behavior",possibleCauses:["Business rule might not align with actual execution flow","Or validation logic is too strict / misaligned"],evidence:{traceMatch:this.getMessageEdvidence("trace_match"),responseMatch:this.getMessageEdvidence("response_match"),originalStatus:this.getStatusEdvidence(t.originalStatus),finalResponse:typeof r?.returnData=="object"?JSON.stringify(r.returnData,null,2):r?.returnData},confidence:{signals:{trace_match:this.signalSource.trace_step_match(.3),response_match:this.signalSource.response_match(.3),logic_error_indicator:this.signalSource.logic_error_indicator(.2)},result:0},finalMessage:["This is NOT a runtime bug","This is likely a business logic issue"],references:e.log.stack}}}catch(t){throw t}}};var C=class extends y{static{a(this,"PostTraceResponseMutationCase")}assign(e){try{let t=this.resolveStatus(e);if(this.isTraceStepMatch(e)&&!this.isResponseMatch(e)&&this.isTraceReturnDataMatch(e))return{type:"Response Mismatch Case (post_processing_suspicious)",message:"Execution flow is identical, but response output differs",possibleCauses:["Post-processing logic may be inconsistent","Response mapping or transformation may be incorrect","Data changes may affect the final result.","Non-deterministic behavior (e.g. random, time-based, shared state)"],evidence:{traceMatch:this.getMessageEdvidence("trace_match"),responseMatch:this.getMessageEdvidence("response_not_match"),originalStatus:this.getStatusEdvidence(t.originalStatus),responseDiff:this.getResponseDiffSection(e)},confidence:{signals:{trace_step_match:this.signalSource.trace_step_match(.3),response_mismatch:this.signalSource.response_not_match(.2),trace_return_data_match:this.signalSource.trace_return_data_match(.3)},result:0},finalMessage:["Execution logic is stable, but output is inconsistent","This may indicate issues in response transformation or side effects","This may occur after the business logic is execute complete."],references:e.log.stack}}catch(t){throw t}}};var k=class extends y{static{a(this,"TraceDivergenceCase")}assign(e){try{let t=this.resolveStatus(e);if(!this.isTraceStepMatch(e)&&!this.isResponseMatch(e)&&!this.isTraceReturnDataMatch(e)&&!this.isResponseStatusMatch(e))return{type:"Trace Divergence Case (execution_path_mismatch)",message:"Execution path diverged between original and replay",possibleCauses:["Conditional branch logic may behave differently","Environment or shared state may affect execution flow","Request context may not be deterministic","Replay execution may enter different logic branches","Hidden dependencies or side effects may exist"],evidence:{traceMatch:this.getMessageEdvidence("trace_not_match"),originalStatus:this.getStatusEdvidence(t.originalStatus),traceDivergence:this.getTraceDivergenceSection(e),responseDiff:this.getResponseDiffSection(e)},confidence:{signals:{trace_step_not_match:this.signalSource.trace_step_not_match(.45),trace_return_data_not_match:this.signalSource.trace_return_data_not_match(.25),response_not_match:this.signalSource.response_not_match(.15),response_status_not_match:this.signalSource.response_status_not_match(.1)},result:0},finalMessage:["Replay execution diverged from the original execution flow","This may indicate unstable conditions or branch inconsistency","Root cause likely exists before response generation"],references:e.log.stack}}catch(t){throw t}}};var K=class{static{a(this,"ReasonAssigner")}get case(){return{business_logic_rejection:new b,post_trace_response_mutation:new C,trace_divergence:new k}}};import g from"chalk";var L=class{static{a(this,"ReasonPrinter")}get reasonSignal(){return new T}title(e){console.log(g.yellowBright("** Reason Title:")),console.log(`[!] ${e}`)}description(e){console.log(g.yellowBright("** Description:")),console.log(e)}possibleCauses(e){console.log(g.yellowBright("** What I think happened:")),e.forEach(t=>{console.log(` \u2192 ${t}`)})}evidence(e){let t=Object.keys(e);console.log(g.yellowBright("** Evidence I saw:")),t.forEach(r=>{console.log(` \u2192 ${r}: ${e[r]}`)})}confidence(e){console.log(g.yellowBright("** Confidence Reason (why I think this): ")),e.signals&&Object.keys(e.signals).forEach(n=>{console.log(` \u2192 ${e.signals[n].message}`)}),e.result=this.reasonSignal.sumSignalWeights(e.signals);let t=Math.round(e.result*100);console.log(`
|
|
18
|
+
`),console.log(g.yellowBright("** Confidence Result: ")),console.log(g.green.italic.bold(` * score: ${e.result.toFixed(2)} / 1 `)),console.log(g.green.italic.bold(` * percent: ${t} / 100 (%) `))}finalMessage(e){e.length!=0&&(console.log(g.yellowBright("** Final Call:")),e.forEach(t=>{console.log(` \u2192 ${t}`)}))}referencePosition(e){if(e&&(console.log(g.yellowBright("* Reference Position: ")),console.log(" \u2192 Suspected position:",g.red.underline(e.primary?.full_path)),e.context&&e.context.length>0)){let t=e.context.length-1;e.context.forEach((r,n)=>{console.log(` \u2192 (Context ${t-n}): ${r.full_path}`)})}}printReason(e){try{if(!e)return;console.log(g.red.italic.bold(`
|
|
19
|
+
Aeeaeae yohh BUT...`)),this.title(e.type),console.log(`
|
|
20
|
+
`),this.description(e.message),console.log(`
|
|
21
|
+
`),this.possibleCauses(e.possibleCauses),console.log(`
|
|
22
|
+
`),this.evidence(e.evidence),console.log(`
|
|
23
|
+
`),this.confidence(e.confidence),console.log(`
|
|
24
|
+
`),this.finalMessage(e.finalMessage||[]),this.referencePosition(e.references)}catch(t){throw t}}};var E=class extends v{constructor(t){super(t);this.config=t}config;static{a(this,"AdvanceReplay")}get reasonPrinter(){return new L}get reasonAssigner(){return new K}printResponseDiff(t){if(t.isDifferent){console.log(d.red("[!] Response DIFF"));for(let r of t.issues)console.log(` - [${r.type}] ${r.message}`)}else console.log(d.green("[OK] Response MATCH"))}printTraceDiff(t){if(t.isDifferent){console.log(d.red("[!] Trace DIFF"));for(let r of t.issues)console.log(` - [${r.type}] ${r.name}`)}else console.log(d.green("[OK] Trace MATCH"))}printRootCauseIssue(t){if(t.length>0){let r=["performance_issue","performance_warning","performance_regression"];if(!t.every(o=>r.includes(o.type))){console.log(d.red("\u26A0 Root Cause Analysis"));for(let o of t)console.log(` - [${o.type}] ${o.message}`)}}else console.log(d.green("[OK] No root cause issues detected"))}printPerformanceIssue(t){let r=t.filter(n=>n.type==="performance_regression");if(r.length>0){console.log(d.yellow(`
|
|
25
|
+
\u26A0 Performance Regression Detected`));for(let n of r)console.log(`- ${n.step}: ${n.message}`)}}print(t){try{let{log:r,responseDiff:n,traceDiff:o,analysis:l}=t;console.log(d.bgYellowBright.bold(` \u25B6 ${r.request.method} ${r.request.url} `)),this.printResponseDiff(n),this.printTraceDiff(o),this.printRootCauseIssue(l),this.printPerformanceIssue(l),this.printReason(t)}catch(r){throw r}}printReason(t){try{let r=this.reasonAssigner.case.business_logic_rejection.assign(t);this.reasonPrinter.printReason(r);let n=this.reasonAssigner.case.post_trace_response_mutation.assign(t);this.reasonPrinter.printReason(n);let o=this.reasonAssigner.case.trace_divergence.assign(t);this.reasonPrinter.printReason(o)}catch(r){throw r}}analyzeRootCause(t){try{let{responseDiff:r,traceDiff:n,logTrace:o,replayData:l}=t,i=[],c=this.config.filters;r.isDifferent&&n.isDifferent&&i.push({type:"flow_break",message:"Response mismatch caused by trace difference"});let p=c?.expectedPerformance;if(!p)return i;for(let f of o){let h=l?.trace?.find(J=>J.name===f.name);if(!h)continue;let D=(h.duration_ms||0)-(f.duration_ms||0),B=Math.max(f.duration_ms||1,20),H=D/B*100,M=f.name.split("."),$=f.name;M.length==2?$=M[1]:$=M[0];let x=p.steps?.[$]??0;if(x===0)continue;let q=x/2;D>x?i.push({type:"performance_regression",step:f.name,severity:"high",message:`Slow step: +${D}ms > ${x}ms (+${H.toFixed(1)}%)`}):D>q&&i.push({type:"performance_warning",step:f.name,severity:"low",message:`Slight delay: +${D}ms`})}return i}catch(r){throw r}}async getTraceResult(t,r){try{let n=R(t.trace||[]),o=R(r.trace||[]),l=await this.filterManager.filterTrace(n),i=await this.filterManager.filterTrace(o),c=this.replayHelper.compareTrace(l,i);return{logTraceFiltered:l,replayTraceFiltered:i,traceDiff:c}}catch(n){throw n}}async getResponseResult(t,r,n){try{let o=await this.filterManager.filterResponse({error:JSON.parse(t.response.error),status:t.response.status}),l=await this.filterManager.filterResponse({error:r,status:n.status});return{responseDiff:this.replayHelper.compareResponse(o,l)}}catch(o){throw o}}async replay(t){try{let r=await this.replayHelper.sendRequest(t),n=await r.json(),o=n.__replay;delete n.__replay;let l=await this.getResponseResult(t,n,r),i=await this.getTraceResult(t,o),c=this.analyzeRootCause({replayData:o,traceDiff:i.traceDiff,logTrace:i.logTraceFiltered,responseDiff:l.responseDiff});r.status<=400&&c.length==0?this.print({log:t,replayResultStatus:r.status,analysis:[],traceDiff:{isDifferent:!1,issues:[]},responseDiff:{isDifferent:!1,issues:[]}}):this.print({log:t,replayResultStatus:r.status,analysis:c,traceDiff:i.traceDiff,responseDiff:l.responseDiff})}catch(r){throw r}}};var A=class{constructor(e){this.config=e}config;static{a(this,"ReplayHandler")}get replayHelper(){return new _(this.config)}async simpleReplay(e){try{console.log("Replaying log data : ",e);let r=await(await this.replayHelper.sendRequest(e)).json();console.log("Replayed response data : ",r)}catch(t){throw t}}async smartReplay(e){try{return new P(this.config).replay(e)}catch(t){throw t}}async advancedReplay(e){try{return new E(this.config).replay(e)}catch(t){throw t}}};export{A as ReplayHandler};
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
"use strict";var W=Object.create;var v=Object.defineProperty;var G=Object.getOwnPropertyDescriptor;var V=Object.getOwnPropertyNames;var Y=Object.getPrototypeOf,Q=Object.prototype.hasOwnProperty;var a=(s,e)=>v(s,"name",{value:e,configurable:!0});var X=(s,e)=>{for(var t in e)v(s,t,{get:e[t],enumerable:!0})},I=(s,e,t,r)=>{if(e&&typeof e=="object"||typeof e=="function")for(let n of V(e))!Q.call(s,n)&&n!==t&&v(s,n,{get:()=>e[n],enumerable:!(r=G(e,n))||r.enumerable});return s};var d=(s,e,t)=>(t=s!=null?W(Y(s)):{},I(e||!s||!s.__esModule?v(t,"default",{value:s,enumerable:!0}):t,s)),Z=s=>I(v({},"__esModule",{value:!0}),s);var ce={};X(ce,{AdvanceReplay:()=>F});module.exports=Z(ce);var h=d(require("chalk"),1);var ae=require("ulid"),N=require("async_hooks");var ee=d(require("fs"),1),te=d(require("chalk"),1),re=d(require("path"),1),se=require("bundle-require");var de=new N.AsyncLocalStorage;var A=d(require("crypto"),1);function B(s){try{return A.default.createHash("md5").update(s).digest("hex")}catch(e){throw e}}a(B,"cryptoHash");var L="__root__";function oe(s){let e=new Map;for(let t of s){let r=t.parentId||L;e.has(r)||e.set(r,[]),e.get(r).push(t)}return e}a(oe,"buildTraceTree");function ie(s,e,t){return`${t}->${s.name}#${e}`}a(ie,"buildSignature");function $(s){try{let n=function(o,l){(t.get(o)||[]).sort((i,p)=>i.start-p.start).forEach((i,p)=>{let f=ie(i,p,l),y=B(f);r.push({...i,signature:y,rawSignature:f}),n(i.id,y)})};var e=n;a(n,"walk");let t=oe(s),r=[];return n(L,L),r}catch(t){throw t}}a($,"flattenTrace");var S=class{constructor(e){this.config=e}config;static{a(this,"ReplayFilterManager")}matchPattern(e,t){try{return e instanceof RegExp?e.test(t):e.includes("*")?new RegExp("^"+e.replace(/\*/g,".*")+"$").test(t):e===t}catch(r){throw r}}async filterTrace(e){try{if(!this.config.filters||!e||e.length===0)return e;let t=this.config.filters;return e.filter(r=>{let n=r.name;return!t.ignoreSteps?.some(l=>this.matchPattern(l,n))})}catch(t){throw t}}async filterNonOptionalTrace(e){try{if(!this.config.filters||!e||e.length===0)return e;let t=this.config.filters;return e.filter(r=>{let n=r.name;return!t.optionalSteps?.some(l=>this.matchPattern(l,n))})}catch(t){throw t}}isOptionalStep(e){try{return this.config.filters?.optionalSteps?.some(t=>this.matchPattern(t,e))}catch(t){throw t}}async filterResponse(e){try{if(!this.config.filters||!e)return e;let t=Object.keys(e.error);if(t.length===0)return e;let r=this.config.filters;for(let n of t)r.ignoreFields?.includes(n)&&delete e.error[n];return{...e,error:e.error}}catch(t){throw t}}};var st=require("dotenv/config.js");var D=class{constructor(e){this.config=e}config;static{a(this,"ReplayHelper")}get filterManager(){return new S(this.config)}setConfig(e){this.config=e}normalize(e){if(!e)return e;if(typeof e=="string")try{return JSON.parse(e)}catch{return e}return e}stableStringify(e){return JSON.stringify(this.sortKeys(e))}sortKeys(e){return Array.isArray(e)?e.map(t=>this.sortKeys(t)):e&&typeof e=="object"?Object.keys(e).sort().reduce((t,r)=>(t[r]=this.sortKeys(e[r]),t),{}):e}compareTrace(e,t){try{let r=[],n=new Map(e.map(c=>[c.signature,c])),o=new Map(t.map(c=>[c.signature,c])),l={};for(let[c,i]of n)l[i.name]={id:i.id,parentId:i.parentId,original:i.returnData,replay:null},o.has(i.signature)||this.filterManager.isOptionalStep(i.name)||r.push({type:"missing_step",name:i.name,message:`Missing step: ${c}`});for(let[c,i]of o)l[i.name].replay=i.returnData,n.has(i.signature)||c&&this.filterManager.isOptionalStep(i.name)||r.push({type:"extra_step",name:i.name,message:`Extra step: ${c}`});for(let c in l){let i=l[c].original,p=l[c].replay;i!==p&&r.push({type:"trace_return_data_mismatch",name:c,message:"Trace return data mismatch",not_matched:{original:i,replay:p}})}return{isDifferent:r.length>0,issues:r}}catch(r){throw r}}compareResponse(e,t){try{let r=[];e.status!==t.status&&r.push({type:"status_mismatch",message:"Status code mismatch",not_matched:{original:e.status,replay:t.status}});let n=this.normalize(e.error),o=this.normalize(t.error),l=this.stableStringify(n),c=this.stableStringify(o);return l!==c&&r.push({type:"body_mismatch",message:"Response mismatch",not_matched:{original:n,replay:o}}),{isDifferent:r.length>0,issues:r}}catch(r){throw r}}fullUrl(e){return`${process.env.SERVER_URL}${e}`}async sendRequest(e){try{return await fetch(this.fullUrl(e.request.url),{method:e.request.method,headers:{"Content-Type":"application/json","x-is-replay":"true"},body:JSON.stringify(e.request.body)})}catch(t){throw t}}};var w=class{constructor(e){this.config=e}config;static{a(this,"BaseReplay")}get filterManager(){return new S(this.config)}get replayHelper(){return new D(this.config)}};var H=d(require("http"),1);var O={trace_step_match:a((s=.1)=>({weight:s,serverity:m(s),message:`trace_match (+${s}) \u2192 trace fully matches replay`}),"trace_step_match"),trace_step_not_match:a((s=.25)=>({weight:s,serverity:m(s),message:`trace_step_not_match (+${s}) \u2192 trace partially matches replay`}),"trace_step_not_match"),trace_return_data_match:a((s=.1)=>({weight:s,serverity:m(s),message:`trace_return_data_match (+${s}) \u2192 trace return data is consistent`}),"trace_return_data_match"),trace_return_data_not_match:a((s=.25)=>({weight:s,serverity:m(s),message:`trace_return_data_not_match (+${s}) \u2192 trace return data is inconsistent`}),"trace_return_data_not_match"),response_match:a((s=.1)=>({weight:s,serverity:m(s),message:`response_match (+${s}) \u2192 response is consistent`}),"response_match"),response_not_match:a((s=.25)=>({weight:s,serverity:m(s),message:`response_not_match (+${s}) \u2192 response is inconsistent`}),"response_not_match"),response_status_match:a((s=.1)=>({weight:s,serverity:m(s),message:`response_status_match (+${s}) \u2192 response status is consistent`}),"response_status_match"),response_status_not_match:a((s=.25)=>({weight:s,serverity:m(s),message:`response_status_not_match (+${s}) \u2192 response status is inconsistent`}),"response_status_not_match"),logic_error_indicator:a((s=.6)=>({weight:s,serverity:m(s),message:`logic_error_indicator (+${s}) \u2192 original response status >= 400 triggered logic flag`}),"logic_error_indicator")},q={trace_match:{value:!0,message:"flow is clean"},trace_not_match:{value:!1,message:"flow is not clean"},trace_step_match:{value:!0,message:"no mismatch"},trace_step_not_match:{value:!1,message:"mismatch"},trace_return_data_match:{value:!0,message:"no mismatch"},trace_return_data_not_match:{value:!1,message:"mismatch"},response_match:{value:!0,message:"no mismatch"},response_not_match:{value:!1,message:"mismatch"}};function m(s){return s>.75?"high":s>.55?"medium":"low"}a(m,"getSignalLevel");var P=class{static{a(this,"ReasonSignalCls")}findSignalByType(e){try{return O[e]}catch(t){throw t}}sumSignalWeights(e){try{return Object.values(e).reduce((t,r)=>t+r.weight,0)}catch(t){throw t}}};var u=d(require("chalk"),1);var R=class{static{a(this,"BaseAssignerCase")}get evidenceSource(){return q}get signalSource(){return O}getTraceDivergenceSection(e){let t=e.traceDiff.issues;if(t.length===0)return"No divergence";let r=`
|
|
2
|
+
`;for(let n of t)n.type==="missing_step"&&(r+=u.default.yellow(`
|
|
3
|
+
* ${n.name}(missing_step):
|
|
4
|
+
`),r+=u.default.green(` \u2192 original: exists
|
|
5
|
+
`),r+=u.default.red(" \u2192 replay: missing"),r+=`
|
|
6
|
+
`),n.type==="extra_step"&&(r+=u.default.yellow(`
|
|
7
|
+
* ${n.name}(extra_step):
|
|
8
|
+
`),r+=u.default.green(` \u2192 original: none
|
|
9
|
+
`),r+=u.default.red(" \u2192 replay: exists"),r+=`
|
|
10
|
+
`);return r.trim()}getMessageEdvidence(e){return`${this.evidenceSource[e].value} (${this.evidenceSource[e].message})`}getStatusEdvidence(e){let t=H.default.STATUS_CODES[e]||"Unknown";return`${e} (${t})`}isTraceMatch(e){return!e.traceDiff.isDifferent}isTraceStepMatch(e){return e.traceDiff.issues.length>0?!e.traceDiff.issues.some(t=>t.type==="missing_step"||t.type==="extra_step"):!0}isTraceReturnDataMatch(e){return e.traceDiff.issues.length>0?!e.traceDiff.issues.some(t=>t.type==="trace_return_data_mismatch"):!0}isResponseMatch(e){return!e.responseDiff.isDifferent}isResponseStatusMatch(e){let{originalStatus:t,replayStatus:r}=this.resolveStatus(e);return t===r}resolveStatus(e){return{originalStatus:Number(e.log.response.status),replayStatus:e.replayResultStatus}}getResponseDiffSection(e){let t=e.responseDiff.issues;if(t.length===0)return"No diff";let r=t.length>1?1:0,n=e.responseDiff.issues[r].not_matched;if(!n)return"No diff";let o=n.original||{},l=n.replay||{},c=new Set([...Object.keys(o),...Object.keys(l)]),i=`
|
|
11
|
+
`;for(let p of c){let f=o[p],y=l[p];f!==y&&(i+=u.default.yellow(` * ${p}:
|
|
12
|
+
`),i+=u.default.green(` \u2192 original: ${JSON.stringify(f)}
|
|
13
|
+
`),i+=u.default.red(` \u2192 replay: ${JSON.stringify(y)}
|
|
14
|
+
`))}return i}};var T=class extends R{static{a(this,"BusinessLogicRejectionCase")}condition(e,t){return this.isTraceMatch(e)&&this.isResponseMatch(e)&&t.originalStatus>=400&&t.replayStatus>=400}assign(e){try{let t=this.resolveStatus(e);if(this.condition(e,t)){let r=e.log.trace?.find(o=>o.parentId===null);return{type:"Business Logic Rejection Case (logic_suspicious)",message:"Response indicates error, but execution original and replay result match expected behavior",possibleCauses:["Business rule might not align with actual execution flow","Or validation logic is too strict / misaligned"],evidence:{traceMatch:this.getMessageEdvidence("trace_match"),responseMatch:this.getMessageEdvidence("response_match"),originalStatus:this.getStatusEdvidence(t.originalStatus),finalResponse:typeof r?.returnData=="object"?JSON.stringify(r.returnData,null,2):r?.returnData},confidence:{signals:{trace_match:this.signalSource.trace_step_match(.3),response_match:this.signalSource.response_match(.3),logic_error_indicator:this.signalSource.logic_error_indicator(.2)},result:0},finalMessage:["This is NOT a runtime bug","This is likely a business logic issue"],references:e.log.stack}}}catch(t){throw t}}};var b=class extends R{static{a(this,"PostTraceResponseMutationCase")}assign(e){try{let t=this.resolveStatus(e);if(this.isTraceStepMatch(e)&&!this.isResponseMatch(e)&&this.isTraceReturnDataMatch(e))return{type:"Response Mismatch Case (post_processing_suspicious)",message:"Execution flow is identical, but response output differs",possibleCauses:["Post-processing logic may be inconsistent","Response mapping or transformation may be incorrect","Data changes may affect the final result.","Non-deterministic behavior (e.g. random, time-based, shared state)"],evidence:{traceMatch:this.getMessageEdvidence("trace_match"),responseMatch:this.getMessageEdvidence("response_not_match"),originalStatus:this.getStatusEdvidence(t.originalStatus),responseDiff:this.getResponseDiffSection(e)},confidence:{signals:{trace_step_match:this.signalSource.trace_step_match(.3),response_mismatch:this.signalSource.response_not_match(.2),trace_return_data_match:this.signalSource.trace_return_data_match(.3)},result:0},finalMessage:["Execution logic is stable, but output is inconsistent","This may indicate issues in response transformation or side effects","This may occur after the business logic is execute complete."],references:e.log.stack}}catch(t){throw t}}};var C=class extends R{static{a(this,"TraceDivergenceCase")}assign(e){try{let t=this.resolveStatus(e);if(!this.isTraceStepMatch(e)&&!this.isResponseMatch(e)&&!this.isTraceReturnDataMatch(e)&&!this.isResponseStatusMatch(e))return{type:"Trace Divergence Case (execution_path_mismatch)",message:"Execution path diverged between original and replay",possibleCauses:["Conditional branch logic may behave differently","Environment or shared state may affect execution flow","Request context may not be deterministic","Replay execution may enter different logic branches","Hidden dependencies or side effects may exist"],evidence:{traceMatch:this.getMessageEdvidence("trace_not_match"),originalStatus:this.getStatusEdvidence(t.originalStatus),traceDivergence:this.getTraceDivergenceSection(e),responseDiff:this.getResponseDiffSection(e)},confidence:{signals:{trace_step_not_match:this.signalSource.trace_step_not_match(.45),trace_return_data_not_match:this.signalSource.trace_return_data_not_match(.25),response_not_match:this.signalSource.response_not_match(.15),response_status_not_match:this.signalSource.response_status_not_match(.1)},result:0},finalMessage:["Replay execution diverged from the original execution flow","This may indicate unstable conditions or branch inconsistency","Root cause likely exists before response generation"],references:e.log.stack}}catch(t){throw t}}};var k=class{static{a(this,"ReasonAssigner")}get case(){return{business_logic_rejection:new T,post_trace_response_mutation:new b,trace_divergence:new C}}};var g=d(require("chalk"),1);var E=class{static{a(this,"ReasonPrinter")}get reasonSignal(){return new P}title(e){console.log(g.default.yellowBright("** Reason Title:")),console.log(`[!] ${e}`)}description(e){console.log(g.default.yellowBright("** Description:")),console.log(e)}possibleCauses(e){console.log(g.default.yellowBright("** What I think happened:")),e.forEach(t=>{console.log(` \u2192 ${t}`)})}evidence(e){let t=Object.keys(e);console.log(g.default.yellowBright("** Evidence I saw:")),t.forEach(r=>{console.log(` \u2192 ${r}: ${e[r]}`)})}confidence(e){console.log(g.default.yellowBright("** Confidence Reason (why I think this): ")),e.signals&&Object.keys(e.signals).forEach(n=>{console.log(` \u2192 ${e.signals[n].message}`)}),e.result=this.reasonSignal.sumSignalWeights(e.signals);let t=Math.round(e.result*100);console.log(`
|
|
15
|
+
`),console.log(g.default.yellowBright("** Confidence Result: ")),console.log(g.default.green.italic.bold(` * score: ${e.result.toFixed(2)} / 1 `)),console.log(g.default.green.italic.bold(` * percent: ${t} / 100 (%) `))}finalMessage(e){e.length!=0&&(console.log(g.default.yellowBright("** Final Call:")),e.forEach(t=>{console.log(` \u2192 ${t}`)}))}referencePosition(e){if(e&&(console.log(g.default.yellowBright("* Reference Position: ")),console.log(" \u2192 Suspected position:",g.default.red.underline(e.primary?.full_path)),e.context&&e.context.length>0)){let t=e.context.length-1;e.context.forEach((r,n)=>{console.log(` \u2192 (Context ${t-n}): ${r.full_path}`)})}}printReason(e){try{if(!e)return;console.log(g.default.red.italic.bold(`
|
|
16
|
+
Aeeaeae yohh BUT...`)),this.title(e.type),console.log(`
|
|
17
|
+
`),this.description(e.message),console.log(`
|
|
18
|
+
`),this.possibleCauses(e.possibleCauses),console.log(`
|
|
19
|
+
`),this.evidence(e.evidence),console.log(`
|
|
20
|
+
`),this.confidence(e.confidence),console.log(`
|
|
21
|
+
`),this.finalMessage(e.finalMessage||[]),this.referencePosition(e.references)}catch(t){throw t}}};var F=class extends w{constructor(t){super(t);this.config=t}config;static{a(this,"AdvanceReplay")}get reasonPrinter(){return new E}get reasonAssigner(){return new k}printResponseDiff(t){if(t.isDifferent){console.log(h.default.red("[!] Response DIFF"));for(let r of t.issues)console.log(` - [${r.type}] ${r.message}`)}else console.log(h.default.green("[OK] Response MATCH"))}printTraceDiff(t){if(t.isDifferent){console.log(h.default.red("[!] Trace DIFF"));for(let r of t.issues)console.log(` - [${r.type}] ${r.name}`)}else console.log(h.default.green("[OK] Trace MATCH"))}printRootCauseIssue(t){if(t.length>0){let r=["performance_issue","performance_warning","performance_regression"];if(!t.every(o=>r.includes(o.type))){console.log(h.default.red("\u26A0 Root Cause Analysis"));for(let o of t)console.log(` - [${o.type}] ${o.message}`)}}else console.log(h.default.green("[OK] No root cause issues detected"))}printPerformanceIssue(t){let r=t.filter(n=>n.type==="performance_regression");if(r.length>0){console.log(h.default.yellow(`
|
|
22
|
+
\u26A0 Performance Regression Detected`));for(let n of r)console.log(`- ${n.step}: ${n.message}`)}}print(t){try{let{log:r,responseDiff:n,traceDiff:o,analysis:l}=t;console.log(h.default.bgYellowBright.bold(` \u25B6 ${r.request.method} ${r.request.url} `)),this.printResponseDiff(n),this.printTraceDiff(o),this.printRootCauseIssue(l),this.printPerformanceIssue(l),this.printReason(t)}catch(r){throw r}}printReason(t){try{let r=this.reasonAssigner.case.business_logic_rejection.assign(t);this.reasonPrinter.printReason(r);let n=this.reasonAssigner.case.post_trace_response_mutation.assign(t);this.reasonPrinter.printReason(n);let o=this.reasonAssigner.case.trace_divergence.assign(t);this.reasonPrinter.printReason(o)}catch(r){throw r}}analyzeRootCause(t){try{let{responseDiff:r,traceDiff:n,logTrace:o,replayData:l}=t,c=[],i=this.config.filters;r.isDifferent&&n.isDifferent&&c.push({type:"flow_break",message:"Response mismatch caused by trace difference"});let p=i?.expectedPerformance;if(!p)return c;for(let f of o){let y=l?.trace?.find(U=>U.name===f.name);if(!y)continue;let _=(y.duration_ms||0)-(f.duration_ms||0),J=Math.max(f.duration_ms||1,20),j=_/J*100,M=f.name.split("."),K=f.name;M.length==2?K=M[1]:K=M[0];let x=p.steps?.[K]??0;if(x===0)continue;let z=x/2;_>x?c.push({type:"performance_regression",step:f.name,severity:"high",message:`Slow step: +${_}ms > ${x}ms (+${j.toFixed(1)}%)`}):_>z&&c.push({type:"performance_warning",step:f.name,severity:"low",message:`Slight delay: +${_}ms`})}return c}catch(r){throw r}}async getTraceResult(t,r){try{let n=$(t.trace||[]),o=$(r.trace||[]),l=await this.filterManager.filterTrace(n),c=await this.filterManager.filterTrace(o),i=this.replayHelper.compareTrace(l,c);return{logTraceFiltered:l,replayTraceFiltered:c,traceDiff:i}}catch(n){throw n}}async getResponseResult(t,r,n){try{let o=await this.filterManager.filterResponse({error:JSON.parse(t.response.error),status:t.response.status}),l=await this.filterManager.filterResponse({error:r,status:n.status});return{responseDiff:this.replayHelper.compareResponse(o,l)}}catch(o){throw o}}async replay(t){try{let r=await this.replayHelper.sendRequest(t),n=await r.json(),o=n.__replay;delete n.__replay;let l=await this.getResponseResult(t,n,r),c=await this.getTraceResult(t,o),i=this.analyzeRootCause({replayData:o,traceDiff:c.traceDiff,logTrace:c.logTraceFiltered,responseDiff:l.responseDiff});r.status<=400&&i.length==0?this.print({log:t,replayResultStatus:r.status,analysis:[],traceDiff:{isDifferent:!1,issues:[]},responseDiff:{isDifferent:!1,issues:[]}}):this.print({log:t,replayResultStatus:r.status,analysis:i,traceDiff:c.traceDiff,responseDiff:l.responseDiff})}catch(r){throw r}}};0&&(module.exports={AdvanceReplay});
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export { AdvanceReplay, PrintParams, RootCauseParams, RootCauseReason } from './replay.cjs';
|
|
2
|
+
import '../../handler.cjs';
|
|
3
|
+
import '../../../error_handle.helper-CQsPSbuz.cjs';
|
|
4
|
+
import 'async_hooks';
|
|
5
|
+
import '../../../setup.cjs';
|
|
6
|
+
import '../../../index-MBKv_hsI.cjs';
|
|
7
|
+
import '../../../enum/log_level.enum.cjs';
|
|
8
|
+
import '../../base.cjs';
|
|
9
|
+
import '../../../trace/filter.cjs';
|
|
10
|
+
import '../../helper.cjs';
|
|
11
|
+
import './reasons/reason_signal.cjs';
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export { AdvanceReplay, PrintParams, RootCauseParams, RootCauseReason } from './replay.js';
|
|
2
|
+
import '../../handler.js';
|
|
3
|
+
import '../../../error_handle.helper-CQsPSbuz.js';
|
|
4
|
+
import 'async_hooks';
|
|
5
|
+
import '../../../setup.js';
|
|
6
|
+
import '../../../index-8u1_ya-u.js';
|
|
7
|
+
import '../../../enum/log_level.enum.js';
|
|
8
|
+
import '../../base.js';
|
|
9
|
+
import '../../../trace/filter.js';
|
|
10
|
+
import '../../helper.js';
|
|
11
|
+
import './reasons/reason_signal.js';
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
var q=Object.defineProperty;var a=(s,e)=>q(s,"name",{value:e,configurable:!0});import d from"chalk";import{ulid as le}from"ulid";import{AsyncLocalStorage as J}from"async_hooks";import Y from"fs";import X from"chalk";import ee from"path";import{bundleRequire as re}from"bundle-require";var ue=new J;import j from"crypto";function $(s){try{return j.createHash("md5").update(s).digest("hex")}catch(e){throw e}}a($,"cryptoHash");var M="__root__";function z(s){let e=new Map;for(let t of s){let r=t.parentId||M;e.has(r)||e.set(r,[]),e.get(r).push(t)}return e}a(z,"buildTraceTree");function U(s,e,t){return`${t}->${s.name}#${e}`}a(U,"buildSignature");function K(s){try{let n=function(o,l){(t.get(o)||[]).sort((i,p)=>i.start-p.start).forEach((i,p)=>{let f=U(i,p,l),h=$(f);r.push({...i,signature:h,rawSignature:f}),n(i.id,h)})};var e=n;a(n,"walk");let t=z(s),r=[];return n(M,M),r}catch(t){throw t}}a(K,"flattenTrace");var R=class{constructor(e){this.config=e}config;static{a(this,"ReplayFilterManager")}matchPattern(e,t){try{return e instanceof RegExp?e.test(t):e.includes("*")?new RegExp("^"+e.replace(/\*/g,".*")+"$").test(t):e===t}catch(r){throw r}}async filterTrace(e){try{if(!this.config.filters||!e||e.length===0)return e;let t=this.config.filters;return e.filter(r=>{let n=r.name;return!t.ignoreSteps?.some(l=>this.matchPattern(l,n))})}catch(t){throw t}}async filterNonOptionalTrace(e){try{if(!this.config.filters||!e||e.length===0)return e;let t=this.config.filters;return e.filter(r=>{let n=r.name;return!t.optionalSteps?.some(l=>this.matchPattern(l,n))})}catch(t){throw t}}isOptionalStep(e){try{return this.config.filters?.optionalSteps?.some(t=>this.matchPattern(t,e))}catch(t){throw t}}async filterResponse(e){try{if(!this.config.filters||!e)return e;let t=Object.keys(e.error);if(t.length===0)return e;let r=this.config.filters;for(let n of t)r.ignoreFields?.includes(n)&&delete e.error[n];return{...e,error:e.error}}catch(t){throw t}}};import"dotenv/config.js";var v=class{constructor(e){this.config=e}config;static{a(this,"ReplayHelper")}get filterManager(){return new R(this.config)}setConfig(e){this.config=e}normalize(e){if(!e)return e;if(typeof e=="string")try{return JSON.parse(e)}catch{return e}return e}stableStringify(e){return JSON.stringify(this.sortKeys(e))}sortKeys(e){return Array.isArray(e)?e.map(t=>this.sortKeys(t)):e&&typeof e=="object"?Object.keys(e).sort().reduce((t,r)=>(t[r]=this.sortKeys(e[r]),t),{}):e}compareTrace(e,t){try{let r=[],n=new Map(e.map(c=>[c.signature,c])),o=new Map(t.map(c=>[c.signature,c])),l={};for(let[c,i]of n)l[i.name]={id:i.id,parentId:i.parentId,original:i.returnData,replay:null},o.has(i.signature)||this.filterManager.isOptionalStep(i.name)||r.push({type:"missing_step",name:i.name,message:`Missing step: ${c}`});for(let[c,i]of o)l[i.name].replay=i.returnData,n.has(i.signature)||c&&this.filterManager.isOptionalStep(i.name)||r.push({type:"extra_step",name:i.name,message:`Extra step: ${c}`});for(let c in l){let i=l[c].original,p=l[c].replay;i!==p&&r.push({type:"trace_return_data_mismatch",name:c,message:"Trace return data mismatch",not_matched:{original:i,replay:p}})}return{isDifferent:r.length>0,issues:r}}catch(r){throw r}}compareResponse(e,t){try{let r=[];e.status!==t.status&&r.push({type:"status_mismatch",message:"Status code mismatch",not_matched:{original:e.status,replay:t.status}});let n=this.normalize(e.error),o=this.normalize(t.error),l=this.stableStringify(n),c=this.stableStringify(o);return l!==c&&r.push({type:"body_mismatch",message:"Response mismatch",not_matched:{original:n,replay:o}}),{isDifferent:r.length>0,issues:r}}catch(r){throw r}}fullUrl(e){return`${process.env.SERVER_URL}${e}`}async sendRequest(e){try{return await fetch(this.fullUrl(e.request.url),{method:e.request.method,headers:{"Content-Type":"application/json","x-is-replay":"true"},body:JSON.stringify(e.request.body)})}catch(t){throw t}}};var x=class{constructor(e){this.config=e}config;static{a(this,"BaseReplay")}get filterManager(){return new R(this.config)}get replayHelper(){return new v(this.config)}};import W from"http";var L={trace_step_match:a((s=.1)=>({weight:s,serverity:u(s),message:`trace_match (+${s}) \u2192 trace fully matches replay`}),"trace_step_match"),trace_step_not_match:a((s=.25)=>({weight:s,serverity:u(s),message:`trace_step_not_match (+${s}) \u2192 trace partially matches replay`}),"trace_step_not_match"),trace_return_data_match:a((s=.1)=>({weight:s,serverity:u(s),message:`trace_return_data_match (+${s}) \u2192 trace return data is consistent`}),"trace_return_data_match"),trace_return_data_not_match:a((s=.25)=>({weight:s,serverity:u(s),message:`trace_return_data_not_match (+${s}) \u2192 trace return data is inconsistent`}),"trace_return_data_not_match"),response_match:a((s=.1)=>({weight:s,serverity:u(s),message:`response_match (+${s}) \u2192 response is consistent`}),"response_match"),response_not_match:a((s=.25)=>({weight:s,serverity:u(s),message:`response_not_match (+${s}) \u2192 response is inconsistent`}),"response_not_match"),response_status_match:a((s=.1)=>({weight:s,serverity:u(s),message:`response_status_match (+${s}) \u2192 response status is consistent`}),"response_status_match"),response_status_not_match:a((s=.25)=>({weight:s,serverity:u(s),message:`response_status_not_match (+${s}) \u2192 response status is inconsistent`}),"response_status_not_match"),logic_error_indicator:a((s=.6)=>({weight:s,serverity:u(s),message:`logic_error_indicator (+${s}) \u2192 original response status >= 400 triggered logic flag`}),"logic_error_indicator")},O={trace_match:{value:!0,message:"flow is clean"},trace_not_match:{value:!1,message:"flow is not clean"},trace_step_match:{value:!0,message:"no mismatch"},trace_step_not_match:{value:!1,message:"mismatch"},trace_return_data_match:{value:!0,message:"no mismatch"},trace_return_data_not_match:{value:!1,message:"mismatch"},response_match:{value:!0,message:"no mismatch"},response_not_match:{value:!1,message:"mismatch"}};function u(s){return s>.75?"high":s>.55?"medium":"low"}a(u,"getSignalLevel");var D=class{static{a(this,"ReasonSignalCls")}findSignalByType(e){try{return L[e]}catch(t){throw t}}sumSignalWeights(e){try{return Object.values(e).reduce((t,r)=>t+r.weight,0)}catch(t){throw t}}};import m from"chalk";var y=class{static{a(this,"BaseAssignerCase")}get evidenceSource(){return O}get signalSource(){return L}getTraceDivergenceSection(e){let t=e.traceDiff.issues;if(t.length===0)return"No divergence";let r=`
|
|
2
|
+
`;for(let n of t)n.type==="missing_step"&&(r+=m.yellow(`
|
|
3
|
+
* ${n.name}(missing_step):
|
|
4
|
+
`),r+=m.green(` \u2192 original: exists
|
|
5
|
+
`),r+=m.red(" \u2192 replay: missing"),r+=`
|
|
6
|
+
`),n.type==="extra_step"&&(r+=m.yellow(`
|
|
7
|
+
* ${n.name}(extra_step):
|
|
8
|
+
`),r+=m.green(` \u2192 original: none
|
|
9
|
+
`),r+=m.red(" \u2192 replay: exists"),r+=`
|
|
10
|
+
`);return r.trim()}getMessageEdvidence(e){return`${this.evidenceSource[e].value} (${this.evidenceSource[e].message})`}getStatusEdvidence(e){let t=W.STATUS_CODES[e]||"Unknown";return`${e} (${t})`}isTraceMatch(e){return!e.traceDiff.isDifferent}isTraceStepMatch(e){return e.traceDiff.issues.length>0?!e.traceDiff.issues.some(t=>t.type==="missing_step"||t.type==="extra_step"):!0}isTraceReturnDataMatch(e){return e.traceDiff.issues.length>0?!e.traceDiff.issues.some(t=>t.type==="trace_return_data_mismatch"):!0}isResponseMatch(e){return!e.responseDiff.isDifferent}isResponseStatusMatch(e){let{originalStatus:t,replayStatus:r}=this.resolveStatus(e);return t===r}resolveStatus(e){return{originalStatus:Number(e.log.response.status),replayStatus:e.replayResultStatus}}getResponseDiffSection(e){let t=e.responseDiff.issues;if(t.length===0)return"No diff";let r=t.length>1?1:0,n=e.responseDiff.issues[r].not_matched;if(!n)return"No diff";let o=n.original||{},l=n.replay||{},c=new Set([...Object.keys(o),...Object.keys(l)]),i=`
|
|
11
|
+
`;for(let p of c){let f=o[p],h=l[p];f!==h&&(i+=m.yellow(` * ${p}:
|
|
12
|
+
`),i+=m.green(` \u2192 original: ${JSON.stringify(f)}
|
|
13
|
+
`),i+=m.red(` \u2192 replay: ${JSON.stringify(h)}
|
|
14
|
+
`))}return i}};var w=class extends y{static{a(this,"BusinessLogicRejectionCase")}condition(e,t){return this.isTraceMatch(e)&&this.isResponseMatch(e)&&t.originalStatus>=400&&t.replayStatus>=400}assign(e){try{let t=this.resolveStatus(e);if(this.condition(e,t)){let r=e.log.trace?.find(o=>o.parentId===null);return{type:"Business Logic Rejection Case (logic_suspicious)",message:"Response indicates error, but execution original and replay result match expected behavior",possibleCauses:["Business rule might not align with actual execution flow","Or validation logic is too strict / misaligned"],evidence:{traceMatch:this.getMessageEdvidence("trace_match"),responseMatch:this.getMessageEdvidence("response_match"),originalStatus:this.getStatusEdvidence(t.originalStatus),finalResponse:typeof r?.returnData=="object"?JSON.stringify(r.returnData,null,2):r?.returnData},confidence:{signals:{trace_match:this.signalSource.trace_step_match(.3),response_match:this.signalSource.response_match(.3),logic_error_indicator:this.signalSource.logic_error_indicator(.2)},result:0},finalMessage:["This is NOT a runtime bug","This is likely a business logic issue"],references:e.log.stack}}}catch(t){throw t}}};var P=class extends y{static{a(this,"PostTraceResponseMutationCase")}assign(e){try{let t=this.resolveStatus(e);if(this.isTraceStepMatch(e)&&!this.isResponseMatch(e)&&this.isTraceReturnDataMatch(e))return{type:"Response Mismatch Case (post_processing_suspicious)",message:"Execution flow is identical, but response output differs",possibleCauses:["Post-processing logic may be inconsistent","Response mapping or transformation may be incorrect","Data changes may affect the final result.","Non-deterministic behavior (e.g. random, time-based, shared state)"],evidence:{traceMatch:this.getMessageEdvidence("trace_match"),responseMatch:this.getMessageEdvidence("response_not_match"),originalStatus:this.getStatusEdvidence(t.originalStatus),responseDiff:this.getResponseDiffSection(e)},confidence:{signals:{trace_step_match:this.signalSource.trace_step_match(.3),response_mismatch:this.signalSource.response_not_match(.2),trace_return_data_match:this.signalSource.trace_return_data_match(.3)},result:0},finalMessage:["Execution logic is stable, but output is inconsistent","This may indicate issues in response transformation or side effects","This may occur after the business logic is execute complete."],references:e.log.stack}}catch(t){throw t}}};var T=class extends y{static{a(this,"TraceDivergenceCase")}assign(e){try{let t=this.resolveStatus(e);if(!this.isTraceStepMatch(e)&&!this.isResponseMatch(e)&&!this.isTraceReturnDataMatch(e)&&!this.isResponseStatusMatch(e))return{type:"Trace Divergence Case (execution_path_mismatch)",message:"Execution path diverged between original and replay",possibleCauses:["Conditional branch logic may behave differently","Environment or shared state may affect execution flow","Request context may not be deterministic","Replay execution may enter different logic branches","Hidden dependencies or side effects may exist"],evidence:{traceMatch:this.getMessageEdvidence("trace_not_match"),originalStatus:this.getStatusEdvidence(t.originalStatus),traceDivergence:this.getTraceDivergenceSection(e),responseDiff:this.getResponseDiffSection(e)},confidence:{signals:{trace_step_not_match:this.signalSource.trace_step_not_match(.45),trace_return_data_not_match:this.signalSource.trace_return_data_not_match(.25),response_not_match:this.signalSource.response_not_match(.15),response_status_not_match:this.signalSource.response_status_not_match(.1)},result:0},finalMessage:["Replay execution diverged from the original execution flow","This may indicate unstable conditions or branch inconsistency","Root cause likely exists before response generation"],references:e.log.stack}}catch(t){throw t}}};var b=class{static{a(this,"ReasonAssigner")}get case(){return{business_logic_rejection:new w,post_trace_response_mutation:new P,trace_divergence:new T}}};import g from"chalk";var C=class{static{a(this,"ReasonPrinter")}get reasonSignal(){return new D}title(e){console.log(g.yellowBright("** Reason Title:")),console.log(`[!] ${e}`)}description(e){console.log(g.yellowBright("** Description:")),console.log(e)}possibleCauses(e){console.log(g.yellowBright("** What I think happened:")),e.forEach(t=>{console.log(` \u2192 ${t}`)})}evidence(e){let t=Object.keys(e);console.log(g.yellowBright("** Evidence I saw:")),t.forEach(r=>{console.log(` \u2192 ${r}: ${e[r]}`)})}confidence(e){console.log(g.yellowBright("** Confidence Reason (why I think this): ")),e.signals&&Object.keys(e.signals).forEach(n=>{console.log(` \u2192 ${e.signals[n].message}`)}),e.result=this.reasonSignal.sumSignalWeights(e.signals);let t=Math.round(e.result*100);console.log(`
|
|
15
|
+
`),console.log(g.yellowBright("** Confidence Result: ")),console.log(g.green.italic.bold(` * score: ${e.result.toFixed(2)} / 1 `)),console.log(g.green.italic.bold(` * percent: ${t} / 100 (%) `))}finalMessage(e){e.length!=0&&(console.log(g.yellowBright("** Final Call:")),e.forEach(t=>{console.log(` \u2192 ${t}`)}))}referencePosition(e){if(e&&(console.log(g.yellowBright("* Reference Position: ")),console.log(" \u2192 Suspected position:",g.red.underline(e.primary?.full_path)),e.context&&e.context.length>0)){let t=e.context.length-1;e.context.forEach((r,n)=>{console.log(` \u2192 (Context ${t-n}): ${r.full_path}`)})}}printReason(e){try{if(!e)return;console.log(g.red.italic.bold(`
|
|
16
|
+
Aeeaeae yohh BUT...`)),this.title(e.type),console.log(`
|
|
17
|
+
`),this.description(e.message),console.log(`
|
|
18
|
+
`),this.possibleCauses(e.possibleCauses),console.log(`
|
|
19
|
+
`),this.evidence(e.evidence),console.log(`
|
|
20
|
+
`),this.confidence(e.confidence),console.log(`
|
|
21
|
+
`),this.finalMessage(e.finalMessage||[]),this.referencePosition(e.references)}catch(t){throw t}}};var F=class extends x{constructor(t){super(t);this.config=t}config;static{a(this,"AdvanceReplay")}get reasonPrinter(){return new C}get reasonAssigner(){return new b}printResponseDiff(t){if(t.isDifferent){console.log(d.red("[!] Response DIFF"));for(let r of t.issues)console.log(` - [${r.type}] ${r.message}`)}else console.log(d.green("[OK] Response MATCH"))}printTraceDiff(t){if(t.isDifferent){console.log(d.red("[!] Trace DIFF"));for(let r of t.issues)console.log(` - [${r.type}] ${r.name}`)}else console.log(d.green("[OK] Trace MATCH"))}printRootCauseIssue(t){if(t.length>0){let r=["performance_issue","performance_warning","performance_regression"];if(!t.every(o=>r.includes(o.type))){console.log(d.red("\u26A0 Root Cause Analysis"));for(let o of t)console.log(` - [${o.type}] ${o.message}`)}}else console.log(d.green("[OK] No root cause issues detected"))}printPerformanceIssue(t){let r=t.filter(n=>n.type==="performance_regression");if(r.length>0){console.log(d.yellow(`
|
|
22
|
+
\u26A0 Performance Regression Detected`));for(let n of r)console.log(`- ${n.step}: ${n.message}`)}}print(t){try{let{log:r,responseDiff:n,traceDiff:o,analysis:l}=t;console.log(d.bgYellowBright.bold(` \u25B6 ${r.request.method} ${r.request.url} `)),this.printResponseDiff(n),this.printTraceDiff(o),this.printRootCauseIssue(l),this.printPerformanceIssue(l),this.printReason(t)}catch(r){throw r}}printReason(t){try{let r=this.reasonAssigner.case.business_logic_rejection.assign(t);this.reasonPrinter.printReason(r);let n=this.reasonAssigner.case.post_trace_response_mutation.assign(t);this.reasonPrinter.printReason(n);let o=this.reasonAssigner.case.trace_divergence.assign(t);this.reasonPrinter.printReason(o)}catch(r){throw r}}analyzeRootCause(t){try{let{responseDiff:r,traceDiff:n,logTrace:o,replayData:l}=t,c=[],i=this.config.filters;r.isDifferent&&n.isDifferent&&c.push({type:"flow_break",message:"Response mismatch caused by trace difference"});let p=i?.expectedPerformance;if(!p)return c;for(let f of o){let h=l?.trace?.find(B=>B.name===f.name);if(!h)continue;let S=(h.duration_ms||0)-(f.duration_ms||0),I=Math.max(f.duration_ms||1,20),N=S/I*100,k=f.name.split("."),E=f.name;k.length==2?E=k[1]:E=k[0];let _=p.steps?.[E]??0;if(_===0)continue;let A=_/2;S>_?c.push({type:"performance_regression",step:f.name,severity:"high",message:`Slow step: +${S}ms > ${_}ms (+${N.toFixed(1)}%)`}):S>A&&c.push({type:"performance_warning",step:f.name,severity:"low",message:`Slight delay: +${S}ms`})}return c}catch(r){throw r}}async getTraceResult(t,r){try{let n=K(t.trace||[]),o=K(r.trace||[]),l=await this.filterManager.filterTrace(n),c=await this.filterManager.filterTrace(o),i=this.replayHelper.compareTrace(l,c);return{logTraceFiltered:l,replayTraceFiltered:c,traceDiff:i}}catch(n){throw n}}async getResponseResult(t,r,n){try{let o=await this.filterManager.filterResponse({error:JSON.parse(t.response.error),status:t.response.status}),l=await this.filterManager.filterResponse({error:r,status:n.status});return{responseDiff:this.replayHelper.compareResponse(o,l)}}catch(o){throw o}}async replay(t){try{let r=await this.replayHelper.sendRequest(t),n=await r.json(),o=n.__replay;delete n.__replay;let l=await this.getResponseResult(t,n,r),c=await this.getTraceResult(t,o),i=this.analyzeRootCause({replayData:o,traceDiff:c.traceDiff,logTrace:c.logTraceFiltered,responseDiff:l.responseDiff});r.status<=400&&i.length==0?this.print({log:t,replayResultStatus:r.status,analysis:[],traceDiff:{isDifferent:!1,issues:[]},responseDiff:{isDifferent:!1,issues:[]}}):this.print({log:t,replayResultStatus:r.status,analysis:i,traceDiff:c.traceDiff,responseDiff:l.responseDiff})}catch(r){throw r}}};export{F as AdvanceReplay};
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
"use strict";var b=Object.create;var c=Object.defineProperty;var P=Object.getOwnPropertyDescriptor;var $=Object.getOwnPropertyNames;var x=Object.getPrototypeOf,R=Object.prototype.hasOwnProperty;var n=(e,t)=>c(e,"name",{value:t,configurable:!0});var T=(e,t)=>{for(var r in t)c(e,r,{get:t[r],enumerable:!0})},y=(e,t,r,s)=>{if(t&&typeof t=="object"||typeof t=="function")for(let a of $(t))!R.call(e,a)&&a!==r&&c(e,a,{get:()=>t[a],enumerable:!(s=P(t,a))||s.enumerable});return e};var d=(e,t,r)=>(r=e!=null?b(x(e)):{},y(t||!e||!e.__esModule?c(r,"default",{value:e,enumerable:!0}):r,e)),k=e=>y(c({},"__esModule",{value:!0}),e);var M={};T(M,{BaseAssignerCase:()=>m});module.exports=k(M);var v=d(require("http"),1);var h={trace_step_match:n((e=.1)=>({weight:e,serverity:o(e),message:`trace_match (+${e}) \u2192 trace fully matches replay`}),"trace_step_match"),trace_step_not_match:n((e=.25)=>({weight:e,serverity:o(e),message:`trace_step_not_match (+${e}) \u2192 trace partially matches replay`}),"trace_step_not_match"),trace_return_data_match:n((e=.1)=>({weight:e,serverity:o(e),message:`trace_return_data_match (+${e}) \u2192 trace return data is consistent`}),"trace_return_data_match"),trace_return_data_not_match:n((e=.25)=>({weight:e,serverity:o(e),message:`trace_return_data_not_match (+${e}) \u2192 trace return data is inconsistent`}),"trace_return_data_not_match"),response_match:n((e=.1)=>({weight:e,serverity:o(e),message:`response_match (+${e}) \u2192 response is consistent`}),"response_match"),response_not_match:n((e=.25)=>({weight:e,serverity:o(e),message:`response_not_match (+${e}) \u2192 response is inconsistent`}),"response_not_match"),response_status_match:n((e=.1)=>({weight:e,serverity:o(e),message:`response_status_match (+${e}) \u2192 response status is consistent`}),"response_status_match"),response_status_not_match:n((e=.25)=>({weight:e,serverity:o(e),message:`response_status_not_match (+${e}) \u2192 response status is inconsistent`}),"response_status_not_match"),logic_error_indicator:n((e=.6)=>({weight:e,serverity:o(e),message:`logic_error_indicator (+${e}) \u2192 original response status >= 400 triggered logic flag`}),"logic_error_indicator")},S={trace_match:{value:!0,message:"flow is clean"},trace_not_match:{value:!1,message:"flow is not clean"},trace_step_match:{value:!0,message:"no mismatch"},trace_step_not_match:{value:!1,message:"mismatch"},trace_return_data_match:{value:!0,message:"no mismatch"},trace_return_data_not_match:{value:!1,message:"mismatch"},response_match:{value:!0,message:"no mismatch"},response_not_match:{value:!1,message:"mismatch"}};function o(e){return e>.75?"high":e>.55?"medium":"low"}n(o,"getSignalLevel");var i=d(require("chalk"),1);var m=class{static{n(this,"BaseAssignerCase")}get evidenceSource(){return S}get signalSource(){return h}getTraceDivergenceSection(t){let r=t.traceDiff.issues;if(r.length===0)return"No divergence";let s=`
|
|
2
|
+
`;for(let a of r)a.type==="missing_step"&&(s+=i.default.yellow(`
|
|
3
|
+
* ${a.name}(missing_step):
|
|
4
|
+
`),s+=i.default.green(` \u2192 original: exists
|
|
5
|
+
`),s+=i.default.red(" \u2192 replay: missing"),s+=`
|
|
6
|
+
`),a.type==="extra_step"&&(s+=i.default.yellow(`
|
|
7
|
+
* ${a.name}(extra_step):
|
|
8
|
+
`),s+=i.default.green(` \u2192 original: none
|
|
9
|
+
`),s+=i.default.red(" \u2192 replay: exists"),s+=`
|
|
10
|
+
`);return s.trim()}getMessageEdvidence(t){return`${this.evidenceSource[t].value} (${this.evidenceSource[t].message})`}getStatusEdvidence(t){let r=v.default.STATUS_CODES[t]||"Unknown";return`${t} (${r})`}isTraceMatch(t){return!t.traceDiff.isDifferent}isTraceStepMatch(t){return t.traceDiff.issues.length>0?!t.traceDiff.issues.some(r=>r.type==="missing_step"||r.type==="extra_step"):!0}isTraceReturnDataMatch(t){return t.traceDiff.issues.length>0?!t.traceDiff.issues.some(r=>r.type==="trace_return_data_mismatch"):!0}isResponseMatch(t){return!t.responseDiff.isDifferent}isResponseStatusMatch(t){let{originalStatus:r,replayStatus:s}=this.resolveStatus(t);return r===s}resolveStatus(t){return{originalStatus:Number(t.log.response.status),replayStatus:t.replayResultStatus}}getResponseDiffSection(t){let r=t.responseDiff.issues;if(r.length===0)return"No diff";let s=r.length>1?1:0,a=t.responseDiff.issues[s].not_matched;if(!a)return"No diff";let g=a.original||{},p=a.replay||{},D=new Set([...Object.keys(g),...Object.keys(p)]),u=`
|
|
11
|
+
`;for(let l of D){let _=g[l],f=p[l];_!==f&&(u+=i.default.yellow(` * ${l}:
|
|
12
|
+
`),u+=i.default.green(` \u2192 original: ${JSON.stringify(_)}
|
|
13
|
+
`),u+=i.default.red(` \u2192 replay: ${JSON.stringify(f)}
|
|
14
|
+
`))}return u}};0&&(module.exports={BaseAssignerCase});
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
import { SignalDetails, evidenceSource } from '../reason_signal.cjs';
|
|
2
|
+
import { PrintParams, RootCauseReason } from '../../replay.cjs';
|
|
3
|
+
import '../../../../handler.cjs';
|
|
4
|
+
import '../../../../../error_handle.helper-CQsPSbuz.cjs';
|
|
5
|
+
import 'async_hooks';
|
|
6
|
+
import '../../../../../setup.cjs';
|
|
7
|
+
import '../../../../../index-MBKv_hsI.cjs';
|
|
8
|
+
import '../../../../../enum/log_level.enum.cjs';
|
|
9
|
+
import '../../../../base.cjs';
|
|
10
|
+
import '../../../../../trace/filter.cjs';
|
|
11
|
+
import '../../../../helper.cjs';
|
|
12
|
+
|
|
13
|
+
type ResolveStatus = {
|
|
14
|
+
originalStatus: number;
|
|
15
|
+
replayStatus: number;
|
|
16
|
+
};
|
|
17
|
+
declare abstract class BaseAssignerCase {
|
|
18
|
+
protected get evidenceSource(): {
|
|
19
|
+
trace_match: {
|
|
20
|
+
value: boolean;
|
|
21
|
+
message: string;
|
|
22
|
+
};
|
|
23
|
+
trace_not_match: {
|
|
24
|
+
value: boolean;
|
|
25
|
+
message: string;
|
|
26
|
+
};
|
|
27
|
+
trace_step_match: {
|
|
28
|
+
value: boolean;
|
|
29
|
+
message: string;
|
|
30
|
+
};
|
|
31
|
+
trace_step_not_match: {
|
|
32
|
+
value: boolean;
|
|
33
|
+
message: string;
|
|
34
|
+
};
|
|
35
|
+
trace_return_data_match: {
|
|
36
|
+
value: boolean;
|
|
37
|
+
message: string;
|
|
38
|
+
};
|
|
39
|
+
trace_return_data_not_match: {
|
|
40
|
+
value: boolean;
|
|
41
|
+
message: string;
|
|
42
|
+
};
|
|
43
|
+
response_match: {
|
|
44
|
+
value: boolean;
|
|
45
|
+
message: string;
|
|
46
|
+
};
|
|
47
|
+
response_not_match: {
|
|
48
|
+
value: boolean;
|
|
49
|
+
message: string;
|
|
50
|
+
};
|
|
51
|
+
};
|
|
52
|
+
protected get signalSource(): {
|
|
53
|
+
readonly trace_step_match: (weight?: number) => SignalDetails;
|
|
54
|
+
readonly trace_step_not_match: (weight?: number) => SignalDetails;
|
|
55
|
+
readonly trace_return_data_match: (weight?: number) => SignalDetails;
|
|
56
|
+
readonly trace_return_data_not_match: (weight?: number) => SignalDetails;
|
|
57
|
+
readonly response_match: (weight?: number) => SignalDetails;
|
|
58
|
+
readonly response_not_match: (weight?: number) => SignalDetails;
|
|
59
|
+
readonly response_status_match: (weight?: number) => SignalDetails;
|
|
60
|
+
readonly response_status_not_match: (weight?: number) => SignalDetails;
|
|
61
|
+
readonly logic_error_indicator: (weight?: number) => SignalDetails;
|
|
62
|
+
};
|
|
63
|
+
/**
|
|
64
|
+
* Get trace divergence section output
|
|
65
|
+
* Example:
|
|
66
|
+
* * missing_step:
|
|
67
|
+
* → replay missing: service.validateUser
|
|
68
|
+
*
|
|
69
|
+
* * extra_step:
|
|
70
|
+
* → replay extra: service.generateCoupon
|
|
71
|
+
*
|
|
72
|
+
* @returns {string}
|
|
73
|
+
*/
|
|
74
|
+
protected getTraceDivergenceSection(params: PrintParams): string;
|
|
75
|
+
/**
|
|
76
|
+
* Map message evidence to get message
|
|
77
|
+
* Example: "true (flow is clean)"
|
|
78
|
+
* @returns {string}
|
|
79
|
+
*/
|
|
80
|
+
protected getMessageEdvidence(kindCase: keyof typeof evidenceSource): string;
|
|
81
|
+
/**
|
|
82
|
+
* Get status edvidence message
|
|
83
|
+
* Example: "200 (OK)"
|
|
84
|
+
* @returns {string}
|
|
85
|
+
*/
|
|
86
|
+
protected getStatusEdvidence(statusCode: number): string;
|
|
87
|
+
/**
|
|
88
|
+
* When: No any issue in trace diff result
|
|
89
|
+
* Meaning: All of trace condition match
|
|
90
|
+
* @returns {boolean}
|
|
91
|
+
*/
|
|
92
|
+
protected isTraceMatch(params: PrintParams): boolean;
|
|
93
|
+
/**
|
|
94
|
+
* When: No "missing_step" or "extra_step" issue in trace diff result
|
|
95
|
+
* Meaning: Trace step match
|
|
96
|
+
* @returns {boolean}
|
|
97
|
+
*/
|
|
98
|
+
protected isTraceStepMatch(params: PrintParams): boolean;
|
|
99
|
+
/**
|
|
100
|
+
* When: No "trace_return_data_mismatch" issue in trace diff result
|
|
101
|
+
* Meaning: Original trace return data & Replay trace return data must match
|
|
102
|
+
* @returns {boolean}
|
|
103
|
+
*/
|
|
104
|
+
protected isTraceReturnDataMatch(params: PrintParams): boolean;
|
|
105
|
+
/**
|
|
106
|
+
* When: No any issue in response diff result
|
|
107
|
+
* Meaning: The original response must match replay response
|
|
108
|
+
* @returns {boolean}
|
|
109
|
+
*/
|
|
110
|
+
protected isResponseMatch(params: PrintParams): boolean;
|
|
111
|
+
/**
|
|
112
|
+
* When: The original status code must match replay status code
|
|
113
|
+
* Meaning: The original response must match replay response
|
|
114
|
+
* @returns {boolean}
|
|
115
|
+
*/
|
|
116
|
+
protected isResponseStatusMatch(params: PrintParams): boolean;
|
|
117
|
+
/**
|
|
118
|
+
* Resolve status code to number type
|
|
119
|
+
* @returns {number}
|
|
120
|
+
*/
|
|
121
|
+
protected resolveStatus(params: PrintParams): ResolveStatus;
|
|
122
|
+
/**
|
|
123
|
+
* Get response different section output
|
|
124
|
+
* Example:
|
|
125
|
+
* * status:
|
|
126
|
+
* → original: 200
|
|
127
|
+
* → replay: 0
|
|
128
|
+
* @returns {string}
|
|
129
|
+
*/
|
|
130
|
+
protected getResponseDiffSection(params: PrintParams): string;
|
|
131
|
+
/**
|
|
132
|
+
* Base Abstract Zone
|
|
133
|
+
*/
|
|
134
|
+
abstract assign(params: PrintParams): RootCauseReason | undefined;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
export { BaseAssignerCase, type ResolveStatus };
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
import { SignalDetails, evidenceSource } from '../reason_signal.js';
|
|
2
|
+
import { PrintParams, RootCauseReason } from '../../replay.js';
|
|
3
|
+
import '../../../../handler.js';
|
|
4
|
+
import '../../../../../error_handle.helper-CQsPSbuz.js';
|
|
5
|
+
import 'async_hooks';
|
|
6
|
+
import '../../../../../setup.js';
|
|
7
|
+
import '../../../../../index-8u1_ya-u.js';
|
|
8
|
+
import '../../../../../enum/log_level.enum.js';
|
|
9
|
+
import '../../../../base.js';
|
|
10
|
+
import '../../../../../trace/filter.js';
|
|
11
|
+
import '../../../../helper.js';
|
|
12
|
+
|
|
13
|
+
type ResolveStatus = {
|
|
14
|
+
originalStatus: number;
|
|
15
|
+
replayStatus: number;
|
|
16
|
+
};
|
|
17
|
+
declare abstract class BaseAssignerCase {
|
|
18
|
+
protected get evidenceSource(): {
|
|
19
|
+
trace_match: {
|
|
20
|
+
value: boolean;
|
|
21
|
+
message: string;
|
|
22
|
+
};
|
|
23
|
+
trace_not_match: {
|
|
24
|
+
value: boolean;
|
|
25
|
+
message: string;
|
|
26
|
+
};
|
|
27
|
+
trace_step_match: {
|
|
28
|
+
value: boolean;
|
|
29
|
+
message: string;
|
|
30
|
+
};
|
|
31
|
+
trace_step_not_match: {
|
|
32
|
+
value: boolean;
|
|
33
|
+
message: string;
|
|
34
|
+
};
|
|
35
|
+
trace_return_data_match: {
|
|
36
|
+
value: boolean;
|
|
37
|
+
message: string;
|
|
38
|
+
};
|
|
39
|
+
trace_return_data_not_match: {
|
|
40
|
+
value: boolean;
|
|
41
|
+
message: string;
|
|
42
|
+
};
|
|
43
|
+
response_match: {
|
|
44
|
+
value: boolean;
|
|
45
|
+
message: string;
|
|
46
|
+
};
|
|
47
|
+
response_not_match: {
|
|
48
|
+
value: boolean;
|
|
49
|
+
message: string;
|
|
50
|
+
};
|
|
51
|
+
};
|
|
52
|
+
protected get signalSource(): {
|
|
53
|
+
readonly trace_step_match: (weight?: number) => SignalDetails;
|
|
54
|
+
readonly trace_step_not_match: (weight?: number) => SignalDetails;
|
|
55
|
+
readonly trace_return_data_match: (weight?: number) => SignalDetails;
|
|
56
|
+
readonly trace_return_data_not_match: (weight?: number) => SignalDetails;
|
|
57
|
+
readonly response_match: (weight?: number) => SignalDetails;
|
|
58
|
+
readonly response_not_match: (weight?: number) => SignalDetails;
|
|
59
|
+
readonly response_status_match: (weight?: number) => SignalDetails;
|
|
60
|
+
readonly response_status_not_match: (weight?: number) => SignalDetails;
|
|
61
|
+
readonly logic_error_indicator: (weight?: number) => SignalDetails;
|
|
62
|
+
};
|
|
63
|
+
/**
|
|
64
|
+
* Get trace divergence section output
|
|
65
|
+
* Example:
|
|
66
|
+
* * missing_step:
|
|
67
|
+
* → replay missing: service.validateUser
|
|
68
|
+
*
|
|
69
|
+
* * extra_step:
|
|
70
|
+
* → replay extra: service.generateCoupon
|
|
71
|
+
*
|
|
72
|
+
* @returns {string}
|
|
73
|
+
*/
|
|
74
|
+
protected getTraceDivergenceSection(params: PrintParams): string;
|
|
75
|
+
/**
|
|
76
|
+
* Map message evidence to get message
|
|
77
|
+
* Example: "true (flow is clean)"
|
|
78
|
+
* @returns {string}
|
|
79
|
+
*/
|
|
80
|
+
protected getMessageEdvidence(kindCase: keyof typeof evidenceSource): string;
|
|
81
|
+
/**
|
|
82
|
+
* Get status edvidence message
|
|
83
|
+
* Example: "200 (OK)"
|
|
84
|
+
* @returns {string}
|
|
85
|
+
*/
|
|
86
|
+
protected getStatusEdvidence(statusCode: number): string;
|
|
87
|
+
/**
|
|
88
|
+
* When: No any issue in trace diff result
|
|
89
|
+
* Meaning: All of trace condition match
|
|
90
|
+
* @returns {boolean}
|
|
91
|
+
*/
|
|
92
|
+
protected isTraceMatch(params: PrintParams): boolean;
|
|
93
|
+
/**
|
|
94
|
+
* When: No "missing_step" or "extra_step" issue in trace diff result
|
|
95
|
+
* Meaning: Trace step match
|
|
96
|
+
* @returns {boolean}
|
|
97
|
+
*/
|
|
98
|
+
protected isTraceStepMatch(params: PrintParams): boolean;
|
|
99
|
+
/**
|
|
100
|
+
* When: No "trace_return_data_mismatch" issue in trace diff result
|
|
101
|
+
* Meaning: Original trace return data & Replay trace return data must match
|
|
102
|
+
* @returns {boolean}
|
|
103
|
+
*/
|
|
104
|
+
protected isTraceReturnDataMatch(params: PrintParams): boolean;
|
|
105
|
+
/**
|
|
106
|
+
* When: No any issue in response diff result
|
|
107
|
+
* Meaning: The original response must match replay response
|
|
108
|
+
* @returns {boolean}
|
|
109
|
+
*/
|
|
110
|
+
protected isResponseMatch(params: PrintParams): boolean;
|
|
111
|
+
/**
|
|
112
|
+
* When: The original status code must match replay status code
|
|
113
|
+
* Meaning: The original response must match replay response
|
|
114
|
+
* @returns {boolean}
|
|
115
|
+
*/
|
|
116
|
+
protected isResponseStatusMatch(params: PrintParams): boolean;
|
|
117
|
+
/**
|
|
118
|
+
* Resolve status code to number type
|
|
119
|
+
* @returns {number}
|
|
120
|
+
*/
|
|
121
|
+
protected resolveStatus(params: PrintParams): ResolveStatus;
|
|
122
|
+
/**
|
|
123
|
+
* Get response different section output
|
|
124
|
+
* Example:
|
|
125
|
+
* * status:
|
|
126
|
+
* → original: 200
|
|
127
|
+
* → replay: 0
|
|
128
|
+
* @returns {string}
|
|
129
|
+
*/
|
|
130
|
+
protected getResponseDiffSection(params: PrintParams): string;
|
|
131
|
+
/**
|
|
132
|
+
* Base Abstract Zone
|
|
133
|
+
*/
|
|
134
|
+
abstract assign(params: PrintParams): RootCauseReason | undefined;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
export { BaseAssignerCase, type ResolveStatus };
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
var h=Object.defineProperty;var a=(e,t)=>h(e,"name",{value:t,configurable:!0});import S from"http";var _={trace_step_match:a((e=.1)=>({weight:e,serverity:n(e),message:`trace_match (+${e}) \u2192 trace fully matches replay`}),"trace_step_match"),trace_step_not_match:a((e=.25)=>({weight:e,serverity:n(e),message:`trace_step_not_match (+${e}) \u2192 trace partially matches replay`}),"trace_step_not_match"),trace_return_data_match:a((e=.1)=>({weight:e,serverity:n(e),message:`trace_return_data_match (+${e}) \u2192 trace return data is consistent`}),"trace_return_data_match"),trace_return_data_not_match:a((e=.25)=>({weight:e,serverity:n(e),message:`trace_return_data_not_match (+${e}) \u2192 trace return data is inconsistent`}),"trace_return_data_not_match"),response_match:a((e=.1)=>({weight:e,serverity:n(e),message:`response_match (+${e}) \u2192 response is consistent`}),"response_match"),response_not_match:a((e=.25)=>({weight:e,serverity:n(e),message:`response_not_match (+${e}) \u2192 response is inconsistent`}),"response_not_match"),response_status_match:a((e=.1)=>({weight:e,serverity:n(e),message:`response_status_match (+${e}) \u2192 response status is consistent`}),"response_status_match"),response_status_not_match:a((e=.25)=>({weight:e,serverity:n(e),message:`response_status_not_match (+${e}) \u2192 response status is inconsistent`}),"response_status_not_match"),logic_error_indicator:a((e=.6)=>({weight:e,serverity:n(e),message:`logic_error_indicator (+${e}) \u2192 original response status >= 400 triggered logic flag`}),"logic_error_indicator")},f={trace_match:{value:!0,message:"flow is clean"},trace_not_match:{value:!1,message:"flow is not clean"},trace_step_match:{value:!0,message:"no mismatch"},trace_step_not_match:{value:!1,message:"mismatch"},trace_return_data_match:{value:!0,message:"no mismatch"},trace_return_data_not_match:{value:!1,message:"mismatch"},response_match:{value:!0,message:"no mismatch"},response_not_match:{value:!1,message:"mismatch"}};function n(e){return e>.75?"high":e>.55?"medium":"low"}a(n,"getSignalLevel");import i from"chalk";var y=class{static{a(this,"BaseAssignerCase")}get evidenceSource(){return f}get signalSource(){return _}getTraceDivergenceSection(t){let r=t.traceDiff.issues;if(r.length===0)return"No divergence";let s=`
|
|
2
|
+
`;for(let o of r)o.type==="missing_step"&&(s+=i.yellow(`
|
|
3
|
+
* ${o.name}(missing_step):
|
|
4
|
+
`),s+=i.green(` \u2192 original: exists
|
|
5
|
+
`),s+=i.red(" \u2192 replay: missing"),s+=`
|
|
6
|
+
`),o.type==="extra_step"&&(s+=i.yellow(`
|
|
7
|
+
* ${o.name}(extra_step):
|
|
8
|
+
`),s+=i.green(` \u2192 original: none
|
|
9
|
+
`),s+=i.red(" \u2192 replay: exists"),s+=`
|
|
10
|
+
`);return s.trim()}getMessageEdvidence(t){return`${this.evidenceSource[t].value} (${this.evidenceSource[t].message})`}getStatusEdvidence(t){let r=S.STATUS_CODES[t]||"Unknown";return`${t} (${r})`}isTraceMatch(t){return!t.traceDiff.isDifferent}isTraceStepMatch(t){return t.traceDiff.issues.length>0?!t.traceDiff.issues.some(r=>r.type==="missing_step"||r.type==="extra_step"):!0}isTraceReturnDataMatch(t){return t.traceDiff.issues.length>0?!t.traceDiff.issues.some(r=>r.type==="trace_return_data_mismatch"):!0}isResponseMatch(t){return!t.responseDiff.isDifferent}isResponseStatusMatch(t){let{originalStatus:r,replayStatus:s}=this.resolveStatus(t);return r===s}resolveStatus(t){return{originalStatus:Number(t.log.response.status),replayStatus:t.replayResultStatus}}getResponseDiffSection(t){let r=t.responseDiff.issues;if(r.length===0)return"No diff";let s=r.length>1?1:0,o=t.responseDiff.issues[s].not_matched;if(!o)return"No diff";let l=o.original||{},m=o.replay||{},d=new Set([...Object.keys(l),...Object.keys(m)]),c=`
|
|
11
|
+
`;for(let u of d){let g=l[u],p=m[u];g!==p&&(c+=i.yellow(` * ${u}:
|
|
12
|
+
`),c+=i.green(` \u2192 original: ${JSON.stringify(g)}
|
|
13
|
+
`),c+=i.red(` \u2192 replay: ${JSON.stringify(p)}
|
|
14
|
+
`))}return c}};export{y as BaseAssignerCase};
|