@superblocksteam/shared 0.9609.5 → 2.0.0-SNAPSHOT.7ea2658f98892d2c
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/dist/constants.d.ts +1 -0
- package/dist/constants.d.ts.map +1 -1
- package/dist/constants.js +2 -1
- package/dist/constants.js.map +1 -1
- package/dist/database-lifecycle/destructiveMigrations.d.ts +1 -0
- package/dist/database-lifecycle/destructiveMigrations.d.ts.map +1 -1
- package/dist/database-lifecycle/destructiveMigrations.js +21 -1
- package/dist/database-lifecycle/destructiveMigrations.js.map +1 -1
- package/dist/database-lifecycle/destructiveMigrations.test.js +22 -0
- package/dist/database-lifecycle/destructiveMigrations.test.js.map +1 -1
- package/dist/socket/heartbeat.d.ts +10 -0
- package/dist/socket/heartbeat.d.ts.map +1 -1
- package/dist/socket/heartbeat.js +5 -0
- package/dist/socket/heartbeat.js.map +1 -1
- package/dist/socket/heartbeat.test.js +36 -0
- package/dist/socket/heartbeat.test.js.map +1 -1
- package/dist/socket/protocol.d.ts +2 -2
- package/dist/socket/protocol.d.ts.map +1 -1
- package/dist/socket/protocol.js.map +1 -1
- package/dist/socket/socket.d.ts +13 -0
- package/dist/socket/socket.d.ts.map +1 -1
- package/dist/socket/socket.js +21 -2
- package/dist/socket/socket.js.map +1 -1
- package/dist/socket/socket.test.js +33 -0
- package/dist/socket/socket.test.js.map +1 -1
- package/dist/types/codeSecurity/index.d.ts +6 -0
- package/dist/types/codeSecurity/index.d.ts.map +1 -1
- package/dist/types/codeSecurity/index.js +23 -0
- package/dist/types/codeSecurity/index.js.map +1 -1
- package/dist/types/codeSecurity/index.test.js +48 -0
- package/dist/types/codeSecurity/index.test.js.map +1 -1
- package/dist/types/policyGate/errors.d.ts +70 -0
- package/dist/types/policyGate/errors.d.ts.map +1 -0
- package/dist/types/policyGate/errors.js +42 -0
- package/dist/types/policyGate/errors.js.map +1 -0
- package/dist/types/policyGate/index.d.ts +3 -0
- package/dist/types/policyGate/index.d.ts.map +1 -1
- package/dist/types/policyGate/index.js +22 -0
- package/dist/types/policyGate/index.js.map +1 -1
- package/dist/types/publishPipeline/displayNames.js +6 -6
- package/dist/types/publishPipeline/displayNames.js.map +1 -1
- package/dist/types/publishPipeline/displayNames.test.js +5 -5
- package/dist/types/publishPipeline/displayNames.test.js.map +1 -1
- package/dist/types/publishPipeline/index.d.ts +3 -3
- package/dist/types/publishPipeline/index.d.ts.map +1 -1
- package/dist/types/publishPipeline/plan.d.ts +1 -11
- package/dist/types/publishPipeline/plan.d.ts.map +1 -1
- package/dist/types/publishPipeline/plan.js +2 -57
- package/dist/types/publishPipeline/plan.js.map +1 -1
- package/dist/types/publishPipeline/plan.test.js +9 -95
- package/dist/types/publishPipeline/plan.test.js.map +1 -1
- package/dist/types/response/PostApplicationCloneResponseBody.d.ts +12 -0
- package/dist/types/response/PostApplicationCloneResponseBody.d.ts.map +1 -0
- package/dist/types/response/PostApplicationCloneResponseBody.js +3 -0
- package/dist/types/response/PostApplicationCloneResponseBody.js.map +1 -0
- package/dist/types/response/index.d.ts +1 -0
- package/dist/types/response/index.d.ts.map +1 -1
- package/dist/types/response/index.js +1 -0
- package/dist/types/response/index.js.map +1 -1
- package/dist/types/reviewPolicy/index.d.ts +5 -0
- package/dist/types/reviewPolicy/index.d.ts.map +1 -1
- package/dist/types/reviewPolicy/index.js.map +1 -1
- package/dist/utils/attachment-upload.d.ts +40 -0
- package/dist/utils/attachment-upload.d.ts.map +1 -1
- package/dist/utils/attachment-upload.js +90 -1
- package/dist/utils/attachment-upload.js.map +1 -1
- package/dist/utils/attachment-upload.test.js +61 -0
- package/dist/utils/attachment-upload.test.js.map +1 -1
- package/dist/utils/git-url.d.ts.map +1 -1
- package/dist/utils/git-url.js +29 -6
- package/dist/utils/git-url.js.map +1 -1
- package/dist/utils/git-url.test.js +60 -0
- package/dist/utils/git-url.test.js.map +1 -1
- package/dist/utils/normalizeRoleName.js +2 -2
- package/dist/utils/normalizeRoleName.js.map +1 -1
- package/dist/utils/normalizeRoleName.test.d.ts +2 -0
- package/dist/utils/normalizeRoleName.test.d.ts.map +1 -0
- package/dist/utils/normalizeRoleName.test.js +25 -0
- package/dist/utils/normalizeRoleName.test.js.map +1 -0
- package/dist-esm/constants.d.ts +1 -0
- package/dist-esm/constants.d.ts.map +1 -1
- package/dist-esm/constants.js +1 -0
- package/dist-esm/constants.js.map +1 -1
- package/dist-esm/database-lifecycle/destructiveMigrations.d.ts +1 -0
- package/dist-esm/database-lifecycle/destructiveMigrations.d.ts.map +1 -1
- package/dist-esm/database-lifecycle/destructiveMigrations.js +21 -2
- package/dist-esm/database-lifecycle/destructiveMigrations.js.map +1 -1
- package/dist-esm/database-lifecycle/destructiveMigrations.test.js +23 -1
- package/dist-esm/database-lifecycle/destructiveMigrations.test.js.map +1 -1
- package/dist-esm/socket/heartbeat.d.ts +10 -0
- package/dist-esm/socket/heartbeat.d.ts.map +1 -1
- package/dist-esm/socket/heartbeat.js +5 -0
- package/dist-esm/socket/heartbeat.js.map +1 -1
- package/dist-esm/socket/heartbeat.test.js +36 -0
- package/dist-esm/socket/heartbeat.test.js.map +1 -1
- package/dist-esm/socket/protocol.d.ts +2 -2
- package/dist-esm/socket/protocol.d.ts.map +1 -1
- package/dist-esm/socket/protocol.js.map +1 -1
- package/dist-esm/socket/socket.d.ts +13 -0
- package/dist-esm/socket/socket.d.ts.map +1 -1
- package/dist-esm/socket/socket.js +20 -1
- package/dist-esm/socket/socket.js.map +1 -1
- package/dist-esm/socket/socket.test.js +33 -0
- package/dist-esm/socket/socket.test.js.map +1 -1
- package/dist-esm/types/codeSecurity/index.d.ts +6 -0
- package/dist-esm/types/codeSecurity/index.d.ts.map +1 -1
- package/dist-esm/types/codeSecurity/index.js +22 -0
- package/dist-esm/types/codeSecurity/index.js.map +1 -1
- package/dist-esm/types/codeSecurity/index.test.js +49 -1
- package/dist-esm/types/codeSecurity/index.test.js.map +1 -1
- package/dist-esm/types/policyGate/errors.d.ts +70 -0
- package/dist-esm/types/policyGate/errors.d.ts.map +1 -0
- package/dist-esm/types/policyGate/errors.js +37 -0
- package/dist-esm/types/policyGate/errors.js.map +1 -0
- package/dist-esm/types/policyGate/index.d.ts +3 -0
- package/dist-esm/types/policyGate/index.d.ts.map +1 -1
- package/dist-esm/types/policyGate/index.js +7 -0
- package/dist-esm/types/policyGate/index.js.map +1 -1
- package/dist-esm/types/publishPipeline/displayNames.js +6 -6
- package/dist-esm/types/publishPipeline/displayNames.js.map +1 -1
- package/dist-esm/types/publishPipeline/displayNames.test.js +5 -5
- package/dist-esm/types/publishPipeline/displayNames.test.js.map +1 -1
- package/dist-esm/types/publishPipeline/index.d.ts +3 -3
- package/dist-esm/types/publishPipeline/index.d.ts.map +1 -1
- package/dist-esm/types/publishPipeline/plan.d.ts +1 -11
- package/dist-esm/types/publishPipeline/plan.d.ts.map +1 -1
- package/dist-esm/types/publishPipeline/plan.js +2 -56
- package/dist-esm/types/publishPipeline/plan.js.map +1 -1
- package/dist-esm/types/publishPipeline/plan.test.js +10 -96
- package/dist-esm/types/publishPipeline/plan.test.js.map +1 -1
- package/dist-esm/types/response/PostApplicationCloneResponseBody.d.ts +12 -0
- package/dist-esm/types/response/PostApplicationCloneResponseBody.d.ts.map +1 -0
- package/dist-esm/types/response/PostApplicationCloneResponseBody.js +2 -0
- package/dist-esm/types/response/PostApplicationCloneResponseBody.js.map +1 -0
- package/dist-esm/types/response/index.d.ts +1 -0
- package/dist-esm/types/response/index.d.ts.map +1 -1
- package/dist-esm/types/response/index.js +1 -0
- package/dist-esm/types/response/index.js.map +1 -1
- package/dist-esm/types/reviewPolicy/index.d.ts +5 -0
- package/dist-esm/types/reviewPolicy/index.d.ts.map +1 -1
- package/dist-esm/types/reviewPolicy/index.js.map +1 -1
- package/dist-esm/utils/attachment-upload.d.ts +40 -0
- package/dist-esm/utils/attachment-upload.d.ts.map +1 -1
- package/dist-esm/utils/attachment-upload.js +85 -0
- package/dist-esm/utils/attachment-upload.js.map +1 -1
- package/dist-esm/utils/attachment-upload.test.js +62 -1
- package/dist-esm/utils/attachment-upload.test.js.map +1 -1
- package/dist-esm/utils/git-url.d.ts.map +1 -1
- package/dist-esm/utils/git-url.js +29 -6
- package/dist-esm/utils/git-url.js.map +1 -1
- package/dist-esm/utils/git-url.test.js +60 -0
- package/dist-esm/utils/git-url.test.js.map +1 -1
- package/dist-esm/utils/normalizeRoleName.js +2 -2
- package/dist-esm/utils/normalizeRoleName.js.map +1 -1
- package/dist-esm/utils/normalizeRoleName.test.d.ts +2 -0
- package/dist-esm/utils/normalizeRoleName.test.d.ts.map +1 -0
- package/dist-esm/utils/normalizeRoleName.test.js +23 -0
- package/dist-esm/utils/normalizeRoleName.test.js.map +1 -0
- package/package.json +1 -1
- package/src/constants.ts +1 -0
- package/src/database-lifecycle/destructiveMigrations.test.ts +27 -1
- package/src/database-lifecycle/destructiveMigrations.ts +22 -2
- package/src/socket/heartbeat.test.ts +44 -0
- package/src/socket/heartbeat.ts +15 -0
- package/src/socket/protocol.ts +2 -1
- package/src/socket/socket.test.ts +43 -0
- package/src/socket/socket.ts +22 -1
- package/src/types/codeSecurity/index.test.ts +58 -1
- package/src/types/codeSecurity/index.ts +38 -0
- package/src/types/policyGate/errors.ts +51 -0
- package/src/types/policyGate/index.ts +12 -0
- package/src/types/publishPipeline/displayNames.test.ts +5 -5
- package/src/types/publishPipeline/displayNames.ts +6 -6
- package/src/types/publishPipeline/index.ts +3 -3
- package/src/types/publishPipeline/plan.test.ts +12 -105
- package/src/types/publishPipeline/plan.ts +3 -62
- package/src/types/response/PostApplicationCloneResponseBody.ts +12 -0
- package/src/types/response/index.ts +1 -0
- package/src/types/reviewPolicy/index.ts +5 -0
- package/src/utils/attachment-upload.test.ts +70 -1
- package/src/utils/attachment-upload.ts +106 -0
- package/src/utils/git-url.test.ts +65 -0
- package/src/utils/git-url.ts +29 -6
- package/src/utils/normalizeRoleName.test.ts +27 -0
- package/src/utils/normalizeRoleName.ts +2 -2
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"attachment-upload.test.js","sourceRoot":"","sources":["../../src/utils/attachment-upload.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC;AAEhD,OAAO,EACL,6BAA6B,EAC7B,6BAA6B,EAC7B,kCAAkC,EAClC,qBAAqB,EACrB,WAAW,EACX,2BAA2B,EAC3B,4BAA4B,EAC7B,MAAM,wBAAwB,CAAC;AAEhC,QAAQ,CAAC,8BAA8B,EAAE,GAAG,EAAE;IAC5C,IAAI,CAAC,+CAA+C,EAAE,GAAG,EAAE;QACzD,MAAM,UAAU,GAAG,4BAA4B,CAAC;YAC9C,IAAI,EAAE,6BAA6B;YACnC,QAAQ,EAAE,YAAY;YACtB,IAAI,EAAE,cAAc;SACrB,CAAC,CAAC;QAEH,MAAM,CAAC,UAAU,CAAC,CAAC,aAAa,CAAC;YAC/B,QAAQ,EAAE,cAAc;YACxB,QAAQ,EAAE,YAAY;SACvB,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,IAAI,CAAC,mEAAmE,EAAE,GAAG,EAAE;QAC7E,MAAM,UAAU,GAAG,4BAA4B,CAAC;YAC9C,IAAI,EAAE,kCAAkC;YACxC,QAAQ,EAAE,iBAAiB;SAC5B,CAAC,CAAC;QAEH,MAAM,CAAC,UAAU,CAAC,CAAC,aAAa,CAAC;YAC/B,QAAQ,EAAE,gBAAgB;YAC1B,QAAQ,EAAE,iBAAiB;SAC5B,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,IAAI,CAAC,4EAA4E,EAAE,GAAG,EAAE;QACtF,MAAM,UAAU,GAAG,4BAA4B,CAAC,IAAI,IAAI,CAAC,CAAC,oBAAoB,CAAC,EAAE,SAAS,EAAE,EAAE,IAAI,EAAE,YAAY,EAAE,CAAC,CAAC,CAAC;QAErH,MAAM,CAAC,UAAU,CAAC,CAAC,aAAa,CAAC;YAC/B,QAAQ,EAAE,SAAS;YACnB,QAAQ,EAAE,YAAY;SACvB,CAAC,CAAC;QACH,MAAM,CAAC,UAAU,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;IACnD,CAAC,CAAC,CAAC;IAEH,IAAI,CAAC,sDAAsD,EAAE,GAAG,EAAE;QAChE,MAAM,UAAU,GAAG,4BAA4B,CAAC,IAAI,IAAI,CAAC,CAAC,aAAa,CAAC,EAAE,WAAW,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC;QAEtG,MAAM,CAAC,UAAU,CAAC,CAAC,aAAa,CAAC;YAC/B,QAAQ,EAAE,WAAW;YACrB,QAAQ,EAAE,YAAY;SACvB,CAAC,CAAC;QACH,MAAM,CAAC,UAAU,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;IACnD,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,+BAA+B,EAAE,GAAG,EAAE;IAC7C,IAAI,CAAC,8CAA8C,EAAE,GAAG,EAAE;QACxD,MAAM,UAAU,GAAG,4BAA4B,CAAC;YAC9C,IAAI,EAAE,6BAA6B;YACnC,QAAQ,EAAE,YAAY;YACtB,IAAI,EAAE,cAAc;SACrB,CAAC,CAAC;QAEH,MAAM,CAAC,UAAU,CAAC,CAAC,GAAG,CAAC,QAAQ,EAAE,CAAC;QAElC,MAAM,QAAQ,GAAG,6BAA6B,CAAC;YAC7C,UAAU,EAAE,UAAW;YACvB,MAAM,EAAE,qBAAqB;SAC9B,CAAC,CAAC;QAEH,MAAM,YAAY,GAAG,QAAQ,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;QAC1C,MAAM,CAAC,YAAY,CAAC,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC;QAC1C,MAAM,
|
|
1
|
+
{"version":3,"file":"attachment-upload.test.js","sourceRoot":"","sources":["../../src/utils/attachment-upload.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC;AAEhD,OAAO,EACL,gCAAgC,EAChC,6BAA6B,EAC7B,6BAA6B,EAC7B,kCAAkC,EAClC,iCAAiC,EACjC,qBAAqB,EACrB,0BAA0B,EAC1B,WAAW,EACX,2BAA2B,EAC3B,4BAA4B,EAC7B,MAAM,wBAAwB,CAAC;AAEhC,QAAQ,CAAC,mCAAmC,EAAE,GAAG,EAAE;IACjD,IAAI,CAAC,IAAI,CAAC;QACR,CAAC,UAAU,EAAE,WAAW,CAAC;QACzB,CAAC,UAAU,EAAE,WAAW,CAAC;QACzB,CAAC,WAAW,EAAE,YAAY,CAAC;QAC3B,CAAC,YAAY,EAAE,YAAY,CAAC;QAC5B,CAAC,eAAe,EAAE,WAAW,CAAC;QAC9B,CAAC,WAAW,EAAE,YAAY,CAAC;QAC3B,CAAC,YAAY,EAAE,iBAAiB,CAAC;QACjC,CAAC,YAAY,EAAE,YAAY,CAAC;QAC5B,CAAC,UAAU,EAAE,UAAU,CAAC;QACxB,CAAC,aAAa,EAAE,kBAAkB,CAAC;KACpC,CAAC,CAAC,gBAAgB,EAAE,CAAC,QAAQ,EAAE,QAAQ,EAAE,EAAE;QAC1C,MAAM,CAAC,iCAAiC,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IACrE,CAAC,CAAC,CAAC;IAEH,IAAI,CAAC,IAAI,CAAC,CAAC,SAAS,EAAE,aAAa,EAAE,aAAa,EAAE,EAAE,CAAC,CAAC,CAAC,oBAAoB,EAAE,CAAC,QAAQ,EAAE,EAAE;QAC1F,MAAM,CAAC,iCAAiC,CAAC,QAAQ,CAAC,CAAC,CAAC,aAAa,EAAE,CAAC;IACtE,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,8BAA8B,EAAE,GAAG,EAAE;IAC5C,IAAI,CAAC,+CAA+C,EAAE,GAAG,EAAE;QACzD,MAAM,UAAU,GAAG,4BAA4B,CAAC;YAC9C,IAAI,EAAE,6BAA6B;YACnC,QAAQ,EAAE,YAAY;YACtB,IAAI,EAAE,cAAc;SACrB,CAAC,CAAC;QAEH,MAAM,CAAC,UAAU,CAAC,CAAC,aAAa,CAAC;YAC/B,QAAQ,EAAE,cAAc;YACxB,QAAQ,EAAE,YAAY;SACvB,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,IAAI,CAAC,mEAAmE,EAAE,GAAG,EAAE;QAC7E,MAAM,UAAU,GAAG,4BAA4B,CAAC;YAC9C,IAAI,EAAE,kCAAkC;YACxC,QAAQ,EAAE,iBAAiB;SAC5B,CAAC,CAAC;QAEH,MAAM,CAAC,UAAU,CAAC,CAAC,aAAa,CAAC;YAC/B,QAAQ,EAAE,gBAAgB;YAC1B,QAAQ,EAAE,iBAAiB;SAC5B,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,IAAI,CAAC,4EAA4E,EAAE,GAAG,EAAE;QACtF,MAAM,UAAU,GAAG,4BAA4B,CAAC,IAAI,IAAI,CAAC,CAAC,oBAAoB,CAAC,EAAE,SAAS,EAAE,EAAE,IAAI,EAAE,YAAY,EAAE,CAAC,CAAC,CAAC;QAErH,MAAM,CAAC,UAAU,CAAC,CAAC,aAAa,CAAC;YAC/B,QAAQ,EAAE,SAAS;YACnB,QAAQ,EAAE,YAAY;SACvB,CAAC,CAAC;QACH,MAAM,CAAC,UAAU,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;IACnD,CAAC,CAAC,CAAC;IAEH,IAAI,CAAC,sDAAsD,EAAE,GAAG,EAAE;QAChE,MAAM,UAAU,GAAG,4BAA4B,CAAC,IAAI,IAAI,CAAC,CAAC,aAAa,CAAC,EAAE,WAAW,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC;QAEtG,MAAM,CAAC,UAAU,CAAC,CAAC,aAAa,CAAC;YAC/B,QAAQ,EAAE,WAAW;YACrB,QAAQ,EAAE,YAAY;SACvB,CAAC,CAAC;QACH,MAAM,CAAC,UAAU,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;IACnD,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,+BAA+B,EAAE,GAAG,EAAE;IAC7C,IAAI,CAAC,8CAA8C,EAAE,GAAG,EAAE;QACxD,MAAM,UAAU,GAAG,4BAA4B,CAAC;YAC9C,IAAI,EAAE,6BAA6B;YACnC,QAAQ,EAAE,YAAY;YACtB,IAAI,EAAE,cAAc;SACrB,CAAC,CAAC;QAEH,MAAM,CAAC,UAAU,CAAC,CAAC,GAAG,CAAC,QAAQ,EAAE,CAAC;QAElC,MAAM,QAAQ,GAAG,6BAA6B,CAAC;YAC7C,UAAU,EAAE,UAAW;YACvB,MAAM,EAAE,qBAAqB;SAC9B,CAAC,CAAC;QAEH,MAAM,YAAY,GAAG,QAAQ,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;QAC1C,MAAM,CAAC,YAAY,CAAC,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC;QAC1C,IAAI,CAAC,CAAC,YAAY,YAAY,IAAI,CAAC,EAAE,CAAC;YACpC,MAAM,IAAI,KAAK,CAAC,eAAe,CAAC,CAAC;QACnC,CAAC;QACD,MAAM,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;QAC/C,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,qBAAqB,CAAC,CAAC;IAC7D,CAAC,CAAC,CAAC;IAEH,IAAI,CAAC,2CAA2C,EAAE,GAAG,EAAE;QACrD,MAAM,UAAU,GAAG,4BAA4B,CAAC;YAC9C,IAAI,EAAE,6BAA6B;YACnC,QAAQ,EAAE,YAAY;YACtB,IAAI,EAAE,WAAW;SAClB,CAAC,CAAC;QAEH,MAAM,CAAC,UAAU,CAAC,CAAC,GAAG,CAAC,QAAQ,EAAE,CAAC;QAElC,MAAM,QAAQ,GAAG,6BAA6B,CAAC;YAC7C,UAAU,EAAE,UAAW;YACvB,MAAM,EAAE,oBAAoB;YAC5B,QAAQ,EAAE,6BAA6B,CAAC;gBACtC,KAAK,EAAE,kBAAkB;gBACzB,OAAO,EAAE,+BAA+B;aACzC,CAAC;SACH,CAAC,CAAC;QAEH,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC,IAAI,CACnC,IAAI,CAAC,SAAS,CAAC;YACb,KAAK,EAAE,kBAAkB;YACzB,OAAO,EAAE,+BAA+B;SACzC,CAAC,CACH,CAAC;IACJ,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,oCAAoC,EAAE,GAAG,EAAE;IAClD,IAAI,CAAC,gEAAgE,EAAE,GAAG,EAAE;QAC1E,MAAM,kBAAkB,GAAG,kCAAkC,CAAC;YAC5D,QAAQ,EAAE;gBACR,YAAY,EAAE,KAAK;gBACnB,QAAQ,EAAE,EAAE;gBACZ,UAAU,EAAE,2BAA2B;gBACvC,QAAQ,EAAE,IAAI;gBACd,OAAO,EAAE,YAAY;gBACrB,SAAS,EAAE,KAAK;gBAChB,SAAS,EAAE,4BAA4B;gBACvC,kBAAkB,EAAE,0BAA0B;gBAC9C,UAAU,EAAE,wBAAwB;aACrC;YACD,gBAAgB,EAAE,UAAU;YAC5B,gBAAgB,EAAE,iBAAiB;YACnC,KAAK,EAAE,MAAM;YACb,OAAO,EAAE,eAAe;SACzB,CAAC,CAAC;QAEH,MAAM,CAAC,kBAAkB,CAAC,CAAC,OAAO,CAAC;YACjC,IAAI,EAAE,UAAU;YAChB,GAAG,EAAE,2BAA2B;YAChC,SAAS,EAAE,4BAA4B;YACvC,SAAS,EAAE,iBAAiB;YAC5B,QAAQ,EAAE,UAAU;YACpB,KAAK,EAAE,MAAM;YACb,OAAO,EAAE,eAAe;YACxB,UAAU,EAAE,wBAAwB;YACpC,kBAAkB,EAAE,0BAA0B;YAC9C,SAAS,EAAE,KAAK;YAChB,aAAa,EAAE,SAAS;SACzB,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,+BAA+B,EAAE,GAAG,EAAE;IAC7C,IAAI,CAAC,+CAA+C,EAAE,GAAG,EAAE;QACzD,MAAM,CACJ,6BAA6B,CAAC;YAC5B,KAAK,EAAE,kBAAkB;YACzB,OAAO,EAAE,+BAA+B;SACzC,CAAC,CACH,CAAC,OAAO,CAAC;YACR,KAAK,EAAE,kBAAkB;YACzB,OAAO,EAAE,+BAA+B;SACzC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,6BAA6B,EAAE,GAAG,EAAE;IAC3C,IAAI,CAAC,sDAAsD,EAAE,GAAG,EAAE;QAChE,MAAM,CACJ,2BAA2B,CAAC;YAC1B,QAAQ,EAAE,eAAe;YACzB,QAAQ,EAAE,YAAY;SACvB,CAAC,CACH,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;IACvB,CAAC,CAAC,CAAC;IAEH,IAAI,CAAC,gEAAgE,EAAE,GAAG,EAAE;QAC1E,MAAM,CACJ,2BAA2B,CAAC;YAC1B,QAAQ,EAAE,WAAW;YACrB,QAAQ,EAAE,kBAAkB;SAC7B,CAAC,CACH,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;IACvB,CAAC,CAAC,CAAC;IAEH,IAAI,CAAC,8CAA8C,EAAE,GAAG,EAAE;QACxD,MAAM,CAAC,2BAA2B,CAAC,EAAE,QAAQ,EAAE,kBAAkB,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;IAC3F,CAAC,CAAC,CAAC;IAEH,IAAI,CAAC,yDAAyD,EAAE,GAAG,EAAE;QACnE,MAAM,CAAC,2BAA2B,CAAC,EAAE,QAAQ,EAAE,wBAAwB,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;IACjG,CAAC,CAAC,CAAC;IAEH,IAAI,CAAC,+CAA+C,EAAE,GAAG,EAAE;QACzD,MAAM,CAAC,2BAA2B,CAAC,EAAE,QAAQ,EAAE,WAAW,EAAE,QAAQ,EAAE,+BAA+B,EAAE,CAAC,CAAC,CAAC,IAAI,CAC5G,+BAA+B,CAChC,CAAC;IACJ,CAAC,CAAC,CAAC;IAEH,IAAI,CAAC,6CAA6C,EAAE,GAAG,EAAE;QACvD,MAAM,CAAC,2BAA2B,CAAC,EAAE,QAAQ,EAAE,UAAU,EAAE,QAAQ,EAAE,eAAe,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC;IACjH,CAAC,CAAC,CAAC;IAEH,IAAI,CAAC,uDAAuD,EAAE,GAAG,EAAE;QACjE,MAAM,CAAC,2BAA2B,CAAC,EAAE,QAAQ,EAAE,eAAe,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC;IAC3F,CAAC,CAAC,CAAC;IAEH,IAAI,CAAC,wDAAwD,EAAE,GAAG,EAAE;QAClE,MAAM,YAAY,GAAG,yEAAyE,CAAC;QAC/F,MAAM,CAAC,2BAA2B,CAAC,EAAE,QAAQ,EAAE,aAAa,EAAE,QAAQ,EAAE,YAAY,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;QAC5G,MAAM,CAAC,2BAA2B,CAAC,EAAE,QAAQ,EAAE,YAAY,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;IACrF,CAAC,CAAC,CAAC;IAEH,IAAI,CAAC,2DAA2D,EAAE,GAAG,EAAE;QACrE,MAAM,YAAY,GAAG,mEAAmE,CAAC;QACzF,MAAM,CAAC,2BAA2B,CAAC,EAAE,QAAQ,EAAE,YAAY,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;IACrF,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,uBAAuB,EAAE,GAAG,EAAE;IACrC,IAAI,CAAC,mEAAmE,EAAE,GAAG,EAAE;QAC7E,MAAM,CACJ,qBAAqB,CAAC;YACpB,QAAQ,EAAE,eAAe;YACzB,QAAQ,EAAE,YAAY;SACvB,CAAC,CACH,CAAC,QAAQ,EAAE,CAAC;IACf,CAAC,CAAC,CAAC;IAEH,IAAI,CAAC,mCAAmC,EAAE,GAAG,EAAE;QAC7C,MAAM,CACJ,qBAAqB,CAAC;YACpB,QAAQ,EAAE,WAAW;YACrB,QAAQ,EAAE,eAAe;SAC1B,CAAC,CACH,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAChB,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,aAAa,EAAE,GAAG,EAAE;IAC3B,IAAI,CAAC,kEAAkE,EAAE,GAAG,EAAE;QAC5E,MAAM,CACJ,WAAW,CAAC;YACV,QAAQ,EAAE,mBAAmB;YAC7B,QAAQ,EAAE,YAAY;SACvB,CAAC,CACH,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACf,CAAC,CAAC,CAAC;IAEH,IAAI,CAAC,qDAAqD,EAAE,GAAG,EAAE;QAC/D,MAAM,CACJ,WAAW,CAAC;YACV,QAAQ,EAAE,yEAAyE;SACpF,CAAC,CACH,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACf,CAAC,CAAC,CAAC;IAEH,IAAI,CAAC,kCAAkC,EAAE,GAAG,EAAE;QAC5C,MAAM,CACJ,WAAW,CAAC;YACV,QAAQ,EAAE,WAAW;YACrB,QAAQ,EAAE,eAAe;SAC1B,CAAC,CACH,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAChB,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,0EAA0E;AAC1E,2EAA2E;AAC3E,wDAAwD;AACxD,QAAQ,CAAC,4BAA4B,EAAE,GAAG,EAAE;IAC1C,IAAI,CAAC,oCAAoC,EAAE,GAAG,EAAE;QAC9C,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC;YAC1B,IAAI,EAAE,gCAAgC;YACtC,KAAK,EAAE,2GAA2G;SACnH,CAAC,CAAC;QACH,MAAM,CAAC,0BAA0B,CAAC,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC;YAC/C,IAAI,EAAE,gCAAgC;YACtC,OAAO,EAAE,2GAA2G;SACrH,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,6EAA6E;IAC7E,yEAAyE;IACzE,6EAA6E;IAC7E,6EAA6E;IAC7E,qCAAqC;IACrC,IAAI,CAAC,IAAI,CAAC;QACR,CAAC,gBAAgB,EAAE,EAAE,KAAK,EAAE,wCAAwC,EAAE,CAAC;QACvE,CAAC,iBAAiB,EAAE,EAAE,IAAI,EAAE,2BAA2B,EAAE,KAAK,EAAE,+BAA+B,EAAE,CAAC;QAClG,CAAC,mBAAmB,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE,KAAK,EAAE,oDAAoD,EAAE,CAAC;KACjG,CAAC,CAAC,6CAA6C,EAAE,CAAC,MAAM,EAAE,IAAI,EAAE,EAAE;QACjE,MAAM,CAAC,0BAA0B,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,aAAa,EAAE,CAAC;IAC3E,CAAC,CAAC,CAAC;IAEH,IAAI,CAAC,IAAI,CAAC;QACR,CAAC,eAAe,EAAE,8BAA8B,CAAC;QACjD,CAAC,YAAY,EAAE,EAAE,CAAC;QAClB,CAAC,iBAAiB,EAAE,KAAK,CAAC;QAC1B,CAAC,6BAA6B,EAAE,oBAAoB,CAAC;QACrD,CAAC,8BAA8B,EAAE,uBAAuB,CAAC;QACzD,CAAC,yBAAyB,EAAE,iBAAiB,CAAC;QAC9C,CAAC,YAAY,EAAE,SAAS,CAAC;QACzB,CAAC,WAAW,EAAE,MAAM,CAAC;KACtB,CAAC,CAAC,kEAAkE,EAAE,CAAC,MAAM,EAAE,IAAI,EAAE,EAAE;QACtF,MAAM,CAAC,0BAA0B,CAAC,IAAI,CAAC,CAAC,CAAC,aAAa,EAAE,CAAC;IAC3D,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"git-url.d.ts","sourceRoot":"","sources":["../../src/utils/git-url.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;
|
|
1
|
+
{"version":3,"file":"git-url.d.ts","sourceRoot":"","sources":["../../src/utils/git-url.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAUH,wBAAgB,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAGlD;AAED,wBAAgB,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAchD;AAED;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAsD5D;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,EAClC,YAAY,EACZ,UAAU,EACV,QAAQ,EACR,KAAK,EACL,IAAI,EACL,EAAE;IACD,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;CACf,GAAG,MAAM,GAAG,IAAI,CAchB;AAED,MAAM,MAAM,WAAW,GAAG,QAAQ,GAAG,QAAQ,GAAG,WAAW,GAAG,cAAc,GAAG,SAAS,CAAC;AAEzF,eAAO,MAAM,gBAAgB,EAAE,MAAM,CAAC,MAAM,EAAE,WAAW,CAMxD,CAAC;AAEF,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,MAAM,GAAG,WAAW,CAgB1D;AAkBD,wBAAgB,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAEtD;AAED,wBAAgB,mBAAmB,CAAC,MAAM,EAAE;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,gBAAgB,EAAE,MAAM,CAAA;CAAE,GAAG,MAAM,GAAG,IAAI,CAerG;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAqD3D;AAOD,wBAAgB,kBAAkB,CAAC,MAAM,EAAE;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,GAAG,OAAO,CAoBjF"}
|
|
@@ -4,10 +4,13 @@
|
|
|
4
4
|
* Parsing, validation, and compare-URL generation for git remote URLs.
|
|
5
5
|
* Used by both the UI and the vite-plugin-file-sync AI agent tooling.
|
|
6
6
|
*/
|
|
7
|
-
|
|
8
|
-
|
|
7
|
+
// Character classes below are bounded ({1,256} / {1,4096}) to avoid polynomial
|
|
8
|
+
// backtracking on adversarial input (SEC-78) — real hosts/paths are far shorter,
|
|
9
|
+
// so behavior is preserved for every valid git remote URL.
|
|
10
|
+
const HTTPS_GIT_URL_RE = /^https?:\/\/[^\s/$.?#]{1,256}(?:\.[^\s/$.?#]{1,256})+\/[^\s/$.?#]{1,256}(?:\/[^\s/$.?#]{1,256})+(?:\.git)?\/?$/i;
|
|
11
|
+
const SSH_GIT_URL_RE = /^[\w-]{1,256}@[\w.-]{1,256}:[\w./-]{1,4096}(?:\.git)?$/;
|
|
9
12
|
// ssh:// protocol format: ssh://git@host/path
|
|
10
|
-
const SSH_PROTOCOL_RE = /^ssh:\/\/[\w-]
|
|
13
|
+
const SSH_PROTOCOL_RE = /^ssh:\/\/[\w-]{1,256}@[\w.-]{1,256}\/[\w./-]{1,4096}(?:\.git)?\/?$/i;
|
|
11
14
|
export function isValidGitUrl(url) {
|
|
12
15
|
const trimmed = url.trim();
|
|
13
16
|
return HTTPS_GIT_URL_RE.test(trimmed) || SSH_GIT_URL_RE.test(trimmed) || SSH_PROTOCOL_RE.test(trimmed);
|
|
@@ -64,7 +67,15 @@ export function gitRemoteUrlToWeb(url) {
|
|
|
64
67
|
// Not a standard URL — try SSH
|
|
65
68
|
}
|
|
66
69
|
// SCP-style SSH: git@host:org/repo.git → https://host/org/repo
|
|
67
|
-
|
|
70
|
+
// Path capture is bounded ({1,4096}) so it cannot drive polynomial
|
|
71
|
+
// backtracking on adversarial input (SEC-78). The char class itself is
|
|
72
|
+
// unchanged (`.`) — paths may legitimately contain spaces (e.g. Azure
|
|
73
|
+
// DevOps project/repo names), and the numeric bound alone is enough to
|
|
74
|
+
// keep matching linear. `trimmed` (see top of function) never ends in
|
|
75
|
+
// whitespace, so the trailing `\s*` that used to sit before `$` was
|
|
76
|
+
// redundant (always zero-width) and only added its own O(n) rescan per
|
|
77
|
+
// lazy-capture step — dropped for a plain `$`.
|
|
78
|
+
const sshMatch = trimmed.match(/^[\w-]{1,256}@([\w.-]{1,256}):(.{1,4096}?)(?:\.git)?$/);
|
|
68
79
|
if (sshMatch?.[1] && sshMatch[2]) {
|
|
69
80
|
const host = sshMatch[1];
|
|
70
81
|
const path = sshMatch[2];
|
|
@@ -181,7 +192,12 @@ export function sshGitUrlToHttps(url) {
|
|
|
181
192
|
const host = parsed.hostname;
|
|
182
193
|
const path = parsed.pathname;
|
|
183
194
|
if (host === 'ssh.dev.azure.com') {
|
|
184
|
-
|
|
195
|
+
// Path capture is bounded ({1,4096}) so the trailing `(?:\.git)?\/?$`
|
|
196
|
+
// cannot drive polynomial backtracking on adversarial input (SEC-78).
|
|
197
|
+
// The char class itself is unchanged (`.`) — Azure DevOps repo names
|
|
198
|
+
// may legitimately contain spaces, and the numeric bound alone is
|
|
199
|
+
// enough to keep matching linear.
|
|
200
|
+
const azureMatch = path.match(/^\/v3\/([^/]{1,256})\/([^/]{1,256})\/(.{1,4096}?)(?:\.git)?\/?$/);
|
|
185
201
|
if (azureMatch) {
|
|
186
202
|
return `https://dev.azure.com/${azureMatch[1]}/${azureMatch[2]}/_git/${azureMatch[3]}`;
|
|
187
203
|
}
|
|
@@ -192,7 +208,14 @@ export function sshGitUrlToHttps(url) {
|
|
|
192
208
|
catch {
|
|
193
209
|
// Not a standard URL — try SCP-style SSH below.
|
|
194
210
|
}
|
|
195
|
-
|
|
211
|
+
// Path capture is bounded ({1,4096}) so it cannot drive polynomial
|
|
212
|
+
// backtracking on adversarial input (SEC-78). The char class itself is
|
|
213
|
+
// unchanged (`.`) — paths may legitimately contain spaces, and the numeric
|
|
214
|
+
// bound alone is enough to keep matching linear. `trimmed` (see top of
|
|
215
|
+
// function) never ends in whitespace, so the trailing `\s*` that used to
|
|
216
|
+
// sit before `$` was redundant (always zero-width) and only added its own
|
|
217
|
+
// O(n) rescan per lazy-capture step — dropped for a plain `$`.
|
|
218
|
+
const sshMatch = trimmed.match(/^[\w-]{1,256}@([\w.-]{1,256}):(.{1,4096}?)(?:\.git)?$/);
|
|
196
219
|
if (sshMatch?.[1] && sshMatch[2]) {
|
|
197
220
|
const host = sshMatch[1];
|
|
198
221
|
const path = sshMatch[2];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"git-url.js","sourceRoot":"","sources":["../../src/utils/git-url.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,MAAM,gBAAgB,GAAG,
|
|
1
|
+
{"version":3,"file":"git-url.js","sourceRoot":"","sources":["../../src/utils/git-url.ts"],"names":[],"mappings":"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"}
|
|
@@ -17,6 +17,9 @@ describe('isValidGitUrl', () => {
|
|
|
17
17
|
it('trims whitespace', () => {
|
|
18
18
|
expect(isValidGitUrl(' https://github.com/org/repo ')).toBe(true);
|
|
19
19
|
});
|
|
20
|
+
it('accepts ssh:// double-slash absolute-path URLs (valid git SSH syntax)', () => {
|
|
21
|
+
expect(isValidGitUrl('ssh://git@host//org/repo.git')).toBe(true);
|
|
22
|
+
});
|
|
20
23
|
});
|
|
21
24
|
describe('isGitHubUrl', () => {
|
|
22
25
|
it.each(['https://github.com/org/repo.git', 'https://github.com/org/repo', 'git@github.com:org/repo.git'])('returns true for %s', (url) => {
|
|
@@ -107,4 +110,61 @@ describe('sshGitUrlToHttps', () => {
|
|
|
107
110
|
expect(sshGitUrlToHttps('not-a-url')).toBeNull();
|
|
108
111
|
});
|
|
109
112
|
});
|
|
113
|
+
describe('git-url ReDoS (SEC-78)', () => {
|
|
114
|
+
it('still validates/normalizes real URLs', () => {
|
|
115
|
+
expect(isValidGitUrl('https://github.com/org/repo.git')).toBe(true);
|
|
116
|
+
expect(isValidGitUrl('git@github.com:org/repo.git')).toBe(true);
|
|
117
|
+
expect(isValidGitUrl('ssh://git@github.com/org/repo')).toBe(true);
|
|
118
|
+
expect(isValidGitUrl('not a url')).toBe(false);
|
|
119
|
+
expect(gitRemoteUrlToWeb('git@github.com:org/repo.git')).toBe('https://github.com/org/repo');
|
|
120
|
+
expect(sshGitUrlToHttps('git@github.com:org/repo.git')).toBe('https://github.com/org/repo.git');
|
|
121
|
+
});
|
|
122
|
+
it('still converts SCP-style paths containing spaces (e.g. Azure DevOps repo names)', () => {
|
|
123
|
+
// Raw SCP `git@host:path` strings are not URL-encoded by convention, so
|
|
124
|
+
// legitimate paths (Azure DevOps project/repo names in particular) may
|
|
125
|
+
// contain literal spaces. The bounded regex must preserve this — only the
|
|
126
|
+
// length is capped, not the character class.
|
|
127
|
+
expect(gitRemoteUrlToWeb('git@host:org/repo name.git')).toBe('https://host/org/repo name');
|
|
128
|
+
expect(sshGitUrlToHttps('git@host:org/repo name.git')).toBe('https://host/org/repo name.git');
|
|
129
|
+
});
|
|
130
|
+
it('does not rescan trailing whitespace polynomially on the SCP sshMatch fallback', () => {
|
|
131
|
+
// Internal-whitespace shape: a long run of spaces BEFORE the final
|
|
132
|
+
// non-whitespace char, rather than after it (the existing adversarial
|
|
133
|
+
// test puts the non-whitespace run first). Against the pre-fix
|
|
134
|
+
// `(?:\.git)?\s*$` tail this drove a genuine O(4096*n) scan (measured
|
|
135
|
+
// ~3.9s at n=1,000,000) because the lazy path capture and the trailing
|
|
136
|
+
// `\s*` were two independent backtracking axes. `trimmed` never ends in
|
|
137
|
+
// whitespace, so `\s*` before the final `$` was always redundant — it
|
|
138
|
+
// was dropped in favor of a plain `$`.
|
|
139
|
+
const evil = 'git@h:' + ' '.repeat(200000) + 'X';
|
|
140
|
+
const start = performance.now();
|
|
141
|
+
gitRemoteUrlToWeb(evil);
|
|
142
|
+
sshGitUrlToHttps(evil);
|
|
143
|
+
expect(performance.now() - start).toBeLessThan(100);
|
|
144
|
+
});
|
|
145
|
+
it('does not backtrack polynomially on adversarial inputs', () => {
|
|
146
|
+
const cases = [
|
|
147
|
+
'https://' + 'a.'.repeat(50000), // HTTPS_GIT_URL_RE host
|
|
148
|
+
'https://x/' + 'a/'.repeat(50000), // HTTPS_GIT_URL_RE path
|
|
149
|
+
'git@' + 'a.'.repeat(50000) + ':x', // SSH_GIT_URL_RE host
|
|
150
|
+
'ssh://git@h/' + 'a/'.repeat(50000), // SSH_PROTOCOL_RE path
|
|
151
|
+
'git@h:' + 'a'.repeat(200000), // SCP sshMatch (L72/226)
|
|
152
|
+
// Trailing-whitespace ambiguity against the `(?:\.git)?\s*$` tail: the
|
|
153
|
+
// lazy `.+?` capture and the `\s*` quantifier are two independent
|
|
154
|
+
// O(n) backtracking axes, which combine into genuine O(n^2) blowup on
|
|
155
|
+
// the pre-fix regex (confirmed: ~35ms at n=8000, ~120ms at n=16000 —
|
|
156
|
+
// consistent ~4x-per-2x quadratic scaling; would take tens of seconds
|
|
157
|
+
// at n=200000 without the bound).
|
|
158
|
+
'git@h:' + 'a'.repeat(16000) + ' '.repeat(16000) + 'X',
|
|
159
|
+
'git@ssh.dev.azure.com:v3/o/p/' + 'a'.repeat(16000) + ' '.repeat(16000) + 'X'
|
|
160
|
+
];
|
|
161
|
+
for (const evil of cases) {
|
|
162
|
+
const start = performance.now();
|
|
163
|
+
isValidGitUrl(evil);
|
|
164
|
+
gitRemoteUrlToWeb(evil);
|
|
165
|
+
sshGitUrlToHttps(evil);
|
|
166
|
+
expect(performance.now() - start).toBeLessThan(150);
|
|
167
|
+
}
|
|
168
|
+
});
|
|
169
|
+
});
|
|
110
170
|
//# sourceMappingURL=git-url.test.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"git-url.test.js","sourceRoot":"","sources":["../../src/utils/git-url.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AAE9C,OAAO,EAAE,mBAAmB,EAAE,iBAAiB,EAAE,WAAW,EAAE,aAAa,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAEpH,QAAQ,CAAC,eAAe,EAAE,GAAG,EAAE;IAC7B,EAAE,CAAC,IAAI,CAAC;QACN,iCAAiC;QACjC,6BAA6B;QAC7B,gCAAgC;QAChC,yDAAyD;QACzD,6BAA6B;QAC7B,yBAAyB;KAC1B,CAAC,CAAC,qBAAqB,EAAE,CAAC,GAAG,EAAE,EAAE;QAChC,MAAM,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACxC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,IAAI,CAAC,CAAC,EAAE,EAAE,WAAW,EAAE,2BAA2B,EAAE,UAAU,EAAE,wBAAwB,CAAC,CAAC,CAAC,sBAAsB,EAAE,CAAC,GAAG,EAAE,EAAE;QAC5H,MAAM,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IACzC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,kBAAkB,EAAE,GAAG,EAAE;QAC1B,MAAM,CAAC,aAAa,CAAC,iCAAiC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACtE,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,aAAa,EAAE,GAAG,EAAE;IAC3B,EAAE,CAAC,IAAI,CAAC,CAAC,iCAAiC,EAAE,6BAA6B,EAAE,6BAA6B,CAAC,CAAC,CACxG,qBAAqB,EACrB,CAAC,GAAG,EAAE,EAAE;QACN,MAAM,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACtC,CAAC,CACF,CAAC;IAEF,EAAE,CAAC,IAAI,CAAC,CAAC,6BAA6B,EAAE,gCAAgC,EAAE,8BAA8B,EAAE,WAAW,CAAC,CAAC,CACrH,sBAAsB,EACtB,CAAC,GAAG,EAAE,EAAE;QACN,MAAM,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IACvC,CAAC,CACF,CAAC;IAEF,EAAE,CAAC,iCAAiC,EAAE,GAAG,EAAE;QACzC,MAAM,CAAC,WAAW,CAAC,6BAA6B,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAChE,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,mBAAmB,EAAE,GAAG,EAAE;IACjC,EAAE,CAAC,IAAI,CAAmB;QACxB,CAAC,iCAAiC,EAAE,6BAA6B,CAAC;QAClE,CAAC,6BAA6B,EAAE,6BAA6B,CAAC;QAC9D,CAAC,gCAAgC,EAAE,4BAA4B,CAAC;QAChE,CAAC,6BAA6B,EAAE,6BAA6B,CAAC;QAC9D,CAAC,mCAAmC,EAAE,mCAAmC,CAAC;QAC1E,8DAA8D;QAC9D,CAAC,yDAAyD,EAAE,mDAAmD,CAAC;QAChH,2BAA2B;QAC3B,CAAC,iDAAiD,EAAE,mDAAmD,CAAC;QACxG,CAAC,uDAAuD,EAAE,mDAAmD,CAAC;KAC/G,CAAC,CAAC,kBAAkB,EAAE,CAAC,KAAK,EAAE,QAAQ,EAAE,EAAE;QACzC,MAAM,CAAC,iBAAiB,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IAClD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,iCAAiC,EAAE,GAAG,EAAE;QACzC,MAAM,CAAC,iBAAiB,CAAC,yDAAyD,CAAC,CAAC,CAAC,IAAI,CACvF,mDAAmD,CACpD,CAAC;IACJ,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,qCAAqC,EAAE,GAAG,EAAE;QAC7C,MAAM,CAAC,iBAAiB,CAAC,WAAW,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC;IACpD,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,qBAAqB,EAAE,GAAG,EAAE;IACnC,MAAM,IAAI,GAAG,EAAE,UAAU,EAAE,cAAc,EAAE,QAAQ,EAAE,MAAM,EAAE,CAAC;IAE9D,EAAE,CAAC,6BAA6B,EAAE,GAAG,EAAE;QACrC,MAAM,CACJ,mBAAmB,CAAC;YAClB,YAAY,EAAE,iCAAiC;YAC/C,GAAG,IAAI;SACR,CAAC,CACH,CAAC,IAAI,CAAC,2DAA2D,CAAC,CAAC;IACtE,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,wBAAwB,EAAE,GAAG,EAAE;QAChC,MAAM,CACJ,mBAAmB,CAAC;YAClB,YAAY,EAAE,iCAAiC;YAC/C,GAAG,IAAI;YACP,KAAK,EAAE,OAAO;YACd,IAAI,EAAE,YAAY;SACnB,CAAC,CACH,CAAC,IAAI,CAAC,oGAAoG,CAAC,CAAC;IAC/G,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,kCAAkC,EAAE,GAAG,EAAE;QAC1C,MAAM,CACJ,mBAAmB,CAAC;YAClB,YAAY,EAAE,6BAA6B;YAC3C,GAAG,IAAI;SACR,CAAC,CACH,CAAC,QAAQ,EAAE,CAAC;IACf,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,qCAAqC,EAAE,GAAG,EAAE;QAC7C,MAAM,CAAC,mBAAmB,CAAC,EAAE,YAAY,EAAE,WAAW,EAAE,GAAG,IAAI,EAAE,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC;IACjF,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,kBAAkB,EAAE,GAAG,EAAE;IAChC,EAAE,CAAC,IAAI,CAAmB;QACxB,CAAC,6BAA6B,EAAE,iCAAiC,CAAC;QAClE,CAAC,yBAAyB,EAAE,iCAAiC,CAAC;QAC9D,CAAC,mCAAmC,EAAE,uCAAuC,CAAC;QAC9E,CAAC,uDAAuD,EAAE,2DAA2D,CAAC;QACtH,CAAC,gCAAgC,EAAE,oCAAoC,CAAC;QACxE,CAAC,mCAAmC,EAAE,iCAAiC,CAAC;QACxE,CAAC,+BAA+B,EAAE,iCAAiC,CAAC;QACpE,CAAC,iDAAiD,EAAE,mDAAmD,CAAC;QACxG,CAAC,uDAAuD,EAAE,mDAAmD,CAAC;KAC/G,CAAC,CAAC,kBAAkB,EAAE,CAAC,KAAK,EAAE,QAAQ,EAAE,EAAE;QACzC,MAAM,CAAC,gBAAgB,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IACjD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,8BAA8B,EAAE,GAAG,EAAE;QACtC,MAAM,CAAC,gBAAgB,CAAC,iCAAiC,CAAC,CAAC,CAAC,IAAI,CAAC,iCAAiC,CAAC,CAAC;IACtG,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,uDAAuD,EAAE,GAAG,EAAE;QAC/D,MAAM,CAAC,gBAAgB,CAAC,6BAA6B,CAAC,CAAC,CAAC,IAAI,CAAC,iCAAiC,CAAC,CAAC;IAClG,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,wDAAwD,EAAE,GAAG,EAAE;QAChE,MAAM,CAAC,gBAAgB,CAAC,mDAAmD,CAAC,CAAC,CAAC,IAAI,CAAC,mDAAmD,CAAC,CAAC;IAC1I,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,+CAA+C,EAAE,GAAG,EAAE;QACvD,MAAM,CACJ,gBAAgB,CAAC,gHAAgH,CAAC,CACnI,CAAC,IAAI,CAAC,gHAAgH,CAAC,CAAC;IAC3H,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,qCAAqC,EAAE,GAAG,EAAE;QAC7C,MAAM,CAAC,gBAAgB,CAAC,WAAW,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC;IACnD,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
|
|
1
|
+
{"version":3,"file":"git-url.test.js","sourceRoot":"","sources":["../../src/utils/git-url.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AAE9C,OAAO,EAAE,mBAAmB,EAAE,iBAAiB,EAAE,WAAW,EAAE,aAAa,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAEpH,QAAQ,CAAC,eAAe,EAAE,GAAG,EAAE;IAC7B,EAAE,CAAC,IAAI,CAAC;QACN,iCAAiC;QACjC,6BAA6B;QAC7B,gCAAgC;QAChC,yDAAyD;QACzD,6BAA6B;QAC7B,yBAAyB;KAC1B,CAAC,CAAC,qBAAqB,EAAE,CAAC,GAAG,EAAE,EAAE;QAChC,MAAM,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACxC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,IAAI,CAAC,CAAC,EAAE,EAAE,WAAW,EAAE,2BAA2B,EAAE,UAAU,EAAE,wBAAwB,CAAC,CAAC,CAAC,sBAAsB,EAAE,CAAC,GAAG,EAAE,EAAE;QAC5H,MAAM,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IACzC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,kBAAkB,EAAE,GAAG,EAAE;QAC1B,MAAM,CAAC,aAAa,CAAC,iCAAiC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACtE,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,uEAAuE,EAAE,GAAG,EAAE;QAC/E,MAAM,CAAC,aAAa,CAAC,8BAA8B,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACnE,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,aAAa,EAAE,GAAG,EAAE;IAC3B,EAAE,CAAC,IAAI,CAAC,CAAC,iCAAiC,EAAE,6BAA6B,EAAE,6BAA6B,CAAC,CAAC,CACxG,qBAAqB,EACrB,CAAC,GAAG,EAAE,EAAE;QACN,MAAM,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACtC,CAAC,CACF,CAAC;IAEF,EAAE,CAAC,IAAI,CAAC,CAAC,6BAA6B,EAAE,gCAAgC,EAAE,8BAA8B,EAAE,WAAW,CAAC,CAAC,CACrH,sBAAsB,EACtB,CAAC,GAAG,EAAE,EAAE;QACN,MAAM,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IACvC,CAAC,CACF,CAAC;IAEF,EAAE,CAAC,iCAAiC,EAAE,GAAG,EAAE;QACzC,MAAM,CAAC,WAAW,CAAC,6BAA6B,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAChE,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,mBAAmB,EAAE,GAAG,EAAE;IACjC,EAAE,CAAC,IAAI,CAAmB;QACxB,CAAC,iCAAiC,EAAE,6BAA6B,CAAC;QAClE,CAAC,6BAA6B,EAAE,6BAA6B,CAAC;QAC9D,CAAC,gCAAgC,EAAE,4BAA4B,CAAC;QAChE,CAAC,6BAA6B,EAAE,6BAA6B,CAAC;QAC9D,CAAC,mCAAmC,EAAE,mCAAmC,CAAC;QAC1E,8DAA8D;QAC9D,CAAC,yDAAyD,EAAE,mDAAmD,CAAC;QAChH,2BAA2B;QAC3B,CAAC,iDAAiD,EAAE,mDAAmD,CAAC;QACxG,CAAC,uDAAuD,EAAE,mDAAmD,CAAC;KAC/G,CAAC,CAAC,kBAAkB,EAAE,CAAC,KAAK,EAAE,QAAQ,EAAE,EAAE;QACzC,MAAM,CAAC,iBAAiB,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IAClD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,iCAAiC,EAAE,GAAG,EAAE;QACzC,MAAM,CAAC,iBAAiB,CAAC,yDAAyD,CAAC,CAAC,CAAC,IAAI,CACvF,mDAAmD,CACpD,CAAC;IACJ,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,qCAAqC,EAAE,GAAG,EAAE;QAC7C,MAAM,CAAC,iBAAiB,CAAC,WAAW,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC;IACpD,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,qBAAqB,EAAE,GAAG,EAAE;IACnC,MAAM,IAAI,GAAG,EAAE,UAAU,EAAE,cAAc,EAAE,QAAQ,EAAE,MAAM,EAAE,CAAC;IAE9D,EAAE,CAAC,6BAA6B,EAAE,GAAG,EAAE;QACrC,MAAM,CACJ,mBAAmB,CAAC;YAClB,YAAY,EAAE,iCAAiC;YAC/C,GAAG,IAAI;SACR,CAAC,CACH,CAAC,IAAI,CAAC,2DAA2D,CAAC,CAAC;IACtE,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,wBAAwB,EAAE,GAAG,EAAE;QAChC,MAAM,CACJ,mBAAmB,CAAC;YAClB,YAAY,EAAE,iCAAiC;YAC/C,GAAG,IAAI;YACP,KAAK,EAAE,OAAO;YACd,IAAI,EAAE,YAAY;SACnB,CAAC,CACH,CAAC,IAAI,CAAC,oGAAoG,CAAC,CAAC;IAC/G,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,kCAAkC,EAAE,GAAG,EAAE;QAC1C,MAAM,CACJ,mBAAmB,CAAC;YAClB,YAAY,EAAE,6BAA6B;YAC3C,GAAG,IAAI;SACR,CAAC,CACH,CAAC,QAAQ,EAAE,CAAC;IACf,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,qCAAqC,EAAE,GAAG,EAAE;QAC7C,MAAM,CAAC,mBAAmB,CAAC,EAAE,YAAY,EAAE,WAAW,EAAE,GAAG,IAAI,EAAE,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC;IACjF,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,kBAAkB,EAAE,GAAG,EAAE;IAChC,EAAE,CAAC,IAAI,CAAmB;QACxB,CAAC,6BAA6B,EAAE,iCAAiC,CAAC;QAClE,CAAC,yBAAyB,EAAE,iCAAiC,CAAC;QAC9D,CAAC,mCAAmC,EAAE,uCAAuC,CAAC;QAC9E,CAAC,uDAAuD,EAAE,2DAA2D,CAAC;QACtH,CAAC,gCAAgC,EAAE,oCAAoC,CAAC;QACxE,CAAC,mCAAmC,EAAE,iCAAiC,CAAC;QACxE,CAAC,+BAA+B,EAAE,iCAAiC,CAAC;QACpE,CAAC,iDAAiD,EAAE,mDAAmD,CAAC;QACxG,CAAC,uDAAuD,EAAE,mDAAmD,CAAC;KAC/G,CAAC,CAAC,kBAAkB,EAAE,CAAC,KAAK,EAAE,QAAQ,EAAE,EAAE;QACzC,MAAM,CAAC,gBAAgB,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IACjD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,8BAA8B,EAAE,GAAG,EAAE;QACtC,MAAM,CAAC,gBAAgB,CAAC,iCAAiC,CAAC,CAAC,CAAC,IAAI,CAAC,iCAAiC,CAAC,CAAC;IACtG,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,uDAAuD,EAAE,GAAG,EAAE;QAC/D,MAAM,CAAC,gBAAgB,CAAC,6BAA6B,CAAC,CAAC,CAAC,IAAI,CAAC,iCAAiC,CAAC,CAAC;IAClG,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,wDAAwD,EAAE,GAAG,EAAE;QAChE,MAAM,CAAC,gBAAgB,CAAC,mDAAmD,CAAC,CAAC,CAAC,IAAI,CAAC,mDAAmD,CAAC,CAAC;IAC1I,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,+CAA+C,EAAE,GAAG,EAAE;QACvD,MAAM,CACJ,gBAAgB,CAAC,gHAAgH,CAAC,CACnI,CAAC,IAAI,CAAC,gHAAgH,CAAC,CAAC;IAC3H,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,qCAAqC,EAAE,GAAG,EAAE;QAC7C,MAAM,CAAC,gBAAgB,CAAC,WAAW,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC;IACnD,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,wBAAwB,EAAE,GAAG,EAAE;IACtC,EAAE,CAAC,sCAAsC,EAAE,GAAG,EAAE;QAC9C,MAAM,CAAC,aAAa,CAAC,iCAAiC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACpE,MAAM,CAAC,aAAa,CAAC,6BAA6B,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAChE,MAAM,CAAC,aAAa,CAAC,+BAA+B,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAClE,MAAM,CAAC,aAAa,CAAC,WAAW,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAC/C,MAAM,CAAC,iBAAiB,CAAC,6BAA6B,CAAC,CAAC,CAAC,IAAI,CAAC,6BAA6B,CAAC,CAAC;QAC7F,MAAM,CAAC,gBAAgB,CAAC,6BAA6B,CAAC,CAAC,CAAC,IAAI,CAAC,iCAAiC,CAAC,CAAC;IAClG,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,iFAAiF,EAAE,GAAG,EAAE;QACzF,wEAAwE;QACxE,uEAAuE;QACvE,0EAA0E;QAC1E,6CAA6C;QAC7C,MAAM,CAAC,iBAAiB,CAAC,4BAA4B,CAAC,CAAC,CAAC,IAAI,CAAC,4BAA4B,CAAC,CAAC;QAC3F,MAAM,CAAC,gBAAgB,CAAC,4BAA4B,CAAC,CAAC,CAAC,IAAI,CAAC,gCAAgC,CAAC,CAAC;IAChG,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,+EAA+E,EAAE,GAAG,EAAE;QACvF,mEAAmE;QACnE,sEAAsE;QACtE,+DAA+D;QAC/D,sEAAsE;QACtE,uEAAuE;QACvE,wEAAwE;QACxE,sEAAsE;QACtE,uCAAuC;QACvC,MAAM,IAAI,GAAG,QAAQ,GAAG,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,GAAG,GAAG,CAAC;QACjD,MAAM,KAAK,GAAG,WAAW,CAAC,GAAG,EAAE,CAAC;QAChC,iBAAiB,CAAC,IAAI,CAAC,CAAC;QACxB,gBAAgB,CAAC,IAAI,CAAC,CAAC;QACvB,MAAM,CAAC,WAAW,CAAC,GAAG,EAAE,GAAG,KAAK,CAAC,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC;IACtD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,uDAAuD,EAAE,GAAG,EAAE;QAC/D,MAAM,KAAK,GAAG;YACZ,UAAU,GAAG,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,wBAAwB;YACzD,YAAY,GAAG,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,wBAAwB;YAC3D,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,IAAI,EAAE,sBAAsB;YAC1D,cAAc,GAAG,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,uBAAuB;YAC5D,QAAQ,GAAG,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,yBAAyB;YACxD,uEAAuE;YACvE,kEAAkE;YAClE,sEAAsE;YACtE,qEAAqE;YACrE,sEAAsE;YACtE,kCAAkC;YAClC,QAAQ,GAAG,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,GAAG;YACtD,+BAA+B,GAAG,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,GAAG;SAC9E,CAAC;QACF,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;YACzB,MAAM,KAAK,GAAG,WAAW,CAAC,GAAG,EAAE,CAAC;YAChC,aAAa,CAAC,IAAI,CAAC,CAAC;YACpB,iBAAiB,CAAC,IAAI,CAAC,CAAC;YACxB,gBAAgB,CAAC,IAAI,CAAC,CAAC;YACvB,MAAM,CAAC,WAAW,CAAC,GAAG,EAAE,GAAG,KAAK,CAAC,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC;QACtD,CAAC;IACH,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
export function normalizeRoleName(displayName) {
|
|
2
2
|
const key = displayName
|
|
3
3
|
.trim() // remove leading/trailing whitespace
|
|
4
|
-
.replace(
|
|
5
|
-
.replace(
|
|
4
|
+
.replace(/[\W_]+/g, '_') // collapse non-alphanumeric runs to a single underscore (linear)
|
|
5
|
+
.replace(/^_|_$/g, ''); // strip the single edge underscore left by the collapse step (no quantifier -> no polynomial shape)
|
|
6
6
|
return key.toLowerCase();
|
|
7
7
|
}
|
|
8
8
|
//# sourceMappingURL=normalizeRoleName.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"normalizeRoleName.js","sourceRoot":"","sources":["../../src/utils/normalizeRoleName.ts"],"names":[],"mappings":"AAAA,MAAM,UAAU,iBAAiB,CAAC,WAAmB;IACnD,MAAM,GAAG,GAAG,WAAW;SACpB,IAAI,EAAE,CAAC,qCAAqC;SAC5C,OAAO,CAAC,
|
|
1
|
+
{"version":3,"file":"normalizeRoleName.js","sourceRoot":"","sources":["../../src/utils/normalizeRoleName.ts"],"names":[],"mappings":"AAAA,MAAM,UAAU,iBAAiB,CAAC,WAAmB;IACnD,MAAM,GAAG,GAAG,WAAW;SACpB,IAAI,EAAE,CAAC,qCAAqC;SAC5C,OAAO,CAAC,SAAS,EAAE,GAAG,CAAC,CAAC,iEAAiE;SACzF,OAAO,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC,CAAC,oGAAoG;IAC9H,OAAO,GAAG,CAAC,WAAW,EAAE,CAAC;AAC3B,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"normalizeRoleName.test.d.ts","sourceRoot":"","sources":["../../src/utils/normalizeRoleName.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { describe, expect, it } from 'vitest';
|
|
2
|
+
import { normalizeRoleName } from './normalizeRoleName.js';
|
|
3
|
+
describe('normalizeRoleName', () => {
|
|
4
|
+
it('lowercases a simple name', () => {
|
|
5
|
+
expect(normalizeRoleName('Admin')).toBe('admin');
|
|
6
|
+
});
|
|
7
|
+
it('collapses internal non-alphanumeric runs to a single underscore', () => {
|
|
8
|
+
expect(normalizeRoleName('Team Lead')).toBe('team_lead');
|
|
9
|
+
expect(normalizeRoleName('a__b')).toBe('a_b');
|
|
10
|
+
});
|
|
11
|
+
it('strips leading and trailing non-alphanumeric characters', () => {
|
|
12
|
+
expect(normalizeRoleName(' Team Lead ')).toBe('team_lead');
|
|
13
|
+
expect(normalizeRoleName('!!!Role@@@')).toBe('role');
|
|
14
|
+
expect(normalizeRoleName('___')).toBe('');
|
|
15
|
+
});
|
|
16
|
+
it('handles a long non-alphanumeric run without catastrophic backtracking', () => {
|
|
17
|
+
const input = `${'!'.repeat(100_000)}role`;
|
|
18
|
+
const start = Date.now();
|
|
19
|
+
expect(normalizeRoleName(input)).toBe('role');
|
|
20
|
+
expect(Date.now() - start).toBeLessThan(1_000);
|
|
21
|
+
});
|
|
22
|
+
});
|
|
23
|
+
//# sourceMappingURL=normalizeRoleName.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"normalizeRoleName.test.js","sourceRoot":"","sources":["../../src/utils/normalizeRoleName.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AAE9C,OAAO,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAE3D,QAAQ,CAAC,mBAAmB,EAAE,GAAG,EAAE;IACjC,EAAE,CAAC,0BAA0B,EAAE,GAAG,EAAE;QAClC,MAAM,CAAC,iBAAiB,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IACnD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,iEAAiE,EAAE,GAAG,EAAE;QACzE,MAAM,CAAC,iBAAiB,CAAC,aAAa,CAAC,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;QAC3D,MAAM,CAAC,iBAAiB,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAChD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,yDAAyD,EAAE,GAAG,EAAE;QACjE,MAAM,CAAC,iBAAiB,CAAC,eAAe,CAAC,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;QAC7D,MAAM,CAAC,iBAAiB,CAAC,YAAY,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QACrD,MAAM,CAAC,iBAAiB,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAC5C,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,uEAAuE,EAAE,GAAG,EAAE;QAC/E,MAAM,KAAK,GAAG,GAAG,GAAG,CAAC,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC;QAC3C,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QACzB,MAAM,CAAC,iBAAiB,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QAC9C,MAAM,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,KAAK,CAAC,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC;IACjD,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@superblocksteam/shared",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "2.0.0-SNAPSHOT.7ea2658f98892d2c",
|
|
4
4
|
"description": "Superblocks Shared Resources",
|
|
5
5
|
"license": "Superblocks Community Software License",
|
|
6
6
|
"repository": "https://github.com/superblocksteam/shared.git",
|
package/src/constants.ts
CHANGED
|
@@ -29,6 +29,7 @@ export const SUPERBLOCKS_COMPONENT_EVENT_HEADER = 'x-superblocks-component-event
|
|
|
29
29
|
export const SUPERBLOCKS_URL_HEADER = 'x-superblocks-url';
|
|
30
30
|
export const SUPERBLOCKS_AUTHORIZATION_HEADER = 'x-superblocks-authorization';
|
|
31
31
|
export const SUPERBLOCKS_EMBED_HEADER = 'x-superblocks-embed';
|
|
32
|
+
export const SUPERBLOCKS_RESOLVED_PROFILE_KEY_HEADER = 'x-superblocks-resolved-profile-key';
|
|
32
33
|
export const SUPERBLOCKS_SESSION_ID_HEADER = 'x-superblocks-session-id';
|
|
33
34
|
export const SUPERBLOCKS_LIVE_GIT_BRANCH = 'superblocks/live';
|
|
34
35
|
// Baseline branch used after disconnecting from git-backed workflows.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { describe, expect, test } from 'vitest';
|
|
2
2
|
|
|
3
|
-
import { analyzeDestructiveMigrations, analyzeDestructiveMigrationsRequiringAck } from './destructiveMigrations.js';
|
|
3
|
+
import { analyzeDestructiveMigrations, analyzeDestructiveMigrationsRequiringAck, stripSqlComments } from './destructiveMigrations.js';
|
|
4
4
|
|
|
5
5
|
describe('analyzeDestructiveMigrations', () => {
|
|
6
6
|
test('returns empty when SQL has no destructive statements', () => {
|
|
@@ -221,3 +221,29 @@ describe('analyzeDestructiveMigrationsRequiringAck', () => {
|
|
|
221
221
|
).toEqual([]);
|
|
222
222
|
});
|
|
223
223
|
});
|
|
224
|
+
|
|
225
|
+
describe('stripSqlComments', () => {
|
|
226
|
+
test('removes a well-formed block comment', () => {
|
|
227
|
+
// Whitespace-normalized: the comment marker is replaced with a single
|
|
228
|
+
// space, so the exact run length around it is an implementation detail.
|
|
229
|
+
expect(stripSqlComments('SELECT 1 /* note */ FROM t').replace(/\s+/g, ' ').trim()).toBe('SELECT 1 FROM t');
|
|
230
|
+
});
|
|
231
|
+
|
|
232
|
+
test('removes line comments', () => {
|
|
233
|
+
expect(stripSqlComments('SELECT 1 -- trailing\nFROM t')).toContain('SELECT 1');
|
|
234
|
+
expect(stripSqlComments('SELECT 1 -- trailing\nFROM t')).not.toContain('trailing');
|
|
235
|
+
});
|
|
236
|
+
|
|
237
|
+
test('leaves an unterminated block comment in place (matches prior behavior)', () => {
|
|
238
|
+
// The original regex did not match an unterminated /* and stripped nothing.
|
|
239
|
+
const input = 'SELECT 1 /* unterminated DROP TABLE x';
|
|
240
|
+
expect(stripSqlComments(input)).toContain('/* unterminated DROP TABLE x');
|
|
241
|
+
});
|
|
242
|
+
|
|
243
|
+
test('handles a long unterminated comment without catastrophic backtracking', () => {
|
|
244
|
+
const input = `SELECT 1 /*${'a'.repeat(200_000)}`;
|
|
245
|
+
const start = Date.now();
|
|
246
|
+
stripSqlComments(input);
|
|
247
|
+
expect(Date.now() - start).toBeLessThan(1_000);
|
|
248
|
+
});
|
|
249
|
+
});
|
|
@@ -51,10 +51,30 @@ const DESTRUCTIVE_PATTERNS: Array<{ kind: DestructiveMigrationKind; re: RegExp }
|
|
|
51
51
|
{ kind: 'drop_column', re: /^\s*DROP\s+COLUMN\b/i }
|
|
52
52
|
];
|
|
53
53
|
|
|
54
|
-
function stripSqlComments(sql: string): string {
|
|
54
|
+
export function stripSqlComments(sql: string): string {
|
|
55
55
|
// Block comments first, then line comments. Good enough for migration files;
|
|
56
56
|
// does not try to handle comment markers inside string literals.
|
|
57
|
-
return sql
|
|
57
|
+
return stripBlockComments(sql).replace(/--[^\n]*/g, ' ');
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
function stripBlockComments(sql: string): string {
|
|
61
|
+
let result = '';
|
|
62
|
+
let index = 0;
|
|
63
|
+
for (;;) {
|
|
64
|
+
const open = sql.indexOf('/*', index);
|
|
65
|
+
if (open === -1) {
|
|
66
|
+
return result + sql.slice(index);
|
|
67
|
+
}
|
|
68
|
+
result += sql.slice(index, open);
|
|
69
|
+
const close = sql.indexOf('*/', open + 2);
|
|
70
|
+
if (close === -1) {
|
|
71
|
+
// Unterminated block comment: leave the remainder untouched, matching the
|
|
72
|
+
// original regex which did not match and thus stripped nothing here.
|
|
73
|
+
return result + sql.slice(open);
|
|
74
|
+
}
|
|
75
|
+
result += ' ';
|
|
76
|
+
index = close + 2;
|
|
77
|
+
}
|
|
58
78
|
}
|
|
59
79
|
|
|
60
80
|
function splitStatements(sql: string): string[] {
|
|
@@ -101,6 +101,50 @@ describe('SocketHeartbeat', () => {
|
|
|
101
101
|
subject.stop();
|
|
102
102
|
});
|
|
103
103
|
|
|
104
|
+
// A refusal is the only outcome where the peer stated why, and a refusal does
|
|
105
|
+
// not clear the counts around it. A silence afterwards overwrites `lastError`
|
|
106
|
+
// with its own generic cause, so the stated one has to be kept apart or the
|
|
107
|
+
// death report attributes a timeout's message to the refusal it still counts.
|
|
108
|
+
it('keeps the refusal reason when a later silence overwrites lastError', async () => {
|
|
109
|
+
const { refuseLast, subject } = heartbeat();
|
|
110
|
+
subject.start();
|
|
111
|
+
subject.recordReceive();
|
|
112
|
+
|
|
113
|
+
await elapse(INTERVAL_MS);
|
|
114
|
+
refuseLast(new Error('sandbox is shutting down (code 7)'));
|
|
115
|
+
await elapse(1);
|
|
116
|
+
|
|
117
|
+
// The beat after it is never answered at all, so it times out.
|
|
118
|
+
await elapse(INTERVAL_MS);
|
|
119
|
+
await elapse(TIMEOUT_MS + 1);
|
|
120
|
+
|
|
121
|
+
expect(subject.account).toMatchObject({
|
|
122
|
+
lastRefusalError: 'sandbox is shutting down (code 7)',
|
|
123
|
+
refusals: 1
|
|
124
|
+
});
|
|
125
|
+
expect(subject.account.lastError).not.toBe('sandbox is shutting down (code 7)');
|
|
126
|
+
subject.stop();
|
|
127
|
+
});
|
|
128
|
+
|
|
129
|
+
// An answered beat settles the account outright, so a refusal it supersedes
|
|
130
|
+
// must not keep explaining a connection that has since proved healthy.
|
|
131
|
+
it('drops the refusal reason once a beat is answered', async () => {
|
|
132
|
+
const { answerLast, refuseLast, subject } = heartbeat();
|
|
133
|
+
subject.start();
|
|
134
|
+
subject.recordReceive();
|
|
135
|
+
|
|
136
|
+
await elapse(INTERVAL_MS);
|
|
137
|
+
refuseLast(new Error('sandbox is shutting down (code 7)'));
|
|
138
|
+
await elapse(1);
|
|
139
|
+
|
|
140
|
+
await elapse(INTERVAL_MS);
|
|
141
|
+
answerLast();
|
|
142
|
+
await elapse(1);
|
|
143
|
+
|
|
144
|
+
expect(subject.account.lastRefusalError).toBeUndefined();
|
|
145
|
+
subject.stop();
|
|
146
|
+
});
|
|
147
|
+
|
|
104
148
|
// A refusal is an answer: the peer is reachable and the request channel works,
|
|
105
149
|
// so whatever is wrong is not the connection. Spending the grace meant for a
|
|
106
150
|
// starved pong on one would tear a working socket down over an
|
package/src/socket/heartbeat.ts
CHANGED
|
@@ -76,6 +76,16 @@ export type HeartbeatAccount = {
|
|
|
76
76
|
*/
|
|
77
77
|
readonly lapses: number;
|
|
78
78
|
readonly lastError?: string;
|
|
79
|
+
/**
|
|
80
|
+
* Why the peer refused, kept apart from {@link HeartbeatAccount.lastError}.
|
|
81
|
+
*
|
|
82
|
+
* A refusal is the only outcome where the peer said why, and it clears none
|
|
83
|
+
* of the counts around it - so a silence after one leaves `refusals` standing
|
|
84
|
+
* while overwriting `lastError` with its own generic cause. A report reading
|
|
85
|
+
* only `lastError` would then attribute a timeout's message to the refusal.
|
|
86
|
+
* Cleared by an answered beat, which settles the whole account.
|
|
87
|
+
*/
|
|
88
|
+
readonly lastRefusalError?: string;
|
|
79
89
|
readonly lastReceivedAt?: number;
|
|
80
90
|
readonly lastSuccessAt?: number;
|
|
81
91
|
/**
|
|
@@ -411,6 +421,7 @@ export class SocketHeartbeat {
|
|
|
411
421
|
this.state.lastSuccessAt = Date.now();
|
|
412
422
|
this.lost = false;
|
|
413
423
|
delete this.state.lastError;
|
|
424
|
+
delete this.state.lastRefusalError;
|
|
414
425
|
return 'success';
|
|
415
426
|
}
|
|
416
427
|
|
|
@@ -429,6 +440,10 @@ export class SocketHeartbeat {
|
|
|
429
440
|
// silence that counter is the only thing left that can end one.
|
|
430
441
|
this.state.refusals += 1;
|
|
431
442
|
this.state.lastError = describe(error);
|
|
443
|
+
// Kept apart because the next unanswered beat overwrites `lastError`
|
|
444
|
+
// without clearing `refusals`, and the peer's own reason is the one thing
|
|
445
|
+
// in this account that was stated rather than inferred.
|
|
446
|
+
this.state.lastRefusalError = this.state.lastError;
|
|
432
447
|
return 'refused';
|
|
433
448
|
}
|
|
434
449
|
// Saturating rather than growing: this is what the caller reports as the
|
package/src/socket/protocol.ts
CHANGED
|
@@ -19,6 +19,7 @@ import {
|
|
|
19
19
|
PageSummary,
|
|
20
20
|
PostApiBranchCreateResponseBody,
|
|
21
21
|
PostApplicationBranchCreateResponseBody,
|
|
22
|
+
PostApplicationCloneResponseBody,
|
|
22
23
|
PostApplicationCreateRequestBody,
|
|
23
24
|
RemoteCommitDto,
|
|
24
25
|
ResponseMeta,
|
|
@@ -181,7 +182,7 @@ export interface ServerMethods {
|
|
|
181
182
|
v2: {
|
|
182
183
|
application: {
|
|
183
184
|
create: ServerMethodSchema<PostApplicationCreateRequestBody, IApplicationV2Dto>;
|
|
184
|
-
clone: ServerMethodSchema<{ applicationId: string },
|
|
185
|
+
clone: ServerMethodSchema<{ applicationId: string }, PostApplicationCloneResponseBody>;
|
|
185
186
|
createBranch: ServerMethodSchema<
|
|
186
187
|
{ applicationId: string; branchName: string; baseBranchName: string },
|
|
187
188
|
PostApplicationBranchCreateResponseBody
|
|
@@ -7,6 +7,49 @@ import { ISocketWithClientAuth } from './socketWithClientAuth.js';
|
|
|
7
7
|
const PING_TIMEOUT_CLOSE_REASON = 'Ping timeout';
|
|
8
8
|
|
|
9
9
|
describe('ISocket', () => {
|
|
10
|
+
it('preserves safe fields from structured handler errors', async () => {
|
|
11
|
+
let messageHandler: ((event: { data: string }) => void) | undefined;
|
|
12
|
+
const ws = {
|
|
13
|
+
addEventListener: vi.fn((event: string, handler: (event: { data: string }) => void) => {
|
|
14
|
+
if (event === 'message') {
|
|
15
|
+
messageHandler = handler;
|
|
16
|
+
}
|
|
17
|
+
}),
|
|
18
|
+
close: vi.fn(),
|
|
19
|
+
send: vi.fn()
|
|
20
|
+
};
|
|
21
|
+
new ISocket(
|
|
22
|
+
ws as never,
|
|
23
|
+
{
|
|
24
|
+
editor: {
|
|
25
|
+
save: [
|
|
26
|
+
async () => {
|
|
27
|
+
throw { code: 2, status: 503, message: 'checkpoint unavailable', details: 'do not expose' };
|
|
28
|
+
}
|
|
29
|
+
]
|
|
30
|
+
}
|
|
31
|
+
} as never,
|
|
32
|
+
[],
|
|
33
|
+
{ onClose: vi.fn() }
|
|
34
|
+
);
|
|
35
|
+
|
|
36
|
+
messageHandler?.({
|
|
37
|
+
data: JSON.stringify({ request: { id: 1, method: 'editor.save', payload: {} } })
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
await vi.waitFor(() => {
|
|
41
|
+
expect(ws.send).toHaveBeenCalledWith(
|
|
42
|
+
JSON.stringify({
|
|
43
|
+
response: {
|
|
44
|
+
payload: null,
|
|
45
|
+
id: 1,
|
|
46
|
+
error: { code: 2, status: 503, message: 'checkpoint unavailable' }
|
|
47
|
+
}
|
|
48
|
+
})
|
|
49
|
+
);
|
|
50
|
+
});
|
|
51
|
+
});
|
|
52
|
+
|
|
10
53
|
it('clears abort cleanup when a no-response timeout rejects the request', async () => {
|
|
11
54
|
vi.useFakeTimers();
|
|
12
55
|
try {
|
package/src/socket/socket.ts
CHANGED
|
@@ -40,12 +40,25 @@ export interface SocketMessage<RequestPayload = unknown, ResponsePayload = unkno
|
|
|
40
40
|
export interface SocketError {
|
|
41
41
|
message: string;
|
|
42
42
|
code: number;
|
|
43
|
+
status?: number;
|
|
43
44
|
stack?: string;
|
|
44
45
|
}
|
|
45
46
|
|
|
46
47
|
// Codes in the 4000s are left available by IETF
|
|
47
48
|
// https://datatracker.ietf.org/doc/html/rfc6455#section-7.4.2
|
|
48
49
|
export const INTENTIONAL_CLOSE_CODE = 4001;
|
|
50
|
+
/**
|
|
51
|
+
* Close reason the dev server sends with INTENTIONAL_CLOSE_CODE when it drops
|
|
52
|
+
* an editor socket on purpose and wants the editor to open a new one, for
|
|
53
|
+
* example after a browser RPC timed out. Without a reason the editor reads an
|
|
54
|
+
* intentional close during a generation as the dev server shutting down and
|
|
55
|
+
* stops reconnecting.
|
|
56
|
+
*
|
|
57
|
+
* The editor bundle and the dev server package ship separately and compare
|
|
58
|
+
* this string by value, so the tests on both sides pin the literal, not the
|
|
59
|
+
* constant. Changing the value breaks the pair until both sides are deployed.
|
|
60
|
+
*/
|
|
61
|
+
export const RECONNECT_REQUESTED_CLOSE_REASON = 'Reconnect requested';
|
|
49
62
|
const CONNECTION_CLOSED_MESSAGE = '[internal] Connection closed';
|
|
50
63
|
|
|
51
64
|
/**
|
|
@@ -208,10 +221,18 @@ export class ISocket<ImplementedMethods, CallableMethods, RequestContext extends
|
|
|
208
221
|
// call the first handler in the chain
|
|
209
222
|
response = await generateNextFn(0)();
|
|
210
223
|
} catch (error) {
|
|
224
|
+
const structuredError =
|
|
225
|
+
typeof error === 'object' && error !== null && 'message' in error && typeof error.message === 'string' ? error : undefined;
|
|
211
226
|
const socketError =
|
|
212
227
|
error instanceof SocketErrorException
|
|
213
228
|
? { code: error.code, message: error.message, stack: error.stack }
|
|
214
|
-
:
|
|
229
|
+
: structuredError && !(structuredError instanceof Error)
|
|
230
|
+
? {
|
|
231
|
+
code: 'code' in structuredError && typeof structuredError.code === 'number' ? structuredError.code : 3,
|
|
232
|
+
status: 'status' in structuredError && typeof structuredError.status === 'number' ? structuredError.status : undefined,
|
|
233
|
+
message: structuredError.message
|
|
234
|
+
}
|
|
235
|
+
: { code: 3, message: String(error), stack: error instanceof Error ? error.stack : undefined };
|
|
215
236
|
this.logger.error(JSON.stringify(socketError));
|
|
216
237
|
return this.respondError(message.request.id, socketError, error);
|
|
217
238
|
}
|