ssrwire 0.1.0 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +22 -1
- package/CONTRIBUTING.md +7 -5
- package/PUBLISHING.md +92 -78
- package/README.md +53 -11
- package/SECURITY.md +8 -4
- package/dist/audit.d.ts.map +1 -1
- package/dist/audit.js +82 -7
- package/dist/audit.js.map +1 -1
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +3 -0
- package/dist/cli.js.map +1 -1
- package/dist/config.d.ts +1 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +7 -0
- package/dist/config.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js.map +1 -1
- package/dist/redact.d.ts.map +1 -1
- package/dist/redact.js +12 -0
- package/dist/redact.js.map +1 -1
- package/dist/reporters.d.ts.map +1 -1
- package/dist/reporters.js +42 -2
- package/dist/reporters.js.map +1 -1
- package/dist/stability.d.ts +9 -0
- package/dist/stability.d.ts.map +1 -0
- package/dist/stability.js +246 -0
- package/dist/stability.js.map +1 -0
- package/dist/types.d.ts +37 -0
- package/dist/types.d.ts.map +1 -1
- package/examples/github-actions.yml +2 -2
- package/examples/ssrwire.config.yml +4 -0
- package/package.json +1 -1
- package/src/audit.ts +116 -8
- package/src/cli.ts +4 -0
- package/src/config.ts +8 -0
- package/src/index.ts +4 -0
- package/src/redact.ts +12 -0
- package/src/reporters.ts +51 -2
- package/src/stability.ts +356 -0
- package/src/types.ts +41 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stability.js","sourceRoot":"","sources":["../src/stability.ts"],"names":[],"mappings":"AAYA,MAAM,iBAAiB,GAAG,IAAI,GAAG,CAAC,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC,CAAC;AAC7D,MAAM,gBAAgB,GAAG;IACvB,CAAC,OAAO,EAAE,SAAS,CAAC;IACpB,CAAC,QAAQ,EAAE,UAAU,CAAC;IACtB,CAAC,SAAS,EAAE,WAAW,CAAC;IACxB,CAAC,SAAS,EAAE,WAAW,CAAC;IACxB,CAAC,WAAW,EAAE,aAAa,CAAC;IAC5B,CAAC,YAAY,EAAE,cAAc,CAAC;CACtB,CAAC;AAOX,SAAS,aAAa,CAAC,KAAa;IAClC,OAAO,KAAK,CAAC,IAAI,EAAE,CAAC,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;AAC3C,CAAC;AAED,SAAS,YAAY,CAAC,KAAa,EAAE,OAAgB;IACnD,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;QAC7E,GAAG,CAAC,IAAI,GAAG,EAAE,CAAC;QACd,OAAO,GAAG,CAAC,IAAI,CAAC;IAClB,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,aAAa,CAAC,KAAK,CAAC,CAAC;IAC9B,CAAC;AACH,CAAC;AAED,SAAS,kBAAkB,CAAC,KAAa,EAAE,OAAe;IACxD,MAAM,UAAU,GAAG,aAAa,CAAC,KAAK,CAAC,CAAC;IACxC,OAAO,UAAU,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,YAAY,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;AAC1E,CAAC;AAED,SAAS,sBAAsB,CAC7B,OAAiC,EACjC,YAAuC,aAAa;IAEpD,OAAO;QACL,GAAG,IAAI,GAAG,CACR,OAAO,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,SAAS,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CACrF;KACF,CAAC,IAAI,EAAE,CAAC;AACX,CAAC;AAED,SAAS,sBAAsB,CAAC,KAAmB;IACjD,MAAM,GAAG,GAAG,KAAK,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IAC3C,IAAI,GAAG,KAAK,WAAW,IAAI,GAAG,KAAK,SAAS;QAAE,OAAO,GAAG,CAAC;IACzD,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED,SAAS,sBAAsB,CAAC,KAAkB;IAChD,MAAM,QAAQ,GAAG,sBAAsB,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;IACrD,MAAM,OAAO,GAAG,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,QAAQ,KAAK,QAAQ,CAAC,CAAC;IACtF,IAAI,QAAQ,KAAK,QAAQ;QAAE,OAAO,OAAO,CAAC;IAC1C,OAAO,CAAC,GAAG,OAAO,EAAE,GAAG,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,QAAQ,KAAK,QAAQ,CAAC,CAAC,CAAC;AAChG,CAAC;AAED,SAAS,qBAAqB,CAAC,OAAgC;IAC7D,MAAM,UAAU,GAAG,IAAI,GAAG,CACxB,OAAO;SACJ,OAAO,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,aAAa,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,WAAW,EAAE,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;SAC5E,GAAG,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,SAAS,CAAC,IAAI,EAAE,CAAC;SACpC,MAAM,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,SAAS,CAAC,MAAM,GAAG,CAAC,CAAC,CAC/C,CAAC;IACF,IAAI,UAAU,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC;QAC9B,UAAU,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;QAC1B,UAAU,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;IAC7B,CAAC;IACD,IAAI,UAAU,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC;QAC7B,UAAU,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;QACxB,UAAU,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;IAC3B,CAAC;IACD,KAAK,MAAM,CAAC,UAAU,EAAE,WAAW,CAAC,IAAI,gBAAgB,EAAE,CAAC;QACzD,IAAI,UAAU,CAAC,GAAG,CAAC,WAAW,CAAC;YAAE,UAAU,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;IACjE,CAAC;IACD,OAAO,CAAC,GAAG,UAAU,CAAC,CAAC,IAAI,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,WAAW,CAAC;AACzD,CAAC;AAED,SAAS,oBAAoB,CAAC,KAAkB;IAC9C,OAAO,qBAAqB,CAAC,sBAAsB,CAAC,KAAK,CAAC,CAAC,CAAC;AAC9D,CAAC;AAED,SAAS,oBAAoB,CAC3B,OAAiC,EACjC,YAAuC,aAAa;IAEpD,MAAM,OAAO,GAAG,OAAO;SACpB,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,SAAS,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC,QAAQ,CAAU,CAAC;SACpE,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;IACzC,OAAO,CAAC,GAAG,IAAI,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,IAAI,CACvF,CAAC,CAAC,SAAS,EAAE,YAAY,CAAC,EAAE,CAAC,UAAU,EAAE,aAAa,CAAC,EAAE,EAAE;QACzD,MAAM,UAAU,GAAG,SAAS,CAAC,aAAa,CAAC,UAAU,CAAC,CAAC;QACvD,OAAO,UAAU,KAAK,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,aAAa,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC;IACnF,CAAC,CACF,CAAC;AACJ,CAAC;AAED,SAAS,oBAAoB,CAAC,KAAkB;IAC9C,MAAM,OAAO,GAAG,sBAAsB,CAAC,KAAK,CAAC;SAC1C,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,qBAAqB,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,MAAM,CAAC,QAAQ,CAAU,CAAC;SAC5E,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,EAAE,EAAE,CAAC,KAAK,KAAK,WAAW,CAAC,CAAC;IAC9C,OAAO,CAAC,GAAG,IAAI,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,IAAI,CACvF,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,aAAa,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,CAC3E,CAAC;AACJ,CAAC;AAED,SAAS,sBAAsB,CAAC,KAAkB;IAChD,MAAM,MAAM,GAAG,KAAK,CAAC,OAAO,CAAC,MAAM,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;IAC1F,OAAO,IAAI,CAAC,SAAS,CAAC;QACpB,KAAK,EAAE,sBAAsB,CAAC,MAAM,CAAC;QACrC,WAAW,EAAE,sBAAsB,CAAC,KAAK,CAAC,OAAO,CAAC,YAAY,CAAC;QAC/D,SAAS,EAAE,sBAAsB,CAAC,KAAK,CAAC,OAAO,CAAC,UAAU,EAAE,CAAC,KAAK,EAAE,EAAE,CACpE,kBAAkB,CAAC,KAAK,EAAE,KAAK,CAAC,QAAQ,CAAC,CAC1C;QACD,MAAM,EAAE,oBAAoB,CAAC,KAAK,CAAC;KACpC,CAAC,CAAC;AACL,CAAC;AAED,SAAS,yBAAyB,CAAC,KAAkB;IACnD,MAAM,MAAM,GAAG,KAAK,CAAC,OAAO,CAAC,MAAM,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;IAC1F,OAAO,IAAI,CAAC,SAAS,CAAC;QACpB,KAAK,EAAE,oBAAoB,CAAC,MAAM,CAAC;QACnC,WAAW,EAAE,oBAAoB,CAAC,KAAK,CAAC,OAAO,CAAC,YAAY,CAAC;QAC7D,SAAS,EAAE,oBAAoB,CAAC,KAAK,CAAC,OAAO,CAAC,UAAU,EAAE,CAAC,KAAK,EAAE,EAAE,CAClE,kBAAkB,CAAC,KAAK,EAAE,KAAK,CAAC,QAAQ,CAAC,CAC1C;QACD,MAAM,EAAE,oBAAoB,CAAC,KAAK,CAAC;KACpC,CAAC,CAAC;AACL,CAAC;AAED,SAAS,sBAAsB,CAAC,KAAkB;IAChD,OAAO,IAAI,CAAC,SAAS,CACnB,KAAK,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;QACjC,MAAM,EAAE,QAAQ,CAAC,MAAM;QACvB,GAAG,EAAE,YAAY,CAAC,QAAQ,CAAC,GAAG,CAAC;QAC/B,QAAQ,EAAE,YAAY,CAAC,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAC,GAAG,CAAC;KACxD,CAAC,CAAC,CACJ,CAAC;AACJ,CAAC;AAED,SAAS,WAAW,CAAC,MAAyB;IAC5C,OAAO,IAAI,GAAG,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC;AAC9B,CAAC;AAED,MAAM,UAAU,oBAAoB,CAAC,MAAyB;IAC5D,MAAM,MAAM,GAAG,MAAM;SAClB,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,KAAK,IAAI,CAAC,CAAC;SACvD,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;IACzB,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,SAAS,CAAC;IAE1C,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;IAC7C,MAAM,KAAK,GAAG,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;IACjC,MAAM,KAAK,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC;IAC7B,MAAM,QAAQ,GACZ,MAAM,CAAC,MAAM,GAAG,CAAC,KAAK,CAAC,IAAI,KAAK,KAAK,SAAS,IAAI,KAAK,KAAK,SAAS;QACnE,CAAC,CAAC,CAAC,KAAK,GAAG,KAAK,CAAC,GAAG,CAAC;QACrB,CAAC,CAAC,CAAC,KAAK,IAAI,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;IAChC,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;IAClE,MAAM,KAAK,GAAG,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;IAC7B,MAAM,KAAK,GAAG,MAAM,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,IAAI,KAAK,CAAC;IAEjD,OAAO;QACL,OAAO,EAAE,MAAM,CAAC,MAAM;QACtB,KAAK;QACL,QAAQ;QACR,KAAK,EAAE,MAAM,CAAC,QAAQ,CAAC,IAAI,KAAK;QAChC,KAAK;QACL,QAAQ,EAAE,KAAK,GAAG,KAAK;KACxB,CAAC;AACJ,CAAC;AAED,SAAS,aAAa,CAAC,OAAiC;IACtD,OAAO,OAAO,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,aAAa,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;AAC1E,CAAC;AAED,MAAM,UAAU,wBAAwB,CACtC,MAAmB,EACnB,KAAkB;IAElB,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,MAAM,EAAE,YAAY,EAAE,GAAG,MAAM,CAAC;IAChC,IAAI,QAAQ,GAAG,CAAC,CAAC;IAEjB,MAAM,WAAW,GAAG,CAAC,MAAiC,EAAW,EAAE;QACjE,QAAQ,IAAI,CAAC,CAAC;QACd,IAAI,MAAM,KAAK,SAAS,IAAI,aAAa,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,KAAK,CAAC;QACnF,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;QACxB,OAAO,IAAI,CAAC;IACd,CAAC,CAAC;IAEF,IAAI,YAAY,CAAC,YAAY,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC;QAAE,OAAO,SAAS,CAAC;IACrF,IAAI,YAAY,CAAC,kBAAkB,IAAI,CAAC,WAAW,CAAC,aAAa,CAAC,KAAK,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC,EAAE,CAAC;QAC/F,OAAO,SAAS,CAAC;IACnB,CAAC;IACD,IAAI,YAAY,CAAC,gBAAgB,EAAE,CAAC;QAClC,MAAM,SAAS,GAAG,KAAK,CAAC,OAAO,CAAC,UAAU,CAAC,IAAI,CAC7C,CAAC,MAAM,EAAE,EAAE,CAAC,kBAAkB,CAAC,MAAM,CAAC,KAAK,EAAE,KAAK,CAAC,QAAQ,CAAC,CAAC,MAAM,GAAG,CAAC,CACxE,CAAC;QACF,IAAI,CAAC,WAAW,CAAC,SAAS,CAAC;YAAE,OAAO,SAAS,CAAC;IAChD,CAAC;IACD,IAAI,YAAY,CAAC,SAAS,IAAI,CAAC,WAAW,CAAC,aAAa,CAAC,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;QAAE,OAAO,SAAS,CAAC;IAC/F,IAAI,YAAY,CAAC,eAAe,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,OAAO,CAAC,aAAa,CAAC;QAAE,OAAO,SAAS,CAAC;IAEhG,OAAO,QAAQ,KAAK,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC,CAAC;AACzD,CAAC;AAED,SAAS,QAAQ,CACf,MAAyB,EACzB,GAA6D,EAC7D,MAAmC;IAEnC,MAAM,KAAK,GAAG,oBAAoB,CAAC,MAAM,CAAC,CAAC;IAC3C,IAAI,KAAK,KAAK,SAAS;QAAE,MAAM,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;AAC/C,CAAC;AAED,SAAS,cAAc,CAAC,MAAmB,EAAE,MAA8B;IACzE,MAAM,KAAK,GAAG,MAAM,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC;IAC/B,IAAI,KAAK,KAAK,SAAS;QAAE,MAAM,IAAI,KAAK,CAAC,wCAAwC,CAAC,CAAC;IACnF,MAAM,QAAQ,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,UAAU,KAAK,UAAU,CAAC,CAAC;IAC3E,MAAM,cAAc,GAAG,MAAM,CAAC,MAAM,CAClC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,MAAM,KAAK,SAAS,IAAI,CAAC,iBAAiB,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,CAC9E,CAAC;IACF,MAAM,OAAO,GAAgC,EAAE,CAAC;IAEhD,QAAQ,CACN,cAAc,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,SAAS,CAAC,EACtD,SAAS,EACT,OAAO,CACR,CAAC;IACF,QAAQ,CACN,MAAM,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,EAAE,CACvB,KAAK,CAAC,OAAO,CAAC,WAAW,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,WAAW,CAAC,CAC3E,EACD,WAAW,EACX,OAAO,CACR,CAAC;IACF,QAAQ,CACN,QAAQ,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,EAAE;QACzB,MAAM,KAAK,GAAG,wBAAwB,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;QACtD,OAAO,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;IAC5C,CAAC,CAAC,EACF,iBAAiB,EACjB,OAAO,CACR,CAAC;IACF,QAAQ,CACN,QAAQ,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,EAAE,CACzB,KAAK,CAAC,OAAO,CAAC,UAAU,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,UAAU,CAAC,CACzE,EACD,UAAU,EACV,OAAO,CACR,CAAC;IAEF,OAAO;QACL,KAAK;QACL,OAAO,EAAE,MAAM,CAAC,MAAM;QACtB,QAAQ,EAAE,QAAQ,CAAC,MAAM;QACzB,UAAU,EAAE,MAAM,CAAC,MAAM,GAAG,QAAQ,CAAC,MAAM;QAC3C,OAAO;QACP,QAAQ,EAAE;YACR,UAAU,EAAE,WAAW,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;YAChE,MAAM,EAAE,WAAW,CAAC,cAAc,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC;YACxE,QAAQ,EAAE,WAAW,CAAC,cAAc,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,YAAY,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC;YAClF,aAAa,EAAE,WAAW,CAAC,MAAM,CAAC,GAAG,CAAC,sBAAsB,CAAC,CAAC;YAC9D,UAAU,EAAE,WAAW,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,UAAU,IAAI,WAAW,CAAC,CAAC;YACjF,cAAc,EAAE,WAAW,CAAC,QAAQ,CAAC,GAAG,CAAC,sBAAsB,CAAC,CAAC;YACjE,iBAAiB,EAAE,WAAW,CAAC,QAAQ,CAAC,GAAG,CAAC,yBAAyB,CAAC,CAAC;SACxE;KACF,CAAC;AACJ,CAAC;AAED,SAAS,OAAO,CACd,MAAmB,EACnB,OAAuB,EACvB,IAAmD,EACnD,QAA4B,EAC5B,MAAyB;IAEzB,MAAM,QAAQ,GAAG,OAAO,CAAC,QAAQ,CAAC;IAClC,OAAO;QACL,IAAI;QACJ,QAAQ;QACR,OAAO,EACL,IAAI,KAAK,sBAAsB;YAC7B,CAAC,CAAC,GAAG,OAAO,CAAC,KAAK,CAAC,KAAK,+DAA+D;YACvF,CAAC,CAAC,GAAG,OAAO,CAAC,KAAK,CAAC,KAAK,+DAA+D;QAC3F,GAAG,EAAE,MAAM,CAAC,GAAG;QACf,KAAK,EAAE,OAAO,CAAC,KAAK,CAAC,GAAG;QACxB,QAAQ,EAAE;YACR,OAAO,EAAE,OAAO,CAAC,OAAO;YACxB,eAAe,EAAE,OAAO,CAAC,QAAQ;YACjC,MAAM,EAAE,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC;YACzB,aAAa,EAAE,MAAM;iBAClB,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,GAAG,KAAK,IAAI,QAAQ,CAAC,KAA8B,CAAC,EAAE,CAAC;iBACtE,IAAI,CAAC,IAAI,CAAC;SACd;KACF,CAAC;AACJ,CAAC;AAED,SAAS,WAAW,CAAC,MAAmB,EAAE,OAAuB;IAC/D,MAAM,QAAQ,GAAc,EAAE,CAAC;IAC/B,MAAM,cAAc,GAAI,CAAC,YAAY,EAAE,QAAQ,EAAE,UAAU,EAAE,eAAe,CAAW,CAAC,MAAM,CAC5F,CAAC,KAAK,EAAE,EAAE,CAAC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,CACvC,CAAC;IACF,IAAI,cAAc,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC9B,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,OAAO,EAAE,sBAAsB,EAAE,SAAS,EAAE,cAAc,CAAC,CAAC,CAAC;IAC7F,CAAC;IAED,MAAM,YAAY,GAAI,CAAC,YAAY,EAAE,gBAAgB,EAAE,mBAAmB,CAAW,CAAC,MAAM,CAC1F,CAAC,KAAK,EAAE,EAAE,CAAC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,CACvC,CAAC;IACF,IAAI,YAAY,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC5B,MAAM,eAAe,GAAG,YAAY,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,KAAK,YAAY,CAAC,CAAC;QAC7E,QAAQ,CAAC,IAAI,CACX,OAAO,CACL,MAAM,EACN,OAAO,EACP,oBAAoB,EACpB,eAAe,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,MAAM,EACpC,YAAY,CACb,CACF,CAAC;IACJ,CAAC;IAED,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED,MAAM,UAAU,gBAAgB,CAC9B,MAAmB,EACnB,MAA8B;IAE9B,MAAM,MAAM,GAAG,IAAI,GAAG,EAAyB,CAAC;IAChD,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;QAC3B,MAAM,KAAK,GAAG,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC;QAChD,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAClB,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;IACrC,CAAC;IAED,MAAM,SAAS,GAAG,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,cAAc,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC,CAAC;IACrF,OAAO;QACL,SAAS;QACT,QAAQ,EAAE,SAAS,CAAC,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,WAAW,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;KACvE,CAAC;AACJ,CAAC"}
|
package/dist/types.d.ts
CHANGED
|
@@ -78,6 +78,8 @@ export interface ProbeResult {
|
|
|
78
78
|
readonly signals: DocumentSignals;
|
|
79
79
|
readonly completion: ProbeCompletion;
|
|
80
80
|
readonly error?: string;
|
|
81
|
+
/** One-based audit sample number. Low-level probeUrl() calls leave this unset. */
|
|
82
|
+
readonly sample?: number;
|
|
81
83
|
}
|
|
82
84
|
export interface TargetExpectations {
|
|
83
85
|
readonly statuses: readonly number[];
|
|
@@ -101,6 +103,39 @@ export interface SsrWireConfig {
|
|
|
101
103
|
readonly timeoutMs: number;
|
|
102
104
|
readonly maxBytes: number;
|
|
103
105
|
readonly maxRedirects: number;
|
|
106
|
+
/** Total samples per target and agent. Defaults to one for programmatic callers. */
|
|
107
|
+
readonly repeat?: number;
|
|
108
|
+
}
|
|
109
|
+
export interface TimingStats {
|
|
110
|
+
readonly samples: number;
|
|
111
|
+
readonly minMs: number;
|
|
112
|
+
readonly medianMs: number;
|
|
113
|
+
readonly p95Ms: number;
|
|
114
|
+
readonly maxMs: number;
|
|
115
|
+
readonly spreadMs: number;
|
|
116
|
+
}
|
|
117
|
+
export interface StabilityTimings {
|
|
118
|
+
readonly headers?: TimingStats;
|
|
119
|
+
readonly firstByte?: TimingStats;
|
|
120
|
+
readonly criticalSignals?: TimingStats;
|
|
121
|
+
readonly complete?: TimingStats;
|
|
122
|
+
}
|
|
123
|
+
export interface StabilityVariants {
|
|
124
|
+
readonly completion: number;
|
|
125
|
+
readonly status: number;
|
|
126
|
+
readonly finalUrl: number;
|
|
127
|
+
readonly redirectChain: number;
|
|
128
|
+
readonly bodySha256: number;
|
|
129
|
+
readonly metadataValues: number;
|
|
130
|
+
readonly metadataLocations: number;
|
|
131
|
+
}
|
|
132
|
+
export interface AgentStability {
|
|
133
|
+
readonly agent: AgentProfile;
|
|
134
|
+
readonly samples: number;
|
|
135
|
+
readonly complete: number;
|
|
136
|
+
readonly incomplete: number;
|
|
137
|
+
readonly timings: StabilityTimings;
|
|
138
|
+
readonly variants: StabilityVariants;
|
|
104
139
|
}
|
|
105
140
|
export interface Finding {
|
|
106
141
|
readonly code: string;
|
|
@@ -114,6 +149,7 @@ export interface TargetAuditResult {
|
|
|
114
149
|
readonly target: AuditTarget;
|
|
115
150
|
readonly probes: readonly ProbeResult[];
|
|
116
151
|
readonly findings: readonly Finding[];
|
|
152
|
+
readonly stability?: readonly AgentStability[];
|
|
117
153
|
}
|
|
118
154
|
export interface AuditSummary {
|
|
119
155
|
readonly targets: number;
|
|
@@ -127,6 +163,7 @@ export interface AuditResult {
|
|
|
127
163
|
readonly version: string;
|
|
128
164
|
readonly generatedAt: string;
|
|
129
165
|
readonly durationMs: number;
|
|
166
|
+
readonly repeat?: number;
|
|
130
167
|
readonly results: readonly TargetAuditResult[];
|
|
131
168
|
readonly summary: AuditSummary;
|
|
132
169
|
}
|
package/dist/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
|
|
@@ -27,7 +27,7 @@ jobs:
|
|
|
27
27
|
if: github.event_name == 'pull_request'
|
|
28
28
|
continue-on-error: true
|
|
29
29
|
run: >-
|
|
30
|
-
npx --yes ssrwire@0.
|
|
30
|
+
npx --yes ssrwire@0.2.0 check
|
|
31
31
|
--config ssrwire.config.yml
|
|
32
32
|
--format sarif
|
|
33
33
|
--output reports/ssrwire.sarif
|
|
@@ -38,7 +38,7 @@ jobs:
|
|
|
38
38
|
if: github.event_name != 'pull_request'
|
|
39
39
|
continue-on-error: true
|
|
40
40
|
run: >-
|
|
41
|
-
npx --yes ssrwire@0.
|
|
41
|
+
npx --yes ssrwire@0.2.0 check
|
|
42
42
|
--config ssrwire.config.yml
|
|
43
43
|
--format sarif
|
|
44
44
|
--output reports/ssrwire.sarif
|
|
@@ -32,6 +32,10 @@ timeoutMs: 15000
|
|
|
32
32
|
maxBytes: 10485760
|
|
33
33
|
maxRedirects: 10
|
|
34
34
|
|
|
35
|
+
# Run each target-agent pair sequentially three times to expose intermittent SSR output.
|
|
36
|
+
# Total requests are targets × agents × repeat, plus redirects.
|
|
37
|
+
repeat: 3
|
|
38
|
+
|
|
35
39
|
# Keep preview credentials in a CI secret or exported environment variable.
|
|
36
40
|
# headers:
|
|
37
41
|
# x-preview-token: "${PREVIEW_TOKEN}"
|
package/package.json
CHANGED
package/src/audit.ts
CHANGED
|
@@ -1,7 +1,15 @@
|
|
|
1
1
|
import { analyzeTarget, summarizeAudit } from "./analyze.js";
|
|
2
2
|
import { probeUrl } from "./http-probe.js";
|
|
3
3
|
import { redactAudit } from "./redact.js";
|
|
4
|
-
import
|
|
4
|
+
import { analyzeStability } from "./stability.js";
|
|
5
|
+
import type {
|
|
6
|
+
AuditResult,
|
|
7
|
+
Finding,
|
|
8
|
+
ProbeOptions,
|
|
9
|
+
ProbeResult,
|
|
10
|
+
SsrWireConfig,
|
|
11
|
+
TargetAuditResult,
|
|
12
|
+
} from "./types.js";
|
|
5
13
|
import { VERSION } from "./version.js";
|
|
6
14
|
|
|
7
15
|
const DEFAULT_CONCURRENCY = 4;
|
|
@@ -12,6 +20,16 @@ interface ProbeTask {
|
|
|
12
20
|
readonly options: ProbeOptions;
|
|
13
21
|
}
|
|
14
22
|
|
|
23
|
+
interface ProbeLane {
|
|
24
|
+
readonly task: ProbeTask;
|
|
25
|
+
readonly probes: readonly ProbeResult[];
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
interface SampleFinding {
|
|
29
|
+
readonly sample: number;
|
|
30
|
+
readonly finding: Finding;
|
|
31
|
+
}
|
|
32
|
+
|
|
15
33
|
async function runPool<T, R>(
|
|
16
34
|
inputs: readonly T[],
|
|
17
35
|
limit: number,
|
|
@@ -37,8 +55,75 @@ async function runPool<T, R>(
|
|
|
37
55
|
return results;
|
|
38
56
|
}
|
|
39
57
|
|
|
58
|
+
function repeatCount(value: number | undefined): number {
|
|
59
|
+
const repeat = value ?? 1;
|
|
60
|
+
if (!Number.isInteger(repeat) || repeat < 1 || repeat > 10) {
|
|
61
|
+
throw new RangeError("repeat must be an integer between 1 and 10.");
|
|
62
|
+
}
|
|
63
|
+
return repeat;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
function mergeEvidence(
|
|
67
|
+
sampled: readonly SampleFinding[],
|
|
68
|
+
repeat: number,
|
|
69
|
+
): Readonly<Record<string, string | number | boolean>> {
|
|
70
|
+
const merged: Record<string, string | number | boolean> & {
|
|
71
|
+
occurrences?: number;
|
|
72
|
+
sampleNumbers?: string;
|
|
73
|
+
totalSamples?: number;
|
|
74
|
+
} = {};
|
|
75
|
+
const keys = [
|
|
76
|
+
...new Set(sampled.flatMap(({ finding }) => Object.keys(finding.evidence ?? {}))),
|
|
77
|
+
].sort();
|
|
78
|
+
|
|
79
|
+
for (const key of keys) {
|
|
80
|
+
const values = sampled.flatMap(({ finding }) => {
|
|
81
|
+
const value = finding.evidence?.[key];
|
|
82
|
+
return value === undefined ? [] : [value];
|
|
83
|
+
});
|
|
84
|
+
const unique = [
|
|
85
|
+
...new Map(values.map((value) => [`${typeof value}:${String(value)}`, value])).values(),
|
|
86
|
+
];
|
|
87
|
+
const first = unique[0];
|
|
88
|
+
if (first !== undefined) {
|
|
89
|
+
merged[key] = unique.length === 1 ? first : unique.map(String).join(" | ");
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
merged.sampleNumbers = [...new Set(sampled.map((item) => item.sample))]
|
|
94
|
+
.sort((a, b) => a - b)
|
|
95
|
+
.join(", ");
|
|
96
|
+
merged.occurrences = sampled.length;
|
|
97
|
+
merged.totalSamples = repeat;
|
|
98
|
+
return merged;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
function coalesceFindings(sampled: readonly SampleFinding[], repeat: number): readonly Finding[] {
|
|
102
|
+
const groups = new Map<string, SampleFinding[]>();
|
|
103
|
+
for (const item of sampled) {
|
|
104
|
+
const { finding } = item;
|
|
105
|
+
const key = JSON.stringify([
|
|
106
|
+
finding.code,
|
|
107
|
+
finding.severity,
|
|
108
|
+
finding.message,
|
|
109
|
+
finding.url,
|
|
110
|
+
finding.agent ?? "",
|
|
111
|
+
]);
|
|
112
|
+
const group = groups.get(key) ?? [];
|
|
113
|
+
group.push(item);
|
|
114
|
+
groups.set(key, group);
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
return [...groups.values()].map((group) => {
|
|
118
|
+
const first = group[0]?.finding;
|
|
119
|
+
if (first === undefined) throw new Error("Cannot coalesce an empty finding group.");
|
|
120
|
+
return { ...first, evidence: mergeEvidence(group, repeat) };
|
|
121
|
+
});
|
|
122
|
+
}
|
|
123
|
+
|
|
40
124
|
export async function runAudit(config: SsrWireConfig): Promise<AuditResult> {
|
|
41
125
|
const started = performance.now();
|
|
126
|
+
const repeat = repeatCount(config.repeat);
|
|
42
127
|
const tasks: ProbeTask[] = [];
|
|
43
128
|
|
|
44
129
|
for (const [targetIndex, target] of config.targets.entries()) {
|
|
@@ -60,21 +145,43 @@ export async function runAudit(config: SsrWireConfig): Promise<AuditResult> {
|
|
|
60
145
|
}
|
|
61
146
|
|
|
62
147
|
const secrets = Object.values(config.headers);
|
|
63
|
-
const
|
|
64
|
-
const
|
|
65
|
-
|
|
148
|
+
const lanes = await runPool<ProbeTask, ProbeLane>(tasks, DEFAULT_CONCURRENCY, async (task) => {
|
|
149
|
+
const probes: ProbeResult[] = [];
|
|
150
|
+
for (let sample = 1; sample <= repeat; sample += 1) {
|
|
151
|
+
const probe = await probeUrl(task.options);
|
|
152
|
+
probes.push(repeat === 1 ? probe : { ...probe, sample });
|
|
153
|
+
}
|
|
154
|
+
return { task, probes };
|
|
66
155
|
});
|
|
67
156
|
|
|
68
157
|
const results: TargetAuditResult[] = config.targets.map((target, targetIndex) => {
|
|
69
|
-
const targetProbes =
|
|
70
|
-
.filter((
|
|
158
|
+
const targetProbes = lanes
|
|
159
|
+
.filter((lane) => lane.task.targetIndex === targetIndex)
|
|
71
160
|
.sort((a, b) => a.task.agentIndex - b.task.agentIndex)
|
|
72
|
-
.
|
|
161
|
+
.flatMap((lane) => lane.probes);
|
|
162
|
+
|
|
163
|
+
if (repeat === 1) {
|
|
164
|
+
return {
|
|
165
|
+
target,
|
|
166
|
+
probes: targetProbes,
|
|
167
|
+
findings: analyzeTarget(target, targetProbes),
|
|
168
|
+
};
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
const sampledFindings: SampleFinding[] = [];
|
|
172
|
+
for (let sample = 1; sample <= repeat; sample += 1) {
|
|
173
|
+
const sampleProbes = targetProbes.filter((probe) => probe.sample === sample);
|
|
174
|
+
sampledFindings.push(
|
|
175
|
+
...analyzeTarget(target, sampleProbes).map((finding) => ({ sample, finding })),
|
|
176
|
+
);
|
|
177
|
+
}
|
|
178
|
+
const stability = analyzeStability(target, targetProbes);
|
|
73
179
|
|
|
74
180
|
return {
|
|
75
181
|
target,
|
|
76
182
|
probes: targetProbes,
|
|
77
|
-
findings:
|
|
183
|
+
findings: [...coalesceFindings(sampledFindings, repeat), ...stability.findings],
|
|
184
|
+
stability: stability.stability,
|
|
78
185
|
};
|
|
79
186
|
});
|
|
80
187
|
|
|
@@ -82,6 +189,7 @@ export async function runAudit(config: SsrWireConfig): Promise<AuditResult> {
|
|
|
82
189
|
version: VERSION,
|
|
83
190
|
generatedAt: new Date().toISOString(),
|
|
84
191
|
durationMs: Math.round(performance.now() - started),
|
|
192
|
+
...(repeat === 1 ? {} : { repeat }),
|
|
85
193
|
results,
|
|
86
194
|
summary: summarizeAudit(results),
|
|
87
195
|
};
|
package/src/cli.ts
CHANGED
|
@@ -14,6 +14,7 @@ interface CliOptions {
|
|
|
14
14
|
readonly timeout?: number;
|
|
15
15
|
readonly maxBytes?: number;
|
|
16
16
|
readonly maxRedirects?: number;
|
|
17
|
+
readonly repeat?: number;
|
|
17
18
|
readonly format: ReportFormat;
|
|
18
19
|
readonly output?: string;
|
|
19
20
|
readonly failOn: "error" | "warning" | "never";
|
|
@@ -40,6 +41,7 @@ agents:
|
|
|
40
41
|
timeoutMs: 15000
|
|
41
42
|
maxBytes: 10485760
|
|
42
43
|
maxRedirects: 10
|
|
44
|
+
repeat: 1
|
|
43
45
|
|
|
44
46
|
# Keep preview credentials in environment variables. SSRWire redacts configured values from reports.
|
|
45
47
|
# headers:
|
|
@@ -80,6 +82,7 @@ function addCheckOptions(command: Command): Command {
|
|
|
80
82
|
.option("--timeout <ms>", "request timeout in milliseconds", parseInteger)
|
|
81
83
|
.option("--max-bytes <bytes>", "maximum response bytes", parseInteger)
|
|
82
84
|
.option("--max-redirects <count>", "maximum redirects", parseInteger)
|
|
85
|
+
.option("--repeat <count>", "sequential samples per URL and agent", parseInteger)
|
|
83
86
|
.option("-f, --format <format>", "terminal, json, or sarif", parseFormat, "terminal")
|
|
84
87
|
.option("-o, --output <path>", "write the report to a file")
|
|
85
88
|
.option("--fail-on <level>", "error, warning, or never", parseFailOn, "error")
|
|
@@ -124,6 +127,7 @@ async function check(urls: readonly string[], options: CliOptions): Promise<void
|
|
|
124
127
|
...(options.timeout === undefined ? {} : { timeoutMs: options.timeout }),
|
|
125
128
|
...(options.maxBytes === undefined ? {} : { maxBytes: options.maxBytes }),
|
|
126
129
|
...(options.maxRedirects === undefined ? {} : { maxRedirects: options.maxRedirects }),
|
|
130
|
+
...(options.repeat === undefined ? {} : { repeat: options.repeat }),
|
|
127
131
|
});
|
|
128
132
|
const audit = await runAudit(config);
|
|
129
133
|
const color =
|
package/src/config.ts
CHANGED
|
@@ -8,6 +8,7 @@ import type { AgentProfile, AuditTarget, SsrWireConfig, TargetExpectations } fro
|
|
|
8
8
|
const DEFAULT_TIMEOUT_MS = 15_000;
|
|
9
9
|
const DEFAULT_MAX_BYTES = 10 * 1024 * 1024;
|
|
10
10
|
const DEFAULT_MAX_REDIRECTS = 10;
|
|
11
|
+
const DEFAULT_REPEAT = 1;
|
|
11
12
|
const DEFAULT_AGENTS = ["browser", "googlebot", "bingbot", "twitterbot"] as const;
|
|
12
13
|
const DEFAULT_CONFIG_FILES = [
|
|
13
14
|
"ssrwire.config.yml",
|
|
@@ -66,6 +67,7 @@ const fileConfigSchema = z
|
|
|
66
67
|
.max(50 * 1024 * 1024)
|
|
67
68
|
.optional(),
|
|
68
69
|
maxRedirects: z.number().int().min(0).max(20).optional(),
|
|
70
|
+
repeat: z.number().int().min(1).max(10).optional(),
|
|
69
71
|
})
|
|
70
72
|
.strict();
|
|
71
73
|
|
|
@@ -79,6 +81,7 @@ export interface LoadConfigOptions {
|
|
|
79
81
|
readonly timeoutMs?: number;
|
|
80
82
|
readonly maxBytes?: number;
|
|
81
83
|
readonly maxRedirects?: number;
|
|
84
|
+
readonly repeat?: number;
|
|
82
85
|
readonly cwd?: string;
|
|
83
86
|
}
|
|
84
87
|
|
|
@@ -291,6 +294,7 @@ export async function loadConfig(options: LoadConfigOptions = {}): Promise<SsrWi
|
|
|
291
294
|
const timeoutMs = options.timeoutMs ?? file.timeoutMs ?? DEFAULT_TIMEOUT_MS;
|
|
292
295
|
const maxBytes = options.maxBytes ?? file.maxBytes ?? DEFAULT_MAX_BYTES;
|
|
293
296
|
const maxRedirects = options.maxRedirects ?? file.maxRedirects ?? DEFAULT_MAX_REDIRECTS;
|
|
297
|
+
const repeat = options.repeat ?? file.repeat ?? DEFAULT_REPEAT;
|
|
294
298
|
|
|
295
299
|
if (!Number.isInteger(timeoutMs) || timeoutMs < 100 || timeoutMs > 120_000) {
|
|
296
300
|
throw new ConfigError("timeoutMs must be an integer between 100 and 120000.");
|
|
@@ -301,6 +305,9 @@ export async function loadConfig(options: LoadConfigOptions = {}): Promise<SsrWi
|
|
|
301
305
|
if (!Number.isInteger(maxRedirects) || maxRedirects < 0 || maxRedirects > 20) {
|
|
302
306
|
throw new ConfigError("maxRedirects must be an integer between 0 and 20.");
|
|
303
307
|
}
|
|
308
|
+
if (!Number.isInteger(repeat) || repeat < 1 || repeat > 10) {
|
|
309
|
+
throw new ConfigError("repeat must be an integer between 1 and 10.");
|
|
310
|
+
}
|
|
304
311
|
|
|
305
312
|
return {
|
|
306
313
|
targets,
|
|
@@ -309,5 +316,6 @@ export async function loadConfig(options: LoadConfigOptions = {}): Promise<SsrWi
|
|
|
309
316
|
timeoutMs,
|
|
310
317
|
maxBytes,
|
|
311
318
|
maxRedirects,
|
|
319
|
+
repeat,
|
|
312
320
|
};
|
|
313
321
|
}
|
package/src/index.ts
CHANGED
|
@@ -8,6 +8,7 @@ export { renderJson, renderReport, renderSarif, renderTerminal } from "./reporte
|
|
|
8
8
|
export { createStreamInspector } from "./stream-parser.js";
|
|
9
9
|
export type {
|
|
10
10
|
AgentProfile,
|
|
11
|
+
AgentStability,
|
|
11
12
|
AuditResult,
|
|
12
13
|
AuditSummary,
|
|
13
14
|
AuditTarget,
|
|
@@ -27,8 +28,11 @@ export type {
|
|
|
27
28
|
RobotsSignal,
|
|
28
29
|
Severity,
|
|
29
30
|
SsrWireConfig,
|
|
31
|
+
StabilityTimings,
|
|
32
|
+
StabilityVariants,
|
|
30
33
|
TargetAuditResult,
|
|
31
34
|
TargetExpectations,
|
|
32
35
|
TimingMark,
|
|
36
|
+
TimingStats,
|
|
33
37
|
} from "./types.js";
|
|
34
38
|
export { VERSION } from "./version.js";
|
package/src/redact.ts
CHANGED
|
@@ -160,6 +160,18 @@ export function redactAudit(audit: AuditResult, secrets: readonly string[]): Aud
|
|
|
160
160
|
},
|
|
161
161
|
},
|
|
162
162
|
probes: result.probes.map((probe) => redactProbeWithPlan(probe, plan)),
|
|
163
|
+
...(result.stability === undefined
|
|
164
|
+
? {}
|
|
165
|
+
: {
|
|
166
|
+
stability: result.stability.map((summary) => ({
|
|
167
|
+
...summary,
|
|
168
|
+
agent: {
|
|
169
|
+
...summary.agent,
|
|
170
|
+
label: redactText(summary.agent.label, plan),
|
|
171
|
+
userAgent: redactText(summary.agent.userAgent, plan),
|
|
172
|
+
},
|
|
173
|
+
})),
|
|
174
|
+
}),
|
|
163
175
|
findings: result.findings.map((finding) => ({
|
|
164
176
|
...finding,
|
|
165
177
|
message: redactText(finding.message, plan),
|
package/src/reporters.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type {
|
|
2
|
+
AgentStability,
|
|
2
3
|
AuditResult,
|
|
3
4
|
ElementSignal,
|
|
4
5
|
Finding,
|
|
@@ -70,8 +71,9 @@ function firstSignal(signals: readonly ElementSignal[]): ElementSignal | undefin
|
|
|
70
71
|
return signals.find((signal) => signal.value.trim().length > 0) ?? signals[0];
|
|
71
72
|
}
|
|
72
73
|
|
|
73
|
-
function probeRow(probe: ProbeResult): readonly string[] {
|
|
74
|
+
function probeRow(probe: ProbeResult, showSample: boolean): readonly string[] {
|
|
74
75
|
return [
|
|
76
|
+
...(showSample ? [String(probe.sample ?? "—")] : []),
|
|
75
77
|
truncate(probe.agent.label, 24),
|
|
76
78
|
probe.status === undefined ? "—" : String(probe.status),
|
|
77
79
|
probe.completion,
|
|
@@ -84,6 +86,34 @@ function probeRow(probe: ProbeResult): readonly string[] {
|
|
|
84
86
|
];
|
|
85
87
|
}
|
|
86
88
|
|
|
89
|
+
function stabilityRows(stability: readonly AgentStability[]): readonly (readonly string[])[] {
|
|
90
|
+
const labels: Readonly<Record<keyof AgentStability["timings"], string>> = {
|
|
91
|
+
headers: "Headers",
|
|
92
|
+
firstByte: "First byte",
|
|
93
|
+
criticalSignals: "Critical signals",
|
|
94
|
+
complete: "Complete",
|
|
95
|
+
};
|
|
96
|
+
const rows: string[][] = [];
|
|
97
|
+
for (const summary of stability) {
|
|
98
|
+
for (const key of ["headers", "firstByte", "criticalSignals", "complete"] as const) {
|
|
99
|
+
const stats = summary.timings[key];
|
|
100
|
+
if (stats === undefined) continue;
|
|
101
|
+
rows.push([
|
|
102
|
+
truncate(summary.agent.label, 24),
|
|
103
|
+
`${summary.complete}/${summary.samples}`,
|
|
104
|
+
labels[key],
|
|
105
|
+
String(stats.samples),
|
|
106
|
+
formatMs(stats.minMs),
|
|
107
|
+
formatMs(stats.medianMs),
|
|
108
|
+
formatMs(stats.p95Ms),
|
|
109
|
+
formatMs(stats.maxMs),
|
|
110
|
+
formatMs(stats.spreadMs),
|
|
111
|
+
]);
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
return rows;
|
|
115
|
+
}
|
|
116
|
+
|
|
87
117
|
function renderTable(headers: readonly string[], rows: readonly (readonly string[])[]): string {
|
|
88
118
|
const widths = headers.map((header, column) =>
|
|
89
119
|
Math.max(header.length, ...rows.map((row) => row[column]?.length ?? 0)),
|
|
@@ -116,12 +146,17 @@ export function renderTerminal(audit: AuditResult, options: ReporterOptions = {}
|
|
|
116
146
|
paint(`SSRWire ${audit.version}`, ANSI.bold, color),
|
|
117
147
|
paint(`Generated ${audit.generatedAt} in ${formatMs(audit.durationMs)}`, ANSI.dim, color),
|
|
118
148
|
];
|
|
149
|
+
if ((audit.repeat ?? 1) > 1) {
|
|
150
|
+
lines.push(paint(`${audit.repeat} sequential samples per URL and agent`, ANSI.dim, color));
|
|
151
|
+
}
|
|
119
152
|
|
|
120
153
|
for (const result of audit.results) {
|
|
154
|
+
const showSample = (audit.repeat ?? 1) > 1;
|
|
121
155
|
lines.push("", paint(terminalSafe(result.target.url), ANSI.bold, color));
|
|
122
156
|
lines.push(
|
|
123
157
|
renderTable(
|
|
124
158
|
[
|
|
159
|
+
...(showSample ? ["Sample"] : []),
|
|
125
160
|
"Agent",
|
|
126
161
|
"HTTP",
|
|
127
162
|
"Result",
|
|
@@ -132,10 +167,24 @@ export function renderTerminal(audit: AuditResult, options: ReporterOptions = {}
|
|
|
132
167
|
"Canonical",
|
|
133
168
|
"Main",
|
|
134
169
|
],
|
|
135
|
-
result.probes.map(probeRow),
|
|
170
|
+
result.probes.map((probe) => probeRow(probe, showSample)),
|
|
136
171
|
),
|
|
137
172
|
);
|
|
138
173
|
|
|
174
|
+
if (result.stability !== undefined) {
|
|
175
|
+
const rows = stabilityRows(result.stability);
|
|
176
|
+
if (rows.length > 0) {
|
|
177
|
+
lines.push(
|
|
178
|
+
"",
|
|
179
|
+
"Stability timings (nearest-rank p95)",
|
|
180
|
+
renderTable(
|
|
181
|
+
["Agent", "Complete", "Metric", "N", "Min", "Median", "P95", "Max", "Spread"],
|
|
182
|
+
rows,
|
|
183
|
+
),
|
|
184
|
+
);
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
|
|
139
188
|
if (result.findings.length === 0) {
|
|
140
189
|
lines.push("Findings: none");
|
|
141
190
|
} else {
|