@testivai/common
Advanced tools
| {"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../src/auth.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAKH,OAAO,EAAE,iBAAiB,EAAE,MAAM,SAAS,CAAC;AAc5C;;GAEG;AACH,wBAAgB,eAAe,CAAC,WAAW,EAAE,iBAAiB,GAAG,IAAI,CAKpE;AAED;;;GAGG;AACH,wBAAgB,eAAe,IAAI,iBAAiB,GAAG,IAAI,CAU1D;AAED;;GAEG;AACH,wBAAgB,iBAAiB,IAAI,IAAI,CAIxC;AAED;;;GAGG;AACH,wBAAgB,SAAS,IAAI,MAAM,GAAG,IAAI,CAUzC;AAED;;GAEG;AACH,wBAAgB,eAAe,IAAI,OAAO,CAEzC"} |
| {"version":3,"file":"auth.js","sourceRoot":"","sources":["../src/auth.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAsBH,0CAKC;AAMD,0CAUC;AAKD,8CAIC;AAMD,8BAUC;AAKD,0CAEC;AAzED,uCAAyB;AACzB,2CAA6B;AAC7B,uCAAyB;AAGzB,MAAM,eAAe,GAAG,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,WAAW,CAAC,CAAC;AAC7D,MAAM,gBAAgB,GAAG,IAAI,CAAC,IAAI,CAAC,eAAe,EAAE,aAAa,CAAC,CAAC;AAEnE;;GAEG;AACH,SAAS,oBAAoB;IAC3B,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,eAAe,CAAC,EAAE,CAAC;QACpC,EAAE,CAAC,SAAS,CAAC,eAAe,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;IAClE,CAAC;AACH,CAAC;AAED;;GAEG;AACH,SAAgB,eAAe,CAAC,WAA8B;IAC5D,oBAAoB,EAAE,CAAC;IACvB,EAAE,CAAC,aAAa,CAAC,gBAAgB,EAAE,IAAI,CAAC,SAAS,CAAC,WAAW,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE;QACvE,IAAI,EAAE,KAAK;KACZ,CAAC,CAAC;AACL,CAAC;AAED;;;GAGG;AACH,SAAgB,eAAe;IAC7B,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,gBAAgB,CAAC,EAAE,CAAC;QACrC,OAAO,IAAI,CAAC;IACd,CAAC;IACD,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,EAAE,CAAC,YAAY,CAAC,gBAAgB,EAAE,OAAO,CAAC,CAAC;QAC3D,OAAO,IAAI,CAAC,KAAK,CAAC,OAAO,CAAsB,CAAC;IAClD,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED;;GAEG;AACH,SAAgB,iBAAiB;IAC/B,IAAI,EAAE,CAAC,UAAU,CAAC,gBAAgB,CAAC,EAAE,CAAC;QACpC,EAAE,CAAC,UAAU,CAAC,gBAAgB,CAAC,CAAC;IAClC,CAAC;AACH,CAAC;AAED;;;GAGG;AACH,SAAgB,SAAS;IACvB,mCAAmC;IACnC,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,gBAAgB,CAAC;IAC5C,IAAI,MAAM,EAAE,CAAC;QACX,OAAO,MAAM,CAAC;IAChB,CAAC;IAED,kCAAkC;IAClC,MAAM,WAAW,GAAG,eAAe,EAAE,CAAC;IACtC,OAAO,WAAW,EAAE,MAAM,IAAI,IAAI,CAAC;AACrC,CAAC;AAED;;GAEG;AACH,SAAgB,eAAe;IAC7B,OAAO,SAAS,EAAE,KAAK,IAAI,CAAC;AAC9B,CAAC"} |
| {"version":3,"file":"compression.d.ts","sourceRoot":"","sources":["../src/compression.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAOH,MAAM,WAAW,kBAAkB;IACjC,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,oBAAoB,CAAC,EAAE,MAAM,CAAC;CAC/B;AAED,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,MAAM,GAAG,MAAM,CAAC;IACtB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC,YAAY,EAAE,MAAM,CAAC;IACrB,cAAc,EAAE,MAAM,CAAC;IACvB,gBAAgB,EAAE,MAAM,CAAC;IACzB,eAAe,EAAE,MAAM,CAAC;CACzB;AAED,qBAAa,iBAAiB;IAC5B,OAAO,CAAC,OAAO,CAA+B;gBAElC,OAAO,GAAE,kBAAuB;IAQ5C;;OAEG;IACG,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,iBAAiB,CAAC;IAoCxD;;OAEG;IACH,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM;IAMlC;;OAEG;IACH,oBAAoB,CAAC,MAAM,EAAE,iBAAiB,GAAG,IAAI;CAQtD;AAED,eAAO,MAAM,iBAAiB,mBAA0B,CAAC"} |
| {"version":3,"file":"compression.js","sourceRoot":"","sources":["../src/compression.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAEH,2CAA6B;AAC7B,+BAAiC;AAEjC,MAAM,SAAS,GAAG,IAAA,gBAAS,EAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAiBvC,MAAa,iBAAiB;IAG5B,YAAY,UAA8B,EAAE;QAC1C,IAAI,CAAC,OAAO,GAAG;YACb,eAAe,EAAE,OAAO,CAAC,eAAe,KAAK,KAAK,EAAE,gBAAgB;YACpE,gBAAgB,EAAE,OAAO,CAAC,gBAAgB,IAAI,CAAC;YAC/C,oBAAoB,EAAE,OAAO,CAAC,oBAAoB,IAAI,CAAC,GAAG,IAAI,GAAG,IAAI,EAAE,MAAM;SAC9E,CAAC;IACJ,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,QAAQ,CAAC,IAAY;QACzB,MAAM,YAAY,GAAG,MAAM,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;QAC7C,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QAE7B,gDAAgD;QAChD,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,eAAe,IAAI,YAAY,GAAG,IAAI,CAAC,OAAO,CAAC,oBAAoB,EAAE,CAAC;YACtF,OAAO;gBACL,IAAI;gBACJ,YAAY;gBACZ,cAAc,EAAE,YAAY;gBAC5B,gBAAgB,EAAE,CAAC;gBACnB,eAAe,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS;aACxC,CAAC;QACJ,CAAC;QAED,oBAAoB;QACpB,MAAM,cAAc,GAAG,MAAM,SAAS,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE;YACxD,KAAK,EAAE,IAAI,CAAC,OAAO,CAAC,gBAAgB;SACrC,CAAC,CAAC;QAEH,MAAM,eAAe,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS,CAAC;QAC/C,MAAM,gBAAgB,GAAG,CAAC,GAAG,cAAc,CAAC,MAAM,GAAG,YAAY,CAAC;QAElE,OAAO;YACL,IAAI,EAAE,cAAc;YACpB,OAAO,EAAE;gBACP,kBAAkB,EAAE,MAAM;gBAC1B,cAAc,EAAE,kBAAkB;aACnC;YACD,YAAY;YACZ,cAAc,EAAE,cAAc,CAAC,MAAM;YACrC,gBAAgB;YAChB,eAAe;SAChB,CAAC;IACJ,CAAC;IAED;;OAEG;IACH,WAAW,CAAC,KAAa;QACvB,IAAI,KAAK,GAAG,IAAI;YAAE,OAAO,KAAK,GAAG,IAAI,CAAC;QACtC,IAAI,KAAK,GAAG,IAAI,GAAG,IAAI;YAAE,OAAO,CAAC,KAAK,GAAG,IAAI,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC;QAClE,OAAO,CAAC,KAAK,GAAG,CAAC,IAAI,GAAG,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC;IACpD,CAAC;IAED;;OAEG;IACH,oBAAoB,CAAC,MAAyB;QAC5C,IAAI,MAAM,CAAC,gBAAgB,GAAG,CAAC,EAAE,CAAC;YAChC,OAAO,CAAC,GAAG,CACT,wCAAwC,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,YAAY,CAAC,KAAK;gBAClF,GAAG,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,cAAc,CAAC,KAAK,CAAC,MAAM,CAAC,gBAAgB,GAAG,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,gBAAgB,MAAM,CAAC,eAAe,KAAK,CACrI,CAAC;QACJ,CAAC;IACH,CAAC;CACF;AAtED,8CAsEC;AAEY,QAAA,iBAAiB,GAAG,IAAI,iBAAiB,EAAE,CAAC"} |
| {"version":3,"file":"config-loader.d.ts","sourceRoot":"","sources":["../src/config-loader.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,OAAO,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAIzC;;GAEG;AACH,eAAO,MAAM,cAAc,EAAE,cAM5B,CAAC;AAEF;;GAEG;AACH,wBAAgB,cAAc,CAAC,QAAQ,GAAE,MAAsB,GAAG,MAAM,GAAG,IAAI,CAc9E;AAED;;;GAGG;AACH,wBAAsB,UAAU,CAAC,UAAU,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,CAAC,CAqB7E;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,GAAG,GAAE,MAAsB,GAAG,OAAO,CAOjE;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,MAAM,EAAE,cAAc,EAAE,OAAO,GAAE,MAAsB,GAAG,MAAM,CAG5F"} |
| {"version":3,"file":"config-loader.js","sourceRoot":"","sources":["../src/config-loader.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAsBH,wCAcC;AAMD,gCAqBC;AAKD,oCAOC;AAKD,oCAGC;AAjFD,uCAAyB;AACzB,2CAA6B;AAG7B,MAAM,iBAAiB,GAAG,CAAC,oBAAoB,EAAE,oBAAoB,CAAC,CAAC;AAEvE;;GAEG;AACU,QAAA,cAAc,GAAmB;IAC5C,SAAS,EAAE,gBAAgB;IAC3B,QAAQ,EAAE;QACR,KAAK,EAAE,IAAI;QACX,MAAM,EAAE,GAAG;KACZ;CACF,CAAC;AAEF;;GAEG;AACH,SAAgB,cAAc,CAAC,WAAmB,OAAO,CAAC,GAAG,EAAE;IAC7D,IAAI,UAAU,GAAG,QAAQ,CAAC;IAE1B,OAAO,UAAU,KAAK,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,EAAE,CAAC;QAC/C,KAAK,MAAM,QAAQ,IAAI,iBAAiB,EAAE,CAAC;YACzC,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,QAAQ,CAAC,CAAC;YACnD,IAAI,EAAE,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;gBAC9B,OAAO,UAAU,CAAC;YACpB,CAAC;QACH,CAAC;QACD,UAAU,GAAG,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;IACxC,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;;GAGG;AACI,KAAK,UAAU,UAAU,CAAC,UAAmB;IAClD,MAAM,YAAY,GAAG,UAAU,IAAI,cAAc,EAAE,CAAC;IAEpD,IAAI,CAAC,YAAY,EAAE,CAAC;QAClB,OAAO,sBAAc,CAAC;IACxB,CAAC;IAED,IAAI,CAAC;QACH,sDAAsD;QACtD,kEAAkE;QAClE,MAAM,YAAY,GAAG,yBAAa,YAAY,uCAAC,CAAC;QAChD,MAAM,UAAU,GAAG,YAAY,CAAC,OAAO,IAAI,YAAY,CAAC;QAExD,OAAO;YACL,GAAG,sBAAc;YACjB,GAAG,UAAU;SACd,CAAC;IACJ,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,CAAC,IAAI,CAAC,uCAAuC,YAAY,mBAAmB,CAAC,CAAC;QACrF,OAAO,sBAAc,CAAC;IACxB,CAAC;AACH,CAAC;AAED;;GAEG;AACH,SAAgB,YAAY,CAAC,MAAc,OAAO,CAAC,GAAG,EAAE;IACtD,KAAK,MAAM,QAAQ,IAAI,iBAAiB,EAAE,CAAC;QACzC,IAAI,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC,EAAE,CAAC;YAC5C,OAAO,IAAI,CAAC;QACd,CAAC;IACH,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;GAEG;AACH,SAAgB,YAAY,CAAC,MAAsB,EAAE,UAAkB,OAAO,CAAC,GAAG,EAAE;IAClF,MAAM,SAAS,GAAG,MAAM,CAAC,SAAS,IAAI,sBAAc,CAAC,SAAU,CAAC;IAChE,OAAO,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,SAAS,CAAC,CAAC;AAChF,CAAC"} |
| {"version":3,"file":"core-api-client.d.ts","sourceRoot":"","sources":["../src/core-api-client.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,EAAE,wBAAwB,EAAE,iBAAiB,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAInF,qBAAa,aAAa;IACxB,OAAO,CAAC,MAAM,CAAgB;IAC9B,OAAO,CAAC,MAAM,CAAS;gBAEX,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM;IAY5C;;OAEG;IACG,cAAc,IAAI,OAAO,CAAC,wBAAwB,CAAC;IAwBzD;;;;OAIG;IACG,iBAAiB,CAAC,IAAI,EAAE,WAAW,GAAG,OAAO,CAAC,iBAAiB,CAAC;IAOtE;;OAEG;IACG,gBAAgB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,iBAAiB,CAAC;CAYtE;AAED,eAAO,MAAM,oBAAoB,+BAAkB,CAAC"} |
| {"version":3,"file":"core-api-client.js","sourceRoot":"","sources":["../src/core-api-client.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAEH,+CAAyD;AAGzD,MAAM,eAAe,GAAG,4BAA4B,CAAC;AAErD,MAAa,aAAa;IAIxB,YAAY,MAAc,EAAE,OAAgB;QAC1C,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QACrB,IAAI,CAAC,MAAM,GAAG,eAAK,CAAC,MAAM,CAAC;YACzB,OAAO,EAAE,OAAO,IAAI,eAAe;YACnC,OAAO,EAAE;gBACP,cAAc,EAAE,kBAAkB;gBAClC,WAAW,EAAE,MAAM;aACpB;YACD,OAAO,EAAE,KAAK;SACf,CAAC,CAAC;IACL,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,cAAc;QAClB,IAAI,CAAC;YACH,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,2BAA2B,CAAC,CAAC;YACpE,OAAO;gBACL,KAAK,EAAE,IAAI;gBACX,SAAS,EAAE,QAAQ,CAAC,IAAI,CAAC,UAAU;gBACnC,WAAW,EAAE,QAAQ,CAAC,IAAI,CAAC,YAAY;gBACvC,cAAc,EAAE,QAAQ,CAAC,IAAI,CAAC,eAAe;gBAC7C,gBAAgB,EAAE,QAAQ,CAAC,IAAI,CAAC,iBAAiB;aAClD,CAAC;QACJ,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,KAAK,YAAY,kBAAU,EAAE,CAAC;gBAChC,IAAI,KAAK,CAAC,QAAQ,EAAE,MAAM,KAAK,GAAG,EAAE,CAAC;oBACnC,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,iBAAiB,EAAE,CAAC;gBACpD,CAAC;gBACD,IAAI,KAAK,CAAC,QAAQ,EAAE,MAAM,KAAK,GAAG,EAAE,CAAC;oBACnC,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,gCAAgC,EAAE,CAAC;gBACnE,CAAC;gBACD,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,CAAC,OAAO,EAAE,CAAC;YAChD,CAAC;YACD,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,wBAAwB,EAAE,CAAC;QAC3D,CAAC;IACH,CAAC;IAED;;;;OAIG;IACH,KAAK,CAAC,iBAAiB,CAAC,IAAiB;QACvC,MAAM,IAAI,KAAK,CACb,qFAAqF;YACrF,6GAA6G,CAC9G,CAAC;IACJ,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,gBAAgB,CAAC,SAAiB;QACtC,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,qBAAqB,SAAS,EAAE,CAAC,CAAC;QACzE,OAAO;YACL,SAAS,EAAE,QAAQ,CAAC,IAAI,CAAC,EAAE;YAC3B,MAAM,EAAE,QAAQ,CAAC,IAAI,CAAC,MAAM;YAC5B,OAAO,EAAE,QAAQ,CAAC,IAAI,CAAC,QAAQ,IAAI,QAAQ,CAAC,IAAI,CAAC,MAAM,KAAK,QAAQ;YACpE,OAAO,EAAE,QAAQ,CAAC,IAAI,CAAC,QAAQ;YAC/B,YAAY,EAAE,QAAQ,CAAC,IAAI,CAAC,aAAa;YACzC,aAAa,EAAE,QAAQ,CAAC,IAAI,CAAC,cAAc;YAC3C,cAAc,EAAE,QAAQ,CAAC,IAAI,CAAC,eAAe;SAC9C,CAAC;IACJ,CAAC;CACF;AAtED,sCAsEC;AAEY,QAAA,oBAAoB,GAAG,eAAe,CAAC"} |
| {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,cAAc,SAAS,CAAC;AAGxB,OAAO,EAAE,aAAa,EAAE,oBAAoB,EAAE,MAAM,mBAAmB,CAAC;AAGxE,OAAO,EACL,eAAe,EACf,eAAe,EACf,iBAAiB,EACjB,SAAS,EACT,eAAe,GAChB,MAAM,QAAQ,CAAC;AAGhB,OAAO,EACL,cAAc,EACd,cAAc,EACd,UAAU,EACV,YAAY,EACZ,YAAY,GACb,MAAM,iBAAiB,CAAC;AAGzB,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAG/C,OAAO,EACL,iBAAiB,EACjB,iBAAiB,EACjB,KAAK,kBAAkB,EACvB,KAAK,iBAAiB,GACvB,MAAM,eAAe,CAAC"} |
| {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;;;;;;;;;;;;;;;AAEH,QAAQ;AACR,0CAAwB;AAExB,kBAAkB;AAClB,qDAAwE;AAA/D,gHAAA,aAAa,OAAA;AAAE,uHAAA,oBAAoB,OAAA;AAE5C,iBAAiB;AACjB,+BAMgB;AALd,uGAAA,eAAe,OAAA;AACf,uGAAA,eAAe,OAAA;AACf,yGAAA,iBAAiB,OAAA;AACjB,iGAAA,SAAS,OAAA;AACT,uGAAA,eAAe,OAAA;AAGjB,gBAAgB;AAChB,iDAMyB;AALvB,+GAAA,cAAc,OAAA;AACd,+GAAA,cAAc,OAAA;AACd,2GAAA,UAAU,OAAA;AACV,6GAAA,YAAY,OAAA;AACZ,6GAAA,YAAY,OAAA;AAGd,oCAAoC;AACpC,uCAA+C;AAAtC,oGAAA,QAAQ,OAAA;AAAE,mGAAA,OAAO,OAAA;AAE1B,wBAAwB;AACxB,6CAKuB;AAJrB,gHAAA,iBAAiB,OAAA;AACjB,gHAAA,iBAAiB,OAAA"} |
| {"version":3,"file":"testivai.d.ts","sourceRoot":"","sources":["../src/testivai.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAIH,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAEvC;;;;;GAKG;AACH,wBAAsB,OAAO,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAqCrE;AAED;;;;GAIG;AACH,eAAO,MAAM,QAAQ;;CAEpB,CAAC"} |
| {"version":3,"file":"testivai.js","sourceRoot":"","sources":["../src/testivai.ts"],"names":[],"mappings":";AAAA;;;;;;;GAOG;;;AAYH,0BAqCC;AA/CD,uDAAkD;AAClD,iCAAmC;AAGnC;;;;;GAKG;AACI,KAAK,UAAU,OAAO,CAAC,IAAU,EAAE,IAAY;IACpD,MAAM,MAAM,GAAG,IAAA,gBAAS,GAAE,CAAC;IAE3B,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,MAAM,IAAI,KAAK,CAAC,+DAA+D,CAAC,CAAC;IACnF,CAAC;IAED,kBAAkB;IAClB,MAAM,UAAU,GAAG,MAAM,IAAI,CAAC,UAAU,CAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC;IAE7D,wBAAwB;IACxB,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IACvB,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,OAAO,EAAE,CAAC;IAElC,qBAAqB;IACrB,MAAM,MAAM,GAAG,IAAI,+BAAa,CAAC,MAAM,CAAC,CAAC;IAEzC,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,iBAAiB,CAAC;YAC5C,IAAI;YACJ,GAAG;YACH,UAAU;YACV,IAAI;YACJ,QAAQ,EAAE,IAAI,CAAC,YAAY,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE;SAC9D,CAAC,CAAC;QAEH,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;YACnB,MAAM,IAAI,KAAK,CAAC,6BAA6B,IAAI,uBAAuB,MAAM,CAAC,YAAY,IAAI,6BAA6B,EAAE,CAAC,CAAC;QAClI,CAAC;QAED,OAAO,CAAC,GAAG,CAAC,0BAA0B,IAAI,EAAE,CAAC,CAAC;IAChD,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,IAAI,KAAK,YAAY,KAAK,EAAE,CAAC;YAC3B,MAAM,KAAK,CAAC;QACd,CAAC;QACD,MAAM,IAAI,KAAK,CAAC,kCAAkC,KAAK,EAAE,CAAC,CAAC;IAC7D,CAAC;AACH,CAAC;AAED;;;;GAIG;AACU,QAAA,QAAQ,GAAG;IACtB,OAAO;CACR,CAAC"} |
| {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"} |
| {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":";AAAA;;GAEG"} |
+21
| MIT License | ||
| Copyright (c) 2025 TestivAI | ||
| Permission is hereby granted, free of charge, to any person obtaining a copy | ||
| of this software and associated documentation files (the "Software"), to deal | ||
| in the Software without restriction, including without limitation the rights | ||
| to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||
| copies of the Software, and to permit persons to whom the Software is | ||
| furnished to do so, subject to the following conditions: | ||
| The above copyright notice and this permission notice shall be included in all | ||
| copies or substantial portions of the Software. | ||
| THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
| IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
| FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
| AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
| LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||
| OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
| SOFTWARE. |
+23
| # @testivai/common | ||
| Shared utilities for TestivAI SDKs and CLI. | ||
| This package is part of [testivai-oss](https://github.com/mcbuddy/testivai-oss). It is typically consumed transitively via `@testivai/witness` or `@testivai/witness-playwright` — you don't usually need to install it directly. | ||
| ## Exports | ||
| - `CoreApiClient`, `DEFAULT_CORE_API_URL` — optional cloud API client | ||
| - `getApiKey`, `saveCredentials`, `loadCredentials`, `deleteCredentials`, `isAuthenticated` — credential helpers | ||
| - `loadConfig`, `findConfigFile`, `configExists`, `getOutputDir`, `DEFAULT_CONFIG` — config loader | ||
| - `CompressionHelper`, `compressionHelper` — GZIP helpers | ||
| - `testivai`, `witness` — optional Playwright helper (requires `playwright` peer dependency) | ||
| ## Installation | ||
| ```bash | ||
| npm install @testivai/common | ||
| ``` | ||
| ## License | ||
| MIT |
+1
-0
@@ -28,1 +28,2 @@ /** | ||
| export declare function isAuthenticated(): boolean; | ||
| //# sourceMappingURL=auth.d.ts.map |
+1
-0
@@ -111,1 +111,2 @@ "use strict"; | ||
| } | ||
| //# sourceMappingURL=auth.js.map |
@@ -35,1 +35,2 @@ /** | ||
| export declare const compressionHelper: CompressionHelper; | ||
| //# sourceMappingURL=compression.d.ts.map |
@@ -108,1 +108,2 @@ "use strict"; | ||
| exports.compressionHelper = new CompressionHelper(); | ||
| //# sourceMappingURL=compression.js.map |
@@ -27,1 +27,2 @@ /** | ||
| export declare function getOutputDir(config: TestivaiConfig, baseDir?: string): string; | ||
| //# sourceMappingURL=config-loader.d.ts.map |
@@ -116,1 +116,2 @@ "use strict"; | ||
| } | ||
| //# sourceMappingURL=config-loader.js.map |
@@ -26,1 +26,2 @@ /** | ||
| export declare const DEFAULT_CORE_API_URL = "https://core-api.testiv.ai"; | ||
| //# sourceMappingURL=core-api-client.d.ts.map |
@@ -109,1 +109,2 @@ "use strict"; | ||
| exports.DEFAULT_CORE_API_URL = DEFAULT_API_URL; | ||
| //# sourceMappingURL=core-api-client.js.map |
+1
-0
@@ -11,1 +11,2 @@ /** | ||
| export { CompressionHelper, compressionHelper, type CompressionOptions, type CompressionResult, } from './compression'; | ||
| //# sourceMappingURL=index.d.ts.map |
+1
-0
@@ -50,1 +50,2 @@ "use strict"; | ||
| Object.defineProperty(exports, "compressionHelper", { enumerable: true, get: function () { return compression_1.compressionHelper; } }); | ||
| //# sourceMappingURL=index.js.map |
@@ -25,1 +25,2 @@ /** | ||
| }; | ||
| //# sourceMappingURL=testivai.d.ts.map |
+1
-0
@@ -61,1 +61,2 @@ "use strict"; | ||
| }; | ||
| //# sourceMappingURL=testivai.js.map |
+1
-0
@@ -134,1 +134,2 @@ /** | ||
| export type CDPerformanceMetrics = BrowserPerformanceMetrics; | ||
| //# sourceMappingURL=types.d.ts.map |
+1
-0
@@ -6,1 +6,2 @@ "use strict"; | ||
| Object.defineProperty(exports, "__esModule", { value: true }); | ||
| //# sourceMappingURL=types.js.map |
+29
-13
| { | ||
| "name": "@testivai/common", | ||
| "version": "0.2.1", | ||
| "version": "0.2.2", | ||
| "description": "Shared utilities for TestivAI SDKs and CLI", | ||
@@ -10,10 +10,7 @@ "main": "dist/index.js", | ||
| }, | ||
| "scripts": { | ||
| "build": "tsc", | ||
| "clean": "rm -rf dist", | ||
| "prepublishOnly": "npm run build", | ||
| "test": "jest", | ||
| "test:unit": "jest", | ||
| "test:watch": "jest --watch" | ||
| }, | ||
| "files": [ | ||
| "dist", | ||
| "README.md", | ||
| "LICENSE" | ||
| ], | ||
| "keywords": [ | ||
@@ -24,7 +21,19 @@ "testivai", | ||
| ], | ||
| "author": "", | ||
| "author": "TestivAI", | ||
| "license": "MIT", | ||
| "repository": { | ||
| "type": "git", | ||
| "url": "git+https://github.com/mcbuddy/testivai-oss.git", | ||
| "directory": "packages/common" | ||
| }, | ||
| "bugs": { | ||
| "url": "https://github.com/mcbuddy/testivai-oss/issues" | ||
| }, | ||
| "homepage": "https://github.com/mcbuddy/testivai-oss/tree/main/packages/common#readme", | ||
| "publishConfig": { | ||
| "access": "public" | ||
| }, | ||
| "engines": { | ||
| "node": ">=18.0.0" | ||
| }, | ||
| "dependencies": { | ||
@@ -34,7 +43,7 @@ "axios": "^1.6.0" | ||
| "devDependencies": { | ||
| "@types/jest": "^30.0.0", | ||
| "@types/node": "^20.10.0", | ||
| "@types/jest": "^30.0.0", | ||
| "jest": "^30.2.0", | ||
| "playwright": "^1.40.0", | ||
| "ts-jest": "^29.4.5", | ||
| "playwright": "^1.40.0", | ||
| "typescript": "^5.3.0" | ||
@@ -49,3 +58,10 @@ }, | ||
| } | ||
| }, | ||
| "scripts": { | ||
| "build": "tsc", | ||
| "clean": "rm -rf dist", | ||
| "test": "jest", | ||
| "test:unit": "jest", | ||
| "test:watch": "jest --watch" | ||
| } | ||
| } | ||
| } |
| /** | ||
| * Tests for compression utilities | ||
| */ | ||
| export {}; |
| "use strict"; | ||
| /** | ||
| * Tests for compression utilities | ||
| */ | ||
| Object.defineProperty(exports, "__esModule", { value: true }); | ||
| const compression_1 = require("../compression"); | ||
| describe('CompressionHelper', () => { | ||
| let compressionHelper; | ||
| beforeEach(() => { | ||
| compressionHelper = new compression_1.CompressionHelper(); | ||
| }); | ||
| describe('compress', () => { | ||
| it('should not compress small data below threshold', async () => { | ||
| const smallData = JSON.stringify({ test: 'small data' }); | ||
| const result = await compressionHelper.compress(smallData); | ||
| expect(result.compressionRatio).toBe(0); | ||
| expect(result.originalSize).toBe(result.compressedSize); | ||
| expect(typeof result.data).toBe('string'); | ||
| expect(result.headers).toBeUndefined(); | ||
| }); | ||
| it('should compress large data above threshold', async () => { | ||
| // Create data larger than 5MB threshold (using smaller threshold for test) | ||
| const testHelper = new compression_1.CompressionHelper({ compressionThreshold: 100 }); | ||
| const largeData = 'x'.repeat(1000); | ||
| const result = await testHelper.compress(largeData); | ||
| expect(result.compressionRatio).toBeGreaterThan(0); | ||
| expect(result.compressedSize).toBeLessThan(result.originalSize); | ||
| expect(Buffer.isBuffer(result.data)).toBe(true); | ||
| expect(result.headers).toEqual({ | ||
| 'Content-Encoding': 'gzip', | ||
| 'Content-Type': 'application/json', | ||
| }); | ||
| }); | ||
| it('should respect compression disabled option', async () => { | ||
| const testHelper = new compression_1.CompressionHelper({ compressUploads: false }); | ||
| const largeData = 'x'.repeat(1000); | ||
| const result = await testHelper.compress(largeData); | ||
| expect(result.compressionRatio).toBe(0); | ||
| expect(result.originalSize).toBe(result.compressedSize); | ||
| }); | ||
| it('should use custom compression level', async () => { | ||
| const testHelper = new compression_1.CompressionHelper({ | ||
| compressionThreshold: 100, | ||
| compressionLevel: 9 // Maximum compression | ||
| }); | ||
| const largeData = 'x'.repeat(1000); | ||
| const result = await testHelper.compress(largeData); | ||
| expect(result.compressionRatio).toBeGreaterThan(0); | ||
| expect(result.compressionTime).toBeGreaterThanOrEqual(0); | ||
| }); | ||
| }); | ||
| describe('formatBytes', () => { | ||
| it('should format bytes correctly', () => { | ||
| expect(compressionHelper.formatBytes(512)).toBe('512 B'); | ||
| expect(compressionHelper.formatBytes(1536)).toBe('1.5 KB'); | ||
| expect(compressionHelper.formatBytes(1048576)).toBe('1.0 MB'); | ||
| }); | ||
| }); | ||
| describe('logCompressionResult', () => { | ||
| it('should log compression result when compressed', () => { | ||
| const consoleSpy = jest.spyOn(console, 'log').mockImplementation(); | ||
| const result = { | ||
| data: Buffer.from('compressed'), | ||
| originalSize: 1000, | ||
| compressedSize: 100, | ||
| compressionRatio: 0.9, | ||
| compressionTime: 50, | ||
| }; | ||
| compressionHelper.logCompressionResult(result); | ||
| expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining('Compressed batch: 1000 B → 100 B (90.0% reduction, 50ms)')); | ||
| consoleSpy.mockRestore(); | ||
| }); | ||
| it('should not log when not compressed', () => { | ||
| const consoleSpy = jest.spyOn(console, 'log').mockImplementation(); | ||
| const result = { | ||
| data: 'uncompressed', | ||
| originalSize: 50, | ||
| compressedSize: 50, | ||
| compressionRatio: 0, | ||
| compressionTime: 0, | ||
| }; | ||
| compressionHelper.logCompressionResult(result); | ||
| // Should not log when compression ratio is 0 | ||
| expect(consoleSpy).not.toHaveBeenCalled(); | ||
| consoleSpy.mockRestore(); | ||
| }); | ||
| }); | ||
| }); |
| /** @type {import('ts-jest').JestConfigWithTsJest} */ | ||
| module.exports = { | ||
| preset: 'ts-jest', | ||
| testEnvironment: 'node', | ||
| roots: ['<rootDir>/src'], | ||
| testMatch: ['**/__tests__/**/*.test.ts'], | ||
| collectCoverageFrom: [ | ||
| 'src/**/*.ts', | ||
| '!src/**/*.d.ts', | ||
| '!src/**/__tests__/**', | ||
| ], | ||
| moduleFileExtensions: ['ts', 'js', 'json'], | ||
| testTimeout: 10000, | ||
| }; |
| /** | ||
| * Tests for compression utilities | ||
| */ | ||
| import { CompressionHelper } from '../compression'; | ||
| describe('CompressionHelper', () => { | ||
| let compressionHelper: CompressionHelper; | ||
| beforeEach(() => { | ||
| compressionHelper = new CompressionHelper(); | ||
| }); | ||
| describe('compress', () => { | ||
| it('should not compress small data below threshold', async () => { | ||
| const smallData = JSON.stringify({ test: 'small data' }); | ||
| const result = await compressionHelper.compress(smallData); | ||
| expect(result.compressionRatio).toBe(0); | ||
| expect(result.originalSize).toBe(result.compressedSize); | ||
| expect(typeof result.data).toBe('string'); | ||
| expect(result.headers).toBeUndefined(); | ||
| }); | ||
| it('should compress large data above threshold', async () => { | ||
| // Create data larger than 5MB threshold (using smaller threshold for test) | ||
| const testHelper = new CompressionHelper({ compressionThreshold: 100 }); | ||
| const largeData = 'x'.repeat(1000); | ||
| const result = await testHelper.compress(largeData); | ||
| expect(result.compressionRatio).toBeGreaterThan(0); | ||
| expect(result.compressedSize).toBeLessThan(result.originalSize); | ||
| expect(Buffer.isBuffer(result.data)).toBe(true); | ||
| expect(result.headers).toEqual({ | ||
| 'Content-Encoding': 'gzip', | ||
| 'Content-Type': 'application/json', | ||
| }); | ||
| }); | ||
| it('should respect compression disabled option', async () => { | ||
| const testHelper = new CompressionHelper({ compressUploads: false }); | ||
| const largeData = 'x'.repeat(1000); | ||
| const result = await testHelper.compress(largeData); | ||
| expect(result.compressionRatio).toBe(0); | ||
| expect(result.originalSize).toBe(result.compressedSize); | ||
| }); | ||
| it('should use custom compression level', async () => { | ||
| const testHelper = new CompressionHelper({ | ||
| compressionThreshold: 100, | ||
| compressionLevel: 9 // Maximum compression | ||
| }); | ||
| const largeData = 'x'.repeat(1000); | ||
| const result = await testHelper.compress(largeData); | ||
| expect(result.compressionRatio).toBeGreaterThan(0); | ||
| expect(result.compressionTime).toBeGreaterThanOrEqual(0); | ||
| }); | ||
| }); | ||
| describe('formatBytes', () => { | ||
| it('should format bytes correctly', () => { | ||
| expect(compressionHelper.formatBytes(512)).toBe('512 B'); | ||
| expect(compressionHelper.formatBytes(1536)).toBe('1.5 KB'); | ||
| expect(compressionHelper.formatBytes(1048576)).toBe('1.0 MB'); | ||
| }); | ||
| }); | ||
| describe('logCompressionResult', () => { | ||
| it('should log compression result when compressed', () => { | ||
| const consoleSpy = jest.spyOn(console, 'log').mockImplementation(); | ||
| const result = { | ||
| data: Buffer.from('compressed'), | ||
| originalSize: 1000, | ||
| compressedSize: 100, | ||
| compressionRatio: 0.9, | ||
| compressionTime: 50, | ||
| }; | ||
| compressionHelper.logCompressionResult(result); | ||
| expect(consoleSpy).toHaveBeenCalledWith( | ||
| expect.stringContaining('Compressed batch: 1000 B → 100 B (90.0% reduction, 50ms)') | ||
| ); | ||
| consoleSpy.mockRestore(); | ||
| }); | ||
| it('should not log when not compressed', () => { | ||
| const consoleSpy = jest.spyOn(console, 'log').mockImplementation(); | ||
| const result = { | ||
| data: 'uncompressed', | ||
| originalSize: 50, | ||
| compressedSize: 50, | ||
| compressionRatio: 0, | ||
| compressionTime: 0, | ||
| }; | ||
| compressionHelper.logCompressionResult(result); | ||
| // Should not log when compression ratio is 0 | ||
| expect(consoleSpy).not.toHaveBeenCalled(); | ||
| consoleSpy.mockRestore(); | ||
| }); | ||
| }); | ||
| }); |
-79
| /** | ||
| * Authentication utilities for TestivAI | ||
| * Handles credential storage and retrieval | ||
| */ | ||
| import * as fs from 'fs'; | ||
| import * as path from 'path'; | ||
| import * as os from 'os'; | ||
| import { StoredCredentials } from './types'; | ||
| const CREDENTIALS_DIR = path.join(os.homedir(), '.testivai'); | ||
| const CREDENTIALS_FILE = path.join(CREDENTIALS_DIR, 'credentials'); | ||
| /** | ||
| * Ensure the credentials directory exists | ||
| */ | ||
| function ensureCredentialsDir(): void { | ||
| if (!fs.existsSync(CREDENTIALS_DIR)) { | ||
| fs.mkdirSync(CREDENTIALS_DIR, { recursive: true, mode: 0o700 }); | ||
| } | ||
| } | ||
| /** | ||
| * Save credentials to the local file system | ||
| */ | ||
| export function saveCredentials(credentials: StoredCredentials): void { | ||
| ensureCredentialsDir(); | ||
| fs.writeFileSync(CREDENTIALS_FILE, JSON.stringify(credentials, null, 2), { | ||
| mode: 0o600, | ||
| }); | ||
| } | ||
| /** | ||
| * Load credentials from the local file system | ||
| * Returns null if no credentials are stored | ||
| */ | ||
| export function loadCredentials(): StoredCredentials | null { | ||
| if (!fs.existsSync(CREDENTIALS_FILE)) { | ||
| return null; | ||
| } | ||
| try { | ||
| const content = fs.readFileSync(CREDENTIALS_FILE, 'utf-8'); | ||
| return JSON.parse(content) as StoredCredentials; | ||
| } catch { | ||
| return null; | ||
| } | ||
| } | ||
| /** | ||
| * Delete stored credentials | ||
| */ | ||
| export function deleteCredentials(): void { | ||
| if (fs.existsSync(CREDENTIALS_FILE)) { | ||
| fs.unlinkSync(CREDENTIALS_FILE); | ||
| } | ||
| } | ||
| /** | ||
| * Get the API key from environment variable or stored credentials | ||
| * Environment variable takes precedence | ||
| */ | ||
| export function getApiKey(): string | null { | ||
| // Check environment variable first | ||
| const envKey = process.env.TESTIVAI_API_KEY; | ||
| if (envKey) { | ||
| return envKey; | ||
| } | ||
| // Fall back to stored credentials | ||
| const credentials = loadCredentials(); | ||
| return credentials?.apiKey || null; | ||
| } | ||
| /** | ||
| * Check if the user is authenticated | ||
| */ | ||
| export function isAuthenticated(): boolean { | ||
| return getApiKey() !== null; | ||
| } |
| /** | ||
| * Compression utilities for TestivAI SDKs | ||
| * Handles gzip compression for upload optimization | ||
| */ | ||
| import * as zlib from 'zlib'; | ||
| import { promisify } from 'util'; | ||
| const gzipAsync = promisify(zlib.gzip); | ||
| export interface CompressionOptions { | ||
| compressUploads?: boolean; | ||
| compressionLevel?: number; | ||
| compressionThreshold?: number; | ||
| } | ||
| export interface CompressionResult { | ||
| data: Buffer | string; | ||
| headers?: Record<string, string>; | ||
| originalSize: number; | ||
| compressedSize: number; | ||
| compressionRatio: number; | ||
| compressionTime: number; | ||
| } | ||
| export class CompressionHelper { | ||
| private options: Required<CompressionOptions>; | ||
| constructor(options: CompressionOptions = {}) { | ||
| this.options = { | ||
| compressUploads: options.compressUploads !== false, // default: true | ||
| compressionLevel: options.compressionLevel || 6, | ||
| compressionThreshold: options.compressionThreshold || 5 * 1024 * 1024, // 5MB | ||
| }; | ||
| } | ||
| /** | ||
| * Compress data if it meets the threshold | ||
| */ | ||
| async compress(data: string): Promise<CompressionResult> { | ||
| const originalSize = Buffer.byteLength(data); | ||
| const startTime = Date.now(); | ||
| // Don't compress if disabled or below threshold | ||
| if (!this.options.compressUploads || originalSize < this.options.compressionThreshold) { | ||
| return { | ||
| data, | ||
| originalSize, | ||
| compressedSize: originalSize, | ||
| compressionRatio: 0, | ||
| compressionTime: Date.now() - startTime, | ||
| }; | ||
| } | ||
| // Compress the data | ||
| const compressedData = await gzipAsync(Buffer.from(data), { | ||
| level: this.options.compressionLevel | ||
| }); | ||
| const compressionTime = Date.now() - startTime; | ||
| const compressionRatio = 1 - compressedData.length / originalSize; | ||
| return { | ||
| data: compressedData, | ||
| headers: { | ||
| 'Content-Encoding': 'gzip', | ||
| 'Content-Type': 'application/json', | ||
| }, | ||
| originalSize, | ||
| compressedSize: compressedData.length, | ||
| compressionRatio, | ||
| compressionTime, | ||
| }; | ||
| } | ||
| /** | ||
| * Format bytes for display | ||
| */ | ||
| formatBytes(bytes: number): string { | ||
| if (bytes < 1024) return bytes + ' B'; | ||
| if (bytes < 1024 * 1024) return (bytes / 1024).toFixed(1) + ' KB'; | ||
| return (bytes / (1024 * 1024)).toFixed(1) + ' MB'; | ||
| } | ||
| /** | ||
| * Log compression result | ||
| */ | ||
| logCompressionResult(result: CompressionResult): void { | ||
| if (result.compressionRatio > 0) { | ||
| console.log( | ||
| `Testivai Reporter: Compressed batch: ${this.formatBytes(result.originalSize)} → ` + | ||
| `${this.formatBytes(result.compressedSize)} (${(result.compressionRatio * 100).toFixed(1)}% reduction, ${result.compressionTime}ms)` | ||
| ); | ||
| } | ||
| } | ||
| } | ||
| export const compressionHelper = new CompressionHelper(); |
| /** | ||
| * Configuration loader for TestivAI | ||
| * Loads testivai.config.ts from the project root | ||
| */ | ||
| import * as fs from 'fs'; | ||
| import * as path from 'path'; | ||
| import { TestivaiConfig } from './types'; | ||
| const CONFIG_FILE_NAMES = ['testivai.config.ts', 'testivai.config.js']; | ||
| /** | ||
| * Default configuration values | ||
| */ | ||
| export const DEFAULT_CONFIG: TestivaiConfig = { | ||
| outputDir: './visual-tests', | ||
| viewport: { | ||
| width: 1280, | ||
| height: 720, | ||
| }, | ||
| }; | ||
| /** | ||
| * Find the config file in the current directory or parent directories | ||
| */ | ||
| export function findConfigFile(startDir: string = process.cwd()): string | null { | ||
| let currentDir = startDir; | ||
| while (currentDir !== path.dirname(currentDir)) { | ||
| for (const fileName of CONFIG_FILE_NAMES) { | ||
| const configPath = path.join(currentDir, fileName); | ||
| if (fs.existsSync(configPath)) { | ||
| return configPath; | ||
| } | ||
| } | ||
| currentDir = path.dirname(currentDir); | ||
| } | ||
| return null; | ||
| } | ||
| /** | ||
| * Load configuration from file | ||
| * Returns default config if no config file is found | ||
| */ | ||
| export async function loadConfig(configPath?: string): Promise<TestivaiConfig> { | ||
| const resolvedPath = configPath || findConfigFile(); | ||
| if (!resolvedPath) { | ||
| return DEFAULT_CONFIG; | ||
| } | ||
| try { | ||
| // For TypeScript files, we need to use dynamic import | ||
| // This requires the project to have ts-node or similar configured | ||
| const configModule = await import(resolvedPath); | ||
| const userConfig = configModule.default || configModule; | ||
| return { | ||
| ...DEFAULT_CONFIG, | ||
| ...userConfig, | ||
| }; | ||
| } catch (error) { | ||
| console.warn(`Warning: Could not load config from ${resolvedPath}. Using defaults.`); | ||
| return DEFAULT_CONFIG; | ||
| } | ||
| } | ||
| /** | ||
| * Check if a config file exists in the current directory | ||
| */ | ||
| export function configExists(dir: string = process.cwd()): boolean { | ||
| for (const fileName of CONFIG_FILE_NAMES) { | ||
| if (fs.existsSync(path.join(dir, fileName))) { | ||
| return true; | ||
| } | ||
| } | ||
| return false; | ||
| } | ||
| /** | ||
| * Get the output directory from config, resolved to absolute path | ||
| */ | ||
| export function getOutputDir(config: TestivaiConfig, baseDir: string = process.cwd()): string { | ||
| const outputDir = config.outputDir || DEFAULT_CONFIG.outputDir!; | ||
| return path.isAbsolute(outputDir) ? outputDir : path.join(baseDir, outputDir); | ||
| } |
| /** | ||
| * Core API Client for TestivAI | ||
| * Handles all HTTP communication with the Core API | ||
| */ | ||
| import axios, { AxiosInstance, AxiosError } from 'axios'; | ||
| import { ApiKeyValidationResponse, VisualCheckResult, CaptureData } from './types'; | ||
| const DEFAULT_API_URL = 'https://core-api.testiv.ai'; | ||
| export class CoreApiClient { | ||
| private client: AxiosInstance; | ||
| private apiKey: string; | ||
| constructor(apiKey: string, baseUrl?: string) { | ||
| this.apiKey = apiKey; | ||
| this.client = axios.create({ | ||
| baseURL: baseUrl || DEFAULT_API_URL, | ||
| headers: { | ||
| 'Content-Type': 'application/json', | ||
| 'X-API-Key': apiKey, | ||
| }, | ||
| timeout: 30000, | ||
| }); | ||
| } | ||
| /** | ||
| * Validate an API key against the Core API | ||
| */ | ||
| async validateApiKey(): Promise<ApiKeyValidationResponse> { | ||
| try { | ||
| const response = await this.client.get('/api/v1/auth/validate-key'); | ||
| return { | ||
| valid: true, | ||
| projectId: response.data.project_id, | ||
| projectName: response.data.project_name, | ||
| organizationId: response.data.organization_id, | ||
| organizationName: response.data.organization_name, | ||
| }; | ||
| } catch (error) { | ||
| if (error instanceof AxiosError) { | ||
| if (error.response?.status === 401) { | ||
| return { valid: false, error: 'Invalid API key' }; | ||
| } | ||
| if (error.response?.status === 403) { | ||
| return { valid: false, error: 'API key is disabled or expired' }; | ||
| } | ||
| return { valid: false, error: error.message }; | ||
| } | ||
| return { valid: false, error: 'Unknown error occurred' }; | ||
| } | ||
| } | ||
| /** | ||
| * Submit a visual check to the Core API | ||
| * Note: This method is deprecated and should not be used. | ||
| * The correct approach is to use the batch ingest endpoints. | ||
| */ | ||
| async submitVisualCheck(data: CaptureData): Promise<VisualCheckResult> { | ||
| throw new Error( | ||
| 'submitVisualCheck is deprecated. The /api/v1/visual-check endpoint does not exist. ' + | ||
| 'Please use the batch ingest flow with /api/v1/ingest/start-batch and /api/v1/ingest/finish-batch endpoints.' | ||
| ); | ||
| } | ||
| /** | ||
| * Get the status of a test run | ||
| */ | ||
| async getTestRunStatus(testRunId: string): Promise<VisualCheckResult> { | ||
| const response = await this.client.get(`/api/v1/test-runs/${testRunId}`); | ||
| return { | ||
| testRunId: response.data.id, | ||
| status: response.data.status, | ||
| hasDiff: response.data.has_diff || response.data.status === 'failed', | ||
| diffUrl: response.data.diff_url, | ||
| dashboardUrl: response.data.dashboard_url, | ||
| pixelsChanged: response.data.pixels_changed, | ||
| percentChanged: response.data.percent_changed, | ||
| }; | ||
| } | ||
| } | ||
| export const DEFAULT_CORE_API_URL = DEFAULT_API_URL; |
-39
| /** | ||
| * @testivai/common | ||
| * Shared utilities for TestivAI SDKs and CLI | ||
| */ | ||
| // Types | ||
| export * from './types'; | ||
| // Core API Client | ||
| export { CoreApiClient, DEFAULT_CORE_API_URL } from './core-api-client'; | ||
| // Authentication | ||
| export { | ||
| saveCredentials, | ||
| loadCredentials, | ||
| deleteCredentials, | ||
| getApiKey, | ||
| isAuthenticated, | ||
| } from './auth'; | ||
| // Configuration | ||
| export { | ||
| DEFAULT_CONFIG, | ||
| findConfigFile, | ||
| loadConfig, | ||
| configExists, | ||
| getOutputDir, | ||
| } from './config-loader'; | ||
| // TestivAI helper for visual checks | ||
| export { testivai, witness } from './testivai'; | ||
| // Compression utilities | ||
| export { | ||
| CompressionHelper, | ||
| compressionHelper, | ||
| type CompressionOptions, | ||
| type CompressionResult, | ||
| } from './compression'; |
| /** | ||
| * TestivAI helper for visual regression testing | ||
| * | ||
| * This is a lightweight wrapper that can be used in generated test scripts. | ||
| * | ||
| * NOTE: The witness function uses the deprecated submitVisualCheck method. | ||
| * For new implementations, use the batch ingest flow instead. | ||
| */ | ||
| import { CoreApiClient } from './core-api-client'; | ||
| import { getApiKey } from './auth'; | ||
| import type { Page } from 'playwright'; | ||
| /** | ||
| * Capture a visual snapshot and submit to TestivAI | ||
| * | ||
| * This is the main function for capturing visual evidence. | ||
| * Aligns with the @testivai/witness-playwright SDK terminology. | ||
| */ | ||
| export async function witness(page: Page, name: string): Promise<void> { | ||
| const apiKey = getApiKey(); | ||
| if (!apiKey) { | ||
| throw new Error('TestivAI API key not found. Run: testivai auth <your-api-key>'); | ||
| } | ||
| // Take screenshot | ||
| const screenshot = await page.screenshot({ fullPage: true }); | ||
| // Get page URL and HTML | ||
| const url = page.url(); | ||
| const html = await page.content(); | ||
| // Submit to TestivAI | ||
| const client = new CoreApiClient(apiKey); | ||
| try { | ||
| const result = await client.submitVisualCheck({ | ||
| name, | ||
| url, | ||
| screenshot, | ||
| html, | ||
| viewport: page.viewportSize() || { width: 1280, height: 720 }, | ||
| }); | ||
| if (result.hasDiff) { | ||
| throw new Error(`Visual diff detected for "${name}". View results at: ${result.dashboardUrl || 'https://dashboard.testiv.ai'}`); | ||
| } | ||
| console.log(`✓ Visual check passed: ${name}`); | ||
| } catch (error) { | ||
| if (error instanceof Error) { | ||
| throw error; | ||
| } | ||
| throw new Error(`Failed to submit visual check: ${error}`); | ||
| } | ||
| } | ||
| /** | ||
| * TestivAI namespace for use in generated scripts | ||
| * | ||
| * Provides the main witness function for capturing visual evidence. | ||
| */ | ||
| export const testivai = { | ||
| witness, | ||
| }; |
-140
| /** | ||
| * Shared TypeScript types for TestivAI SDKs and CLI | ||
| */ | ||
| /** | ||
| * TestivAI configuration options | ||
| */ | ||
| export interface TestivaiConfig { | ||
| /** Base URL for visual tests (optional, can be overridden per test) */ | ||
| baseUrl?: string; | ||
| /** Output directory for generated tests */ | ||
| outputDir?: string; | ||
| /** Viewport settings */ | ||
| viewport?: { | ||
| width: number; | ||
| height: number; | ||
| }; | ||
| } | ||
| /** | ||
| * API Key validation response from Core API | ||
| */ | ||
| export interface ApiKeyValidationResponse { | ||
| valid: boolean; | ||
| projectId?: string; | ||
| projectName?: string; | ||
| organizationId?: string; | ||
| organizationName?: string; | ||
| error?: string; | ||
| } | ||
| /** | ||
| * Credentials stored locally | ||
| */ | ||
| export interface StoredCredentials { | ||
| apiKey: string; | ||
| validatedAt: string; | ||
| projectId?: string; | ||
| projectName?: string; | ||
| } | ||
| /** | ||
| * Visual check result | ||
| */ | ||
| export interface VisualCheckResult { | ||
| testRunId: string; | ||
| status: 'passed' | 'failed' | 'new_baseline'; | ||
| hasDiff: boolean; | ||
| diffUrl?: string; | ||
| dashboardUrl?: string; | ||
| pixelsChanged?: number; | ||
| percentChanged?: number; | ||
| } | ||
| /** | ||
| * Capture data sent to Core API | ||
| */ | ||
| export interface CaptureData { | ||
| snapshotName?: string; | ||
| name?: string; | ||
| url: string; | ||
| /** | ||
| * Page structure data (raw HTML string) | ||
| * @renamed Was `dom` — renamed to conceal internal layer terminology (IP protection) | ||
| */ | ||
| structure?: string; | ||
| html?: string; | ||
| layout?: object; | ||
| screenshot: Buffer; | ||
| viewport: { | ||
| width: number; | ||
| height: number; | ||
| }; | ||
| metadata?: Record<string, unknown>; | ||
| } | ||
| /** | ||
| * Unified Browser Performance metrics for both Playwright and Witness SDKs | ||
| */ | ||
| export interface BrowserPerformanceMetrics { | ||
| /** Browser runtime metrics */ | ||
| cdp?: { | ||
| Timestamp?: number; | ||
| Documents?: number; | ||
| Frames?: number; | ||
| JSEventListeners?: number; | ||
| Nodes?: number; | ||
| LayoutCount?: number; | ||
| RecalcStyleCount?: number; | ||
| LayoutDuration?: number; | ||
| RecalcStyleDuration?: number; | ||
| ScriptDuration?: number; | ||
| TaskDuration?: number; | ||
| JSHeapUsedSize?: number; | ||
| JSHeapTotalSize?: number; | ||
| }; | ||
| /** Navigation timing and Web Vitals */ | ||
| timing?: { | ||
| navigation?: { | ||
| type: number; | ||
| redirectCount: number; | ||
| }; | ||
| timing?: { | ||
| navigationStart: number; | ||
| unloadEventStart: number; | ||
| unloadEventEnd: number; | ||
| redirectStart: number; | ||
| redirectEnd: number; | ||
| fetchStart: number; | ||
| domainLookupStart: number; | ||
| domainLookupEnd: number; | ||
| connectStart: number; | ||
| connectEnd: number; | ||
| secureConnectionStart: number; | ||
| requestStart: number; | ||
| responseStart: number; | ||
| responseEnd: number; | ||
| domLoading: number; | ||
| domInteractive: number; | ||
| domContentLoadedEventStart: number; | ||
| domContentLoadedEventEnd: number; | ||
| domComplete: number; | ||
| loadEventStart: number; | ||
| loadEventEnd: number; | ||
| }; | ||
| webVitals?: { | ||
| firstContentfulPaint?: number; | ||
| largestContentfulPaint?: number; | ||
| cumulativeLayoutShift?: number; | ||
| firstInputDelay?: number; | ||
| }; | ||
| }; | ||
| /** Timestamp when metrics were captured */ | ||
| timestamp?: number; | ||
| } | ||
| /** | ||
| * @deprecated Use BrowserPerformanceMetrics instead | ||
| */ | ||
| export type CDPerformanceMetrics = BrowserPerformanceMetrics; |
| { | ||
| "compilerOptions": { | ||
| "target": "ES2020", | ||
| "module": "commonjs", | ||
| "lib": ["ES2020"], | ||
| "declaration": true, | ||
| "outDir": "./dist", | ||
| "strict": true, | ||
| "esModuleInterop": true, | ||
| "allowSyntheticDefaultImports": true, | ||
| "skipLibCheck": true, | ||
| "forceConsistentCasingInFileNames": true, | ||
| "resolveJsonModule": true, | ||
| "moduleResolution": "node", | ||
| "types": ["node", "jest"] | ||
| }, | ||
| "include": ["src/**/*"], | ||
| "exclude": ["node_modules", "dist"] | ||
| } |
URL strings
Supply chain riskPackage contains fragments of external URLs or IP addresses, which the package may be accessing at runtime.
No README
QualityPackage does not have a README. This may indicate a failed publish or a low quality package.
Filesystem access
Supply chain riskAccesses the file system, and could potentially read sensitive data.
No contributors or author data
MaintenancePackage does not specify a list of contributors or an author in package.json.
No bug tracker
MaintenancePackage does not have a linked bug tracker in package.json.
No repository
Supply chain riskPackage does not have a linked source code repository. Without this field, a package will have no reference to the location of the source code use to generate the package.
No website
QualityPackage does not have a website.
URL strings
Supply chain riskPackage contains fragments of external URLs or IP addresses, which the package may be accessing at runtime.
31
14.81%0
-100%1
-50%1
-50%24
Infinity%5
-44.44%48873
-10.59%834
-46.98%