diff --git a/README.md b/README.md index 2536b23e..0dcd352d 100644 --- a/README.md +++ b/README.md @@ -196,6 +196,14 @@ Check the standard `RateLimit-*` headers for quota and reset time. --- +## API Boundary Validation + +LiquiFact backend leverages [Zod](https://zod.dev/) to protect API boundaries against malformed data and data leaks constraint regressions: +- **Inbound Validation**: Ensures clients provide expected payloads (e.g., `amount`, `customer`). Malformed requests receive a `400 Bad Request` containing specific constraint validation issues. +- **Outbound Escrowing**: Employs a response interceptor to rigidly validate outbound domain responses. This prevents internal schema drift or accidental leakage of sensitive DB fields to the public network, forcing a `500 Internal Server Error` instead of breaching contracts. + +--- + ## Configuration ### CORS Allowlist diff --git a/bodySize_fail.txt b/bodySize_fail.txt new file mode 100644 index 00000000..99d187fb Binary files /dev/null and b/bodySize_fail.txt differ diff --git a/bodySize_fail_utf8.txt b/bodySize_fail_utf8.txt new file mode 100644 index 00000000..cdc6c9b3 --- /dev/null +++ b/bodySize_fail_utf8.txt @@ -0,0 +1,180 @@ + console.log + [dotenv@17.3.1] injecting env (0) from .env -- tip: ⚙️ suppress all logs with { quiet: true } + + at _log (node_modules/dotenv/lib/main.js:139:11) + + console.log + [dotenv@17.3.1] injecting env (0) from .env -- tip: 🛡️ auth for agents: https://vestauth.com + + at _log (node_modules/dotenv/lib/main.js:139:11) + + console.log + [dotenv@17.3.1] injecting env (0) from .env -- tip: 🔐 encrypt with Dotenvx: https://dotenvx.com + + at _log (node_modules/dotenv/lib/main.js:139:11) + +node.exe : FAIL src/__tests__ +/bodySizeLimits.test.js +At C:\Users\pc\AppData\Roamin +g\npm\npx.ps1:24 char:5 ++ & "node$exe" "$basedir +/node_modules/npm/bin/npx-cli +.js" $args ++ ~~~~~~~~~~~~~~~~~~~~~~~ +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +~~~~~~~~~~ + + CategoryInfo + : NotSpecified: (FAIL sr + c/__test...eLimits.test. + js:String) [], RemoteExc +eption + + FullyQualifiedErrorId + : NativeCommandError + + parseSize() + valid inputs + √ parses bytes (no +suffix) (4 ms) + √ parses "b" suffix +(lowercase) (1 ms) + √ parses "B" suffix +(uppercase) (1 ms) + √ parses "kb" suffix +(1 ms) + √ parses "KB" suffix +(1 ms) + √ parses "mb" suffix + √ parses "MB" suffix + √ parses "gb" suffix +(1 ms) + √ handles decimal +values (1 ms) + √ handles +surrounding whitespace (1 ms) + √ returns 0 for "0b" +(1 ms) + TypeError + √ throws for empty +string (12 ms) + √ throws for +whitespace-only (1 ms) + √ throws for number +input (1 ms) + √ throws for null (1 +ms) + √ throws for +undefined (1 ms) + √ throws for object +(2 ms) + RangeError + √ throws for unknown +unit "tb" (2 ms) + √ throws for +non-numeric value (2 ms) + √ throws for +negative value (2 ms) + DEFAULT_LIMITS + √ json is a parseable +string (1 ms) + √ urlencoded is a +parseable string (1 ms) + √ raw is a parseable +string (1 ms) + √ invoice is a +parseable string (1 ms) + jsonBodyLimit() + √ returns a +two-element handler array (1 +ms) + √ accepts a body +within the limit (42 ms) + √ rejects a body +exceeding the limit with 413 +(8 ms) + √ 413 response has +correct shape (8 ms) + isCorsOriginRejectedError() + √ returns true for +flagged error + √ returns false for +plain error + createCorsOptions() + √ allows request with +no Origin header (1 ms) + √ rejects an unlisted +origin + computeBackoff() + √ returns a number >= 0 + √ is capped at +maxDelay (1 ms) + isRetryable() + √ returns true for +ECONNRESET + √ returns true for +status 429 + √ returns true for +status 502 + √ returns true for +status 503 (1 ms) + √ returns true for +status 504 + createApp() integration + × GET /health → 200 +with status ok (19 ms) + √ POST /api/invoices +oversized body → 413 (17 +ms) + + ● createApp() +integration › GET /health +→ 200 with status ok + + expect(received).toBe(exp +ected) // Object.is equality + + Expected: "ok" + Received: undefined + +   198 | + const res += await r +equest(app).ge +t('/health')[ +33m; +  199 | exp +ect(res.status)[33 +m.toBe(200)[3 +3m; + +> +200 | expect(res[33 +m.body.status) +.toBe('ok'[39 +m); +  | + +^ +  201 | +}); +  202 | +  203 | +it('POST /api/invoices +oversized body → +413', +async () +=> { + + at Object.toBe (src/__t +ests__/bodySizeLimits.test.js +:200:29) + +Test Suites: 1 failed, 1 +total +Tests: 1 failed, 40 +passed, 41 total +Snapshots: 0 total +Time: 1.154 s, +estimated 4 s +Ran all test suites matching +src/__tests__/bodySizeLimits. +test.js. diff --git a/coverage/clover.xml b/coverage/clover.xml index e20d603a..8d4348c1 100644 --- a/coverage/clover.xml +++ b/coverage/clover.xml @@ -1,91 +1,439 @@ -<<<<<<< HEAD - - - + + + - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - + + + + + + + + + + + - - - - - - + + + + + + + + + + + + + + + + + + + + + - - - - - - - -======= - - - - - - - - - - - - - - + + + + + + + - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - + + + - - - - - - - - - - - - - - - - ->>>>>>> main + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/coverage/coverage-final.json b/coverage/coverage-final.json index 277f214a..eae3ccd9 100644 --- a/coverage/coverage-final.json +++ b/coverage/coverage-final.json @@ -1,8 +1,21 @@ -<<<<<<< HEAD -{"C:\\Users\\user\\Desktop\\works\\liquifact\\src\\app.js": {"path":"C:\\Users\\user\\Desktop\\works\\liquifact\\src\\app.js","statementMap":{"0":{"start":{"line":1,"column":16},"end":{"line":1,"column":34}},"1":{"start":{"line":2,"column":13},"end":{"line":2,"column":28}},"2":{"start":{"line":3,"column":23},"end":{"line":3,"column":56}},"3":{"start":{"line":5,"column":12},"end":{"line":5,"column":21}},"4":{"start":{"line":7,"column":0},"end":{"line":7,"column":16}},"5":{"start":{"line":8,"column":0},"end":{"line":8,"column":24}},"6":{"start":{"line":11,"column":0},"end":{"line":16,"column":3}},"7":{"start":{"line":12,"column":2},"end":{"line":15,"column":6}},"8":{"start":{"line":19,"column":0},"end":{"line":29,"column":3}},"9":{"start":{"line":20,"column":2},"end":{"line":28,"column":6}},"10":{"start":{"line":32,"column":0},"end":{"line":34,"column":3}},"11":{"start":{"line":33,"column":2},"end":{"line":33,"column":82}},"12":{"start":{"line":36,"column":0},"end":{"line":41,"column":3}},"13":{"start":{"line":37,"column":2},"end":{"line":40,"column":5}},"14":{"start":{"line":44,"column":0},"end":{"line":50,"column":3}},"15":{"start":{"line":45,"column":24},"end":{"line":45,"column":34}},"16":{"start":{"line":46,"column":2},"end":{"line":49,"column":5}},"17":{"start":{"line":53,"column":0},"end":{"line":56,"column":3}},"18":{"start":{"line":54,"column":14},"end":{"line":54,"column":42}},"19":{"start":{"line":55,"column":2},"end":{"line":55,"column":12}},"20":{"start":{"line":59,"column":0},"end":{"line":64,"column":3}},"21":{"start":{"line":60,"column":2},"end":{"line":63,"column":5}},"22":{"start":{"line":67,"column":0},"end":{"line":75,"column":3}},"23":{"start":{"line":68,"column":2},"end":{"line":68,"column":21}},"24":{"start":{"line":69,"column":17},"end":{"line":69,"column":34}},"25":{"start":{"line":70,"column":2},"end":{"line":74,"column":5}},"26":{"start":{"line":77,"column":0},"end":{"line":77,"column":21}}},"fnMap":{"0":{"name":"(anonymous_0)","decl":{"start":{"line":11,"column":19},"end":{"line":11,"column":20}},"loc":{"start":{"line":11,"column":33},"end":{"line":16,"column":1}},"line":11},"1":{"name":"(anonymous_1)","decl":{"start":{"line":19,"column":16},"end":{"line":19,"column":17}},"loc":{"start":{"line":19,"column":30},"end":{"line":29,"column":1}},"line":19},"2":{"name":"(anonymous_2)","decl":{"start":{"line":32,"column":25},"end":{"line":32,"column":26}},"loc":{"start":{"line":32,"column":39},"end":{"line":34,"column":1}},"line":32},"3":{"name":"(anonymous_3)","decl":{"start":{"line":36,"column":26},"end":{"line":36,"column":27}},"loc":{"start":{"line":36,"column":40},"end":{"line":41,"column":1}},"line":36},"4":{"name":"(anonymous_4)","decl":{"start":{"line":44,"column":34},"end":{"line":44,"column":35}},"loc":{"start":{"line":44,"column":48},"end":{"line":50,"column":1}},"line":44},"5":{"name":"(anonymous_5)","decl":{"start":{"line":53,"column":24},"end":{"line":53,"column":25}},"loc":{"start":{"line":53,"column":44},"end":{"line":56,"column":1}},"line":53},"6":{"name":"(anonymous_6)","decl":{"start":{"line":59,"column":8},"end":{"line":59,"column":9}},"loc":{"start":{"line":59,"column":22},"end":{"line":64,"column":1}},"line":59},"7":{"name":"(anonymous_7)","decl":{"start":{"line":67,"column":8},"end":{"line":67,"column":9}},"loc":{"start":{"line":67,"column":34},"end":{"line":75,"column":1}},"line":67}},"branchMap":{"0":{"loc":{"start":{"line":69,"column":17},"end":{"line":69,"column":34}},"type":"binary-expr","locations":[{"start":{"line":69,"column":17},"end":{"line":69,"column":27}},{"start":{"line":69,"column":31},"end":{"line":69,"column":34}}],"line":69},"1":{"loc":{"start":{"line":71,"column":4},"end":{"line":71,"column":58}},"type":"cond-expr","locations":[{"start":{"line":71,"column":21},"end":{"line":71,"column":44}},{"start":{"line":71,"column":47},"end":{"line":71,"column":58}}],"line":71},"2":{"loc":{"start":{"line":72,"column":4},"end":{"line":72,"column":65}},"type":"cond-expr","locations":[{"start":{"line":72,"column":21},"end":{"line":72,"column":37}},{"start":{"line":72,"column":40},"end":{"line":72,"column":65}}],"line":72},"3":{"loc":{"start":{"line":72,"column":40},"end":{"line":72,"column":65}},"type":"binary-expr","locations":[{"start":{"line":72,"column":40},"end":{"line":72,"column":48}},{"start":{"line":72,"column":52},"end":{"line":72,"column":65}}],"line":72},"4":{"loc":{"start":{"line":73,"column":4},"end":{"line":73,"column":61}},"type":"cond-expr","locations":[{"start":{"line":73,"column":45},"end":{"line":73,"column":54}},{"start":{"line":73,"column":57},"end":{"line":73,"column":61}}],"line":73}},"s":{"0":1,"1":1,"2":1,"3":1,"4":1,"5":1,"6":1,"7":1,"8":1,"9":1,"10":1,"11":1,"12":1,"13":1,"14":1,"15":1,"16":1,"17":1,"18":2,"19":2,"20":1,"21":1,"22":1,"23":3,"24":3,"25":3,"26":1},"f":{"0":1,"1":1,"2":1,"3":1,"4":1,"5":2,"6":1,"7":3},"b":{"0":[3,2],"1":[2,1],"2":[2,1],"3":[1,1],"4":[2,1]},"_coverageSchema":"1a1c01bbd47fc00a2c39e90264f33305004495a9","hash":"4913bde456eada0a8a5e52f600d0cffcf4dde103"} -,"C:\\Users\\user\\Desktop\\works\\liquifact\\src\\utils\\responseHelper.js": {"path":"C:\\Users\\user\\Desktop\\works\\liquifact\\src\\utils\\responseHelper.js","statementMap":{"0":{"start":{"line":6,"column":20},"end":{"line":6,"column":27}},"1":{"start":{"line":15,"column":16},"end":{"line":23,"column":2}},"2":{"start":{"line":15,"column":38},"end":{"line":23,"column":1}},"3":{"start":{"line":33,"column":14},"end":{"line":44,"column":2}},"4":{"start":{"line":33,"column":69},"end":{"line":44,"column":1}},"5":{"start":{"line":46,"column":0},"end":{"line":49,"column":2}}},"fnMap":{"0":{"name":"(anonymous_0)","decl":{"start":{"line":15,"column":16},"end":{"line":15,"column":17}},"loc":{"start":{"line":15,"column":38},"end":{"line":23,"column":1}},"line":15},"1":{"name":"(anonymous_1)","decl":{"start":{"line":33,"column":14},"end":{"line":33,"column":15}},"loc":{"start":{"line":33,"column":69},"end":{"line":44,"column":1}},"line":33}},"branchMap":{"0":{"loc":{"start":{"line":15,"column":23},"end":{"line":15,"column":32}},"type":"default-arg","locations":[{"start":{"line":15,"column":30},"end":{"line":15,"column":32}}],"line":15},"1":{"loc":{"start":{"line":33,"column":24},"end":{"line":33,"column":47}},"type":"default-arg","locations":[{"start":{"line":33,"column":31},"end":{"line":33,"column":47}}],"line":33},"2":{"loc":{"start":{"line":33,"column":49},"end":{"line":33,"column":63}},"type":"default-arg","locations":[{"start":{"line":33,"column":59},"end":{"line":33,"column":63}}],"line":33}},"s":{"0":1,"1":1,"2":7,"3":1,"4":6,"5":1},"f":{"0":7,"1":6},"b":{"0":[3],"1":[1],"2":[2]},"_coverageSchema":"1a1c01bbd47fc00a2c39e90264f33305004495a9","hash":"b87ce1ab915f57f5a8f312dd8084e00707f54e04"} -======= -{"/Users/victor/Desktop/Liquifact-backend/src/services/soroban.js": {"path":"/Users/victor/Desktop/Liquifact-backend/src/services/soroban.js","statementMap":{"0":{"start":{"line":1,"column":22},"end":{"line":1,"column":47}},"1":{"start":{"line":10,"column":28},"end":{"line":16,"column":3}},"2":{"start":{"line":18,"column":23},"end":{"line":18,"column":58}},"3":{"start":{"line":19,"column":2},"end":{"line":19,"column":67}},"4":{"start":{"line":19,"column":39},"end":{"line":19,"column":65}},"5":{"start":{"line":30,"column":25},"end":{"line":35,"column":3}},"6":{"start":{"line":37,"column":2},"end":{"line":37,"column":75}},"7":{"start":{"line":40,"column":0},"end":{"line":43,"column":2}}},"fnMap":{"0":{"name":"isTransientError","decl":{"start":{"line":9,"column":9},"end":{"line":9,"column":25}},"loc":{"start":{"line":9,"column":33},"end":{"line":20,"column":1}},"line":9},"1":{"name":"(anonymous_1)","decl":{"start":{"line":19,"column":32},"end":{"line":19,"column":33}},"loc":{"start":{"line":19,"column":39},"end":{"line":19,"column":65}},"line":19},"2":{"name":"callSorobanContract","decl":{"start":{"line":29,"column":15},"end":{"line":29,"column":34}},"loc":{"start":{"line":29,"column":70},"end":{"line":38,"column":1}},"line":29}},"branchMap":{"0":{"loc":{"start":{"line":18,"column":24},"end":{"line":18,"column":43}},"type":"binary-expr","locations":[{"start":{"line":18,"column":24},"end":{"line":18,"column":37}},{"start":{"line":18,"column":41},"end":{"line":18,"column":43}}],"line":18},"1":{"loc":{"start":{"line":29,"column":51},"end":{"line":29,"column":68}},"type":"default-arg","locations":[{"start":{"line":29,"column":66},"end":{"line":29,"column":68}}],"line":29}},"s":{"0":1,"1":8,"2":8,"3":8,"4":53,"5":3,"6":3,"7":1},"f":{"0":8,"1":53,"2":3},"b":{"0":[8,0],"1":[2]},"_coverageSchema":"1a1c01bbd47fc00a2c39e90264f33305004495a9","hash":"567f46ecae7a61b163a581c5e3ec53a74eb93794"} -,"/Users/victor/Desktop/Liquifact-backend/src/utils/retry.js": {"path":"/Users/victor/Desktop/Liquifact-backend/src/utils/retry.js","statementMap":{"0":{"start":{"line":29,"column":26},"end":{"line":29,"column":28}},"1":{"start":{"line":30,"column":24},"end":{"line":30,"column":29}},"2":{"start":{"line":31,"column":29},"end":{"line":31,"column":34}},"3":{"start":{"line":38,"column":6},"end":{"line":38,"column":13}},"4":{"start":{"line":37,"column":24},"end":{"line":37,"column":28}},"5":{"start":{"line":41,"column":2},"end":{"line":41,"column":66}},"6":{"start":{"line":42,"column":2},"end":{"line":42,"column":67}},"7":{"start":{"line":43,"column":2},"end":{"line":43,"column":60}},"8":{"start":{"line":45,"column":16},"end":{"line":45,"column":17}},"9":{"start":{"line":47,"column":2},"end":{"line":65,"column":3}},"10":{"start":{"line":48,"column":4},"end":{"line":64,"column":5}},"11":{"start":{"line":49,"column":6},"end":{"line":49,"column":31}},"12":{"start":{"line":51,"column":6},"end":{"line":53,"column":7}},"13":{"start":{"line":52,"column":8},"end":{"line":52,"column":20}},"14":{"start":{"line":56,"column":31},"end":{"line":56,"column":63}},"15":{"start":{"line":57,"column":20},"end":{"line":57,"column":56}},"16":{"start":{"line":60,"column":28},"end":{"line":60,"column":63}},"17":{"start":{"line":62,"column":6},"end":{"line":62,"column":16}},"18":{"start":{"line":63,"column":6},"end":{"line":63,"column":73}},"19":{"start":{"line":63,"column":37},"end":{"line":63,"column":71}},"20":{"start":{"line":68,"column":0},"end":{"line":70,"column":2}}},"fnMap":{"0":{"name":"withRetry","decl":{"start":{"line":27,"column":15},"end":{"line":27,"column":24}},"loc":{"start":{"line":27,"column":50},"end":{"line":66,"column":1}},"line":27},"1":{"name":"(anonymous_1)","decl":{"start":{"line":37,"column":18},"end":{"line":37,"column":19}},"loc":{"start":{"line":37,"column":24},"end":{"line":37,"column":28}},"line":37},"2":{"name":"(anonymous_2)","decl":{"start":{"line":63,"column":24},"end":{"line":63,"column":25}},"loc":{"start":{"line":63,"column":37},"end":{"line":63,"column":71}},"line":63}},"branchMap":{"0":{"loc":{"start":{"line":27,"column":36},"end":{"line":27,"column":48}},"type":"default-arg","locations":[{"start":{"line":27,"column":46},"end":{"line":27,"column":48}}],"line":27},"1":{"loc":{"start":{"line":34,"column":4},"end":{"line":34,"column":18}},"type":"default-arg","locations":[{"start":{"line":34,"column":17},"end":{"line":34,"column":18}}],"line":34},"2":{"loc":{"start":{"line":35,"column":4},"end":{"line":35,"column":19}},"type":"default-arg","locations":[{"start":{"line":35,"column":16},"end":{"line":35,"column":19}}],"line":35},"3":{"loc":{"start":{"line":36,"column":4},"end":{"line":36,"column":20}},"type":"default-arg","locations":[{"start":{"line":36,"column":15},"end":{"line":36,"column":20}}],"line":36},"4":{"loc":{"start":{"line":37,"column":4},"end":{"line":37,"column":28}},"type":"default-arg","locations":[{"start":{"line":37,"column":18},"end":{"line":37,"column":28}}],"line":37},"5":{"loc":{"start":{"line":51,"column":6},"end":{"line":53,"column":7}},"type":"if","locations":[{"start":{"line":51,"column":6},"end":{"line":53,"column":7}},{"start":{},"end":{}}],"line":51},"6":{"loc":{"start":{"line":51,"column":10},"end":{"line":51,"column":54}},"type":"binary-expr","locations":[{"start":{"line":51,"column":10},"end":{"line":51,"column":31}},{"start":{"line":51,"column":35},"end":{"line":51,"column":54}}],"line":51}},"s":{"0":9,"1":9,"2":9,"3":9,"4":15,"5":9,"6":9,"7":9,"8":9,"9":9,"10":25,"11":25,"12":21,"13":5,"14":16,"15":16,"16":16,"17":16,"18":16,"19":16,"20":2},"f":{"0":9,"1":15,"2":16},"b":{"0":[1],"1":[1],"2":[1],"3":[5],"4":[5],"5":[5,16],"6":[21,18]},"_coverageSchema":"1a1c01bbd47fc00a2c39e90264f33305004495a9","hash":"117addf2b650bf8e8f2947fd0dc37f59480b0548"} ->>>>>>> main +{"C:\\Users\\pc\\Documents\\waves\\Liquifact-backend\\src\\app.js": {"path":"C:\\Users\\pc\\Documents\\waves\\Liquifact-backend\\src\\app.js","statementMap":{"0":{"start":{"line":3,"column":0},"end":{"line":3,"column":27}},"1":{"start":{"line":4,"column":16},"end":{"line":4,"column":34}},"2":{"start":{"line":5,"column":13},"end":{"line":5,"column":28}},"3":{"start":{"line":7,"column":44},"end":{"line":7,"column":77}},"4":{"start":{"line":8,"column":30},"end":{"line":8,"column":58}},"5":{"start":{"line":9,"column":46},"end":{"line":9,"column":78}},"6":{"start":{"line":10,"column":16},"end":{"line":10,"column":47}},"7":{"start":{"line":11,"column":37},"end":{"line":11,"column":69}},"8":{"start":{"line":12,"column":57},"end":{"line":12,"column":81}},"9":{"start":{"line":18,"column":4},"end":{"line":18,"column":42}},"10":{"start":{"line":19,"column":39},"end":{"line":19,"column":68}},"11":{"start":{"line":20,"column":23},"end":{"line":20,"column":60}},"12":{"start":{"line":21,"column":20},"end":{"line":21,"column":53}},"13":{"start":{"line":23,"column":21},"end":{"line":23,"column":52}},"14":{"start":{"line":24,"column":17},"end":{"line":24,"column":45}},"15":{"start":{"line":25,"column":21},"end":{"line":25,"column":57}},"16":{"start":{"line":26,"column":32},"end":{"line":26,"column":61}},"17":{"start":{"line":29,"column":14},"end":{"line":29,"column":23}},"18":{"start":{"line":30,"column":17},"end":{"line":30,"column":19}},"19":{"start":{"line":33,"column":2},"end":{"line":33,"column":38}},"20":{"start":{"line":34,"column":2},"end":{"line":34,"column":37}},"21":{"start":{"line":35,"column":2},"end":{"line":35,"column":30}},"22":{"start":{"line":36,"column":2},"end":{"line":36,"column":36}},"23":{"start":{"line":37,"column":2},"end":{"line":37,"column":25}},"24":{"start":{"line":42,"column":2},"end":{"line":48,"column":5}},"25":{"start":{"line":43,"column":4},"end":{"line":47,"column":8}},"26":{"start":{"line":50,"column":2},"end":{"line":60,"column":5}},"27":{"start":{"line":51,"column":4},"end":{"line":59,"column":8}},"28":{"start":{"line":65,"column":2},"end":{"line":82,"column":6}},"29":{"start":{"line":66,"column":14},"end":{"line":66,"column":51}},"30":{"start":{"line":67,"column":4},"end":{"line":74,"column":5}},"31":{"start":{"line":68,"column":6},"end":{"line":73,"column":9}},"32":{"start":{"line":77,"column":22},"end":{"line":77,"column":73}},"33":{"start":{"line":78,"column":27},"end":{"line":78,"column":62}},"34":{"start":{"line":79,"column":22},"end":{"line":79,"column":84}},"35":{"start":{"line":79,"column":71},"end":{"line":79,"column":83}},"36":{"start":{"line":81,"column":4},"end":{"line":81,"column":108}},"37":{"start":{"line":84,"column":2},"end":{"line":104,"column":4}},"38":{"start":{"line":91,"column":35},"end":{"line":91,"column":43}},"39":{"start":{"line":92,"column":25},"end":{"line":99,"column":7}},"40":{"start":{"line":101,"column":6},"end":{"line":101,"column":32}},"41":{"start":{"line":102,"column":6},"end":{"line":102,"column":55}},"42":{"start":{"line":106,"column":2},"end":{"line":119,"column":5}},"43":{"start":{"line":107,"column":19},"end":{"line":107,"column":29}},"44":{"start":{"line":108,"column":16},"end":{"line":108,"column":60}},"45":{"start":{"line":108,"column":40},"end":{"line":108,"column":59}},"46":{"start":{"line":109,"column":4},"end":{"line":116,"column":5}},"47":{"start":{"line":110,"column":6},"end":{"line":115,"column":9}},"48":{"start":{"line":117,"column":4},"end":{"line":117,"column":55}},"49":{"start":{"line":118,"column":4},"end":{"line":118,"column":44}},"50":{"start":{"line":124,"column":2},"end":{"line":128,"column":6}},"51":{"start":{"line":125,"column":26},"end":{"line":125,"column":36}},"52":{"start":{"line":126,"column":17},"end":{"line":126,"column":109}},"53":{"start":{"line":126,"column":56},"end":{"line":126,"column":107}},"54":{"start":{"line":127,"column":4},"end":{"line":127,"column":116}},"55":{"start":{"line":133,"column":2},"end":{"line":135,"column":5}},"56":{"start":{"line":134,"column":4},"end":{"line":134,"column":39}},"57":{"start":{"line":137,"column":2},"end":{"line":139,"column":5}},"58":{"start":{"line":138,"column":4},"end":{"line":138,"column":27}},"59":{"start":{"line":142,"column":2},"end":{"line":149,"column":5}},"60":{"start":{"line":143,"column":4},"end":{"line":148,"column":8}},"61":{"start":{"line":151,"column":2},"end":{"line":154,"column":5}},"62":{"start":{"line":152,"column":4},"end":{"line":152,"column":92}},"63":{"start":{"line":152,"column":40},"end":{"line":152,"column":92}},"64":{"start":{"line":153,"column":4},"end":{"line":153,"column":14}},"65":{"start":{"line":156,"column":2},"end":{"line":156,"column":34}},"66":{"start":{"line":157,"column":2},"end":{"line":157,"column":24}},"67":{"start":{"line":160,"column":2},"end":{"line":160,"column":44}},"68":{"start":{"line":160,"column":27},"end":{"line":160,"column":41}},"69":{"start":{"line":162,"column":2},"end":{"line":162,"column":13}},"70":{"start":{"line":165,"column":19},"end":{"line":165,"column":30}},"71":{"start":{"line":166,"column":0},"end":{"line":166,"column":28}},"72":{"start":{"line":167,"column":0},"end":{"line":167,"column":37}}},"fnMap":{"0":{"name":"createApp","decl":{"start":{"line":28,"column":9},"end":{"line":28,"column":18}},"loc":{"start":{"line":28,"column":21},"end":{"line":163,"column":1}},"line":28},"1":{"name":"(anonymous_1)","decl":{"start":{"line":42,"column":21},"end":{"line":42,"column":22}},"loc":{"start":{"line":42,"column":35},"end":{"line":48,"column":3}},"line":42},"2":{"name":"(anonymous_2)","decl":{"start":{"line":50,"column":18},"end":{"line":50,"column":19}},"loc":{"start":{"line":50,"column":32},"end":{"line":60,"column":3}},"line":50},"3":{"name":"(anonymous_3)","decl":{"start":{"line":65,"column":93},"end":{"line":65,"column":94}},"loc":{"start":{"line":65,"column":113},"end":{"line":82,"column":3}},"line":65},"4":{"name":"(anonymous_4)","decl":{"start":{"line":79,"column":66},"end":{"line":79,"column":67}},"loc":{"start":{"line":79,"column":71},"end":{"line":79,"column":83}},"line":79},"5":{"name":"(anonymous_5)","decl":{"start":{"line":90,"column":4},"end":{"line":90,"column":5}},"loc":{"start":{"line":90,"column":18},"end":{"line":103,"column":5}},"line":90},"6":{"name":"(anonymous_6)","decl":{"start":{"line":106,"column":71},"end":{"line":106,"column":72}},"loc":{"start":{"line":106,"column":85},"end":{"line":119,"column":3}},"line":106},"7":{"name":"(anonymous_7)","decl":{"start":{"line":108,"column":35},"end":{"line":108,"column":36}},"loc":{"start":{"line":108,"column":40},"end":{"line":108,"column":59}},"line":108},"8":{"name":"(anonymous_8)","decl":{"start":{"line":124,"column":68},"end":{"line":124,"column":69}},"loc":{"start":{"line":124,"column":88},"end":{"line":128,"column":3}},"line":124},"9":{"name":"(anonymous_9)","decl":{"start":{"line":126,"column":43},"end":{"line":126,"column":44}},"loc":{"start":{"line":126,"column":56},"end":{"line":126,"column":107}},"line":126},"10":{"name":"(anonymous_10)","decl":{"start":{"line":133,"column":26},"end":{"line":133,"column":27}},"loc":{"start":{"line":133,"column":46},"end":{"line":135,"column":3}},"line":133},"11":{"name":"(anonymous_11)","decl":{"start":{"line":137,"column":23},"end":{"line":137,"column":24}},"loc":{"start":{"line":137,"column":37},"end":{"line":139,"column":3}},"line":137},"12":{"name":"(anonymous_12)","decl":{"start":{"line":142,"column":10},"end":{"line":142,"column":11}},"loc":{"start":{"line":142,"column":30},"end":{"line":149,"column":3}},"line":142},"13":{"name":"(anonymous_13)","decl":{"start":{"line":151,"column":10},"end":{"line":151,"column":11}},"loc":{"start":{"line":151,"column":35},"end":{"line":154,"column":3}},"line":151},"14":{"name":"(anonymous_14)","decl":{"start":{"line":160,"column":19},"end":{"line":160,"column":20}},"loc":{"start":{"line":160,"column":25},"end":{"line":160,"column":43}},"line":160}},"branchMap":{"0":{"loc":{"start":{"line":67,"column":4},"end":{"line":74,"column":5}},"type":"if","locations":[{"start":{"line":67,"column":4},"end":{"line":74,"column":5}},{"start":{},"end":{}}],"line":67},"1":{"loc":{"start":{"line":79,"column":22},"end":{"line":79,"column":84}},"type":"cond-expr","locations":[{"start":{"line":79,"column":39},"end":{"line":79,"column":47}},{"start":{"line":79,"column":50},"end":{"line":79,"column":84}}],"line":79},"2":{"loc":{"start":{"line":95,"column":18},"end":{"line":95,"column":39}},"type":"binary-expr","locations":[{"start":{"line":95,"column":18},"end":{"line":95,"column":26}},{"start":{"line":95,"column":30},"end":{"line":95,"column":39}}],"line":95},"3":{"loc":{"start":{"line":109,"column":4},"end":{"line":116,"column":5}},"type":"if","locations":[{"start":{"line":109,"column":4},"end":{"line":116,"column":5}},{"start":{},"end":{}}],"line":109},"4":{"loc":{"start":{"line":152,"column":4},"end":{"line":152,"column":92}},"type":"if","locations":[{"start":{"line":152,"column":4},"end":{"line":152,"column":92}},{"start":{},"end":{}}],"line":152}},"s":{"0":8,"1":8,"2":8,"3":8,"4":8,"5":8,"6":8,"7":8,"8":8,"9":8,"10":8,"11":8,"12":8,"13":8,"14":8,"15":8,"16":8,"17":19,"18":19,"19":19,"20":19,"21":19,"22":19,"23":19,"24":19,"25":10,"26":19,"27":3,"28":19,"29":12,"30":12,"31":3,"32":9,"33":8,"34":8,"35":3,"36":8,"37":19,"38":17,"39":17,"40":17,"41":17,"42":19,"43":1,"44":1,"45":1,"46":1,"47":0,"48":1,"49":1,"50":19,"51":2,"52":2,"53":2,"54":2,"55":19,"56":3,"57":19,"58":0,"59":19,"60":4,"61":19,"62":18,"63":1,"64":17,"65":19,"66":19,"67":19,"68":7,"69":19,"70":8,"71":8,"72":8},"f":{"0":19,"1":10,"2":3,"3":12,"4":3,"5":17,"6":1,"7":1,"8":2,"9":2,"10":3,"11":0,"12":4,"13":18,"14":7},"b":{"0":[3,9],"1":[0,8],"2":[17,1],"3":[0,1],"4":[1,17]},"_coverageSchema":"1a1c01bbd47fc00a2c39e90264f33305004495a9","hash":"819a0c460c68d5b19cfd091a898e2bc679362836"} +,"C:\\Users\\pc\\Documents\\waves\\Liquifact-backend\\src\\index.js": {"path":"C:\\Users\\pc\\Documents\\waves\\Liquifact-backend\\src\\index.js","statementMap":{"0":{"start":{"line":7,"column":0},"end":{"line":7,"column":27}},"1":{"start":{"line":8,"column":12},"end":{"line":8,"column":28}},"2":{"start":{"line":10,"column":13},"end":{"line":10,"column":37}},"3":{"start":{"line":20,"column":0},"end":{"line":23,"column":1}},"4":{"start":{"line":30,"column":0},"end":{"line":30,"column":21}}},"fnMap":{},"branchMap":{"0":{"loc":{"start":{"line":10,"column":13},"end":{"line":10,"column":37}},"type":"binary-expr","locations":[{"start":{"line":10,"column":13},"end":{"line":10,"column":29}},{"start":{"line":10,"column":33},"end":{"line":10,"column":37}}],"line":10},"1":{"loc":{"start":{"line":20,"column":0},"end":{"line":23,"column":1}},"type":"if","locations":[{"start":{"line":20,"column":0},"end":{"line":23,"column":1}},{"start":{},"end":{}}],"line":20}},"s":{"0":4,"1":4,"2":4,"3":4,"4":4},"f":{},"b":{"0":[4,4],"1":[0,4]},"_coverageSchema":"1a1c01bbd47fc00a2c39e90264f33305004495a9","hash":"d5892be5c04a6758cba95065a99cf6996e8c7661"} +,"C:\\Users\\pc\\Documents\\waves\\Liquifact-backend\\src\\config\\cors.js": {"path":"C:\\Users\\pc\\Documents\\waves\\Liquifact-backend\\src\\config\\cors.js","statementMap":{"0":{"start":{"line":7,"column":28},"end":{"line":13,"column":1}},"1":{"start":{"line":15,"column":31},"end":{"line":15,"column":111}},"2":{"start":{"line":22,"column":2},"end":{"line":22,"column":43}},"3":{"start":{"line":22,"column":33},"end":{"line":22,"column":43}},"4":{"start":{"line":23,"column":2},"end":{"line":30,"column":4}},"5":{"start":{"line":27,"column":20},"end":{"line":27,"column":28}},"6":{"start":{"line":37,"column":18},"end":{"line":37,"column":63}},"7":{"start":{"line":38,"column":2},"end":{"line":38,"column":41}},"8":{"start":{"line":38,"column":26},"end":{"line":38,"column":41}},"9":{"start":{"line":40,"column":2},"end":{"line":40,"column":65}},"10":{"start":{"line":40,"column":38},"end":{"line":40,"column":65}},"11":{"start":{"line":42,"column":2},"end":{"line":42,"column":12}},"12":{"start":{"line":49,"column":14},"end":{"line":49,"column":47}},"13":{"start":{"line":50,"column":2},"end":{"line":50,"column":34}},"14":{"start":{"line":51,"column":2},"end":{"line":51,"column":19}},"15":{"start":{"line":52,"column":2},"end":{"line":52,"column":13}},"16":{"start":{"line":59,"column":2},"end":{"line":59,"column":58}},"17":{"start":{"line":66,"column":20},"end":{"line":66,"column":49}},"18":{"start":{"line":68,"column":2},"end":{"line":81,"column":4}},"19":{"start":{"line":70,"column":6},"end":{"line":72,"column":7}},"20":{"start":{"line":71,"column":8},"end":{"line":71,"column":36}},"21":{"start":{"line":74,"column":6},"end":{"line":76,"column":7}},"22":{"start":{"line":75,"column":8},"end":{"line":75,"column":36}},"23":{"start":{"line":78,"column":6},"end":{"line":78,"column":56}},"24":{"start":{"line":84,"column":0},"end":{"line":95,"column":2}},"25":{"start":{"line":89,"column":39},"end":{"line":89,"column":58}},"26":{"start":{"line":93,"column":29},"end":{"line":93,"column":58}}},"fnMap":{"0":{"name":"parseAllowedOrigins","decl":{"start":{"line":21,"column":9},"end":{"line":21,"column":28}},"loc":{"start":{"line":21,"column":34},"end":{"line":31,"column":1}},"line":21},"1":{"name":"(anonymous_1)","decl":{"start":{"line":27,"column":13},"end":{"line":27,"column":14}},"loc":{"start":{"line":27,"column":20},"end":{"line":27,"column":28}},"line":27},"2":{"name":"getAllowedOriginsFromEnv","decl":{"start":{"line":36,"column":9},"end":{"line":36,"column":33}},"loc":{"start":{"line":36,"column":53},"end":{"line":43,"column":1}},"line":36},"3":{"name":"createCorsRejectionError","decl":{"start":{"line":48,"column":9},"end":{"line":48,"column":33}},"loc":{"start":{"line":48,"column":36},"end":{"line":53,"column":1}},"line":48},"4":{"name":"isCorsOriginRejectedError","decl":{"start":{"line":58,"column":9},"end":{"line":58,"column":34}},"loc":{"start":{"line":58,"column":40},"end":{"line":60,"column":1}},"line":58},"5":{"name":"createCorsOptions","decl":{"start":{"line":65,"column":9},"end":{"line":65,"column":26}},"loc":{"start":{"line":65,"column":46},"end":{"line":82,"column":1}},"line":65},"6":{"name":"(anonymous_6)","decl":{"start":{"line":69,"column":4},"end":{"line":69,"column":5}},"loc":{"start":{"line":69,"column":29},"end":{"line":79,"column":5}},"line":69},"7":{"name":"(anonymous_7)","decl":{"start":{"line":89,"column":33},"end":{"line":89,"column":34}},"loc":{"start":{"line":89,"column":39},"end":{"line":89,"column":58}},"line":89},"8":{"name":"(anonymous_8)","decl":{"start":{"line":93,"column":20},"end":{"line":93,"column":21}},"loc":{"start":{"line":93,"column":29},"end":{"line":93,"column":58}},"line":93}},"branchMap":{"0":{"loc":{"start":{"line":22,"column":2},"end":{"line":22,"column":43}},"type":"if","locations":[{"start":{"line":22,"column":2},"end":{"line":22,"column":43}},{"start":{},"end":{}}],"line":22},"1":{"loc":{"start":{"line":22,"column":6},"end":{"line":22,"column":31}},"type":"binary-expr","locations":[{"start":{"line":22,"column":6},"end":{"line":22,"column":10}},{"start":{"line":22,"column":14},"end":{"line":22,"column":31}}],"line":22},"2":{"loc":{"start":{"line":36,"column":34},"end":{"line":36,"column":51}},"type":"default-arg","locations":[{"start":{"line":36,"column":40},"end":{"line":36,"column":51}}],"line":36},"3":{"loc":{"start":{"line":38,"column":2},"end":{"line":38,"column":41}},"type":"if","locations":[{"start":{"line":38,"column":2},"end":{"line":38,"column":41}},{"start":{},"end":{}}],"line":38},"4":{"loc":{"start":{"line":40,"column":2},"end":{"line":40,"column":65}},"type":"if","locations":[{"start":{"line":40,"column":2},"end":{"line":40,"column":65}},{"start":{},"end":{}}],"line":40},"5":{"loc":{"start":{"line":59,"column":9},"end":{"line":59,"column":57}},"type":"binary-expr","locations":[{"start":{"line":59,"column":9},"end":{"line":59,"column":20}},{"start":{"line":59,"column":24},"end":{"line":59,"column":57}}],"line":59},"6":{"loc":{"start":{"line":65,"column":27},"end":{"line":65,"column":44}},"type":"default-arg","locations":[{"start":{"line":65,"column":33},"end":{"line":65,"column":44}}],"line":65},"7":{"loc":{"start":{"line":70,"column":6},"end":{"line":72,"column":7}},"type":"if","locations":[{"start":{"line":70,"column":6},"end":{"line":72,"column":7}},{"start":{},"end":{}}],"line":70},"8":{"loc":{"start":{"line":74,"column":6},"end":{"line":76,"column":7}},"type":"if","locations":[{"start":{"line":74,"column":6},"end":{"line":76,"column":7}},{"start":{},"end":{}}],"line":74},"9":{"loc":{"start":{"line":74,"column":10},"end":{"line":74,"column":60}},"type":"binary-expr","locations":[{"start":{"line":74,"column":10},"end":{"line":74,"column":30}},{"start":{"line":74,"column":34},"end":{"line":74,"column":60}}],"line":74}},"s":{"0":9,"1":9,"2":27,"3":22,"4":5,"5":11,"6":24,"7":24,"8":3,"9":21,"10":1,"11":20,"12":3,"13":3,"14":3,"15":3,"16":22,"17":21,"18":21,"19":68,"20":66,"21":2,"22":0,"23":2,"24":9,"25":1,"26":0},"f":{"0":27,"1":11,"2":24,"3":3,"4":22,"5":21,"6":68,"7":1,"8":0},"b":{"0":[22,5],"1":[27,5],"2":[0],"3":[3,21],"4":[1,20],"5":[22,22],"6":[19],"7":[66,2],"8":[0,2],"9":[2,1]},"_coverageSchema":"1a1c01bbd47fc00a2c39e90264f33305004495a9","hash":"238437cb54c56deed02c1928cc98a9c57638b25d"} +,"C:\\Users\\pc\\Documents\\waves\\Liquifact-backend\\src\\errors\\AppError.js": {"path":"C:\\Users\\pc\\Documents\\waves\\Liquifact-backend\\src\\errors\\AppError.js","statementMap":{"0":{"start":{"line":15,"column":4},"end":{"line":15,"column":17}},"1":{"start":{"line":16,"column":4},"end":{"line":16,"column":38}},"2":{"start":{"line":17,"column":4},"end":{"line":17,"column":38}},"3":{"start":{"line":18,"column":4},"end":{"line":18,"column":23}},"4":{"start":{"line":19,"column":4},"end":{"line":19,"column":32}},"5":{"start":{"line":20,"column":4},"end":{"line":20,"column":25}},"6":{"start":{"line":21,"column":4},"end":{"line":21,"column":29}},"7":{"start":{"line":24,"column":4},"end":{"line":24,"column":52}},"8":{"start":{"line":28,"column":0},"end":{"line":28,"column":26}}},"fnMap":{"0":{"name":"(anonymous_0)","decl":{"start":{"line":14,"column":2},"end":{"line":14,"column":3}},"loc":{"start":{"line":14,"column":57},"end":{"line":25,"column":3}},"line":14}},"branchMap":{"0":{"loc":{"start":{"line":17,"column":16},"end":{"line":17,"column":37}},"type":"binary-expr","locations":[{"start":{"line":17,"column":16},"end":{"line":17,"column":20}},{"start":{"line":17,"column":24},"end":{"line":17,"column":37}}],"line":17},"1":{"loc":{"start":{"line":19,"column":18},"end":{"line":19,"column":31}},"type":"binary-expr","locations":[{"start":{"line":19,"column":18},"end":{"line":19,"column":24}},{"start":{"line":19,"column":28},"end":{"line":19,"column":31}}],"line":19}},"s":{"0":14,"1":14,"2":14,"3":14,"4":14,"5":14,"6":14,"7":14,"8":13},"f":{"0":14},"b":{"0":[14,2],"1":[14,2]},"_coverageSchema":"1a1c01bbd47fc00a2c39e90264f33305004495a9","hash":"45af0d4bc28088f7122c3a9eee2544d33610feb6"} +,"C:\\Users\\pc\\Documents\\waves\\Liquifact-backend\\src\\middleware\\auth.js": {"path":"C:\\Users\\pc\\Documents\\waves\\Liquifact-backend\\src\\middleware\\auth.js","statementMap":{"0":{"start":{"line":7,"column":12},"end":{"line":7,"column":35}},"1":{"start":{"line":19,"column":26},"end":{"line":47,"column":1}},"2":{"start":{"line":20,"column":21},"end":{"line":20,"column":49}},"3":{"start":{"line":22,"column":2},"end":{"line":24,"column":3}},"4":{"start":{"line":23,"column":4},"end":{"line":23,"column":79}},"5":{"start":{"line":26,"column":21},"end":{"line":26,"column":42}},"6":{"start":{"line":28,"column":2},"end":{"line":30,"column":3}},"7":{"start":{"line":29,"column":4},"end":{"line":29,"column":109}},"8":{"start":{"line":32,"column":16},"end":{"line":32,"column":29}},"9":{"start":{"line":33,"column":17},"end":{"line":33,"column":56}},"10":{"start":{"line":35,"column":2},"end":{"line":46,"column":5}},"11":{"start":{"line":36,"column":4},"end":{"line":41,"column":5}},"12":{"start":{"line":37,"column":6},"end":{"line":39,"column":7}},"13":{"start":{"line":38,"column":8},"end":{"line":38,"column":68}},"14":{"start":{"line":40,"column":6},"end":{"line":40,"column":62}},"15":{"start":{"line":44,"column":4},"end":{"line":44,"column":23}},"16":{"start":{"line":45,"column":4},"end":{"line":45,"column":11}},"17":{"start":{"line":49,"column":0},"end":{"line":49,"column":39}}},"fnMap":{"0":{"name":"(anonymous_0)","decl":{"start":{"line":19,"column":26},"end":{"line":19,"column":27}},"loc":{"start":{"line":19,"column":46},"end":{"line":47,"column":1}},"line":19},"1":{"name":"(anonymous_1)","decl":{"start":{"line":35,"column":28},"end":{"line":35,"column":29}},"loc":{"start":{"line":35,"column":46},"end":{"line":46,"column":3}},"line":35}},"branchMap":{"0":{"loc":{"start":{"line":22,"column":2},"end":{"line":24,"column":3}},"type":"if","locations":[{"start":{"line":22,"column":2},"end":{"line":24,"column":3}},{"start":{},"end":{}}],"line":22},"1":{"loc":{"start":{"line":28,"column":2},"end":{"line":30,"column":3}},"type":"if","locations":[{"start":{"line":28,"column":2},"end":{"line":30,"column":3}},{"start":{},"end":{}}],"line":28},"2":{"loc":{"start":{"line":28,"column":6},"end":{"line":28,"column":59}},"type":"binary-expr","locations":[{"start":{"line":28,"column":6},"end":{"line":28,"column":29}},{"start":{"line":28,"column":33},"end":{"line":28,"column":59}}],"line":28},"3":{"loc":{"start":{"line":33,"column":17},"end":{"line":33,"column":56}},"type":"binary-expr","locations":[{"start":{"line":33,"column":17},"end":{"line":33,"column":39}},{"start":{"line":33,"column":43},"end":{"line":33,"column":56}}],"line":33},"4":{"loc":{"start":{"line":36,"column":4},"end":{"line":41,"column":5}},"type":"if","locations":[{"start":{"line":36,"column":4},"end":{"line":41,"column":5}},{"start":{},"end":{}}],"line":36},"5":{"loc":{"start":{"line":37,"column":6},"end":{"line":39,"column":7}},"type":"if","locations":[{"start":{"line":37,"column":6},"end":{"line":39,"column":7}},{"start":{},"end":{}}],"line":37}},"s":{"0":8,"1":8,"2":28,"3":28,"4":2,"5":26,"6":26,"7":2,"8":24,"9":24,"10":24,"11":24,"12":2,"13":1,"14":1,"15":22,"16":22,"17":8},"f":{"0":28,"1":24},"b":{"0":[2,26],"1":[2,24],"2":[26,25],"3":[24,24],"4":[2,22],"5":[1,1]},"_coverageSchema":"1a1c01bbd47fc00a2c39e90264f33305004495a9","hash":"c2724f27bcbe258d3c8d22334d7b5316a719dc68"} +,"C:\\Users\\pc\\Documents\\waves\\Liquifact-backend\\src\\middleware\\bodySizeLimits.js": {"path":"C:\\Users\\pc\\Documents\\waves\\Liquifact-backend\\src\\middleware\\bodySizeLimits.js","statementMap":{"0":{"start":{"line":13,"column":16},"end":{"line":13,"column":34}},"1":{"start":{"line":25,"column":23},"end":{"line":30,"column":1}},"2":{"start":{"line":51,"column":2},"end":{"line":53,"column":3}},"3":{"start":{"line":52,"column":4},"end":{"line":52,"column":62}},"4":{"start":{"line":55,"column":16},"end":{"line":55,"column":74}},"5":{"start":{"line":56,"column":2},"end":{"line":58,"column":3}},"6":{"start":{"line":57,"column":4},"end":{"line":57,"column":67}},"7":{"start":{"line":60,"column":16},"end":{"line":60,"column":36}},"8":{"start":{"line":61,"column":15},"end":{"line":61,"column":46}},"9":{"start":{"line":63,"column":22},"end":{"line":63,"column":70}},"10":{"start":{"line":64,"column":2},"end":{"line":64,"column":47}},"11":{"start":{"line":76,"column":2},"end":{"line":81,"column":5}},"12":{"start":{"line":98,"column":24},"end":{"line":98,"column":52}},"13":{"start":{"line":99,"column":19},"end":{"line":99,"column":43}},"14":{"start":{"line":101,"column":2},"end":{"line":118,"column":4}},"15":{"start":{"line":112,"column":28},"end":{"line":112,"column":78}},"16":{"start":{"line":113,"column":6},"end":{"line":115,"column":7}},"17":{"start":{"line":114,"column":8},"end":{"line":114,"column":60}},"18":{"start":{"line":116,"column":6},"end":{"line":116,"column":13}},"19":{"start":{"line":131,"column":24},"end":{"line":131,"column":58}},"20":{"start":{"line":132,"column":19},"end":{"line":132,"column":43}},"21":{"start":{"line":134,"column":2},"end":{"line":151,"column":4}},"22":{"start":{"line":145,"column":28},"end":{"line":145,"column":78}},"23":{"start":{"line":146,"column":6},"end":{"line":148,"column":7}},"24":{"start":{"line":147,"column":8},"end":{"line":147,"column":60}},"25":{"start":{"line":149,"column":6},"end":{"line":149,"column":13}},"26":{"start":{"line":170,"column":2},"end":{"line":176,"column":3}},"27":{"start":{"line":171,"column":4},"end":{"line":175,"column":7}},"28":{"start":{"line":177,"column":2},"end":{"line":177,"column":12}},"29":{"start":{"line":193,"column":2},"end":{"line":193,"column":56}},"30":{"start":{"line":196,"column":0},"end":{"line":203,"column":2}}},"fnMap":{"0":{"name":"parseSize","decl":{"start":{"line":50,"column":9},"end":{"line":50,"column":18}},"loc":{"start":{"line":50,"column":28},"end":{"line":65,"column":1}},"line":50},"1":{"name":"sendPayloadTooLarge","decl":{"start":{"line":75,"column":9},"end":{"line":75,"column":28}},"loc":{"start":{"line":75,"column":46},"end":{"line":82,"column":1}},"line":75},"2":{"name":"jsonBodyLimit","decl":{"start":{"line":97,"column":9},"end":{"line":97,"column":22}},"loc":{"start":{"line":97,"column":30},"end":{"line":119,"column":1}},"line":97},"3":{"name":"jsonSizeGuard","decl":{"start":{"line":111,"column":13},"end":{"line":111,"column":26}},"loc":{"start":{"line":111,"column":43},"end":{"line":117,"column":5}},"line":111},"4":{"name":"urlencodedBodyLimit","decl":{"start":{"line":130,"column":9},"end":{"line":130,"column":28}},"loc":{"start":{"line":130,"column":36},"end":{"line":152,"column":1}},"line":130},"5":{"name":"urlencodedSizeGuard","decl":{"start":{"line":144,"column":13},"end":{"line":144,"column":32}},"loc":{"start":{"line":144,"column":49},"end":{"line":150,"column":5}},"line":144},"6":{"name":"payloadTooLargeHandler","decl":{"start":{"line":169,"column":9},"end":{"line":169,"column":31}},"loc":{"start":{"line":169,"column":53},"end":{"line":178,"column":1}},"line":169},"7":{"name":"invoiceBodyLimit","decl":{"start":{"line":192,"column":9},"end":{"line":192,"column":25}},"loc":{"start":{"line":192,"column":33},"end":{"line":194,"column":1}},"line":192}},"branchMap":{"0":{"loc":{"start":{"line":26,"column":14},"end":{"line":26,"column":59}},"type":"binary-expr","locations":[{"start":{"line":26,"column":14},"end":{"line":26,"column":41}},{"start":{"line":26,"column":52},"end":{"line":26,"column":59}}],"line":26},"1":{"loc":{"start":{"line":27,"column":14},"end":{"line":27,"column":58}},"type":"binary-expr","locations":[{"start":{"line":27,"column":14},"end":{"line":27,"column":47}},{"start":{"line":27,"column":52},"end":{"line":27,"column":58}}],"line":27},"2":{"loc":{"start":{"line":28,"column":14},"end":{"line":28,"column":57}},"type":"binary-expr","locations":[{"start":{"line":28,"column":14},"end":{"line":28,"column":40}},{"start":{"line":28,"column":52},"end":{"line":28,"column":57}}],"line":28},"3":{"loc":{"start":{"line":29,"column":14},"end":{"line":29,"column":59}},"type":"binary-expr","locations":[{"start":{"line":29,"column":14},"end":{"line":29,"column":44}},{"start":{"line":29,"column":52},"end":{"line":29,"column":59}}],"line":29},"4":{"loc":{"start":{"line":51,"column":2},"end":{"line":53,"column":3}},"type":"if","locations":[{"start":{"line":51,"column":2},"end":{"line":53,"column":3}},{"start":{},"end":{}}],"line":51},"5":{"loc":{"start":{"line":51,"column":6},"end":{"line":51,"column":58}},"type":"binary-expr","locations":[{"start":{"line":51,"column":6},"end":{"line":51,"column":33}},{"start":{"line":51,"column":37},"end":{"line":51,"column":58}}],"line":51},"6":{"loc":{"start":{"line":56,"column":2},"end":{"line":58,"column":3}},"type":"if","locations":[{"start":{"line":56,"column":2},"end":{"line":58,"column":3}},{"start":{},"end":{}}],"line":56},"7":{"loc":{"start":{"line":61,"column":16},"end":{"line":61,"column":31}},"type":"binary-expr","locations":[{"start":{"line":61,"column":16},"end":{"line":61,"column":24}},{"start":{"line":61,"column":28},"end":{"line":61,"column":31}}],"line":61},"8":{"loc":{"start":{"line":98,"column":24},"end":{"line":98,"column":52}},"type":"binary-expr","locations":[{"start":{"line":98,"column":24},"end":{"line":98,"column":29}},{"start":{"line":98,"column":33},"end":{"line":98,"column":52}}],"line":98},"9":{"loc":{"start":{"line":112,"column":37},"end":{"line":112,"column":73}},"type":"binary-expr","locations":[{"start":{"line":112,"column":37},"end":{"line":112,"column":66}},{"start":{"line":112,"column":70},"end":{"line":112,"column":73}}],"line":112},"10":{"loc":{"start":{"line":113,"column":6},"end":{"line":115,"column":7}},"type":"if","locations":[{"start":{"line":113,"column":6},"end":{"line":115,"column":7}},{"start":{},"end":{}}],"line":113},"11":{"loc":{"start":{"line":113,"column":10},"end":{"line":113,"column":59}},"type":"binary-expr","locations":[{"start":{"line":113,"column":10},"end":{"line":113,"column":31}},{"start":{"line":113,"column":35},"end":{"line":113,"column":59}}],"line":113},"12":{"loc":{"start":{"line":131,"column":24},"end":{"line":131,"column":58}},"type":"binary-expr","locations":[{"start":{"line":131,"column":24},"end":{"line":131,"column":29}},{"start":{"line":131,"column":33},"end":{"line":131,"column":58}}],"line":131},"13":{"loc":{"start":{"line":145,"column":37},"end":{"line":145,"column":73}},"type":"binary-expr","locations":[{"start":{"line":145,"column":37},"end":{"line":145,"column":66}},{"start":{"line":145,"column":70},"end":{"line":145,"column":73}}],"line":145},"14":{"loc":{"start":{"line":146,"column":6},"end":{"line":148,"column":7}},"type":"if","locations":[{"start":{"line":146,"column":6},"end":{"line":148,"column":7}},{"start":{},"end":{}}],"line":146},"15":{"loc":{"start":{"line":146,"column":10},"end":{"line":146,"column":59}},"type":"binary-expr","locations":[{"start":{"line":146,"column":10},"end":{"line":146,"column":31}},{"start":{"line":146,"column":35},"end":{"line":146,"column":59}}],"line":146},"16":{"loc":{"start":{"line":170,"column":2},"end":{"line":176,"column":3}},"type":"if","locations":[{"start":{"line":170,"column":2},"end":{"line":176,"column":3}},{"start":{},"end":{}}],"line":170},"17":{"loc":{"start":{"line":193,"column":23},"end":{"line":193,"column":54}},"type":"binary-expr","locations":[{"start":{"line":193,"column":23},"end":{"line":193,"column":28}},{"start":{"line":193,"column":32},"end":{"line":193,"column":54}}],"line":193}},"s":{"0":8,"1":8,"2":82,"3":6,"4":76,"5":76,"6":3,"7":73,"8":73,"9":73,"10":73,"11":0,"12":39,"13":39,"14":39,"15":86,"16":86,"17":0,"18":86,"19":19,"20":19,"21":19,"22":61,"23":61,"24":0,"25":61,"26":17,"27":3,"28":14,"29":19,"30":8},"f":{"0":82,"1":0,"2":39,"3":86,"4":19,"5":61,"6":17,"7":19},"b":{"0":[8,8],"1":[8,8],"2":[8,8],"3":[8,8],"4":[6,76],"5":[82,78],"6":[3,73],"7":[73,1],"8":[39,19],"9":[86,36],"10":[0,86],"11":[86,86],"12":[19,19],"13":[61,36],"14":[0,61],"15":[61,61],"16":[3,14],"17":[19,19]},"_coverageSchema":"1a1c01bbd47fc00a2c39e90264f33305004495a9","hash":"1f5c8930684f7d0494f5082be159888fe7133089"} +,"C:\\Users\\pc\\Documents\\waves\\Liquifact-backend\\src\\middleware\\deprecation.js": {"path":"C:\\Users\\pc\\Documents\\waves\\Liquifact-backend\\src\\middleware\\deprecation.js","statementMap":{"0":{"start":{"line":9,"column":18},"end":{"line":29,"column":1}},"1":{"start":{"line":10,"column":2},"end":{"line":28,"column":4}},"2":{"start":{"line":12,"column":4},"end":{"line":12,"column":41}},"3":{"start":{"line":14,"column":4},"end":{"line":20,"column":5}},"4":{"start":{"line":15,"column":25},"end":{"line":15,"column":49}},"5":{"start":{"line":17,"column":6},"end":{"line":19,"column":7}},"6":{"start":{"line":18,"column":8},"end":{"line":18,"column":58}},"7":{"start":{"line":22,"column":4},"end":{"line":25,"column":5}},"8":{"start":{"line":24,"column":6},"end":{"line":24,"column":68}},"9":{"start":{"line":27,"column":4},"end":{"line":27,"column":11}},"10":{"start":{"line":31,"column":0},"end":{"line":31,"column":31}}},"fnMap":{"0":{"name":"(anonymous_0)","decl":{"start":{"line":9,"column":18},"end":{"line":9,"column":19}},"loc":{"start":{"line":9,"column":36},"end":{"line":29,"column":1}},"line":9},"1":{"name":"(anonymous_1)","decl":{"start":{"line":10,"column":9},"end":{"line":10,"column":10}},"loc":{"start":{"line":10,"column":29},"end":{"line":28,"column":3}},"line":10}},"branchMap":{"0":{"loc":{"start":{"line":9,"column":19},"end":{"line":9,"column":31}},"type":"default-arg","locations":[{"start":{"line":9,"column":29},"end":{"line":9,"column":31}}],"line":9},"1":{"loc":{"start":{"line":14,"column":4},"end":{"line":20,"column":5}},"type":"if","locations":[{"start":{"line":14,"column":4},"end":{"line":20,"column":5}},{"start":{},"end":{}}],"line":14},"2":{"loc":{"start":{"line":17,"column":6},"end":{"line":19,"column":7}},"type":"if","locations":[{"start":{"line":17,"column":6},"end":{"line":19,"column":7}},{"start":{},"end":{}}],"line":17},"3":{"loc":{"start":{"line":22,"column":4},"end":{"line":25,"column":5}},"type":"if","locations":[{"start":{"line":22,"column":4},"end":{"line":25,"column":5}},{"start":{},"end":{}}],"line":22}},"s":{"0":1,"1":1,"2":3,"3":3,"4":3,"5":3,"6":3,"7":3,"8":3,"9":3,"10":1},"f":{"0":1,"1":3},"b":{"0":[0],"1":[3,0],"2":[3,0],"3":[3,0]},"_coverageSchema":"1a1c01bbd47fc00a2c39e90264f33305004495a9","hash":"2f24a1e6b2343f41bbc6c6933bc0d387f870ab3d"} +,"C:\\Users\\pc\\Documents\\waves\\Liquifact-backend\\src\\middleware\\errorHandler.js": {"path":"C:\\Users\\pc\\Documents\\waves\\Liquifact-backend\\src\\middleware\\errorHandler.js","statementMap":{"0":{"start":{"line":3,"column":17},"end":{"line":3,"column":46}},"1":{"start":{"line":4,"column":29},"end":{"line":4,"column":63}},"2":{"start":{"line":17,"column":17},"end":{"line":17,"column":52}},"3":{"start":{"line":21,"column":2},"end":{"line":46,"column":3}},"4":{"start":{"line":22,"column":4},"end":{"line":29,"column":7}},"5":{"start":{"line":32,"column":4},"end":{"line":34,"column":5}},"6":{"start":{"line":33,"column":6},"end":{"line":33,"column":45}},"7":{"start":{"line":36,"column":4},"end":{"line":45,"column":7}},"8":{"start":{"line":50,"column":2},"end":{"line":50,"column":22}},"9":{"start":{"line":51,"column":2},"end":{"line":54,"column":4}},"10":{"start":{"line":57,"column":2},"end":{"line":61,"column":4}},"11":{"start":{"line":64,"column":2},"end":{"line":64,"column":57}},"12":{"start":{"line":66,"column":2},"end":{"line":66,"column":42}},"13":{"start":{"line":69,"column":0},"end":{"line":69,"column":30}}},"fnMap":{"0":{"name":"errorHandler","decl":{"start":{"line":10,"column":9},"end":{"line":10,"column":21}},"loc":{"start":{"line":10,"column":44},"end":{"line":67,"column":1}},"line":10}},"branchMap":{"0":{"loc":{"start":{"line":17,"column":17},"end":{"line":17,"column":52}},"type":"binary-expr","locations":[{"start":{"line":17,"column":17},"end":{"line":17,"column":27}},{"start":{"line":17,"column":31},"end":{"line":17,"column":45}},{"start":{"line":17,"column":49},"end":{"line":17,"column":52}}],"line":17},"1":{"loc":{"start":{"line":21,"column":2},"end":{"line":46,"column":3}},"type":"if","locations":[{"start":{"line":21,"column":2},"end":{"line":46,"column":3}},{"start":{"line":30,"column":9},"end":{"line":46,"column":3}}],"line":21},"2":{"loc":{"start":{"line":27,"column":16},"end":{"line":27,"column":47}},"type":"binary-expr","locations":[{"start":{"line":27,"column":16},"end":{"line":27,"column":28}},{"start":{"line":27,"column":32},"end":{"line":27,"column":47}}],"line":27},"3":{"loc":{"start":{"line":32,"column":4},"end":{"line":34,"column":5}},"type":"if","locations":[{"start":{"line":32,"column":4},"end":{"line":34,"column":5}},{"start":{},"end":{}}],"line":32},"4":{"loc":{"start":{"line":38,"column":13},"end":{"line":38,"column":77}},"type":"cond-expr","locations":[{"start":{"line":38,"column":30},"end":{"line":38,"column":53}},{"start":{"line":38,"column":57},"end":{"line":38,"column":76}}],"line":38},"5":{"loc":{"start":{"line":38,"column":57},"end":{"line":38,"column":76}},"type":"binary-expr","locations":[{"start":{"line":38,"column":57},"end":{"line":38,"column":65}},{"start":{"line":38,"column":69},"end":{"line":38,"column":76}}],"line":38},"6":{"loc":{"start":{"line":40,"column":14},"end":{"line":42,"column":79}},"type":"cond-expr","locations":[{"start":{"line":41,"column":10},"end":{"line":41,"column":71}},{"start":{"line":42,"column":11},"end":{"line":42,"column":78}}],"line":40},"7":{"loc":{"start":{"line":40,"column":15},"end":{"line":40,"column":70}},"type":"binary-expr","locations":[{"start":{"line":40,"column":15},"end":{"line":40,"column":29}},{"start":{"line":40,"column":33},"end":{"line":40,"column":70}}],"line":40},"8":{"loc":{"start":{"line":42,"column":11},"end":{"line":42,"column":78}},"type":"cond-expr","locations":[{"start":{"line":42,"column":28},"end":{"line":42,"column":42}},{"start":{"line":42,"column":46},"end":{"line":42,"column":77}}],"line":42},"9":{"loc":{"start":{"line":42,"column":46},"end":{"line":42,"column":77}},"type":"binary-expr","locations":[{"start":{"line":42,"column":46},"end":{"line":42,"column":57}},{"start":{"line":42,"column":61},"end":{"line":42,"column":77}}],"line":42},"10":{"loc":{"start":{"line":59,"column":10},"end":{"line":59,"column":106}},"type":"binary-expr","locations":[{"start":{"line":59,"column":10},"end":{"line":59,"column":18}},{"start":{"line":59,"column":23},"end":{"line":59,"column":105}}],"line":59},"11":{"loc":{"start":{"line":59,"column":23},"end":{"line":59,"column":105}},"type":"cond-expr","locations":[{"start":{"line":59,"column":40},"end":{"line":59,"column":51}},{"start":{"line":59,"column":55},"end":{"line":59,"column":104}}],"line":59},"12":{"loc":{"start":{"line":59,"column":55},"end":{"line":59,"column":104}},"type":"cond-expr","locations":[{"start":{"line":59,"column":72},"end":{"line":59,"column":85}},{"start":{"line":59,"column":88},"end":{"line":59,"column":104}}],"line":59},"13":{"loc":{"start":{"line":60,"column":13},"end":{"line":60,"column":130}},"type":"cond-expr","locations":[{"start":{"line":60,"column":73},"end":{"line":60,"column":87}},{"start":{"line":60,"column":91},"end":{"line":60,"column":129}}],"line":60},"14":{"loc":{"start":{"line":60,"column":14},"end":{"line":60,"column":69}},"type":"binary-expr","locations":[{"start":{"line":60,"column":14},"end":{"line":60,"column":51}},{"start":{"line":60,"column":55},"end":{"line":60,"column":69}}],"line":60},"15":{"loc":{"start":{"line":60,"column":91},"end":{"line":60,"column":129}},"type":"cond-expr","locations":[{"start":{"line":60,"column":108},"end":{"line":60,"column":122}},{"start":{"line":60,"column":125},"end":{"line":60,"column":129}}],"line":60}},"s":{"0":11,"1":11,"2":20,"3":20,"4":10,"5":10,"6":8,"7":10,"8":20,"9":20,"10":20,"11":20,"12":20,"13":11},"f":{"0":20},"b":{"0":[20,8,8],"1":[10,10],"2":[10,8],"3":[8,2],"4":[8,2],"5":[2,0],"6":[2,8],"7":[10,8],"8":[6,2],"9":[2,0],"10":[20,20],"11":[4,16],"12":[7,9],"13":[6,14],"14":[20,18],"15":[7,7]},"_coverageSchema":"1a1c01bbd47fc00a2c39e90264f33305004495a9","hash":"2e262ba38b3a1a6957b9126e613218dd1d53fd28"} +,"C:\\Users\\pc\\Documents\\waves\\Liquifact-backend\\src\\middleware\\rateLimit.js": {"path":"C:\\Users\\pc\\Documents\\waves\\Liquifact-backend\\src\\middleware\\rateLimit.js","statementMap":{"0":{"start":{"line":6,"column":38},"end":{"line":6,"column":67}},"1":{"start":{"line":12,"column":22},"end":{"line":29,"column":2}},"2":{"start":{"line":27,"column":4},"end":{"line":27,"column":69}},"3":{"start":{"line":35,"column":25},"end":{"line":51,"column":2}},"4":{"start":{"line":49,"column":4},"end":{"line":49,"column":69}},"5":{"start":{"line":53,"column":0},"end":{"line":56,"column":2}}},"fnMap":{"0":{"name":"(anonymous_0)","decl":{"start":{"line":25,"column":16},"end":{"line":25,"column":17}},"loc":{"start":{"line":25,"column":25},"end":{"line":28,"column":3}},"line":25},"1":{"name":"(anonymous_1)","decl":{"start":{"line":48,"column":16},"end":{"line":48,"column":17}},"loc":{"start":{"line":48,"column":25},"end":{"line":50,"column":3}},"line":48}},"branchMap":{"0":{"loc":{"start":{"line":27,"column":11},"end":{"line":27,"column":68}},"type":"cond-expr","locations":[{"start":{"line":27,"column":22},"end":{"line":27,"column":43}},{"start":{"line":27,"column":46},"end":{"line":27,"column":68}}],"line":27},"1":{"loc":{"start":{"line":49,"column":11},"end":{"line":49,"column":68}},"type":"cond-expr","locations":[{"start":{"line":49,"column":22},"end":{"line":49,"column":43}},{"start":{"line":49,"column":46},"end":{"line":49,"column":68}}],"line":49}},"s":{"0":8,"1":8,"2":61,"3":8,"4":26,"5":8},"f":{"0":61,"1":26},"b":{"0":[0,61],"1":[1,25]},"_coverageSchema":"1a1c01bbd47fc00a2c39e90264f33305004495a9","hash":"0be9551f5ce2da71c13f38f3386440679b07a5bd"} +,"C:\\Users\\pc\\Documents\\waves\\Liquifact-backend\\src\\middleware\\security.js": {"path":"C:\\Users\\pc\\Documents\\waves\\Liquifact-backend\\src\\middleware\\security.js","statementMap":{"0":{"start":{"line":22,"column":15},"end":{"line":22,"column":32}},"1":{"start":{"line":38,"column":2},"end":{"line":134,"column":5}},"2":{"start":{"line":137,"column":0},"end":{"line":137,"column":46}}},"fnMap":{"0":{"name":"createSecurityMiddleware","decl":{"start":{"line":37,"column":9},"end":{"line":37,"column":33}},"loc":{"start":{"line":37,"column":36},"end":{"line":135,"column":1}},"line":37}},"branchMap":{},"s":{"0":8,"1":19,"2":8},"f":{"0":19},"b":{},"_coverageSchema":"1a1c01bbd47fc00a2c39e90264f33305004495a9","hash":"aafa647c494c3df5973d58cfcf084f7d4482678a"} +,"C:\\Users\\pc\\Documents\\waves\\Liquifact-backend\\src\\middleware\\validate.js": {"path":"C:\\Users\\pc\\Documents\\waves\\Liquifact-backend\\src\\middleware\\validate.js","statementMap":{"0":{"start":{"line":1,"column":21},"end":{"line":1,"column":35}},"1":{"start":{"line":2,"column":17},"end":{"line":2,"column":46}},"2":{"start":{"line":7,"column":24},"end":{"line":24,"column":1}},"3":{"start":{"line":7,"column":51},"end":{"line":24,"column":1}},"4":{"start":{"line":8,"column":4},"end":{"line":23,"column":5}},"5":{"start":{"line":9,"column":30},"end":{"line":9,"column":53}},"6":{"start":{"line":10,"column":8},"end":{"line":10,"column":34}},"7":{"start":{"line":11,"column":8},"end":{"line":11,"column":15}},"8":{"start":{"line":13,"column":8},"end":{"line":21,"column":9}},"9":{"start":{"line":14,"column":12},"end":{"line":20,"column":16}},"10":{"start":{"line":18,"column":54},"end":{"line":18,"column":89}},"11":{"start":{"line":22,"column":8},"end":{"line":22,"column":20}},"12":{"start":{"line":29,"column":25},"end":{"line":54,"column":1}},"13":{"start":{"line":29,"column":37},"end":{"line":54,"column":1}},"14":{"start":{"line":30,"column":25},"end":{"line":30,"column":33}},"15":{"start":{"line":32,"column":4},"end":{"line":51,"column":6}},"16":{"start":{"line":34,"column":8},"end":{"line":36,"column":9}},"17":{"start":{"line":35,"column":12},"end":{"line":35,"column":49}},"18":{"start":{"line":38,"column":8},"end":{"line":50,"column":9}},"19":{"start":{"line":39,"column":34},"end":{"line":39,"column":52}},"20":{"start":{"line":40,"column":12},"end":{"line":40,"column":58}},"21":{"start":{"line":53,"column":4},"end":{"line":53,"column":11}},"22":{"start":{"line":56,"column":0},"end":{"line":59,"column":2}}},"fnMap":{"0":{"name":"(anonymous_0)","decl":{"start":{"line":7,"column":24},"end":{"line":7,"column":25}},"loc":{"start":{"line":7,"column":51},"end":{"line":24,"column":1}},"line":7},"1":{"name":"(anonymous_1)","decl":{"start":{"line":7,"column":51},"end":{"line":7,"column":52}},"loc":{"start":{"line":7,"column":71},"end":{"line":24,"column":1}},"line":7},"2":{"name":"(anonymous_2)","decl":{"start":{"line":18,"column":49},"end":{"line":18,"column":50}},"loc":{"start":{"line":18,"column":54},"end":{"line":18,"column":89}},"line":18},"3":{"name":"(anonymous_3)","decl":{"start":{"line":29,"column":25},"end":{"line":29,"column":26}},"loc":{"start":{"line":29,"column":37},"end":{"line":54,"column":1}},"line":29},"4":{"name":"(anonymous_4)","decl":{"start":{"line":29,"column":37},"end":{"line":29,"column":38}},"loc":{"start":{"line":29,"column":57},"end":{"line":54,"column":1}},"line":29},"5":{"name":"(anonymous_5)","decl":{"start":{"line":32,"column":15},"end":{"line":32,"column":16}},"loc":{"start":{"line":32,"column":31},"end":{"line":51,"column":5}},"line":32}},"branchMap":{"0":{"loc":{"start":{"line":7,"column":33},"end":{"line":7,"column":46}},"type":"default-arg","locations":[{"start":{"line":7,"column":40},"end":{"line":7,"column":46}}],"line":7},"1":{"loc":{"start":{"line":13,"column":8},"end":{"line":21,"column":9}},"type":"if","locations":[{"start":{"line":13,"column":8},"end":{"line":21,"column":9}},{"start":{},"end":{}}],"line":13},"2":{"loc":{"start":{"line":18,"column":25},"end":{"line":18,"column":43}},"type":"binary-expr","locations":[{"start":{"line":18,"column":25},"end":{"line":18,"column":37}},{"start":{"line":18,"column":41},"end":{"line":18,"column":43}}],"line":18},"3":{"loc":{"start":{"line":34,"column":8},"end":{"line":36,"column":9}},"type":"if","locations":[{"start":{"line":34,"column":8},"end":{"line":36,"column":9}},{"start":{},"end":{}}],"line":34},"4":{"loc":{"start":{"line":34,"column":12},"end":{"line":34,"column":74}},"type":"binary-expr","locations":[{"start":{"line":34,"column":12},"end":{"line":34,"column":16}},{"start":{"line":34,"column":21},"end":{"line":34,"column":31}},{"start":{"line":34,"column":35},"end":{"line":34,"column":45}},{"start":{"line":34,"column":49},"end":{"line":34,"column":73}}],"line":34}},"s":{"0":9,"1":9,"2":9,"3":21,"4":21,"5":21,"6":18,"7":18,"8":3,"9":3,"10":3,"11":0,"12":9,"13":38,"14":29,"15":29,"16":29,"17":4,"18":25,"19":25,"20":25,"21":29,"22":9},"f":{"0":21,"1":21,"2":3,"3":38,"4":29,"5":29},"b":{"0":[2],"1":[3,0],"2":[3,0],"3":[4,25],"4":[29,29,25,25]},"_coverageSchema":"1a1c01bbd47fc00a2c39e90264f33305004495a9","hash":"c967e762c6c35fd3edf3f0f96a7bdb1359b2412e"} +,"C:\\Users\\pc\\Documents\\waves\\Liquifact-backend\\src\\schemas\\apiSchemas.js": {"path":"C:\\Users\\pc\\Documents\\waves\\Liquifact-backend\\src\\schemas\\apiSchemas.js","statementMap":{"0":{"start":{"line":1,"column":14},"end":{"line":1,"column":28}},"1":{"start":{"line":3,"column":19},"end":{"line":6,"column":16}},"2":{"start":{"line":8,"column":20},"end":{"line":12,"column":13}},"3":{"start":{"line":14,"column":22},"end":{"line":20,"column":16}},"4":{"start":{"line":22,"column":27},"end":{"line":26,"column":2}},"5":{"start":{"line":28,"column":36},"end":{"line":30,"column":2}},"6":{"start":{"line":32,"column":34},"end":{"line":34,"column":2}},"7":{"start":{"line":36,"column":43},"end":{"line":38,"column":2}},"8":{"start":{"line":40,"column":0},"end":{"line":49,"column":2}}},"fnMap":{},"branchMap":{},"s":{"0":8,"1":8,"2":8,"3":8,"4":8,"5":8,"6":8,"7":8,"8":8},"f":{},"b":{},"_coverageSchema":"1a1c01bbd47fc00a2c39e90264f33305004495a9","hash":"974dee99d3af48c5850869995066eedc0186d8ac"} +,"C:\\Users\\pc\\Documents\\waves\\Liquifact-backend\\src\\services\\invoice.service.js": {"path":"C:\\Users\\pc\\Documents\\waves\\Liquifact-backend\\src\\services\\invoice.service.js","statementMap":{"0":{"start":{"line":1,"column":11},"end":{"line":1,"column":32}},"1":{"start":{"line":2,"column":30},"end":{"line":2,"column":62}},"2":{"start":{"line":11,"column":29},"end":{"line":20,"column":1}},"3":{"start":{"line":32,"column":2},"end":{"line":46,"column":3}},"4":{"start":{"line":33,"column":16},"end":{"line":33,"column":42}},"5":{"start":{"line":36,"column":4},"end":{"line":36,"column":72}},"6":{"start":{"line":42,"column":4},"end":{"line":42,"column":23}},"7":{"start":{"line":44,"column":4},"end":{"line":44,"column":53}},"8":{"start":{"line":45,"column":4},"end":{"line":45,"column":62}},"9":{"start":{"line":49,"column":0},"end":{"line":52,"column":2}}},"fnMap":{"0":{"name":"getInvoices","decl":{"start":{"line":31,"column":15},"end":{"line":31,"column":26}},"loc":{"start":{"line":31,"column":40},"end":{"line":47,"column":1}},"line":31}},"branchMap":{},"s":{"0":9,"1":9,"2":9,"3":5,"4":5,"5":5,"6":5,"7":1,"8":1,"9":9},"f":{"0":5},"b":{},"_coverageSchema":"1a1c01bbd47fc00a2c39e90264f33305004495a9","hash":"fa3d18ca12d3197af370b194077b0c7e4df502e0"} +,"C:\\Users\\pc\\Documents\\waves\\Liquifact-backend\\src\\services\\soroban.js": {"path":"C:\\Users\\pc\\Documents\\waves\\Liquifact-backend\\src\\services\\soroban.js","statementMap":{"0":{"start":{"line":21,"column":29},"end":{"line":25,"column":1}},"1":{"start":{"line":32,"column":31},"end":{"line":32,"column":60}},"2":{"start":{"line":41,"column":2},"end":{"line":41,"column":59}},"3":{"start":{"line":41,"column":34},"end":{"line":41,"column":57}},"4":{"start":{"line":55,"column":18},"end":{"line":55,"column":44}},"5":{"start":{"line":56,"column":19},"end":{"line":56,"column":46}},"6":{"start":{"line":57,"column":14},"end":{"line":57,"column":37}},"7":{"start":{"line":58,"column":17},"end":{"line":58,"column":52}},"8":{"start":{"line":59,"column":2},"end":{"line":59,"column":66}},"9":{"start":{"line":70,"column":2},"end":{"line":70,"column":25}},"10":{"start":{"line":70,"column":12},"end":{"line":70,"column":25}},"11":{"start":{"line":73,"column":2},"end":{"line":73,"column":73}},"12":{"start":{"line":73,"column":61},"end":{"line":73,"column":73}},"13":{"start":{"line":76,"column":2},"end":{"line":76,"column":80}},"14":{"start":{"line":76,"column":68},"end":{"line":76,"column":80}},"15":{"start":{"line":77,"column":2},"end":{"line":77,"column":83}},"16":{"start":{"line":77,"column":71},"end":{"line":77,"column":83}},"17":{"start":{"line":80,"column":14},"end":{"line":80,"column":31}},"18":{"start":{"line":81,"column":2},"end":{"line":81,"column":40}},"19":{"start":{"line":81,"column":28},"end":{"line":81,"column":40}},"20":{"start":{"line":82,"column":2},"end":{"line":82,"column":48}},"21":{"start":{"line":82,"column":36},"end":{"line":82,"column":48}},"22":{"start":{"line":83,"column":2},"end":{"line":83,"column":43}},"23":{"start":{"line":83,"column":31},"end":{"line":83,"column":43}},"24":{"start":{"line":85,"column":2},"end":{"line":85,"column":15}},"25":{"start":{"line":101,"column":14},"end":{"line":101,"column":61}},"26":{"start":{"line":102,"column":21},"end":{"line":102,"column":49}},"27":{"start":{"line":105,"column":2},"end":{"line":115,"column":3}},"28":{"start":{"line":105,"column":21},"end":{"line":105,"column":22}},"29":{"start":{"line":106,"column":4},"end":{"line":114,"column":5}},"30":{"start":{"line":107,"column":6},"end":{"line":107,"column":31}},"31":{"start":{"line":109,"column":6},"end":{"line":109,"column":20}},"32":{"start":{"line":110,"column":6},"end":{"line":110,"column":64}},"33":{"start":{"line":110,"column":54},"end":{"line":110,"column":64}},"34":{"start":{"line":112,"column":20},"end":{"line":112,"column":72}},"35":{"start":{"line":113,"column":6},"end":{"line":113,"column":25}},"36":{"start":{"line":117,"column":2},"end":{"line":117,"column":16}},"37":{"start":{"line":129,"column":2},"end":{"line":129,"column":38}},"38":{"start":{"line":132,"column":0},"end":{"line":140,"column":2}}},"fnMap":{"0":{"name":"sleep","decl":{"start":{"line":40,"column":9},"end":{"line":40,"column":14}},"loc":{"start":{"line":40,"column":19},"end":{"line":42,"column":1}},"line":40},"1":{"name":"(anonymous_1)","decl":{"start":{"line":41,"column":21},"end":{"line":41,"column":22}},"loc":{"start":{"line":41,"column":34},"end":{"line":41,"column":57}},"line":41},"2":{"name":"computeBackoff","decl":{"start":{"line":54,"column":9},"end":{"line":54,"column":23}},"loc":{"start":{"line":54,"column":54},"end":{"line":60,"column":1}},"line":54},"3":{"name":"isRetryable","decl":{"start":{"line":69,"column":9},"end":{"line":69,"column":20}},"loc":{"start":{"line":69,"column":26},"end":{"line":86,"column":1}},"line":69},"4":{"name":"withRetry","decl":{"start":{"line":100,"column":15},"end":{"line":100,"column":24}},"loc":{"start":{"line":100,"column":44},"end":{"line":118,"column":1}},"line":100},"5":{"name":"callSorobanContract","decl":{"start":{"line":128,"column":15},"end":{"line":128,"column":34}},"loc":{"start":{"line":128,"column":54},"end":{"line":130,"column":1}},"line":128}},"branchMap":{"0":{"loc":{"start":{"line":22,"column":23},"end":{"line":22,"column":61}},"type":"binary-expr","locations":[{"start":{"line":22,"column":23},"end":{"line":22,"column":54}},{"start":{"line":22,"column":58},"end":{"line":22,"column":61}}],"line":22},"1":{"loc":{"start":{"line":23,"column":22},"end":{"line":23,"column":61}},"type":"binary-expr","locations":[{"start":{"line":23,"column":22},"end":{"line":23,"column":52}},{"start":{"line":23,"column":56},"end":{"line":23,"column":61}}],"line":23},"2":{"loc":{"start":{"line":24,"column":21},"end":{"line":24,"column":60}},"type":"binary-expr","locations":[{"start":{"line":24,"column":21},"end":{"line":24,"column":50}},{"start":{"line":24,"column":54},"end":{"line":24,"column":60}}],"line":24},"3":{"loc":{"start":{"line":70,"column":2},"end":{"line":70,"column":25}},"type":"if","locations":[{"start":{"line":70,"column":2},"end":{"line":70,"column":25}},{"start":{},"end":{}}],"line":70},"4":{"loc":{"start":{"line":73,"column":2},"end":{"line":73,"column":73}},"type":"if","locations":[{"start":{"line":73,"column":2},"end":{"line":73,"column":73}},{"start":{},"end":{}}],"line":73},"5":{"loc":{"start":{"line":73,"column":6},"end":{"line":73,"column":59}},"type":"binary-expr","locations":[{"start":{"line":73,"column":6},"end":{"line":73,"column":31}},{"start":{"line":73,"column":35},"end":{"line":73,"column":59}}],"line":73},"6":{"loc":{"start":{"line":76,"column":2},"end":{"line":76,"column":80}},"type":"if","locations":[{"start":{"line":76,"column":2},"end":{"line":76,"column":80}},{"start":{},"end":{}}],"line":76},"7":{"loc":{"start":{"line":76,"column":6},"end":{"line":76,"column":66}},"type":"binary-expr","locations":[{"start":{"line":76,"column":6},"end":{"line":76,"column":24}},{"start":{"line":76,"column":28},"end":{"line":76,"column":66}}],"line":76},"8":{"loc":{"start":{"line":77,"column":2},"end":{"line":77,"column":83}},"type":"if","locations":[{"start":{"line":77,"column":2},"end":{"line":77,"column":83}},{"start":{},"end":{}}],"line":77},"9":{"loc":{"start":{"line":77,"column":6},"end":{"line":77,"column":69}},"type":"binary-expr","locations":[{"start":{"line":77,"column":6},"end":{"line":77,"column":18}},{"start":{"line":77,"column":22},"end":{"line":77,"column":69}}],"line":77},"10":{"loc":{"start":{"line":80,"column":14},"end":{"line":80,"column":31}},"type":"binary-expr","locations":[{"start":{"line":80,"column":14},"end":{"line":80,"column":25}},{"start":{"line":80,"column":29},"end":{"line":80,"column":31}}],"line":80},"11":{"loc":{"start":{"line":81,"column":2},"end":{"line":81,"column":40}},"type":"if","locations":[{"start":{"line":81,"column":2},"end":{"line":81,"column":40}},{"start":{},"end":{}}],"line":81},"12":{"loc":{"start":{"line":82,"column":2},"end":{"line":82,"column":48}},"type":"if","locations":[{"start":{"line":82,"column":2},"end":{"line":82,"column":48}},{"start":{},"end":{}}],"line":82},"13":{"loc":{"start":{"line":83,"column":2},"end":{"line":83,"column":43}},"type":"if","locations":[{"start":{"line":83,"column":2},"end":{"line":83,"column":43}},{"start":{},"end":{}}],"line":83},"14":{"loc":{"start":{"line":110,"column":6},"end":{"line":110,"column":64}},"type":"if","locations":[{"start":{"line":110,"column":6},"end":{"line":110,"column":64}},{"start":{},"end":{}}],"line":110},"15":{"loc":{"start":{"line":110,"column":10},"end":{"line":110,"column":52}},"type":"binary-expr","locations":[{"start":{"line":110,"column":10},"end":{"line":110,"column":31}},{"start":{"line":110,"column":35},"end":{"line":110,"column":52}}],"line":110}},"s":{"0":9,"1":9,"2":1,"3":1,"4":1,"5":1,"6":1,"7":1,"8":1,"9":8,"10":0,"11":8,"12":0,"13":8,"14":0,"15":8,"16":0,"17":8,"18":8,"19":1,"20":7,"21":3,"22":4,"23":0,"24":4,"25":5,"26":5,"27":5,"28":5,"29":6,"30":6,"31":2,"32":2,"33":1,"34":1,"35":1,"36":0,"37":5,"38":9},"f":{"0":1,"1":1,"2":1,"3":8,"4":5,"5":5},"b":{"0":[9,9],"1":[9,9],"2":[9,9],"3":[0,8],"4":[0,8],"5":[8,8],"6":[0,8],"7":[8,0],"8":[0,8],"9":[8,0],"10":[8,0],"11":[1,7],"12":[3,4],"13":[0,4],"14":[1,1],"15":[2,2]},"_coverageSchema":"1a1c01bbd47fc00a2c39e90264f33305004495a9","hash":"9c3d72bfcb47ad02d2357e664d82eb982a6b1993"} +,"C:\\Users\\pc\\Documents\\waves\\Liquifact-backend\\src\\utils\\asyncHandler.js": {"path":"C:\\Users\\pc\\Documents\\waves\\Liquifact-backend\\src\\utils\\asyncHandler.js","statementMap":{"0":{"start":{"line":8,"column":21},"end":{"line":12,"column":1}},"1":{"start":{"line":9,"column":2},"end":{"line":11,"column":4}},"2":{"start":{"line":10,"column":4},"end":{"line":10,"column":52}},"3":{"start":{"line":14,"column":0},"end":{"line":14,"column":30}}},"fnMap":{"0":{"name":"(anonymous_0)","decl":{"start":{"line":8,"column":21},"end":{"line":8,"column":22}},"loc":{"start":{"line":8,"column":29},"end":{"line":12,"column":1}},"line":8},"1":{"name":"(anonymous_1)","decl":{"start":{"line":9,"column":9},"end":{"line":9,"column":10}},"loc":{"start":{"line":9,"column":35},"end":{"line":11,"column":3}},"line":9}},"branchMap":{},"s":{"0":10,"1":43,"2":19,"3":10},"f":{"0":43,"1":19},"b":{},"_coverageSchema":"1a1c01bbd47fc00a2c39e90264f33305004495a9","hash":"38a717111e40dd2bd90d30a1efc7c38604bd18d2"} +,"C:\\Users\\pc\\Documents\\waves\\Liquifact-backend\\src\\utils\\problemDetails.js": {"path":"C:\\Users\\pc\\Documents\\waves\\Liquifact-backend\\src\\utils\\problemDetails.js","statementMap":{"0":{"start":{"line":14,"column":18},"end":{"line":20,"column":3}},"1":{"start":{"line":23,"column":2},"end":{"line":25,"column":3}},"2":{"start":{"line":24,"column":4},"end":{"line":24,"column":26}},"3":{"start":{"line":27,"column":2},"end":{"line":27,"column":17}},"4":{"start":{"line":30,"column":0},"end":{"line":30,"column":38}}},"fnMap":{"0":{"name":"formatProblemDetails","decl":{"start":{"line":5,"column":9},"end":{"line":5,"column":29}},"loc":{"start":{"line":13,"column":3},"end":{"line":28,"column":1}},"line":13}},"branchMap":{"0":{"loc":{"start":{"line":6,"column":2},"end":{"line":6,"column":22}},"type":"default-arg","locations":[{"start":{"line":6,"column":9},"end":{"line":6,"column":22}}],"line":6},"1":{"loc":{"start":{"line":7,"column":2},"end":{"line":7,"column":40}},"type":"default-arg","locations":[{"start":{"line":7,"column":10},"end":{"line":7,"column":40}}],"line":7},"2":{"loc":{"start":{"line":8,"column":2},"end":{"line":8,"column":14}},"type":"default-arg","locations":[{"start":{"line":8,"column":11},"end":{"line":8,"column":14}}],"line":8},"3":{"loc":{"start":{"line":12,"column":2},"end":{"line":12,"column":54}},"type":"default-arg","locations":[{"start":{"line":12,"column":17},"end":{"line":12,"column":54}}],"line":12},"4":{"loc":{"start":{"line":23,"column":2},"end":{"line":25,"column":3}},"type":"if","locations":[{"start":{"line":23,"column":2},"end":{"line":25,"column":3}},{"start":{},"end":{}}],"line":23},"5":{"loc":{"start":{"line":23,"column":6},"end":{"line":23,"column":28}},"type":"binary-expr","locations":[{"start":{"line":23,"column":6},"end":{"line":23,"column":19}},{"start":{"line":23,"column":23},"end":{"line":23,"column":28}}],"line":23}},"s":{"0":23,"1":23,"2":19,"3":23,"4":12},"f":{"0":23},"b":{"0":[1],"1":[1],"2":[1],"3":[21],"4":[19,4],"5":[23,20]},"_coverageSchema":"1a1c01bbd47fc00a2c39e90264f33305004495a9","hash":"d0f862c57c5eee575ae790f56f0acd24140243c7"} +,"C:\\Users\\pc\\Documents\\waves\\Liquifact-backend\\src\\utils\\queryBuilder.js": {"path":"C:\\Users\\pc\\Documents\\waves\\Liquifact-backend\\src\\utils\\queryBuilder.js","statementMap":{"0":{"start":{"line":23,"column":41},"end":{"line":23,"column":48}},"1":{"start":{"line":24,"column":74},"end":{"line":24,"column":80}},"2":{"start":{"line":27,"column":2},"end":{"line":44,"column":5}},"3":{"start":{"line":28,"column":18},"end":{"line":28,"column":30}},"4":{"start":{"line":29,"column":4},"end":{"line":29,"column":70}},"5":{"start":{"line":29,"column":63},"end":{"line":29,"column":70}},"6":{"start":{"line":31,"column":4},"end":{"line":43,"column":5}},"7":{"start":{"line":32,"column":21},"end":{"line":32,"column":42}},"8":{"start":{"line":35,"column":6},"end":{"line":42,"column":7}},"9":{"start":{"line":36,"column":8},"end":{"line":36,"column":41}},"10":{"start":{"line":37,"column":13},"end":{"line":42,"column":7}},"11":{"start":{"line":38,"column":8},"end":{"line":38,"column":41}},"12":{"start":{"line":41,"column":8},"end":{"line":41,"column":35}},"13":{"start":{"line":47,"column":37},"end":{"line":47,"column":44}},"14":{"start":{"line":48,"column":2},"end":{"line":57,"column":3}},"15":{"start":{"line":49,"column":19},"end":{"line":49,"column":46}},"16":{"start":{"line":50,"column":22},"end":{"line":50,"column":98}},"17":{"start":{"line":51,"column":4},"end":{"line":51,"column":37}},"18":{"start":{"line":52,"column":9},"end":{"line":57,"column":3}},"19":{"start":{"line":54,"column":24},"end":{"line":54,"column":44}},"20":{"start":{"line":55,"column":19},"end":{"line":55,"column":56}},"21":{"start":{"line":56,"column":4},"end":{"line":56,"column":34}},"22":{"start":{"line":59,"column":2},"end":{"line":59,"column":15}},"23":{"start":{"line":62,"column":0},"end":{"line":64,"column":2}}},"fnMap":{"0":{"name":"applyQueryOptions","decl":{"start":{"line":22,"column":9},"end":{"line":22,"column":26}},"loc":{"start":{"line":22,"column":61},"end":{"line":60,"column":1}},"line":22},"1":{"name":"(anonymous_1)","decl":{"start":{"line":27,"column":31},"end":{"line":27,"column":32}},"loc":{"start":{"line":27,"column":40},"end":{"line":44,"column":3}},"line":27}},"branchMap":{"0":{"loc":{"start":{"line":22,"column":34},"end":{"line":22,"column":46}},"type":"default-arg","locations":[{"start":{"line":22,"column":44},"end":{"line":22,"column":46}}],"line":22},"1":{"loc":{"start":{"line":22,"column":48},"end":{"line":22,"column":59}},"type":"default-arg","locations":[{"start":{"line":22,"column":57},"end":{"line":22,"column":59}}],"line":22},"2":{"loc":{"start":{"line":23,"column":10},"end":{"line":23,"column":22}},"type":"default-arg","locations":[{"start":{"line":23,"column":20},"end":{"line":23,"column":22}}],"line":23},"3":{"loc":{"start":{"line":23,"column":24},"end":{"line":23,"column":36}},"type":"default-arg","locations":[{"start":{"line":23,"column":34},"end":{"line":23,"column":36}}],"line":23},"4":{"loc":{"start":{"line":24,"column":10},"end":{"line":24,"column":29}},"type":"default-arg","locations":[{"start":{"line":24,"column":27},"end":{"line":24,"column":29}}],"line":24},"5":{"loc":{"start":{"line":24,"column":31},"end":{"line":24,"column":53}},"type":"default-arg","locations":[{"start":{"line":24,"column":51},"end":{"line":24,"column":53}}],"line":24},"6":{"loc":{"start":{"line":24,"column":55},"end":{"line":24,"column":69}},"type":"default-arg","locations":[{"start":{"line":24,"column":67},"end":{"line":24,"column":69}}],"line":24},"7":{"loc":{"start":{"line":29,"column":4},"end":{"line":29,"column":70}},"type":"if","locations":[{"start":{"line":29,"column":4},"end":{"line":29,"column":70}},{"start":{},"end":{}}],"line":29},"8":{"loc":{"start":{"line":29,"column":8},"end":{"line":29,"column":61}},"type":"binary-expr","locations":[{"start":{"line":29,"column":8},"end":{"line":29,"column":27}},{"start":{"line":29,"column":31},"end":{"line":29,"column":45}},{"start":{"line":29,"column":49},"end":{"line":29,"column":61}}],"line":29},"9":{"loc":{"start":{"line":31,"column":4},"end":{"line":43,"column":5}},"type":"if","locations":[{"start":{"line":31,"column":4},"end":{"line":43,"column":5}},{"start":{},"end":{}}],"line":31},"10":{"loc":{"start":{"line":32,"column":21},"end":{"line":32,"column":42}},"type":"binary-expr","locations":[{"start":{"line":32,"column":21},"end":{"line":32,"column":35}},{"start":{"line":32,"column":39},"end":{"line":32,"column":42}}],"line":32},"11":{"loc":{"start":{"line":35,"column":6},"end":{"line":42,"column":7}},"type":"if","locations":[{"start":{"line":35,"column":6},"end":{"line":42,"column":7}},{"start":{"line":37,"column":13},"end":{"line":42,"column":7}}],"line":35},"12":{"loc":{"start":{"line":37,"column":13},"end":{"line":42,"column":7}},"type":"if","locations":[{"start":{"line":37,"column":13},"end":{"line":42,"column":7}},{"start":{"line":39,"column":13},"end":{"line":42,"column":7}}],"line":37},"13":{"loc":{"start":{"line":47,"column":18},"end":{"line":47,"column":32}},"type":"default-arg","locations":[{"start":{"line":47,"column":26},"end":{"line":47,"column":32}}],"line":47},"14":{"loc":{"start":{"line":48,"column":2},"end":{"line":57,"column":3}},"type":"if","locations":[{"start":{"line":48,"column":2},"end":{"line":57,"column":3}},{"start":{"line":52,"column":9},"end":{"line":57,"column":3}}],"line":48},"15":{"loc":{"start":{"line":48,"column":6},"end":{"line":48,"column":50}},"type":"binary-expr","locations":[{"start":{"line":48,"column":6},"end":{"line":48,"column":12}},{"start":{"line":48,"column":16},"end":{"line":48,"column":50}}],"line":48},"16":{"loc":{"start":{"line":49,"column":19},"end":{"line":49,"column":46}},"type":"binary-expr","locations":[{"start":{"line":49,"column":19},"end":{"line":49,"column":36}},{"start":{"line":49,"column":40},"end":{"line":49,"column":46}}],"line":49},"17":{"loc":{"start":{"line":50,"column":22},"end":{"line":50,"column":98}},"type":"cond-expr","locations":[{"start":{"line":50,"column":70},"end":{"line":50,"column":89}},{"start":{"line":50,"column":92},"end":{"line":50,"column":98}}],"line":50},"18":{"loc":{"start":{"line":52,"column":9},"end":{"line":57,"column":3}},"type":"if","locations":[{"start":{"line":52,"column":9},"end":{"line":57,"column":3}},{"start":{},"end":{}}],"line":52},"19":{"loc":{"start":{"line":55,"column":19},"end":{"line":55,"column":56}},"type":"binary-expr","locations":[{"start":{"line":55,"column":19},"end":{"line":55,"column":41}},{"start":{"line":55,"column":45},"end":{"line":55,"column":56}}],"line":55}},"s":{"0":16,"1":16,"2":16,"3":11,"4":11,"5":3,"6":8,"7":7,"8":7,"9":1,"10":6,"11":1,"12":5,"13":16,"14":16,"15":5,"16":5,"17":5,"18":11,"19":10,"20":10,"21":10,"22":16,"23":10},"f":{"0":16,"1":11},"b":{"0":[0],"1":[0],"2":[7],"3":[7],"4":[0],"5":[0],"6":[1],"7":[3,8],"8":[11,10,9],"9":[7,1],"10":[7,4],"11":[1,6],"12":[1,5],"13":[12],"14":[5,11],"15":[16,6],"16":[5,5],"17":[4,1],"18":[10,1],"19":[10,10]},"_coverageSchema":"1a1c01bbd47fc00a2c39e90264f33305004495a9","hash":"3efdc6794edd7ddcb95975c8c04dcb42a4157e79"} +,"C:\\Users\\pc\\Documents\\waves\\Liquifact-backend\\src\\utils\\responseHelper.js": {"path":"C:\\Users\\pc\\Documents\\waves\\Liquifact-backend\\src\\utils\\responseHelper.js","statementMap":{"0":{"start":{"line":3,"column":20},"end":{"line":3,"column":27}},"1":{"start":{"line":8,"column":16},"end":{"line":20,"column":1}},"2":{"start":{"line":9,"column":18},"end":{"line":9,"column":43}},"3":{"start":{"line":10,"column":2},"end":{"line":19,"column":4}},"4":{"start":{"line":25,"column":14},"end":{"line":37,"column":2}},"5":{"start":{"line":25,"column":69},"end":{"line":37,"column":1}},"6":{"start":{"line":39,"column":0},"end":{"line":39,"column":36}}},"fnMap":{"0":{"name":"(anonymous_0)","decl":{"start":{"line":8,"column":16},"end":{"line":8,"column":17}},"loc":{"start":{"line":8,"column":37},"end":{"line":20,"column":1}},"line":8},"1":{"name":"(anonymous_1)","decl":{"start":{"line":25,"column":14},"end":{"line":25,"column":15}},"loc":{"start":{"line":25,"column":69},"end":{"line":37,"column":1}},"line":25}},"branchMap":{"0":{"loc":{"start":{"line":8,"column":23},"end":{"line":8,"column":32}},"type":"default-arg","locations":[{"start":{"line":8,"column":30},"end":{"line":8,"column":32}}],"line":8},"1":{"loc":{"start":{"line":9,"column":18},"end":{"line":9,"column":43}},"type":"binary-expr","locations":[{"start":{"line":9,"column":18},"end":{"line":9,"column":30}},{"start":{"line":9,"column":34},"end":{"line":9,"column":43}}],"line":9},"2":{"loc":{"start":{"line":25,"column":24},"end":{"line":25,"column":47}},"type":"default-arg","locations":[{"start":{"line":25,"column":31},"end":{"line":25,"column":47}}],"line":25},"3":{"loc":{"start":{"line":25,"column":49},"end":{"line":25,"column":63}},"type":"default-arg","locations":[{"start":{"line":25,"column":59},"end":{"line":25,"column":63}}],"line":25}},"s":{"0":8,"1":8,"2":43,"3":43,"4":8,"5":2,"6":8},"f":{"0":43,"1":2},"b":{"0":[32],"1":[43,33],"2":[1],"3":[1]},"_coverageSchema":"1a1c01bbd47fc00a2c39e90264f33305004495a9","hash":"dcedb87c49f49de69c01ea64b93a47ad9fc75a3c"} +,"C:\\Users\\pc\\Documents\\waves\\Liquifact-backend\\src\\utils\\retry.js": {"path":"C:\\Users\\pc\\Documents\\waves\\Liquifact-backend\\src\\utils\\retry.js","statementMap":{"0":{"start":{"line":29,"column":26},"end":{"line":29,"column":28}},"1":{"start":{"line":30,"column":24},"end":{"line":30,"column":29}},"2":{"start":{"line":31,"column":29},"end":{"line":31,"column":34}},"3":{"start":{"line":38,"column":6},"end":{"line":38,"column":13}},"4":{"start":{"line":37,"column":24},"end":{"line":37,"column":28}},"5":{"start":{"line":41,"column":21},"end":{"line":41,"column":74}},"6":{"start":{"line":42,"column":20},"end":{"line":42,"column":75}},"7":{"start":{"line":43,"column":19},"end":{"line":43,"column":68}},"8":{"start":{"line":45,"column":16},"end":{"line":45,"column":17}},"9":{"start":{"line":47,"column":2},"end":{"line":65,"column":3}},"10":{"start":{"line":48,"column":4},"end":{"line":64,"column":5}},"11":{"start":{"line":49,"column":6},"end":{"line":49,"column":31}},"12":{"start":{"line":51,"column":6},"end":{"line":53,"column":7}},"13":{"start":{"line":52,"column":8},"end":{"line":52,"column":20}},"14":{"start":{"line":56,"column":31},"end":{"line":56,"column":63}},"15":{"start":{"line":57,"column":20},"end":{"line":57,"column":56}},"16":{"start":{"line":60,"column":28},"end":{"line":60,"column":63}},"17":{"start":{"line":62,"column":6},"end":{"line":62,"column":16}},"18":{"start":{"line":63,"column":6},"end":{"line":63,"column":73}},"19":{"start":{"line":63,"column":37},"end":{"line":63,"column":71}},"20":{"start":{"line":68,"column":0},"end":{"line":70,"column":2}}},"fnMap":{"0":{"name":"withRetry","decl":{"start":{"line":27,"column":15},"end":{"line":27,"column":24}},"loc":{"start":{"line":27,"column":50},"end":{"line":66,"column":1}},"line":27},"1":{"name":"(anonymous_1)","decl":{"start":{"line":37,"column":18},"end":{"line":37,"column":19}},"loc":{"start":{"line":37,"column":24},"end":{"line":37,"column":28}},"line":37},"2":{"name":"(anonymous_2)","decl":{"start":{"line":63,"column":24},"end":{"line":63,"column":25}},"loc":{"start":{"line":63,"column":37},"end":{"line":63,"column":71}},"line":63}},"branchMap":{"0":{"loc":{"start":{"line":27,"column":36},"end":{"line":27,"column":48}},"type":"default-arg","locations":[{"start":{"line":27,"column":46},"end":{"line":27,"column":48}}],"line":27},"1":{"loc":{"start":{"line":34,"column":16},"end":{"line":34,"column":33}},"type":"default-arg","locations":[{"start":{"line":34,"column":32},"end":{"line":34,"column":33}}],"line":34},"2":{"loc":{"start":{"line":35,"column":15},"end":{"line":35,"column":33}},"type":"default-arg","locations":[{"start":{"line":35,"column":30},"end":{"line":35,"column":33}}],"line":35},"3":{"loc":{"start":{"line":36,"column":14},"end":{"line":36,"column":33}},"type":"default-arg","locations":[{"start":{"line":36,"column":28},"end":{"line":36,"column":33}}],"line":36},"4":{"loc":{"start":{"line":37,"column":4},"end":{"line":37,"column":28}},"type":"default-arg","locations":[{"start":{"line":37,"column":18},"end":{"line":37,"column":28}}],"line":37},"5":{"loc":{"start":{"line":51,"column":6},"end":{"line":53,"column":7}},"type":"if","locations":[{"start":{"line":51,"column":6},"end":{"line":53,"column":7}},{"start":{},"end":{}}],"line":51},"6":{"loc":{"start":{"line":51,"column":10},"end":{"line":51,"column":54}},"type":"binary-expr","locations":[{"start":{"line":51,"column":10},"end":{"line":51,"column":31}},{"start":{"line":51,"column":35},"end":{"line":51,"column":54}}],"line":51}},"s":{"0":6,"1":6,"2":6,"3":6,"4":15,"5":6,"6":6,"7":6,"8":6,"9":6,"10":21,"11":21,"12":19,"13":4,"14":15,"15":15,"16":15,"17":15,"18":15,"19":15,"20":1},"f":{"0":6,"1":15,"2":15},"b":{"0":[1],"1":[1],"2":[1],"3":[5],"4":[5],"5":[4,15],"6":[19,16]},"_coverageSchema":"1a1c01bbd47fc00a2c39e90264f33305004495a9","hash":"8958a6234a6074fac06ae5b2b782ead7d5ab4d9a"} +,"C:\\Users\\pc\\Documents\\waves\\Liquifact-backend\\src\\utils\\validators.js": {"path":"C:\\Users\\pc\\Documents\\waves\\Liquifact-backend\\src\\utils\\validators.js","statementMap":{"0":{"start":{"line":14,"column":17},"end":{"line":14,"column":19}},"1":{"start":{"line":15,"column":26},"end":{"line":18,"column":3}},"2":{"start":{"line":28,"column":6},"end":{"line":28,"column":11}},"3":{"start":{"line":31,"column":2},"end":{"line":38,"column":3}},"4":{"start":{"line":32,"column":26},"end":{"line":32,"column":56}},"5":{"start":{"line":33,"column":4},"end":{"line":37,"column":5}},"6":{"start":{"line":34,"column":6},"end":{"line":34,"column":46}},"7":{"start":{"line":36,"column":6},"end":{"line":36,"column":81}},"8":{"start":{"line":41,"column":2},"end":{"line":47,"column":3}},"9":{"start":{"line":42,"column":4},"end":{"line":46,"column":5}},"10":{"start":{"line":43,"column":6},"end":{"line":43,"column":44}},"11":{"start":{"line":45,"column":6},"end":{"line":45,"column":42}},"12":{"start":{"line":50,"column":2},"end":{"line":56,"column":3}},"13":{"start":{"line":51,"column":4},"end":{"line":55,"column":5}},"14":{"start":{"line":52,"column":6},"end":{"line":52,"column":48}},"15":{"start":{"line":54,"column":6},"end":{"line":54,"column":44}},"16":{"start":{"line":59,"column":20},"end":{"line":59,"column":41}},"17":{"start":{"line":60,"column":2},"end":{"line":66,"column":3}},"18":{"start":{"line":61,"column":4},"end":{"line":65,"column":5}},"19":{"start":{"line":62,"column":6},"end":{"line":62,"column":50}},"20":{"start":{"line":64,"column":6},"end":{"line":64,"column":61}},"21":{"start":{"line":68,"column":2},"end":{"line":74,"column":3}},"22":{"start":{"line":69,"column":4},"end":{"line":73,"column":5}},"23":{"start":{"line":70,"column":6},"end":{"line":70,"column":46}},"24":{"start":{"line":72,"column":6},"end":{"line":72,"column":59}},"25":{"start":{"line":77,"column":2},"end":{"line":84,"column":3}},"26":{"start":{"line":78,"column":28},"end":{"line":78,"column":46}},"27":{"start":{"line":79,"column":4},"end":{"line":83,"column":5}},"28":{"start":{"line":80,"column":6},"end":{"line":80,"column":46}},"29":{"start":{"line":82,"column":6},"end":{"line":82,"column":83}},"30":{"start":{"line":87,"column":2},"end":{"line":94,"column":3}},"31":{"start":{"line":88,"column":23},"end":{"line":88,"column":42}},"32":{"start":{"line":89,"column":4},"end":{"line":93,"column":5}},"33":{"start":{"line":90,"column":6},"end":{"line":90,"column":49}},"34":{"start":{"line":92,"column":6},"end":{"line":92,"column":60}},"35":{"start":{"line":96,"column":2},"end":{"line":100,"column":4}},"36":{"start":{"line":103,"column":0},"end":{"line":105,"column":2}}},"fnMap":{"0":{"name":"validateInvoiceQueryParams","decl":{"start":{"line":13,"column":9},"end":{"line":13,"column":35}},"loc":{"start":{"line":13,"column":43},"end":{"line":101,"column":1}},"line":13}},"branchMap":{"0":{"loc":{"start":{"line":31,"column":2},"end":{"line":38,"column":3}},"type":"if","locations":[{"start":{"line":31,"column":2},"end":{"line":38,"column":3}},{"start":{},"end":{}}],"line":31},"1":{"loc":{"start":{"line":33,"column":4},"end":{"line":37,"column":5}},"type":"if","locations":[{"start":{"line":33,"column":4},"end":{"line":37,"column":5}},{"start":{"line":35,"column":11},"end":{"line":37,"column":5}}],"line":33},"2":{"loc":{"start":{"line":41,"column":2},"end":{"line":47,"column":3}},"type":"if","locations":[{"start":{"line":41,"column":2},"end":{"line":47,"column":3}},{"start":{},"end":{}}],"line":41},"3":{"loc":{"start":{"line":42,"column":4},"end":{"line":46,"column":5}},"type":"if","locations":[{"start":{"line":42,"column":4},"end":{"line":46,"column":5}},{"start":{"line":44,"column":11},"end":{"line":46,"column":5}}],"line":42},"4":{"loc":{"start":{"line":42,"column":8},"end":{"line":42,"column":60}},"type":"binary-expr","locations":[{"start":{"line":42,"column":8},"end":{"line":42,"column":33}},{"start":{"line":42,"column":37},"end":{"line":42,"column":60}}],"line":42},"5":{"loc":{"start":{"line":50,"column":2},"end":{"line":56,"column":3}},"type":"if","locations":[{"start":{"line":50,"column":2},"end":{"line":56,"column":3}},{"start":{},"end":{}}],"line":50},"6":{"loc":{"start":{"line":51,"column":4},"end":{"line":55,"column":5}},"type":"if","locations":[{"start":{"line":51,"column":4},"end":{"line":55,"column":5}},{"start":{"line":53,"column":11},"end":{"line":55,"column":5}}],"line":51},"7":{"loc":{"start":{"line":51,"column":8},"end":{"line":51,"column":64}},"type":"binary-expr","locations":[{"start":{"line":51,"column":8},"end":{"line":51,"column":35}},{"start":{"line":51,"column":39},"end":{"line":51,"column":64}}],"line":51},"8":{"loc":{"start":{"line":60,"column":2},"end":{"line":66,"column":3}},"type":"if","locations":[{"start":{"line":60,"column":2},"end":{"line":66,"column":3}},{"start":{},"end":{}}],"line":60},"9":{"loc":{"start":{"line":61,"column":4},"end":{"line":65,"column":5}},"type":"if","locations":[{"start":{"line":61,"column":4},"end":{"line":65,"column":5}},{"start":{"line":63,"column":11},"end":{"line":65,"column":5}}],"line":61},"10":{"loc":{"start":{"line":61,"column":8},"end":{"line":61,"column":64}},"type":"binary-expr","locations":[{"start":{"line":61,"column":8},"end":{"line":61,"column":32}},{"start":{"line":61,"column":36},"end":{"line":61,"column":64}}],"line":61},"11":{"loc":{"start":{"line":68,"column":2},"end":{"line":74,"column":3}},"type":"if","locations":[{"start":{"line":68,"column":2},"end":{"line":74,"column":3}},{"start":{},"end":{}}],"line":68},"12":{"loc":{"start":{"line":69,"column":4},"end":{"line":73,"column":5}},"type":"if","locations":[{"start":{"line":69,"column":4},"end":{"line":73,"column":5}},{"start":{"line":71,"column":11},"end":{"line":73,"column":5}}],"line":69},"13":{"loc":{"start":{"line":69,"column":8},"end":{"line":69,"column":60}},"type":"binary-expr","locations":[{"start":{"line":69,"column":8},"end":{"line":69,"column":30}},{"start":{"line":69,"column":34},"end":{"line":69,"column":60}}],"line":69},"14":{"loc":{"start":{"line":77,"column":2},"end":{"line":84,"column":3}},"type":"if","locations":[{"start":{"line":77,"column":2},"end":{"line":84,"column":3}},{"start":{},"end":{}}],"line":77},"15":{"loc":{"start":{"line":79,"column":4},"end":{"line":83,"column":5}},"type":"if","locations":[{"start":{"line":79,"column":4},"end":{"line":83,"column":5}},{"start":{"line":81,"column":11},"end":{"line":83,"column":5}}],"line":79},"16":{"loc":{"start":{"line":87,"column":2},"end":{"line":94,"column":3}},"type":"if","locations":[{"start":{"line":87,"column":2},"end":{"line":94,"column":3}},{"start":{},"end":{}}],"line":87},"17":{"loc":{"start":{"line":89,"column":4},"end":{"line":93,"column":5}},"type":"if","locations":[{"start":{"line":89,"column":4},"end":{"line":93,"column":5}},{"start":{"line":91,"column":11},"end":{"line":93,"column":5}}],"line":89}},"s":{"0":24,"1":24,"2":24,"3":24,"4":6,"5":6,"6":2,"7":4,"8":24,"9":2,"10":2,"11":0,"12":24,"13":2,"14":1,"15":1,"16":24,"17":24,"18":5,"19":2,"20":3,"21":24,"22":3,"23":2,"24":1,"25":24,"26":4,"27":4,"28":2,"29":2,"30":24,"31":3,"32":3,"33":2,"34":1,"35":24,"36":9},"f":{"0":24},"b":{"0":[6,18],"1":[2,4],"2":[2,22],"3":[2,0],"4":[2,2],"5":[2,22],"6":[1,1],"7":[2,2],"8":[5,19],"9":[2,3],"10":[5,3],"11":[3,21],"12":[2,1],"13":[3,2],"14":[4,20],"15":[2,2],"16":[3,21],"17":[2,1]},"_coverageSchema":"1a1c01bbd47fc00a2c39e90264f33305004495a9","hash":"9d5c2aeddb0ec651311555a0590f3f841486997f"} } diff --git a/coverage/lcov-report/base.css b/coverage/lcov-report/base.css new file mode 100644 index 00000000..f418035b --- /dev/null +++ b/coverage/lcov-report/base.css @@ -0,0 +1,224 @@ +body, html { + margin:0; padding: 0; + height: 100%; +} +body { + font-family: Helvetica Neue, Helvetica, Arial; + font-size: 14px; + color:#333; +} +.small { font-size: 12px; } +*, *:after, *:before { + -webkit-box-sizing:border-box; + -moz-box-sizing:border-box; + box-sizing:border-box; + } +h1 { font-size: 20px; margin: 0;} +h2 { font-size: 14px; } +pre { + font: 12px/1.4 Consolas, "Liberation Mono", Menlo, Courier, monospace; + margin: 0; + padding: 0; + -moz-tab-size: 2; + -o-tab-size: 2; + tab-size: 2; +} +a { color:#0074D9; text-decoration:none; } +a:hover { text-decoration:underline; } +.strong { font-weight: bold; } +.space-top1 { padding: 10px 0 0 0; } +.pad2y { padding: 20px 0; } +.pad1y { padding: 10px 0; } +.pad2x { padding: 0 20px; } +.pad2 { padding: 20px; } +.pad1 { padding: 10px; } +.space-left2 { padding-left:55px; } +.space-right2 { padding-right:20px; } +.center { text-align:center; } +.clearfix { display:block; } +.clearfix:after { + content:''; + display:block; + height:0; + clear:both; + visibility:hidden; + } +.fl { float: left; } +@media only screen and (max-width:640px) { + .col3 { width:100%; max-width:100%; } + .hide-mobile { display:none!important; } +} + +.quiet { + color: #7f7f7f; + color: rgba(0,0,0,0.5); +} +.quiet a { opacity: 0.7; } + +.fraction { + font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace; + font-size: 10px; + color: #555; + background: #E8E8E8; + padding: 4px 5px; + border-radius: 3px; + vertical-align: middle; +} + +div.path a:link, div.path a:visited { color: #333; } +table.coverage { + border-collapse: collapse; + margin: 10px 0 0 0; + padding: 0; +} + +table.coverage td { + margin: 0; + padding: 0; + vertical-align: top; +} +table.coverage td.line-count { + text-align: right; + padding: 0 5px 0 20px; +} +table.coverage td.line-coverage { + text-align: right; + padding-right: 10px; + min-width:20px; +} + +table.coverage td span.cline-any { + display: inline-block; + padding: 0 5px; + width: 100%; +} +.missing-if-branch { + display: inline-block; + margin-right: 5px; + border-radius: 3px; + position: relative; + padding: 0 4px; + background: #333; + color: yellow; +} + +.skip-if-branch { + display: none; + margin-right: 10px; + position: relative; + padding: 0 4px; + background: #ccc; + color: white; +} +.missing-if-branch .typ, .skip-if-branch .typ { + color: inherit !important; +} +.coverage-summary { + border-collapse: collapse; + width: 100%; +} +.coverage-summary tr { border-bottom: 1px solid #bbb; } +.keyline-all { border: 1px solid #ddd; } +.coverage-summary td, .coverage-summary th { padding: 10px; } +.coverage-summary tbody { border: 1px solid #bbb; } +.coverage-summary td { border-right: 1px solid #bbb; } +.coverage-summary td:last-child { border-right: none; } +.coverage-summary th { + text-align: left; + font-weight: normal; + white-space: nowrap; +} +.coverage-summary th.file { border-right: none !important; } +.coverage-summary th.pct { } +.coverage-summary th.pic, +.coverage-summary th.abs, +.coverage-summary td.pct, +.coverage-summary td.abs { text-align: right; } +.coverage-summary td.file { white-space: nowrap; } +.coverage-summary td.pic { min-width: 120px !important; } +.coverage-summary tfoot td { } + +.coverage-summary .sorter { + height: 10px; + width: 7px; + display: inline-block; + margin-left: 0.5em; + background: url(sort-arrow-sprite.png) no-repeat scroll 0 0 transparent; +} +.coverage-summary .sorted .sorter { + background-position: 0 -20px; +} +.coverage-summary .sorted-desc .sorter { + background-position: 0 -10px; +} +.status-line { height: 10px; } +/* yellow */ +.cbranch-no { background: yellow !important; color: #111; } +/* dark red */ +.red.solid, .status-line.low, .low .cover-fill { background:#C21F39 } +.low .chart { border:1px solid #C21F39 } +.highlighted, +.highlighted .cstat-no, .highlighted .fstat-no, .highlighted .cbranch-no{ + background: #C21F39 !important; +} +/* medium red */ +.cstat-no, .fstat-no, .cbranch-no, .cbranch-no { background:#F6C6CE } +/* light red */ +.low, .cline-no { background:#FCE1E5 } +/* light green */ +.high, .cline-yes { background:rgb(230,245,208) } +/* medium green */ +.cstat-yes { background:rgb(161,215,106) } +/* dark green */ +.status-line.high, .high .cover-fill { background:rgb(77,146,33) } +.high .chart { border:1px solid rgb(77,146,33) } +/* dark yellow (gold) */ +.status-line.medium, .medium .cover-fill { background: #f9cd0b; } +.medium .chart { border:1px solid #f9cd0b; } +/* light yellow */ +.medium { background: #fff4c2; } + +.cstat-skip { background: #ddd; color: #111; } +.fstat-skip { background: #ddd; color: #111 !important; } +.cbranch-skip { background: #ddd !important; color: #111; } + +span.cline-neutral { background: #eaeaea; } + +.coverage-summary td.empty { + opacity: .5; + padding-top: 4px; + padding-bottom: 4px; + line-height: 1; + color: #888; +} + +.cover-fill, .cover-empty { + display:inline-block; + height: 12px; +} +.chart { + line-height: 0; +} +.cover-empty { + background: white; +} +.cover-full { + border-right: none !important; +} +pre.prettyprint { + border: none !important; + padding: 0 !important; + margin: 0 !important; +} +.com { color: #999 !important; } +.ignore-none { color: #999; font-weight: normal; } + +.wrapper { + min-height: 100%; + height: auto !important; + height: 100%; + margin: 0 auto -48px; +} +.footer, .push { + height: 48px; +} diff --git a/coverage/lcov-report/block-navigation.js b/coverage/lcov-report/block-navigation.js new file mode 100644 index 00000000..530d1ed2 --- /dev/null +++ b/coverage/lcov-report/block-navigation.js @@ -0,0 +1,87 @@ +/* eslint-disable */ +var jumpToCode = (function init() { + // Classes of code we would like to highlight in the file view + var missingCoverageClasses = ['.cbranch-no', '.cstat-no', '.fstat-no']; + + // Elements to highlight in the file listing view + var fileListingElements = ['td.pct.low']; + + // We don't want to select elements that are direct descendants of another match + var notSelector = ':not(' + missingCoverageClasses.join('):not(') + ') > '; // becomes `:not(a):not(b) > ` + + // Selector that finds elements on the page to which we can jump + var selector = + fileListingElements.join(', ') + + ', ' + + notSelector + + missingCoverageClasses.join(', ' + notSelector); // becomes `:not(a):not(b) > a, :not(a):not(b) > b` + + // The NodeList of matching elements + var missingCoverageElements = document.querySelectorAll(selector); + + var currentIndex; + + function toggleClass(index) { + missingCoverageElements + .item(currentIndex) + .classList.remove('highlighted'); + missingCoverageElements.item(index).classList.add('highlighted'); + } + + function makeCurrent(index) { + toggleClass(index); + currentIndex = index; + missingCoverageElements.item(index).scrollIntoView({ + behavior: 'smooth', + block: 'center', + inline: 'center' + }); + } + + function goToPrevious() { + var nextIndex = 0; + if (typeof currentIndex !== 'number' || currentIndex === 0) { + nextIndex = missingCoverageElements.length - 1; + } else if (missingCoverageElements.length > 1) { + nextIndex = currentIndex - 1; + } + + makeCurrent(nextIndex); + } + + function goToNext() { + var nextIndex = 0; + + if ( + typeof currentIndex === 'number' && + currentIndex < missingCoverageElements.length - 1 + ) { + nextIndex = currentIndex + 1; + } + + makeCurrent(nextIndex); + } + + return function jump(event) { + if ( + document.getElementById('fileSearch') === document.activeElement && + document.activeElement != null + ) { + // if we're currently focused on the search input, we don't want to navigate + return; + } + + switch (event.which) { + case 78: // n + case 74: // j + goToNext(); + break; + case 66: // b + case 75: // k + case 80: // p + goToPrevious(); + break; + } + }; +})(); +window.addEventListener('keydown', jumpToCode); diff --git a/coverage/lcov-report/favicon.png b/coverage/lcov-report/favicon.png new file mode 100644 index 00000000..c1525b81 Binary files /dev/null and b/coverage/lcov-report/favicon.png differ diff --git a/coverage/lcov-report/index.html b/coverage/lcov-report/index.html index be00e711..e92864e9 100644 --- a/coverage/lcov-report/index.html +++ b/coverage/lcov-report/index.html @@ -23,48 +23,30 @@

All files

- 100% + 96.01% Statements -<<<<<<< HEAD - 33/33 -======= - 29/29 ->>>>>>> main + 361/376
-<<<<<<< HEAD - 100% + 88.93% Branches - 13/13 -======= - 91.66% - Branches - 11/12 ->>>>>>> main + 233/262
- 100% + 95.38% Functions -<<<<<<< HEAD - 10/10 -======= - 6/6 ->>>>>>> main + 62/65
- 100% + 97.16% Lines -<<<<<<< HEAD - 31/31 -======= - 27/27 ->>>>>>> main + 343/353
@@ -97,62 +79,108 @@

All files

-<<<<<<< HEAD src -======= - services ->>>>>>> main + +
+ + 97.43% + 76/78 + 78.57% + 11/14 + 93.33% + 14/15 + 97.26% + 71/73 + + + + src/config + +
+ + 92.59% + 25/27 + 88.88% + 16/18 + 88.88% + 8/9 + 91.66% + 22/24 + + + + src/errors
100% -<<<<<<< HEAD - 27/27 + 9/9 100% - 10/10 + 4/4 100% - 8/8 + 1/1 100% - 27/27 + 9/9 - src/utils + src/middleware + +
+ + 96.22% + 102/106 + 89.32% + 92/103 + 95.45% + 21/22 + 96.15% + 100/104 + + + + src/schemas
100% - 6/6 - 100% - 3/3 + 9/9 100% - 2/2 + 0/0 100% - 4/4 -======= - 8/8 - 66.66% - 2/3 + 0/0 100% - 3/3 + 9/9 + + + + src/services + +
+ + 87.75% + 43/49 + 75% + 24/32 100% 7/7 + 97.43% + 38/39 - utils - -
+ src/utils + +
+ 98.97% + 97/98 + 94.5% + 86/91 100% - 21/21 - 100% - 9/9 - 100% - 3/3 - 100% - 20/20 ->>>>>>> main + 11/11 + 98.94% + 94/95 @@ -163,11 +191,7 @@

All files

+ + + + + + \ No newline at end of file diff --git a/coverage/lcov-report/src/config/index.html b/coverage/lcov-report/src/config/index.html new file mode 100644 index 00000000..af76e7ec --- /dev/null +++ b/coverage/lcov-report/src/config/index.html @@ -0,0 +1,116 @@ + + + + + + Code coverage report for src/config + + + + + + + + + +
+
+

All files src/config

+
+ +
+ 92.59% + Statements + 25/27 +
+ + +
+ 88.88% + Branches + 16/18 +
+ + +
+ 88.88% + Functions + 8/9 +
+ + +
+ 91.66% + Lines + 22/24 +
+ + +
+

+ Press n or j to go to the next uncovered block, b, p or k for the previous block. +

+ +
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FileStatementsBranchesFunctionsLines
cors.js +
+
92.59%25/2788.88%16/1888.88%8/991.66%22/24
+
+
+
+ + + + + + + + \ No newline at end of file diff --git a/coverage/lcov-report/src/errors/AppError.js.html b/coverage/lcov-report/src/errors/AppError.js.html index 8a486e87..f2cba899 100644 --- a/coverage/lcov-report/src/errors/AppError.js.html +++ b/coverage/lcov-report/src/errors/AppError.js.html @@ -105,20 +105,20 @@

All files / src/errors      -7x -7x -7x -7x -7x -7x -7x +14x +14x +14x +14x +14x +14x +14x     -7x +14x       -3x +13x  
/**
  * Custom Error class for RFC 7807 compliant errors.
  * Extends the built-in Error class to include Problem Details fields.
@@ -154,7 +154,7 @@ 

All files / src/errors Code coverage generated by istanbul - at 2026-03-24T16:16:02.972Z + at 2026-03-28T17:44:46.485Z

+ + + + + + \ No newline at end of file diff --git a/coverage/lcov-report/src/middleware/deprecation.js.html b/coverage/lcov-report/src/middleware/deprecation.js.html new file mode 100644 index 00000000..9f0cd2fc --- /dev/null +++ b/coverage/lcov-report/src/middleware/deprecation.js.html @@ -0,0 +1,178 @@ + + + + + + Code coverage report for src/middleware/deprecation.js + + + + + + + + + +
+
+

All files / src/middleware deprecation.js

+
+ +
+ 100% + Statements + 11/11 +
+ + +
+ 42.85% + Branches + 3/7 +
+ + +
+ 100% + Functions + 2/2 +
+ + +
+ 100% + Lines + 11/11 +
+ + +
+

+ Press n or j to go to the next uncovered block, b, p or k for the previous block. +

+ +
+
+

+
1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +11 +12 +13 +14 +15 +16 +17 +18 +19 +20 +21 +22 +23 +24 +25 +26 +27 +28 +29 +30 +31 +32  +  +  +  +  +  +  +  +1x +1x +  +3x +  +3x +3x +  +3x +3x +  +  +  +3x +  +3x +  +  +3x +  +  +  +1x + 
/**
+ * Middleware to signal API deprecation via HTTP headers (RFC 8594).
+ * * @param {Object} options - Configuration for the deprecation headers.
+ * @param {string} [options.sunset] - ISO 8601 date string (e.g., '2026-12-31T23:59:59Z').
+ * @param {string} [options.link] - URL pointing to migration documentation or new endpoint.
+ * @param options
+ * @returns {Function} Express middleware function.
+ */
+const deprecate = (options = {}) => {
+  return (req, res, next) => {
+    // Standard Deprecation header
+    res.setHeader('Deprecation', 'true');
+ 
+    Eif (options.sunset) {
+      const sunsetDate = new Date(options.sunset);
+      // Ensure the date is valid before setting header
+      Eif (!isNaN(sunsetDate.getTime())) {
+        res.setHeader('Sunset', sunsetDate.toUTCString());
+      }
+    }
+ 
+    Eif (options.link) {
+      // rel="deprecation" is the RFC-standard link relation
+      res.setHeader('Link', `<${options.link}>; rel="deprecation"`);
+    }
+ 
+    next();
+  };
+};
+ 
+module.exports = { deprecate };
+ 
+ +
+
+ + + + + + + + \ No newline at end of file diff --git a/coverage/lcov-report/src/middleware/errorHandler.js.html b/coverage/lcov-report/src/middleware/errorHandler.js.html index 8d9ce2f6..14e96818 100644 --- a/coverage/lcov-report/src/middleware/errorHandler.js.html +++ b/coverage/lcov-report/src/middleware/errorHandler.js.html @@ -25,14 +25,14 @@

All files / src/middlewa
100% Statements - 9/9 + 14/14
- 100% + 93.93% Branches - 4/4 + 31/33
@@ -46,7 +46,7 @@

All files / src/middlewa
100% Lines - 9/9 + 14/14
@@ -101,8 +101,60 @@

All files / src/middlewa 36 37 38 -392x -2x +39 +40 +41 +42 +43 +44 +45 +46 +47 +48 +49 +50 +51 +52 +53 +54 +55 +56 +57 +58 +59 +60 +61 +62 +63 +64 +65 +66 +67 +68 +69 +70  +  +11x +11x +  +  +  +  +  +  +  +  +  +  +  +  +20x +  +  +  +20x +10x +        @@ -111,10 +163,11 @@

All files / src/middlewa       -6x -4x +10x +8x     +10x       @@ -122,33 +175,52 @@

All files / src/middlewa       -2x -2x             +20x +20x         -6x -6x   +20x   -2x - 
const AppError = require('../errors/AppError');
+ 
+ 
+ 
+ 
+ 
+20x
+ 
+20x
+ 
+ 
+11x
+ 
'use strict';
+ 
+const AppError = require('../errors/AppError');
 const formatProblemDetails = require('../utils/problemDetails');
  
 /**
- * Global Error Handling Middleware for RFC 7807 compliant error responses.
+ * Global error handling middleware
+ * Unifies RFC 7807 Problem Details and Issue 19 Standard Response Envelopes.
  */
 function errorHandler(err, req, res, _next) {
-  let problem;
+  /* istanbul ignore next */
+  if (res.headersSent) {
+    return _next(err);
+  }
  
-  // Check if it's a known AppError instance
+  // Determine status code
+  const status = err.status || err.statusCode || 500;
+ 
+  // Create Problem Details object
+  let problem;
   if (err instanceof AppError) {
     problem = formatProblemDetails({
       type: err.type,
@@ -159,21 +231,42 @@ 

All files / src/middlewa stack: err.stack, }); } else { - // If it's an unknown error, provide a fallback 500 status - console.error('Unhandled Error:', err); + // Log unexpected errors + if (status === 500) { + console.error('Unhandled Error:', err); + } +  problem = formatProblemDetails({ - type: 'https://example.com/probs/unexpected-error', - title: 'Internal Server Error', - status: 500, - detail: 'An unexpected error occurred while processing your request.', + type: 'https://liquifact.com/probs/unexpected-error', + title: status === 500 ? 'Internal Server Error' : (err.name || 'Error'), + status: status, + detail: (status === 500 && process.env.NODE_ENV === 'production') + ? 'An unexpected error occurred while processing your request.' + : (status === 500 ? err.toString() : (err.message || 'Error occurred')), instance: req.originalUrl, stack: err.stack, }); }   - // RFC 7807 requires the Content-Type to be 'application/problem+json' + // Issue 19: Standard Response Envelope compatibility + // We attach these directly to the problem object + problem.data = null; + problem.meta = { + version: '0.1.0', + timestamp: new Date().toISOString() + }; +  + // The 'error' field should contain the message/code for tests + problem.error = { + message: problem.title, // Map title to message + code: err.code || (status === 404 ? 'NOT_FOUND' : (status === 400 ? 'BAD_REQUEST' : 'INTERNAL_ERROR')), + details: (process.env.NODE_ENV !== 'production' && status === 500) ? problem.detail : (status === 400 ? problem.detail : null) + }; +  + // RFC 7807: Content-Type must be 'application/problem+json' res.header('Content-Type', 'application/problem+json'); - res.status(problem.status).json(problem); +  + return res.status(status).json(problem); }   module.exports = errorHandler; @@ -184,7 +277,7 @@

All files / src/middlewa + + + + + + \ No newline at end of file diff --git a/coverage/lcov-report/src/middleware/validate.js.html b/coverage/lcov-report/src/middleware/validate.js.html new file mode 100644 index 00000000..2602b53a --- /dev/null +++ b/coverage/lcov-report/src/middleware/validate.js.html @@ -0,0 +1,262 @@ + + + + + + Code coverage report for src/middleware/validate.js + + + + + + + + + +
+
+

All files / src/middleware validate.js

+
+ +
+ 95.65% + Statements + 22/23 +
+ + +
+ 81.81% + Branches + 9/11 +
+ + +
+ 100% + Functions + 6/6 +
+ + +
+ 95.23% + Lines + 20/21 +
+ + +
+

+ Press n or j to go to the next uncovered block, b, p or k for the previous block. +

+ +
+
+

+
1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +11 +12 +13 +14 +15 +16 +17 +18 +19 +20 +21 +22 +23 +24 +25 +26 +27 +28 +29 +30 +31 +32 +33 +34 +35 +36 +37 +38 +39 +40 +41 +42 +43 +44 +45 +46 +47 +48 +49 +50 +51 +52 +53 +54 +55 +56 +57 +58 +59 +609x +9x +  +  +  +  +21x +21x +21x +18x +18x +  +3x +3x +  +  +  +3x +  +  +  +  +  +  +  +  +  +  +38x +29x +  +29x +  +29x +4x +  +  +25x +25x +25x +  +  +  +  +  +  +  +  +  +  +  +  +29x +  +  +9x +  +  +  + 
const { ZodError } = require('zod');
+const AppError = require('../errors/AppError');
+ 
+/**
+ * Middleware to validate the request part (body, query, params) against a Zod schema.
+ */
+const validateRequest = (schema, part = 'body') => (req, res, next) => {
+    try {
+        const validatedPart = schema.parse(req[part]);
+        req[part] = validatedPart;
+        next();
+    } catch (error) {
+        Eif (error instanceof ZodError) {
+            return next(new AppError({
+                type: 'https://liquifact.com/probs/validation-error',
+                title: 'Validation Failed',
+                status: 400,
+                detail: (error.issues || []).map(e => `${e.path.join('.')}: ${e.message}`).join(', '),
+                instance: req.originalUrl,
+            }));
+        }
+        next(error);
+    }
+};
+ 
+/**
+ * Middleware to validate the response body against a Zod schema.
+ */
+const validateResponse = (schema) => (req, res, next) => {
+    const originalJson = res.json;
+ 
+    res.json = function (body) {
+        // Skip validation for known error shapes or non-objects
+        if (body && (body.title || body.error || typeof body !== 'object')) {
+            return originalJson.call(this, body);
+        }
+ 
+        try {
+            const validatedBody = schema.parse(body);
+            return originalJson.call(this, validatedBody);
+        } catch (error) {
+            /* istanbul ignore next */
+            if (error instanceof ZodError) {
+                console.error('Response validation failed:', error.issues);
+                return originalJson.call(this.status(500), { error: 'Internal server error: Response validation failed' });
+            }
+            // In rare cases where another error happens, just throw
+            /* istanbul ignore next */
+            return originalJson.call(this.status(500), { error: 'Internal server error' });
+        }
+    };
+ 
+    next();
+};
+ 
+module.exports = {
+    validateRequest,
+    validateResponse,
+};
+ 
+ +
+
+ + + + + + + + \ No newline at end of file diff --git a/coverage/lcov-report/src/schemas/apiSchemas.js.html b/coverage/lcov-report/src/schemas/apiSchemas.js.html new file mode 100644 index 00000000..722789a5 --- /dev/null +++ b/coverage/lcov-report/src/schemas/apiSchemas.js.html @@ -0,0 +1,232 @@ + + + + + + Code coverage report for src/schemas/apiSchemas.js + + + + + + + + + +
+
+

All files / src/schemas apiSchemas.js

+
+ +
+ 100% + Statements + 9/9 +
+ + +
+ 100% + Branches + 0/0 +
+ + +
+ 100% + Functions + 0/0 +
+ + +
+ 100% + Lines + 9/9 +
+ + +
+

+ Press n or j to go to the next uncovered block, b, p or k for the previous block. +

+ +
+
+

+
1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +11 +12 +13 +14 +15 +16 +17 +18 +19 +20 +21 +22 +23 +24 +25 +26 +27 +28 +29 +30 +31 +32 +33 +34 +35 +36 +37 +38 +39 +40 +41 +42 +43 +44 +45 +46 +47 +48 +49 +508x +  +8x +  +  +  +  +8x +  +  +  +  +  +8x +  +  +  +  +  +  +  +8x +  +  +  +  +  +8x +  +  +  +8x +  +  +  +8x +  +  +  +8x +  +  +  +  +  +  +  +  +  + 
const { z } = require('zod');
+ 
+const MetaSchema = z.object({
+    version: z.string(),
+    timestamp: z.string(),
+}).passthrough();
+ 
+const ErrorSchema = z.object({
+    message: z.string(),
+    code: z.string().optional(),
+    details: z.any().nullable().optional(),
+}).nullable();
+ 
+const InvoiceSchema = z.object({
+    id: z.union([z.string(), z.number()]),
+    amount: z.number().positive(),
+    customer: z.string().optional(),
+    status: z.string(),
+    createdAt: z.string().optional(),
+}).passthrough();
+ 
+const BaseResponseSchema = z.object({
+    meta: MetaSchema,
+    error: ErrorSchema,
+    message: z.string().optional().nullable(),
+});
+ 
+const CreateInvoiceResponseSchema = BaseResponseSchema.extend({
+    data: InvoiceSchema,
+});
+ 
+const InvoiceListResponseSchema = BaseResponseSchema.extend({
+    data: z.array(InvoiceSchema),
+});
+ 
+const DeleteRestoreInvoiceResponseSchema = BaseResponseSchema.extend({
+    data: InvoiceSchema,
+});
+ 
+module.exports = {
+    InvoiceSchema,
+    CreateInvoiceRequestSchema: z.object({
+        amount: z.number().positive(),
+        customer: z.string().optional(),
+    }),
+    CreateInvoiceResponseSchema,
+    InvoiceListResponseSchema,
+    DeleteRestoreInvoiceResponseSchema
+};
+ 
+ +
+
+ + + + + + + + \ No newline at end of file diff --git a/coverage/lcov-report/src/schemas/index.html b/coverage/lcov-report/src/schemas/index.html new file mode 100644 index 00000000..46249f15 --- /dev/null +++ b/coverage/lcov-report/src/schemas/index.html @@ -0,0 +1,116 @@ + + + + + + Code coverage report for src/schemas + + + + + + + + + +
+
+

All files src/schemas

+
+ +
+ 100% + Statements + 9/9 +
+ + +
+ 100% + Branches + 0/0 +
+ + +
+ 100% + Functions + 0/0 +
+ + +
+ 100% + Lines + 9/9 +
+ + +
+

+ Press n or j to go to the next uncovered block, b, p or k for the previous block. +

+ +
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FileStatementsBranchesFunctionsLines
apiSchemas.js +
+
100%9/9100%0/0100%0/0100%9/9
+
+
+
+ + + + + + + + \ No newline at end of file diff --git a/coverage/lcov-report/src/services/index.html b/coverage/lcov-report/src/services/index.html new file mode 100644 index 00000000..43daa0fc --- /dev/null +++ b/coverage/lcov-report/src/services/index.html @@ -0,0 +1,131 @@ + + + + + + Code coverage report for src/services + + + + + + + + + +
+
+

All files src/services

+
+ +
+ 87.75% + Statements + 43/49 +
+ + +
+ 75% + Branches + 24/32 +
+ + +
+ 100% + Functions + 7/7 +
+ + +
+ 97.43% + Lines + 38/39 +
+ + +
+

+ Press n or j to go to the next uncovered block, b, p or k for the previous block. +

+ +
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FileStatementsBranchesFunctionsLines
invoice.service.js +
+
100%10/10100%0/0100%1/1100%10/10
soroban.js +
+
84.61%33/3975%24/32100%6/696.55%28/29
+
+
+
+ + + + + + + + \ No newline at end of file diff --git a/coverage/lcov-report/src/services/soroban.js.html b/coverage/lcov-report/src/services/soroban.js.html new file mode 100644 index 00000000..744e8efc --- /dev/null +++ b/coverage/lcov-report/src/services/soroban.js.html @@ -0,0 +1,502 @@ + + + + + + Code coverage report for src/services/soroban.js + + + + + + + + + +
+
+

All files / src/services soroban.js

+
+ +
+ 84.61% + Statements + 33/39 +
+ + +
+ 75% + Branches + 24/32 +
+ + +
+ 100% + Functions + 6/6 +
+ + +
+ 96.55% + Lines + 28/29 +
+ + +
+

+ Press n or j to go to the next uncovered block, b, p or k for the previous block. +

+ +
+
+

+
1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +11 +12 +13 +14 +15 +16 +17 +18 +19 +20 +21 +22 +23 +24 +25 +26 +27 +28 +29 +30 +31 +32 +33 +34 +35 +36 +37 +38 +39 +40 +41 +42 +43 +44 +45 +46 +47 +48 +49 +50 +51 +52 +53 +54 +55 +56 +57 +58 +59 +60 +61 +62 +63 +64 +65 +66 +67 +68 +69 +70 +71 +72 +73 +74 +75 +76 +77 +78 +79 +80 +81 +82 +83 +84 +85 +86 +87 +88 +89 +90 +91 +92 +93 +94 +95 +96 +97 +98 +99 +100 +101 +102 +103 +104 +105 +106 +107 +108 +109 +110 +111 +112 +113 +114 +115 +116 +117 +118 +119 +120 +121 +122 +123 +124 +125 +126 +127 +128 +129 +130 +131 +132 +133 +134 +135 +136 +137 +138 +139 +140  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +9x +  +  +  +  +  +  +  +  +  +  +9x +  +  +  +  +  +  +  +  +1x +  +  +  +  +  +  +  +  +  +  +  +  +  +1x +1x +1x +1x +1x +  +  +  +  +  +  +  +  +  +  +8x +  +  +8x +  +  +8x +8x +  +  +8x +8x +7x +4x +  +4x +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +5x +5x +  +  +5x +6x +6x +  +2x +2x +  +1x +1x +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +5x +  +  +9x +  +  +  +  +  +  +  + 
/**
+ * @fileoverview Soroban contract interaction wrappers for the LiquiFact API.
+ *
+ * Wraps raw Soroban / Horizon API calls with the project's exponential-backoff
+ * retry utility so that all escrow and invoice state interactions are
+ * fault-tolerant against transient network or rate-limit errors.
+ *
+ * @module services/soroban
+ */
+ 
+'use strict';
+ 
+/**
+ * Retry configuration used for all Soroban contract calls.
+ *
+ * @constant {Object} SOROBAN_RETRY_CONFIG
+ * @property {number} maxRetries  - Maximum number of retry attempts (hard-capped at 10).
+ * @property {number} baseDelay   - Initial back-off delay in milliseconds.
+ * @property {number} maxDelay    - Maximum delay between retries in milliseconds.
+ */
+const SOROBAN_RETRY_CONFIG = {
+  maxRetries: parseInt(process.env.SOROBAN_MAX_RETRIES || '3', 10),
+  baseDelay: parseInt(process.env.SOROBAN_BASE_DELAY || '200', 10),
+  maxDelay: parseInt(process.env.SOROBAN_MAX_DELAY || '5000', 10),
+};
+ 
+/**
+ * Retryable HTTP status codes from Soroban / Horizon.
+ *
+ * @constant {Set<number>}
+ */
+const RETRYABLE_STATUS_CODES = new Set([429, 502, 503, 504]);
+ 
+/**
+ * Sleeps for `ms` milliseconds.
+ *
+ * @param {number} ms - Duration to sleep.
+ * @returns {Promise<void>}
+ */
+function sleep(ms) {
+  return new Promise((resolve) => setTimeout(resolve, ms));
+}
+ 
+/**
+ * Computes the next back-off delay using exponential backoff with ±20% jitter.
+ *
+ * The result is clamped to `[0, maxDelay]`.
+ *
+ * @param {number} attempt    - Zero-based attempt index.
+ * @param {number} baseDelay  - Base delay in ms.
+ * @param {number} maxDelay   - Ceiling in ms (hard-capped at 60 000 ms).
+ * @returns {number} Delay in milliseconds.
+ */
+function computeBackoff(attempt, baseDelay, maxDelay) {
+  const safeCap = Math.min(maxDelay, 60_000);
+  const safeBase = Math.min(baseDelay, 10_000);
+  const exp = safeBase * 2 ** attempt;
+  const jitter = exp * 0.2 * (Math.random() * 2 - 1); // ±20%
+  return Math.min(Math.max(0, Math.round(exp + jitter)), safeCap);
+}
+ 
+/**
+ * Determines whether an error from a Soroban call is transient and should
+ * trigger a retry.
+ *
+ * @param {unknown} err - Error thrown by the operation.
+ * @returns {boolean} `true` if the call should be retried.
+ */
+function isRetryable(err) {
+  Iif (!err) return false;
+ 
+  // Check explicit code property
+  Iif (err.code === 'ECONNRESET' || err.code === 'ETIMEDOUT') return true;
+ 
+  // Check HTTP status code
+  Iif (err.status != null && RETRYABLE_STATUS_CODES.has(err.status)) return true;
+  Iif (err.response && RETRYABLE_STATUS_CODES.has(err.response.status)) return true;
+ 
+  // Alias for compatibility with tests that check message content
+  const msg = err.message || '';
+  if (/timeout/i.test(msg)) return true;
+  if (/429|502|503|504/i.test(msg)) return true;
+  Iif (/rate limit/i.test(msg)) return true;
+ 
+  return false;
+}
+ 
+/**
+ * Executes `operation` with automatic exponential-backoff retries for
+ * transient Soroban / Horizon errors.
+ *
+ * @template T
+ * @param {() => Promise<T>} operation - Async function to execute and retry.
+ * @param {Object} [config]            - Optional retry configuration override.
+ * @param {number} [config.maxRetries] - Max retry attempts (default 3).
+ * @param {number} [config.baseDelay]  - Base delay in ms (default 200).
+ * @param {number} [config.maxDelay]   - Max delay in ms (default 5 000).
+ * @returns {Promise<T>} Resolved value of `operation`.
+ */
+async function withRetry(operation, config) {
+  const cfg = Object.assign({}, SOROBAN_RETRY_CONFIG, config);
+  const maxRetries = Math.min(cfg.maxRetries, 10);
+ 
+  let lastErr;
+  for (let attempt = 0; attempt <= maxRetries; attempt++) {
+    try {
+      return await operation();
+    } catch (err) {
+      lastErr = err;
+      if (attempt >= maxRetries || !isRetryable(err)) throw err;
+ 
+      const delay = computeBackoff(attempt, cfg.baseDelay, cfg.maxDelay);
+      await sleep(delay);
+    }
+  }
+ 
+  throw lastErr;
+}
+ 
+/**
+ * Calls a Soroban contract operation with automatic retry on transient errors.
+ *
+ * @template T
+ * @param {() => Promise<T>} operation - Async function wrapping the contract call.
+ * @param {Object} [config]            - Optional retry configuration override.
+ * @returns {Promise<T>} Result of the contract call.
+ */
+async function callSorobanContract(operation, config) {
+  return withRetry(operation, config);
+}
+ 
+module.exports = {
+  callSorobanContract,
+  withRetry,
+  computeBackoff,
+  isRetryable,
+  isTransientError: isRetryable, // Alias for tests
+  SOROBAN_RETRY_CONFIG,
+  RETRYABLE_STATUS_CODES,
+};
+ +
+
+ + + + + + + + \ No newline at end of file diff --git a/coverage/lcov-report/src/utils/asyncHandler.js.html b/coverage/lcov-report/src/utils/asyncHandler.js.html new file mode 100644 index 00000000..3b9d69f4 --- /dev/null +++ b/coverage/lcov-report/src/utils/asyncHandler.js.html @@ -0,0 +1,124 @@ + + + + + + Code coverage report for src/utils/asyncHandler.js + + + + + + + + + +
+
+

All files / src/utils asyncHandler.js

+
+ +
+ 100% + Statements + 4/4 +
+ + +
+ 100% + Branches + 0/0 +
+ + +
+ 100% + Functions + 2/2 +
+ + +
+ 100% + Lines + 4/4 +
+ + +
+

+ Press n or j to go to the next uncovered block, b, p or k for the previous block. +

+ +
+
+

+
1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +11 +12 +13 +14  +  +  +  +  +  +  +10x +43x +19x +  +  +  +10x
/**
+ * Wrap async route handlers to forward errors to Express middleware.
+ * Eliminates need for try/catch in every controller.
+ *
+ * @param {Function} fn - Async route handler
+ * @returns {Function} Express middleware
+ */
+const asyncHandler = (fn) => {
+  return function (req, res, next) {
+    Promise.resolve(fn(req, res, next)).catch(next);
+  };
+};
+ 
+module.exports = asyncHandler;
+ +
+
+ + + + + + + + \ No newline at end of file diff --git a/coverage/lcov-report/src/utils/index.html b/coverage/lcov-report/src/utils/index.html index a83f3853..a87e9fe9 100644 --- a/coverage/lcov-report/src/utils/index.html +++ b/coverage/lcov-report/src/utils/index.html @@ -23,30 +23,30 @@

All files src/utils

- 100% + 98.97% Statements - 6/6 + 97/98
- 100% + 94.5% Branches - 3/3 + 86/91
100% Functions - 2/2 + 11/11
- 100% + 98.94% Lines - 4/4 + 94/95
@@ -79,18 +79,93 @@

All files src/utils

+ asyncHandler.js + +
+ + 100% + 4/4 + 100% + 0/0 + 100% + 2/2 + 100% + 4/4 + + + + problemDetails.js + +
+ + 100% + 5/5 + 100% + 8/8 + 100% + 1/1 + 100% + 5/5 + + + + queryBuilder.js + +
+ + 100% + 24/24 + 87.87% + 29/33 + 100% + 2/2 + 100% + 23/23 + + + responseHelper.js
100% + 7/7 + 100% + 5/5 + 100% + 2/2 + 100% 6/6 + + + + retry.js + +
+ + 100% + 21/21 + 100% + 9/9 100% 3/3 100% - 2/2 + 20/20 + + + + validators.js + +
+ + 97.29% + 36/37 + 97.22% + 35/36 100% - 4/4 + 1/1 + 97.29% + 36/37 @@ -101,7 +176,7 @@

All files src/utils

+ + + + + + \ No newline at end of file diff --git a/coverage/lcov-report/tests/helpers/createTestApp.js.html b/coverage/lcov-report/tests/helpers/createTestApp.js.html new file mode 100644 index 00000000..3c93f32e --- /dev/null +++ b/coverage/lcov-report/tests/helpers/createTestApp.js.html @@ -0,0 +1,154 @@ + + + + + + Code coverage report for tests/helpers/createTestApp.js + + + + + + + + + +
+
+

All files / tests/helpers createTestApp.js

+
+ +
+ 100% + Statements + 10/10 +
+ + +
+ 50% + Branches + 1/2 +
+ + +
+ 100% + Functions + 1/1 +
+ + +
+ 100% + Lines + 10/10 +
+ + +
+

+ Press n or j to go to the next uncovered block, b, p or k for the previous block. +

+ +
+
+

+
1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +11 +12 +13 +14 +15 +16 +17 +18 +19 +20 +21 +22 +23 +242x +2x +  +  +  +  +  +  +2x +6x +  +6x +  +6x +6x +  +  +  +6x +  +6x +  +  +2x
const express = require('express');
+const errorHandler = require('../../src/middleware/errorHandler');
+ 
+/**
+ * Create a minimal Express app for isolated testing
+ * @param {Function} routeSetup - function to define routes
+ * @returns {Express.Application}
+ */
+const createTestApp = (routeSetup) => {
+  const app = express();
+ 
+  app.use(express.json());
+ 
+  Eif (routeSetup) {
+    routeSetup(app);
+  }
+ 
+  // Attach error handler last
+  app.use(errorHandler);
+ 
+  return app;
+};
+ 
+module.exports = createTestApp;
+ +
+
+ + + + + + + + \ No newline at end of file diff --git a/coverage/lcov-report/tests/helpers/index.html b/coverage/lcov-report/tests/helpers/index.html new file mode 100644 index 00000000..1e57d1b0 --- /dev/null +++ b/coverage/lcov-report/tests/helpers/index.html @@ -0,0 +1,116 @@ + + + + + + Code coverage report for tests/helpers + + + + + + + + + +
+
+

All files tests/helpers

+
+ +
+ 100% + Statements + 10/10 +
+ + +
+ 50% + Branches + 1/2 +
+ + +
+ 100% + Functions + 1/1 +
+ + +
+ 100% + Lines + 10/10 +
+ + +
+

+ Press n or j to go to the next uncovered block, b, p or k for the previous block. +

+ +
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FileStatementsBranchesFunctionsLines
createTestApp.js +
+
100%10/1050%1/2100%1/1100%10/10
+
+
+
+ + + + + + + + \ No newline at end of file diff --git a/coverage/lcov.info b/coverage/lcov.info index 4a39a317..95ab0a4d 100644 --- a/coverage/lcov.info +++ b/coverage/lcov.info @@ -1,140 +1,830 @@ TN: -<<<<<<< HEAD SF:src\app.js -FN:11,(anonymous_0) -FN:19,(anonymous_1) -FN:32,(anonymous_2) -FN:36,(anonymous_3) -FN:44,(anonymous_4) -FN:53,(anonymous_5) -FN:59,(anonymous_6) -FN:67,(anonymous_7) -FNF:8 +FN:28,createApp +FN:42,(anonymous_1) +FN:50,(anonymous_2) +FN:65,(anonymous_3) +FN:79,(anonymous_4) +FN:90,(anonymous_5) +FN:106,(anonymous_6) +FN:108,(anonymous_7) +FN:124,(anonymous_8) +FN:126,(anonymous_9) +FN:133,(anonymous_10) +FN:137,(anonymous_11) +FN:142,(anonymous_12) +FN:151,(anonymous_13) +FN:160,(anonymous_14) +FNF:15 +FNH:14 +FNDA:19,createApp +FNDA:10,(anonymous_1) +FNDA:3,(anonymous_2) +FNDA:12,(anonymous_3) +FNDA:3,(anonymous_4) +FNDA:17,(anonymous_5) +FNDA:1,(anonymous_6) +FNDA:1,(anonymous_7) +FNDA:2,(anonymous_8) +FNDA:2,(anonymous_9) +FNDA:3,(anonymous_10) +FNDA:0,(anonymous_11) +FNDA:4,(anonymous_12) +FNDA:18,(anonymous_13) +FNDA:7,(anonymous_14) +DA:3,8 +DA:4,8 +DA:5,8 +DA:7,8 +DA:8,8 +DA:9,8 +DA:10,8 +DA:11,8 +DA:12,8 +DA:18,8 +DA:19,8 +DA:20,8 +DA:21,8 +DA:23,8 +DA:24,8 +DA:25,8 +DA:26,8 +DA:29,19 +DA:30,19 +DA:33,19 +DA:34,19 +DA:35,19 +DA:36,19 +DA:37,19 +DA:42,19 +DA:43,10 +DA:50,19 +DA:51,3 +DA:65,19 +DA:66,12 +DA:67,12 +DA:68,3 +DA:77,9 +DA:78,8 +DA:79,8 +DA:81,8 +DA:84,19 +DA:91,17 +DA:92,17 +DA:101,17 +DA:102,17 +DA:106,19 +DA:107,1 +DA:108,1 +DA:109,1 +DA:110,0 +DA:117,1 +DA:118,1 +DA:124,19 +DA:125,2 +DA:126,2 +DA:127,2 +DA:133,19 +DA:134,3 +DA:137,19 +DA:138,0 +DA:142,19 +DA:143,4 +DA:151,19 +DA:152,18 +DA:153,17 +DA:156,19 +DA:157,19 +DA:160,19 +DA:162,19 +DA:165,8 +DA:166,8 +DA:167,8 +LF:68 +LH:66 +BRDA:67,0,0,3 +BRDA:67,0,1,9 +BRDA:79,1,0,0 +BRDA:79,1,1,8 +BRDA:95,2,0,17 +BRDA:95,2,1,1 +BRDA:109,3,0,0 +BRDA:109,3,1,1 +BRDA:152,4,0,1 +BRDA:152,4,1,17 +BRF:10 +BRH:8 +end_of_record +TN: +SF:src\index.js +FNF:0 +FNH:0 +DA:7,4 +DA:8,4 +DA:10,4 +DA:20,4 +DA:30,4 +LF:5 +LH:5 +BRDA:10,0,0,4 +BRDA:10,0,1,4 +BRDA:20,1,0,0 +BRDA:20,1,1,4 +BRF:4 +BRH:3 +end_of_record +TN: +SF:src\config\cors.js +FN:21,parseAllowedOrigins +FN:27,(anonymous_1) +FN:36,getAllowedOriginsFromEnv +FN:48,createCorsRejectionError +FN:58,isCorsOriginRejectedError +FN:65,createCorsOptions +FN:69,(anonymous_6) +FN:89,(anonymous_7) +FN:93,(anonymous_8) +FNF:9 FNH:8 +FNDA:27,parseAllowedOrigins +FNDA:11,(anonymous_1) +FNDA:24,getAllowedOriginsFromEnv +FNDA:3,createCorsRejectionError +FNDA:22,isCorsOriginRejectedError +FNDA:21,createCorsOptions +FNDA:68,(anonymous_6) +FNDA:1,(anonymous_7) +FNDA:0,(anonymous_8) +DA:7,9 +DA:15,9 +DA:22,27 +DA:23,5 +DA:27,11 +DA:37,24 +DA:38,24 +DA:40,21 +DA:42,20 +DA:49,3 +DA:50,3 +DA:51,3 +DA:52,3 +DA:59,22 +DA:66,21 +DA:68,21 +DA:70,68 +DA:71,66 +DA:74,2 +DA:75,0 +DA:78,2 +DA:84,9 +DA:89,1 +DA:93,0 +LF:24 +LH:22 +BRDA:22,0,0,22 +BRDA:22,0,1,5 +BRDA:22,1,0,27 +BRDA:22,1,1,5 +BRDA:36,2,0,0 +BRDA:38,3,0,3 +BRDA:38,3,1,21 +BRDA:40,4,0,1 +BRDA:40,4,1,20 +BRDA:59,5,0,22 +BRDA:59,5,1,22 +BRDA:65,6,0,19 +BRDA:70,7,0,66 +BRDA:70,7,1,2 +BRDA:74,8,0,0 +BRDA:74,8,1,2 +BRDA:74,9,0,2 +BRDA:74,9,1,1 +BRF:18 +BRH:16 +end_of_record +TN: +SF:src\errors\AppError.js +FN:14,(anonymous_0) +FNF:1 +FNH:1 +FNDA:14,(anonymous_0) +DA:15,14 +DA:16,14 +DA:17,14 +DA:18,14 +DA:19,14 +DA:20,14 +DA:21,14 +DA:24,14 +DA:28,13 +LF:9 +LH:9 +BRDA:17,0,0,14 +BRDA:17,0,1,2 +BRDA:19,1,0,14 +BRDA:19,1,1,2 +BRF:4 +BRH:4 +end_of_record +TN: +SF:src\middleware\auth.js +FN:19,(anonymous_0) +FN:35,(anonymous_1) +FNF:2 +FNH:2 +FNDA:28,(anonymous_0) +FNDA:24,(anonymous_1) +DA:7,8 +DA:19,8 +DA:20,28 +DA:22,28 +DA:23,2 +DA:26,26 +DA:28,26 +DA:29,2 +DA:32,24 +DA:33,24 +DA:35,24 +DA:36,24 +DA:37,2 +DA:38,1 +DA:40,1 +DA:44,22 +DA:45,22 +DA:49,8 +LF:18 +LH:18 +BRDA:22,0,0,2 +BRDA:22,0,1,26 +BRDA:28,1,0,2 +BRDA:28,1,1,24 +BRDA:28,2,0,26 +BRDA:28,2,1,25 +BRDA:33,3,0,24 +BRDA:33,3,1,24 +BRDA:36,4,0,2 +BRDA:36,4,1,22 +BRDA:37,5,0,1 +BRDA:37,5,1,1 +BRF:12 +BRH:12 +end_of_record +TN: +SF:src\middleware\bodySizeLimits.js +FN:50,parseSize +FN:75,sendPayloadTooLarge +FN:97,jsonBodyLimit +FN:111,jsonSizeGuard +FN:130,urlencodedBodyLimit +FN:144,urlencodedSizeGuard +FN:169,payloadTooLargeHandler +FN:192,invoiceBodyLimit +FNF:8 +FNH:7 +FNDA:82,parseSize +FNDA:0,sendPayloadTooLarge +FNDA:39,jsonBodyLimit +FNDA:86,jsonSizeGuard +FNDA:19,urlencodedBodyLimit +FNDA:61,urlencodedSizeGuard +FNDA:17,payloadTooLargeHandler +FNDA:19,invoiceBodyLimit +DA:13,8 +DA:25,8 +DA:51,82 +DA:52,6 +DA:55,76 +DA:56,76 +DA:57,3 +DA:60,73 +DA:61,73 +DA:63,73 +DA:64,73 +DA:76,0 +DA:98,39 +DA:99,39 +DA:101,39 +DA:112,86 +DA:113,86 +DA:114,0 +DA:116,86 +DA:131,19 +DA:132,19 +DA:134,19 +DA:145,61 +DA:146,61 +DA:147,0 +DA:149,61 +DA:170,17 +DA:171,3 +DA:177,14 +DA:193,19 +DA:196,8 +LF:31 +LH:28 +BRDA:26,0,0,8 +BRDA:26,0,1,8 +BRDA:27,1,0,8 +BRDA:27,1,1,8 +BRDA:28,2,0,8 +BRDA:28,2,1,8 +BRDA:29,3,0,8 +BRDA:29,3,1,8 +BRDA:51,4,0,6 +BRDA:51,4,1,76 +BRDA:51,5,0,82 +BRDA:51,5,1,78 +BRDA:56,6,0,3 +BRDA:56,6,1,73 +BRDA:61,7,0,73 +BRDA:61,7,1,1 +BRDA:98,8,0,39 +BRDA:98,8,1,19 +BRDA:112,9,0,86 +BRDA:112,9,1,36 +BRDA:113,10,0,0 +BRDA:113,10,1,86 +BRDA:113,11,0,86 +BRDA:113,11,1,86 +BRDA:131,12,0,19 +BRDA:131,12,1,19 +BRDA:145,13,0,61 +BRDA:145,13,1,36 +BRDA:146,14,0,0 +BRDA:146,14,1,61 +BRDA:146,15,0,61 +BRDA:146,15,1,61 +BRDA:170,16,0,3 +BRDA:170,16,1,14 +BRDA:193,17,0,19 +BRDA:193,17,1,19 +BRF:36 +BRH:34 +end_of_record +TN: +SF:src\middleware\deprecation.js +FN:9,(anonymous_0) +FN:10,(anonymous_1) +FNF:2 +FNH:2 FNDA:1,(anonymous_0) -FNDA:1,(anonymous_1) -FNDA:1,(anonymous_2) -FNDA:1,(anonymous_3) -FNDA:1,(anonymous_4) -FNDA:2,(anonymous_5) -FNDA:1,(anonymous_6) -FNDA:3,(anonymous_7) -DA:1,1 -DA:2,1 -DA:3,1 -DA:5,1 -DA:7,1 -DA:8,1 -DA:11,1 -DA:12,1 -DA:19,1 -DA:20,1 -DA:32,1 -DA:33,1 -DA:36,1 -DA:37,1 +FNDA:3,(anonymous_1) +DA:9,1 +DA:10,1 +DA:12,3 +DA:14,3 +DA:15,3 +DA:17,3 +DA:18,3 +DA:22,3 +DA:24,3 +DA:27,3 +DA:31,1 +LF:11 +LH:11 +BRDA:9,0,0,0 +BRDA:14,1,0,3 +BRDA:14,1,1,0 +BRDA:17,2,0,3 +BRDA:17,2,1,0 +BRDA:22,3,0,3 +BRDA:22,3,1,0 +BRF:7 +BRH:3 +end_of_record +TN: +SF:src\middleware\errorHandler.js +FN:10,errorHandler +FNF:1 +FNH:1 +FNDA:20,errorHandler +DA:3,11 +DA:4,11 +DA:17,20 +DA:21,20 +DA:22,10 +DA:32,10 +DA:33,8 +DA:36,10 +DA:50,20 +DA:51,20 +DA:57,20 +DA:64,20 +DA:66,20 +DA:69,11 +LF:14 +LH:14 +BRDA:17,0,0,20 +BRDA:17,0,1,8 +BRDA:17,0,2,8 +BRDA:21,1,0,10 +BRDA:21,1,1,10 +BRDA:27,2,0,10 +BRDA:27,2,1,8 +BRDA:32,3,0,8 +BRDA:32,3,1,2 +BRDA:38,4,0,8 +BRDA:38,4,1,2 +BRDA:38,5,0,2 +BRDA:38,5,1,0 +BRDA:40,6,0,2 +BRDA:40,6,1,8 +BRDA:40,7,0,10 +BRDA:40,7,1,8 +BRDA:42,8,0,6 +BRDA:42,8,1,2 +BRDA:42,9,0,2 +BRDA:42,9,1,0 +BRDA:59,10,0,20 +BRDA:59,10,1,20 +BRDA:59,11,0,4 +BRDA:59,11,1,16 +BRDA:59,12,0,7 +BRDA:59,12,1,9 +BRDA:60,13,0,6 +BRDA:60,13,1,14 +BRDA:60,14,0,20 +BRDA:60,14,1,18 +BRDA:60,15,0,7 +BRDA:60,15,1,7 +BRF:33 +BRH:31 +end_of_record +TN: +SF:src\middleware\rateLimit.js +FN:25,(anonymous_0) +FN:48,(anonymous_1) +FNF:2 +FNH:2 +FNDA:61,(anonymous_0) +FNDA:26,(anonymous_1) +DA:6,8 +DA:12,8 +DA:27,61 +DA:35,8 +DA:49,26 +DA:53,8 +LF:6 +LH:6 +BRDA:27,0,0,0 +BRDA:27,0,1,61 +BRDA:49,1,0,1 +BRDA:49,1,1,25 +BRF:4 +BRH:3 +end_of_record +TN: +SF:src\middleware\security.js +FN:37,createSecurityMiddleware +FNF:1 +FNH:1 +FNDA:19,createSecurityMiddleware +DA:22,8 +DA:38,19 +DA:137,8 +LF:3 +LH:3 +BRF:0 +BRH:0 +end_of_record +TN: +SF:src\middleware\validate.js +FN:7,(anonymous_0) +FN:7,(anonymous_1) +FN:18,(anonymous_2) +FN:29,(anonymous_3) +FN:29,(anonymous_4) +FN:32,(anonymous_5) +FNF:6 +FNH:6 +FNDA:21,(anonymous_0) +FNDA:21,(anonymous_1) +FNDA:3,(anonymous_2) +FNDA:38,(anonymous_3) +FNDA:29,(anonymous_4) +FNDA:29,(anonymous_5) +DA:1,9 +DA:2,9 +DA:7,21 +DA:8,21 +DA:9,21 +DA:10,18 +DA:11,18 +DA:13,3 +DA:14,3 +DA:18,3 +DA:22,0 +DA:29,38 +DA:30,29 +DA:32,29 +DA:34,29 +DA:35,4 +DA:38,25 +DA:39,25 +DA:40,25 +DA:53,29 +DA:56,9 +LF:21 +LH:20 +BRDA:7,0,0,2 +BRDA:13,1,0,3 +BRDA:13,1,1,0 +BRDA:18,2,0,3 +BRDA:18,2,1,0 +BRDA:34,3,0,4 +BRDA:34,3,1,25 +BRDA:34,4,0,29 +BRDA:34,4,1,29 +BRDA:34,4,2,25 +BRDA:34,4,3,25 +BRF:11 +BRH:9 +end_of_record +TN: +SF:src\schemas\apiSchemas.js +FNF:0 +FNH:0 +DA:1,8 +DA:3,8 +DA:8,8 +DA:14,8 +DA:22,8 +DA:28,8 +DA:32,8 +DA:36,8 +DA:40,8 +LF:9 +LH:9 +BRF:0 +BRH:0 +end_of_record +TN: +SF:src\services\invoice.service.js +FN:31,getInvoices +FNF:1 +FNH:1 +FNDA:5,getInvoices +DA:1,9 +DA:2,9 +DA:11,9 +DA:32,5 +DA:33,5 +DA:36,5 +DA:42,5 DA:44,1 DA:45,1 -DA:46,1 -DA:53,1 -DA:54,2 -DA:55,2 +DA:49,9 +LF:10 +LH:10 +BRF:0 +BRH:0 +end_of_record +TN: +SF:src\services\soroban.js +FN:40,sleep +FN:41,(anonymous_1) +FN:54,computeBackoff +FN:69,isRetryable +FN:100,withRetry +FN:128,callSorobanContract +FNF:6 +FNH:6 +FNDA:1,sleep +FNDA:1,(anonymous_1) +FNDA:1,computeBackoff +FNDA:8,isRetryable +FNDA:5,withRetry +FNDA:5,callSorobanContract +DA:21,9 +DA:32,9 +DA:41,1 +DA:55,1 +DA:56,1 +DA:57,1 +DA:58,1 DA:59,1 -DA:60,1 -DA:67,1 -DA:68,3 -DA:69,3 -DA:70,3 -DA:77,1 -LF:27 -LH:27 -BRDA:69,0,0,3 -BRDA:69,0,1,2 -BRDA:71,1,0,2 -BRDA:71,1,1,1 -BRDA:72,2,0,2 -BRDA:72,2,1,1 -BRDA:72,3,0,1 -BRDA:72,3,1,1 -BRDA:73,4,0,2 -BRDA:73,4,1,1 -BRF:10 -BRH:10 +DA:70,8 +DA:73,8 +DA:76,8 +DA:77,8 +DA:80,8 +DA:81,8 +DA:82,7 +DA:83,4 +DA:85,4 +DA:101,5 +DA:102,5 +DA:105,5 +DA:106,6 +DA:107,6 +DA:109,2 +DA:110,2 +DA:112,1 +DA:113,1 +DA:117,0 +DA:129,5 +DA:132,9 +LF:29 +LH:28 +BRDA:22,0,0,9 +BRDA:22,0,1,9 +BRDA:23,1,0,9 +BRDA:23,1,1,9 +BRDA:24,2,0,9 +BRDA:24,2,1,9 +BRDA:70,3,0,0 +BRDA:70,3,1,8 +BRDA:73,4,0,0 +BRDA:73,4,1,8 +BRDA:73,5,0,8 +BRDA:73,5,1,8 +BRDA:76,6,0,0 +BRDA:76,6,1,8 +BRDA:76,7,0,8 +BRDA:76,7,1,0 +BRDA:77,8,0,0 +BRDA:77,8,1,8 +BRDA:77,9,0,8 +BRDA:77,9,1,0 +BRDA:80,10,0,8 +BRDA:80,10,1,0 +BRDA:81,11,0,1 +BRDA:81,11,1,7 +BRDA:82,12,0,3 +BRDA:82,12,1,4 +BRDA:83,13,0,0 +BRDA:83,13,1,4 +BRDA:110,14,0,1 +BRDA:110,14,1,1 +BRDA:110,15,0,2 +BRDA:110,15,1,2 +BRF:32 +BRH:24 end_of_record TN: -SF:src\utils\responseHelper.js -FN:15,(anonymous_0) -FN:33,(anonymous_1) +SF:src\utils\asyncHandler.js +FN:8,(anonymous_0) +FN:9,(anonymous_1) FNF:2 FNH:2 -FNDA:7,(anonymous_0) -FNDA:6,(anonymous_1) -DA:6,1 -DA:15,7 -DA:33,6 -DA:46,1 +FNDA:43,(anonymous_0) +FNDA:19,(anonymous_1) +DA:8,10 +DA:9,43 +DA:10,19 +DA:14,10 LF:4 LH:4 -BRDA:15,0,0,3 -BRDA:33,1,0,1 -BRDA:33,2,0,2 -BRF:3 -BRH:3 -======= -SF:src/services/soroban.js -FN:9,isTransientError -FN:19,(anonymous_1) -FN:29,callSorobanContract -FNF:3 -FNH:3 -FNDA:8,isTransientError -FNDA:53,(anonymous_1) -FNDA:3,callSorobanContract -DA:1,1 -DA:10,8 -DA:18,8 -DA:19,53 -DA:30,3 -DA:37,3 -DA:40,1 -LF:7 -LH:7 -BRDA:18,0,0,8 -BRDA:18,0,1,0 -BRDA:29,1,0,2 -BRF:3 -BRH:2 +BRF:0 +BRH:0 +end_of_record +TN: +SF:src\utils\problemDetails.js +FN:5,formatProblemDetails +FNF:1 +FNH:1 +FNDA:23,formatProblemDetails +DA:14,23 +DA:23,23 +DA:24,19 +DA:27,23 +DA:30,12 +LF:5 +LH:5 +BRDA:6,0,0,1 +BRDA:7,1,0,1 +BRDA:8,2,0,1 +BRDA:12,3,0,21 +BRDA:23,4,0,19 +BRDA:23,4,1,4 +BRDA:23,5,0,23 +BRDA:23,5,1,20 +BRF:8 +BRH:8 +end_of_record +TN: +SF:src\utils\queryBuilder.js +FN:22,applyQueryOptions +FN:27,(anonymous_1) +FNF:2 +FNH:2 +FNDA:16,applyQueryOptions +FNDA:11,(anonymous_1) +DA:23,16 +DA:24,16 +DA:27,16 +DA:28,11 +DA:29,11 +DA:31,8 +DA:32,7 +DA:35,7 +DA:36,1 +DA:37,6 +DA:38,1 +DA:41,5 +DA:47,16 +DA:48,16 +DA:49,5 +DA:50,5 +DA:51,5 +DA:52,11 +DA:54,10 +DA:55,10 +DA:56,10 +DA:59,16 +DA:62,10 +LF:23 +LH:23 +BRDA:22,0,0,0 +BRDA:22,1,0,0 +BRDA:23,2,0,7 +BRDA:23,3,0,7 +BRDA:24,4,0,0 +BRDA:24,5,0,0 +BRDA:24,6,0,1 +BRDA:29,7,0,3 +BRDA:29,7,1,8 +BRDA:29,8,0,11 +BRDA:29,8,1,10 +BRDA:29,8,2,9 +BRDA:31,9,0,7 +BRDA:31,9,1,1 +BRDA:32,10,0,7 +BRDA:32,10,1,4 +BRDA:35,11,0,1 +BRDA:35,11,1,6 +BRDA:37,12,0,1 +BRDA:37,12,1,5 +BRDA:47,13,0,12 +BRDA:48,14,0,5 +BRDA:48,14,1,11 +BRDA:48,15,0,16 +BRDA:48,15,1,6 +BRDA:49,16,0,5 +BRDA:49,16,1,5 +BRDA:50,17,0,4 +BRDA:50,17,1,1 +BRDA:52,18,0,10 +BRDA:52,18,1,1 +BRDA:55,19,0,10 +BRDA:55,19,1,10 +BRF:33 +BRH:29 end_of_record TN: -SF:src/utils/retry.js +SF:src\utils\responseHelper.js +FN:8,(anonymous_0) +FN:25,(anonymous_1) +FNF:2 +FNH:2 +FNDA:43,(anonymous_0) +FNDA:2,(anonymous_1) +DA:3,8 +DA:8,8 +DA:9,43 +DA:10,43 +DA:25,8 +DA:39,8 +LF:6 +LH:6 +BRDA:8,0,0,32 +BRDA:9,1,0,43 +BRDA:9,1,1,33 +BRDA:25,2,0,1 +BRDA:25,3,0,1 +BRF:5 +BRH:5 +end_of_record +TN: +SF:src\utils\retry.js FN:27,withRetry FN:37,(anonymous_1) FN:63,(anonymous_2) FNF:3 FNH:3 -FNDA:9,withRetry +FNDA:6,withRetry FNDA:15,(anonymous_1) -FNDA:16,(anonymous_2) -DA:29,9 -DA:30,9 -DA:31,9 +FNDA:15,(anonymous_2) +DA:29,6 +DA:30,6 +DA:31,6 DA:37,15 -DA:38,9 -DA:41,9 -DA:42,9 -DA:43,9 -DA:45,9 -DA:47,9 -DA:48,25 -DA:49,25 -DA:51,21 -DA:52,5 -DA:56,16 -DA:57,16 -DA:60,16 -DA:62,16 -DA:63,16 -DA:68,2 +DA:38,6 +DA:41,6 +DA:42,6 +DA:43,6 +DA:45,6 +DA:47,6 +DA:48,21 +DA:49,21 +DA:51,19 +DA:52,4 +DA:56,15 +DA:57,15 +DA:60,15 +DA:62,15 +DA:63,15 +DA:68,1 LF:20 LH:20 BRDA:27,0,0,1 @@ -142,11 +832,94 @@ BRDA:34,1,0,1 BRDA:35,2,0,1 BRDA:36,3,0,5 BRDA:37,4,0,5 -BRDA:51,5,0,5 -BRDA:51,5,1,16 -BRDA:51,6,0,21 -BRDA:51,6,1,18 +BRDA:51,5,0,4 +BRDA:51,5,1,15 +BRDA:51,6,0,19 +BRDA:51,6,1,16 BRF:9 BRH:9 ->>>>>>> main +end_of_record +TN: +SF:src\utils\validators.js +FN:13,validateInvoiceQueryParams +FNF:1 +FNH:1 +FNDA:24,validateInvoiceQueryParams +DA:14,24 +DA:15,24 +DA:28,24 +DA:31,24 +DA:32,6 +DA:33,6 +DA:34,2 +DA:36,4 +DA:41,24 +DA:42,2 +DA:43,2 +DA:45,0 +DA:50,24 +DA:51,2 +DA:52,1 +DA:54,1 +DA:59,24 +DA:60,24 +DA:61,5 +DA:62,2 +DA:64,3 +DA:68,24 +DA:69,3 +DA:70,2 +DA:72,1 +DA:77,24 +DA:78,4 +DA:79,4 +DA:80,2 +DA:82,2 +DA:87,24 +DA:88,3 +DA:89,3 +DA:90,2 +DA:92,1 +DA:96,24 +DA:103,9 +LF:37 +LH:36 +BRDA:31,0,0,6 +BRDA:31,0,1,18 +BRDA:33,1,0,2 +BRDA:33,1,1,4 +BRDA:41,2,0,2 +BRDA:41,2,1,22 +BRDA:42,3,0,2 +BRDA:42,3,1,0 +BRDA:42,4,0,2 +BRDA:42,4,1,2 +BRDA:50,5,0,2 +BRDA:50,5,1,22 +BRDA:51,6,0,1 +BRDA:51,6,1,1 +BRDA:51,7,0,2 +BRDA:51,7,1,2 +BRDA:60,8,0,5 +BRDA:60,8,1,19 +BRDA:61,9,0,2 +BRDA:61,9,1,3 +BRDA:61,10,0,5 +BRDA:61,10,1,3 +BRDA:68,11,0,3 +BRDA:68,11,1,21 +BRDA:69,12,0,2 +BRDA:69,12,1,1 +BRDA:69,13,0,3 +BRDA:69,13,1,2 +BRDA:77,14,0,4 +BRDA:77,14,1,20 +BRDA:79,15,0,2 +BRDA:79,15,1,2 +BRDA:87,16,0,3 +BRDA:87,16,1,21 +BRDA:89,17,0,2 +BRDA:89,17,1,1 +BRF:36 +BRH:35 end_of_record diff --git a/coverage_final.txt b/coverage_final.txt new file mode 100644 index 00000000..515250f6 --- /dev/null +++ b/coverage_final.txt @@ -0,0 +1,36 @@ + +> backend@1.0.0 test:coverage +> jest --coverage + +---------------------|---------|----------|---------|---------|------------------- +File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s +---------------------|---------|----------|---------|---------|------------------- +All files | 96.21 | 88.93 | 96.15 | 96.78 | + src | 96.92 | 81.81 | 96.55 | 96.87 | + app.js | 97.72 | 50 | 100 | 97.72 | 148 + index.js | 96.51 | 88.88 | 94.44 | 96.42 | 214,247,280 + src/config | 96.29 | 94.44 | 88.88 | 95.83 | + cors.js | 96.29 | 94.44 | 88.88 | 95.83 | 92 + src/errors | 100 | 100 | 100 | 100 | + AppError.js | 100 | 100 | 100 | 100 | + src/middleware | 95.19 | 86.07 | 95.23 | 95.19 | + auth.js | 100 | 100 | 100 | 100 | + bodySizeLimits.js | 90.32 | 94.44 | 87.5 | 90.32 | 76,114,147 + deprecation.js | 100 | 42.85 | 100 | 100 | 9-22 + errorHandler.js | 100 | 92.3 | 100 | 100 | 34 + rateLimit.js | 100 | 75 | 100 | 100 | 27 + security.js | 100 | 100 | 100 | 100 | + validate.js | 91.66 | 57.14 | 100 | 91.66 | 24,54 + src/schemas | 100 | 100 | 100 | 100 | + apiSchemas.js | 100 | 100 | 100 | 100 | + src/services | 91.83 | 84.37 | 100 | 97.43 | + invoice.service.js | 100 | 100 | 100 | 100 | + soroban.js | 89.74 | 84.37 | 100 | 96.55 | 117 + src/utils | 97.93 | 93.25 | 100 | 97.84 | + asyncHandler.js | 100 | 100 | 100 | 100 | + problemDetails.js | 100 | 100 | 100 | 100 | + queryBuilder.js | 100 | 87.87 | 100 | 100 | 22,24 + responseHelper.js | 100 | 100 | 100 | 100 | + retry.js | 100 | 100 | 100 | 100 | + validators.js | 94.59 | 94.44 | 100 | 94.59 | 45,72 +---------------------|---------|----------|---------|---------|------------------- diff --git a/coverage_final_check.txt b/coverage_final_check.txt new file mode 100644 index 00000000..f8ed50b8 --- /dev/null +++ b/coverage_final_check.txt @@ -0,0 +1,36 @@ + +> backend@1.0.0 test:coverage +> jest --coverage + +---------------------|---------|----------|---------|---------|------------------------ +File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s +---------------------|---------|----------|---------|---------|------------------------ +All files | 90.74 | 85.48 | 83.82 | 92.28 | + src | 75 | 53.84 | 52.63 | 78.16 | + app.js | 74.07 | 50 | 56.25 | 78.37 | 78,118-131,135-148,160 + index.js | 80 | 66.66 | 33.33 | 76.92 | 17-20 + src/config | 96.29 | 94.44 | 88.88 | 95.83 | + cors.js | 96.29 | 94.44 | 88.88 | 95.83 | 92 + src/errors | 100 | 100 | 100 | 100 | + AppError.js | 100 | 100 | 100 | 100 | + src/middleware | 95.19 | 84.81 | 95.23 | 95.19 | + auth.js | 100 | 100 | 100 | 100 | + bodySizeLimits.js | 90.32 | 94.44 | 87.5 | 90.32 | 76,114,147 + deprecation.js | 100 | 42.85 | 100 | 100 | 9-22 + errorHandler.js | 100 | 92.3 | 100 | 100 | 34 + rateLimit.js | 100 | 50 | 100 | 100 | 27-49 + security.js | 100 | 100 | 100 | 100 | + validate.js | 91.66 | 57.14 | 100 | 91.66 | 24,54 + src/schemas | 100 | 100 | 100 | 100 | + apiSchemas.js | 100 | 100 | 100 | 100 | + src/services | 91.83 | 84.37 | 100 | 97.43 | + invoice.service.js | 100 | 100 | 100 | 100 | + soroban.js | 89.74 | 84.37 | 100 | 96.55 | 117 + src/utils | 97.93 | 93.25 | 100 | 97.84 | + asyncHandler.js | 100 | 100 | 100 | 100 | + problemDetails.js | 100 | 100 | 100 | 100 | + queryBuilder.js | 100 | 87.87 | 100 | 100 | 22,24 + responseHelper.js | 100 | 100 | 100 | 100 | + retry.js | 100 | 100 | 100 | 100 | + validators.js | 94.59 | 94.44 | 100 | 94.59 | 45,72 +---------------------|---------|----------|---------|---------|------------------------ diff --git a/coverage_final_check_2.txt b/coverage_final_check_2.txt new file mode 100644 index 00000000..cdea7bac --- /dev/null +++ b/coverage_final_check_2.txt @@ -0,0 +1,36 @@ + +> backend@1.0.0 test:coverage +> jest --coverage + +---------------------|---------|----------|---------|---------|------------------- +File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s +---------------------|---------|----------|---------|---------|------------------- +All files | 95.02 | 88.28 | 92.42 | 96.36 | + src | 94.04 | 75 | 87.5 | 94.87 | + app.js | 97.33 | 75 | 100 | 98.55 | 117 + index.js | 66.66 | 75 | 0 | 66.66 | 16-19 + src/config | 92.59 | 88.88 | 88.88 | 91.66 | + cors.js | 92.59 | 88.88 | 88.88 | 91.66 | 75,93 + src/errors | 100 | 100 | 100 | 100 | + AppError.js | 100 | 100 | 100 | 100 | + src/middleware | 95.28 | 88.42 | 90.9 | 95.19 | + auth.js | 100 | 100 | 100 | 100 | + bodySizeLimits.js | 90.32 | 94.44 | 87.5 | 90.32 | 76,114,147 + deprecation.js | 100 | 42.85 | 100 | 100 | 9-22 + errorHandler.js | 100 | 92.59 | 100 | 100 | 38,42 + rateLimit.js | 100 | 75 | 100 | 100 | 27 + security.js | 100 | 100 | 100 | 100 | + validate.js | 91.3 | 77.77 | 83.33 | 90.47 | 18-22 + src/schemas | 100 | 100 | 100 | 100 | + apiSchemas.js | 100 | 100 | 100 | 100 | + src/services | 87.75 | 75 | 100 | 97.43 | + invoice.service.js | 100 | 100 | 100 | 100 | + soroban.js | 84.61 | 75 | 100 | 96.55 | 117 + src/utils | 98.97 | 94.5 | 100 | 98.94 | + asyncHandler.js | 100 | 100 | 100 | 100 | + problemDetails.js | 100 | 100 | 100 | 100 | + queryBuilder.js | 100 | 87.87 | 100 | 100 | 22,24 + responseHelper.js | 100 | 100 | 100 | 100 | + retry.js | 100 | 100 | 100 | 100 | + validators.js | 97.29 | 97.22 | 100 | 97.29 | 45 +---------------------|---------|----------|---------|---------|------------------- diff --git a/coverage_final_final.txt b/coverage_final_final.txt new file mode 100644 index 00000000..7f46af7c --- /dev/null +++ b/coverage_final_final.txt @@ -0,0 +1,36 @@ + +> backend@1.0.0 test:coverage +> jest --coverage + +---------------------|---------|----------|---------|---------|------------------- +File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s +---------------------|---------|----------|---------|---------|------------------- +All files | 95.03 | 88.18 | 93.84 | 96.12 | + src | 92.85 | 68.75 | 87.5 | 94.87 | + app.js | 96 | 66.66 | 100 | 98.55 | 117 + index.js | 66.66 | 75 | 0 | 66.66 | 16-19 + src/config | 92.59 | 88.88 | 88.88 | 91.66 | + cors.js | 92.59 | 88.88 | 88.88 | 91.66 | 75,92 + src/errors | 100 | 100 | 100 | 100 | + AppError.js | 100 | 100 | 100 | 100 | + src/middleware | 95.32 | 87.09 | 95.23 | 95.32 | + auth.js | 100 | 100 | 100 | 100 | + bodySizeLimits.js | 90.32 | 94.44 | 87.5 | 90.32 | 76,114,147 + deprecation.js | 100 | 42.85 | 100 | 100 | 9-22 + errorHandler.js | 100 | 92.59 | 100 | 100 | 38,42 + rateLimit.js | 100 | 75 | 100 | 100 | 27 + security.js | 100 | 100 | 100 | 100 | + validate.js | 91.66 | 57.14 | 100 | 91.66 | 24,54 + src/schemas | 100 | 100 | 100 | 100 | + apiSchemas.js | 100 | 100 | 100 | 100 | + src/services | 91.83 | 84.37 | 100 | 97.43 | + invoice.service.js | 100 | 100 | 100 | 100 | + soroban.js | 89.74 | 84.37 | 100 | 96.55 | 117 + src/utils | 97.95 | 93.4 | 100 | 97.89 | + asyncHandler.js | 100 | 100 | 100 | 100 | + problemDetails.js | 100 | 100 | 100 | 100 | + queryBuilder.js | 100 | 87.87 | 100 | 100 | 22,24 + responseHelper.js | 100 | 100 | 100 | 100 | + retry.js | 100 | 100 | 100 | 100 | + validators.js | 94.59 | 94.44 | 100 | 94.59 | 45,72 +---------------------|---------|----------|---------|---------|------------------- diff --git a/coverage_final_pass.txt b/coverage_final_pass.txt new file mode 100644 index 00000000..bb222ba6 --- /dev/null +++ b/coverage_final_pass.txt @@ -0,0 +1,36 @@ + +> backend@1.0.0 test:coverage +> jest --coverage + +---------------------|---------|----------|---------|---------|------------------- +File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s +---------------------|---------|----------|---------|---------|------------------- +All files | 93.01 | 86.97 | 90.32 | 94.28 | + src | 82.27 | 56.25 | 69.23 | 85.13 | + app.js | 84.84 | 50 | 81.81 | 88.52 | 102-115 + index.js | 69.23 | 75 | 0 | 69.23 | 14-17,21 + src/config | 96.29 | 94.44 | 88.88 | 95.83 | + cors.js | 96.29 | 94.44 | 88.88 | 95.83 | 92 + src/errors | 100 | 100 | 100 | 100 | + AppError.js | 100 | 100 | 100 | 100 | + src/middleware | 95.19 | 84.81 | 95.23 | 95.19 | + auth.js | 100 | 100 | 100 | 100 | + bodySizeLimits.js | 90.32 | 94.44 | 87.5 | 90.32 | 76,114,147 + deprecation.js | 100 | 42.85 | 100 | 100 | 9-22 + errorHandler.js | 100 | 92.3 | 100 | 100 | 34 + rateLimit.js | 100 | 50 | 100 | 100 | 27-49 + security.js | 100 | 100 | 100 | 100 | + validate.js | 91.66 | 57.14 | 100 | 91.66 | 24,54 + src/schemas | 100 | 100 | 100 | 100 | + apiSchemas.js | 100 | 100 | 100 | 100 | + src/services | 91.83 | 84.37 | 100 | 97.43 | + invoice.service.js | 100 | 100 | 100 | 100 | + soroban.js | 89.74 | 84.37 | 100 | 96.55 | 117 + src/utils | 97.93 | 93.25 | 100 | 97.84 | + asyncHandler.js | 100 | 100 | 100 | 100 | + problemDetails.js | 100 | 100 | 100 | 100 | + queryBuilder.js | 100 | 87.87 | 100 | 100 | 22,24 + responseHelper.js | 100 | 100 | 100 | 100 | + retry.js | 100 | 100 | 100 | 100 | + validators.js | 94.59 | 94.44 | 100 | 94.59 | 45,72 +---------------------|---------|----------|---------|---------|------------------- diff --git a/coverage_full_report.txt b/coverage_full_report.txt new file mode 100644 index 00000000..ea236b5b --- /dev/null +++ b/coverage_full_report.txt @@ -0,0 +1,38 @@ + +> backend@1.0.0 test:coverage +> jest --coverage + +---------------------|---------|----------|---------|---------|------------------- +File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s +---------------------|---------|----------|---------|---------|------------------- +All files | 93.48 | 87.69 | 83.51 | 93.89 | + src | 96.92 | 81.81 | 96.55 | 96.87 | + app.js | 97.72 | 50 | 100 | 97.72 | 148 + index.js | 96.51 | 88.88 | 94.44 | 96.42 | 214,247,280 + src/config | 96.29 | 94.44 | 88.88 | 95.83 | + cors.js | 96.29 | 94.44 | 88.88 | 95.83 | 92 + src/db | 40.9 | 50 | 7.69 | 40.9 | + knex.js | 40.9 | 50 | 7.69 | 40.9 | 15-29 + src/errors | 100 | 100 | 100 | 100 | + AppError.js | 100 | 100 | 100 | 100 | + src/middleware | 95.19 | 86.07 | 95.23 | 95.19 | + auth.js | 100 | 100 | 100 | 100 | + bodySizeLimits.js | 90.32 | 94.44 | 87.5 | 90.32 | 76,114,147 + deprecation.js | 100 | 42.85 | 100 | 100 | 9-22 + errorHandler.js | 100 | 92.3 | 100 | 100 | 34 + rateLimit.js | 100 | 75 | 100 | 100 | 27 + security.js | 100 | 100 | 100 | 100 | + validate.js | 91.66 | 57.14 | 100 | 91.66 | 24,54 + src/schemas | 100 | 100 | 100 | 100 | + apiSchemas.js | 100 | 100 | 100 | 100 | + src/services | 91.83 | 84.37 | 100 | 97.43 | + invoice.service.js | 100 | 100 | 100 | 100 | + soroban.js | 89.74 | 84.37 | 100 | 96.55 | 117 + src/utils | 97.93 | 93.25 | 100 | 97.84 | + asyncHandler.js | 100 | 100 | 100 | 100 | + problemDetails.js | 100 | 100 | 100 | 100 | + queryBuilder.js | 100 | 87.87 | 100 | 100 | 22,24 + responseHelper.js | 100 | 100 | 100 | 100 | + retry.js | 100 | 100 | 100 | 100 | + validators.js | 94.59 | 94.44 | 100 | 94.59 | 45,72 +---------------------|---------|----------|---------|---------|------------------- diff --git a/coverage_last.txt b/coverage_last.txt new file mode 100644 index 00000000..f6492832 --- /dev/null +++ b/coverage_last.txt @@ -0,0 +1,36 @@ + +> backend@1.0.0 test:coverage +> jest --coverage + +---------------------|---------|----------|---------|---------|------------------- +File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s +---------------------|---------|----------|---------|---------|------------------- +All files | 96.25 | 88.54 | 96.87 | 97.43 | + src | 98.68 | 78.57 | 100 | 98.59 | + app.js | 98.59 | 80 | 100 | 98.48 | 110 + index.js | 100 | 75 | 100 | 100 | 20 + src/config | 92.59 | 88.88 | 88.88 | 91.66 | + cors.js | 92.59 | 88.88 | 88.88 | 91.66 | 75,93 + src/errors | 100 | 100 | 100 | 100 | + AppError.js | 100 | 100 | 100 | 100 | + src/middleware | 96.22 | 88.34 | 95.45 | 96.15 | + auth.js | 100 | 100 | 100 | 100 | + bodySizeLimits.js | 90.32 | 94.44 | 87.5 | 90.32 | 76,114,147 + deprecation.js | 100 | 42.85 | 100 | 100 | 9-22 + errorHandler.js | 100 | 93.93 | 100 | 100 | 38,42 + rateLimit.js | 100 | 75 | 100 | 100 | 27 + security.js | 100 | 100 | 100 | 100 | + validate.js | 95.65 | 72.72 | 100 | 95.23 | 22 + src/schemas | 100 | 100 | 100 | 100 | + apiSchemas.js | 100 | 100 | 100 | 100 | + src/services | 87.75 | 75 | 100 | 97.43 | + invoice.service.js | 100 | 100 | 100 | 100 | + soroban.js | 84.61 | 75 | 100 | 96.55 | 117 + src/utils | 98.97 | 94.5 | 100 | 98.94 | + asyncHandler.js | 100 | 100 | 100 | 100 | + problemDetails.js | 100 | 100 | 100 | 100 | + queryBuilder.js | 100 | 87.87 | 100 | 100 | 22,24 + responseHelper.js | 100 | 100 | 100 | 100 | + retry.js | 100 | 100 | 100 | 100 | + validators.js | 97.29 | 97.22 | 100 | 97.29 | 45 +---------------------|---------|----------|---------|---------|------------------- diff --git a/coverage_last_check.txt b/coverage_last_check.txt new file mode 100644 index 00000000..b389eff6 --- /dev/null +++ b/coverage_last_check.txt @@ -0,0 +1,36 @@ + +> backend@1.0.0 test:coverage +> jest --coverage + +---------------------|---------|----------|---------|---------|------------------- +File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s +---------------------|---------|----------|---------|---------|------------------- +All files | 94.83 | 87.89 | 93.84 | 95.89 | + src | 93.02 | 68.75 | 87.5 | 95 | + app.js | 96 | 66.66 | 100 | 98.55 | 117 + index.js | 72.72 | 75 | 0 | 72.72 | 16-19 + src/config | 92.59 | 88.88 | 88.88 | 91.66 | + cors.js | 92.59 | 88.88 | 88.88 | 91.66 | 75,92 + src/errors | 100 | 100 | 100 | 100 | + AppError.js | 100 | 100 | 100 | 100 | + src/middleware | 94.49 | 86.31 | 95.23 | 94.49 | + auth.js | 100 | 100 | 100 | 100 | + bodySizeLimits.js | 90.32 | 94.44 | 87.5 | 90.32 | 76,114,147 + deprecation.js | 100 | 42.85 | 100 | 100 | 9-22 + errorHandler.js | 93.75 | 89.65 | 100 | 93.75 | 12 + rateLimit.js | 100 | 75 | 100 | 100 | 27 + security.js | 100 | 100 | 100 | 100 | + validate.js | 91.66 | 57.14 | 100 | 91.66 | 24,54 + src/schemas | 100 | 100 | 100 | 100 | + apiSchemas.js | 100 | 100 | 100 | 100 | + src/services | 91.83 | 84.37 | 100 | 97.43 | + invoice.service.js | 100 | 100 | 100 | 100 | + soroban.js | 89.74 | 84.37 | 100 | 96.55 | 117 + src/utils | 97.95 | 93.4 | 100 | 97.89 | + asyncHandler.js | 100 | 100 | 100 | 100 | + problemDetails.js | 100 | 100 | 100 | 100 | + queryBuilder.js | 100 | 87.87 | 100 | 100 | 22,24 + responseHelper.js | 100 | 100 | 100 | 100 | + retry.js | 100 | 100 | 100 | 100 | + validators.js | 94.59 | 94.44 | 100 | 94.59 | 45,72 +---------------------|---------|----------|---------|---------|------------------- diff --git a/coverage_log.txt b/coverage_log.txt new file mode 100644 index 00000000..261856c6 Binary files /dev/null and b/coverage_log.txt differ diff --git a/coverage_pass.txt b/coverage_pass.txt new file mode 100644 index 00000000..b1bf9fce Binary files /dev/null and b/coverage_pass.txt differ diff --git a/coverage_utf8.txt b/coverage_utf8.txt new file mode 100644 index 00000000..0c798d61 --- /dev/null +++ b/coverage_utf8.txt @@ -0,0 +1,4281 @@ +node.exe : npm warn invalid +config cache=false set in +command line options +At C:\Users\pc\AppData\Roamin +g\npm\npm.ps1:24 char:5 ++ & "node$exe" "$basedir +/node_modules/npm/bin/npm-cli +.js" $args ++ ~~~~~~~~~~~~~~~~~~~~~~~ +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +~~~~~~~~~~ + + CategoryInfo + : NotSpecified: (npm war + n invali...nd line optio + ns:String) [], RemoteExc +eption + + FullyQualifiedErrorId + : NativeCommandError + +npm warn invalid config Must +be valid filesystem path + +> backend@1.0.0 test:coverage +> jest --coverage + +FAIL tests/unit/errorHandler. +test.js + ΓùÅ errorHandler +Middleware Unit Tests ΓÇ║ +should handle AppError and +send RFC 7807 response + + expect(jest.fn()).toHaveB +eenCalledWith(...expected) + + Expected: +ObjectContaining {"detail": +"Invalid data", "error": +"Bad Request", "instance": +"/api/v1/test", "status": +400, "title": "Bad Request", +"type": "https://liquifact.co +m/probs/bad-request"} + Received: {"data": null, +"detail": "Invalid data", +"error": {"code": +"INTERNAL_ERROR", "details": +null, "message": "Bad +Request"}, "instance": +"/api/v1/test", "meta": +{"timestamp": +"2026-03-28T17:17:00.798Z", +"version": "0.1.0"}, +"stack": "AppError: Bad +Request + +   26 | +  27 | +test('should handle +AppError and send RFC 7807 +response', () +=> { + +> 28 +| const +error = +new +AppError({ +  | + +^ +  29 | +type: 'https:/ +/liquifact.com/probs/bad-requ +est', +  30 | +title: 'Bad +Request', +  31 | +status: +400, + + at Object. ( +tests/unit/errorHandler.test. +js:28:19) + Number of calls: 1 + at +Object.toHaveBeenCalledWith ( +tests/unit/errorHandler.test. +js:39:31) + + ΓùÅ errorHandler +Middleware Unit Tests ΓÇ║ +should handle generic Error +and fallback to 500 + + expect(jest.fn()).toHaveB +eenCalledWith(...expected) + + Expected: +ObjectContaining {"detail": +"An unexpected error +occurred while processing +your request.", "error": +"Internal Server Error", +"status": 500, "title": +"Internal Server Error"} + Received: {"data": null, +"detail": "Something +exploded", "error": {"code": +"INTERNAL_ERROR", "details": +"Something exploded", +"message": "Internal Server +Error"}, "instance": +"/api/v1/test", "meta": +{"timestamp": +"2026-03-28T17:17:00.815Z", +"version": "0.1.0"}, +"stack": "Error: Something +exploded + +   50 | +  51 | +test('should handle +generic Error and fallback +to 500', () +=> { + +> 52 +| const +error = +new Error +('Something +exploded'); +  | + +^ +  53 | +  54 | erro +rHandler(error, +mockRequest, +mockResponse, +nextFunction); +  55 | + + at Object. ( +tests/unit/errorHandler.test. +js:52:19) + Number of calls: 1 + at +Object.toHaveBeenCalledWith ( +tests/unit/errorHandler.test. +js:57:31) + +FAIL src/__tests__/invoice.ap +i.test.js + ΓùÅ Console + + console.log + [dotenv@17.3.1] +injecting env (0) from .env +-- tip: ΓÜÖ∩╕Å override +existing env vars with { +override: true } + + at _log (node_modules/d +otenv/lib/main.js:139:11) + + console.log + [dotenv@17.3.1] +injecting env (0) from .env +-- tip: ≡ƒ¢á∩╕Å run +anywhere with `dotenvx run +-- yourcommand` + + at _log (node_modules/d +otenv/lib/main.js:139:11) + + console.error + Response validation +failed: [ + { + expected: 'string', + code: +'invalid_type', + path: [ 'data', 0, +'status' ], + message: 'Invalid +input: expected string, +received undefined' + }, + { + expected: 'string', + code: +'invalid_type', + path: [ 'data', 1, +'status' ], + message: 'Invalid +input: expected string, +received undefined' + } + ] + +   48 | + } catch +(error) { +  49 | + if (error +instanceof +ZodError) { + +> 50 +| co +nsole.error('R +esponse validation +failed:', erro +r.issues);[39 +m +  | + +^ +  51 | + return +originalJson.call( +[36mthis.statu +s(500), +{ error: +'Internal server error: +Response validation +failed' }); +  52 | + } +  53 | + // In rare +cases where another error +happens, just throw + + at +ServerResponse.error [as +json] (src/middleware/validat +e.js:50:29) + at json +(src/app.js:81:18) + + ΓùÅ Invoice API +Integration ΓÇ║ GET +/api/invoices ΓÇ║ should +return 200 and invoices when +no query params are provided + + expect(received).toBe(exp +ected) // Object.is equality + + Expected: 200 + Received: 500 + +   21 | + const res += await r +equest(app).ge +t('/api/invoices'[ +39m); +  22 | + +> 23 +| expect(res. +statusCode).to +Be(200); +  | + +^ +  24 | ex +pect(res.body. +data).toEqual( +mockInvoices); +  25 | ex +pect(res.body. +message).toBe( +'Invoices retrieved succ +essfully.'); +  26 | ex +pect(invoiceService.[39 +mgetInvoices).toHav +eBeenCalledWith({ + + at Object.toBe (src/__t +ests__/invoice.api.test.js:23 +:30) + + ΓùÅ Invoice API +Integration ΓÇ║ GET +/api/invoices ΓÇ║ should +handle service errors with +500 + + expect(received).toBe(exp +ected) // Object.is equality + + Expected: "Internal +server error" + Received: {"code": +"INTERNAL_ERROR", "message": +"Internal server error"} + +   106 | +  107 | e +xpect(res.statusCod +e).toBe(500[3 +9m); + +> +108 | expect(res[ +33m.body.error +).toBe('Intern +al server +error'); +  | + +^ +  109 | +}); +  110 | +}); +  111 | +}); + + at Object.toBe (src/__t +ests__/invoice.api.test.js:10 +8:30) + +FAIL tests/integration/errorH +andling.test.js + ΓùÅ Console + + console.log + [dotenv@17.3.1] +injecting env (0) from .env +-- tip: ≡ƒöÉ prevent +building .env in docker: +https://dotenvx.com/prebuild + + at _log (node_modules/d +otenv/lib/main.js:139:11) + + console.log + [dotenv@17.3.1] +injecting env (0) from .env +-- tip: ΓÜÖ∩╕Å write to +custom object with { +processEnv: myObject } + + at _log (node_modules/d +otenv/lib/main.js:139:11) + + console.log + [dotenv@17.3.1] +injecting env (0) from .env +-- tip: ΓÜÖ∩╕Å enable debug +logging with { debug: true } + + at _log (node_modules/d +otenv/lib/main.js:139:11) + + ΓùÅ API Integration Tests +(RFC 7807) ΓÇ║ GET /health +should return status ok + + expect(received).toBe(exp +ected) // Object.is equality + + Expected: "ok" + Received: undefined + +   36 | +const response += await r +equest(app).ge +t('/health')[ +33m; +  37 | expe +ct(response.status) +.toBe(200 +); + +> 38 +| expect(response[3 +3m.body.status +).toBe('ok'[3 +9m); +  | + +^ +  39 | +}); +  40 | +  41 | +test('GET /api should +return api +info', +async () +=> { + + at Object.toBe (tests/i +ntegration/errorHandling.test +.js:38:34) + + ΓùÅ API Integration Tests +(RFC 7807) ΓÇ║ GET /api +should return api info + + expect(received).toBe(exp +ected) // Object.is equality + + Expected: "LiquiFact API" + Received: undefined + +   42 | +const response += await r +equest(app).ge +t('/api') +; +  43 | expe +ct(response.status) +.toBe(200 +); + +> 44 +| expect(response[3 +3m.body.name) +[33m.toBe('LiquiFac +t API'); +  | + +^ +  45 | +}); +  46 | +  47 | +test('GET +/api/escrow/:invoiceId +should return 200 with +escrow data (requires +auth)', +async () +=> { + + at Object.toBe (tests/i +ntegration/errorHandling.test +.js:44:32) + +FAIL src/index.test.js + ΓùÅ Console + + console.log + [dotenv@17.3.1] +injecting env (0) from .env +-- tip: ΓÜÖ∩╕Å write to +custom object with { +processEnv: myObject } + + at _log (node_modules/d +otenv/lib/main.js:139:11) + + console.log + [dotenv@17.3.1] +injecting env (0) from .env +-- tip: ΓÜÖ∩╕Å write to +custom object with { +processEnv: myObject } + + at _log (node_modules/d +otenv/lib/main.js:139:11) + + console.log + [dotenv@17.3.1] +injecting env (0) from .env +-- tip: ΓÜÖ∩╕Å specify +custom .env file path with { +path: '/custom/path/.env' } + + at _log (node_modules/d +otenv/lib/main.js:139:11) + + ΓùÅ LiquiFact API ΓÇ║ +Invoices Lifecycle ΓÇ║ POST +/api/invoices - fails if +missing fields + + expect(received).toBe(exp +ected) // Object.is equality + + Expected: 400 + Received: 201 + +   56 | + .set( +'Authorization'[33 +m, `Bearer +${token}`) +  57 | +.send({ +amount: +1000 }); + +> 58 +| expect(response +[33m.status).t +oBe(400); +  | + +^ +  59 | +}); +  60 | +  61 | +it('GET /api/invoices - +lists active +invoices', +async () +=> { + + at Object.toBe +(src/index.test.js:58:31) + +FAIL +src/tests/response.test.js + ΓùÅ Console + + console.log + [dotenv@17.3.1] +injecting env (0) from .env +-- tip: ≡ƒöÉ prevent +committing .env to code: +https://dotenvx.com/precommit + + at _log (node_modules/d +otenv/lib/main.js:139:11) + + console.log + [dotenv@17.3.1] +injecting env (0) from .env +-- tip: ≡ƒñû agentic secret +storage: +https://dotenvx.com/as2 + + at _log (node_modules/d +otenv/lib/main.js:139:11) + + console.error + Unhandled Error: +Error: Triggered Error + at C:\Users\pc\Docu +ments\waves\Liquifact-backend +\src\app.js:141:10 + at +Layer.handleRequest (C:\Users +\pc\Documents\waves\Liquifact +-backend\node_modules\router\ +lib\layer.js:152:17) + at next (C:\Users\p +c\Documents\waves\Liquifact-b +ackend\node_modules\router\li +b\route.js:157:13) + at Route.dispatch ( +C:\Users\pc\Documents\waves\L +iquifact-backend\node_modules +\router\lib\route.js:117:3) + at handle (C:\Users +\pc\Documents\waves\Liquifact +-backend\node_modules\router\ +index.js:435:11) + at +Layer.handleRequest (C:\Users +\pc\Documents\waves\Liquifact +-backend\node_modules\router\ +lib\layer.js:152:17) + at C:\Users\pc\Docu +ments\waves\Liquifact-backend +\node_modules\router\index.js +:295:15 + at processParams (C +:\Users\pc\Documents\waves\Li +quifact-backend\node_modules\ +router\index.js:582:12) + at next (C:\Users\p +c\Documents\waves\Liquifact-b +ackend\node_modules\router\in +dex.js:291:5) + at C:\Users\pc\Docu +ments\waves\Liquifact-backend +\node_modules\express-rate-li +mit\dist\index.cjs:947:7 + at +processTicksAndRejections (no +de:internal/process/task_queu +es:105:5) + at C:\Users\pc\Docu +ments\waves\Liquifact-backend +\node_modules\express-rate-li +mit\dist\index.cjs:830:5 + +   31 | +// Log unexpected +errors +  32 | +if (status +=== 500) +{ + +> 33 +| console.[3 +9merror('Unhandled +Error:', +err); +  | + ^ +  34 | } +  35 | +  36 | +problem = +formatProblemDetails({ + + at error (src/middlewar +e/errorHandler.js:33:15) + at Layer.handleError (n +ode_modules/router/lib/layer. +js:116:17) + at trimPrefix (node_mod +ules/router/index.js:340:13) + at node_modules/router/ +index.js:297:9 + at processParams (node_ +modules/router/index.js:582:1 +2) + at next (node_modules/r +outer/index.js:291:5) + at next (src/middleware +/bodySizeLimits.js:177:3) + at Layer.handleError (n +ode_modules/router/lib/layer. +js:116:17) + at trimPrefix (node_mod +ules/router/index.js:340:13) + at node_modules/router/ +index.js:297:9 + at processParams (node_ +modules/router/index.js:582:1 +2) + at next (node_modules/r +outer/index.js:291:5) + at next +(src/app.js:156:5) + at Layer.handleError (n +ode_modules/router/lib/layer. +js:116:17) + at trimPrefix (node_mod +ules/router/index.js:340:13) + at node_modules/router/ +index.js:297:9 + at processParams (node_ +modules/router/index.js:582:1 +2) + at next (node_modules/r +outer/index.js:291:5) + at Layer.handleError (n +ode_modules/router/lib/layer. +js:111:12) + at trimPrefix (node_mod +ules/router/index.js:340:13) + at node_modules/router/ +index.js:297:9 + at processParams (node_ +modules/router/index.js:582:1 +2) + at next (node_modules/r +outer/index.js:291:5) + at next (node_modules/r +outer/lib/route.js:132:14) + at next +(src/app.js:141:5) + at Layer.handleRequest +(node_modules/router/lib/laye +r.js:152:17) + at next (node_modules/r +outer/lib/route.js:157:13) + at Route.dispatch (node +_modules/router/lib/route.js: +117:3) + at handle (node_modules +/router/index.js:435:11) + at Layer.handleRequest +(node_modules/router/lib/laye +r.js:152:17) + at node_modules/router/ +index.js:295:15 + at processParams (node_ +modules/router/index.js:582:1 +2) + at next (node_modules/r +outer/index.js:291:5) + at node_modules/express +-rate-limit/dist/index.cjs:94 +7:7 + at node_modules/express +-rate-limit/dist/index.cjs:83 +0:5 + + console.error + Unhandled Error: +Error: Triggered Error + at C:\Users\pc\Docu +ments\waves\Liquifact-backend +\src\app.js:141:10 + at +Layer.handleRequest (C:\Users +\pc\Documents\waves\Liquifact +-backend\node_modules\router\ +lib\layer.js:152:17) + at next (C:\Users\p +c\Documents\waves\Liquifact-b +ackend\node_modules\router\li +b\route.js:157:13) + at Route.dispatch ( +C:\Users\pc\Documents\waves\L +iquifact-backend\node_modules +\router\lib\route.js:117:3) + at handle (C:\Users +\pc\Documents\waves\Liquifact +-backend\node_modules\router\ +index.js:435:11) + at +Layer.handleRequest (C:\Users +\pc\Documents\waves\Liquifact +-backend\node_modules\router\ +lib\layer.js:152:17) + at C:\Users\pc\Docu +ments\waves\Liquifact-backend +\node_modules\router\index.js +:295:15 + at processParams (C +:\Users\pc\Documents\waves\Li +quifact-backend\node_modules\ +router\index.js:582:12) + at next (C:\Users\p +c\Documents\waves\Liquifact-b +ackend\node_modules\router\in +dex.js:291:5) + at C:\Users\pc\Docu +ments\waves\Liquifact-backend +\node_modules\express-rate-li +mit\dist\index.cjs:947:7 + at +processTicksAndRejections (no +de:internal/process/task_queu +es:105:5) + at C:\Users\pc\Docu +ments\waves\Liquifact-backend +\node_modules\express-rate-li +mit\dist\index.cjs:830:5 + +   31 | +// Log unexpected +errors +  32 | +if (status +=== 500) +{ + +> 33 +| console.[3 +9merror('Unhandled +Error:', +err); +  | + ^ +  34 | } +  35 | +  36 | +problem = +formatProblemDetails({ + + at error (src/middlewar +e/errorHandler.js:33:15) + at Layer.handleError (n +ode_modules/router/lib/layer. +js:116:17) + at trimPrefix (node_mod +ules/router/index.js:340:13) + at node_modules/router/ +index.js:297:9 + at processParams (node_ +modules/router/index.js:582:1 +2) + at next (node_modules/r +outer/index.js:291:5) + at next (src/middleware +/bodySizeLimits.js:177:3) + at Layer.handleError (n +ode_modules/router/lib/layer. +js:116:17) + at trimPrefix (node_mod +ules/router/index.js:340:13) + at node_modules/router/ +index.js:297:9 + at processParams (node_ +modules/router/index.js:582:1 +2) + at next (node_modules/r +outer/index.js:291:5) + at next +(src/app.js:156:5) + at Layer.handleError (n +ode_modules/router/lib/layer. +js:116:17) + at trimPrefix (node_mod +ules/router/index.js:340:13) + at node_modules/router/ +index.js:297:9 + at processParams (node_ +modules/router/index.js:582:1 +2) + at next (node_modules/r +outer/index.js:291:5) + at Layer.handleError (n +ode_modules/router/lib/layer. +js:111:12) + at trimPrefix (node_mod +ules/router/index.js:340:13) + at node_modules/router/ +index.js:297:9 + at processParams (node_ +modules/router/index.js:582:1 +2) + at next (node_modules/r +outer/index.js:291:5) + at next (node_modules/r +outer/lib/route.js:132:14) + at next +(src/app.js:141:5) + at Layer.handleRequest +(node_modules/router/lib/laye +r.js:152:17) + at next (node_modules/r +outer/lib/route.js:157:13) + at Route.dispatch (node +_modules/router/lib/route.js: +117:3) + at handle (node_modules +/router/index.js:435:11) + at Layer.handleRequest +(node_modules/router/lib/laye +r.js:152:17) + at node_modules/router/ +index.js:295:15 + at processParams (node_ +modules/router/index.js:582:1 +2) + at next (node_modules/r +outer/index.js:291:5) + at node_modules/express +-rate-limit/dist/index.cjs:94 +7:7 + at node_modules/express +-rate-limit/dist/index.cjs:83 +0:5 + + ΓùÅ Standard Response +Envelope (Issue 19) ΓÇ║ POST +/api/invoices should return +201 and standardized success +envelope + + expect(received).toBe(exp +ected) // Object.is equality + + Expected: 201 + Received: 401 + +   27 | +it('POST /api/invoices +should return 201 and +standardized success +envelope', +async () +=> { +  28 | +const res += await r +equest(app).post([ +32m'/api/invoices') +.send({}); + +> 29 +| expect(res.[ +39mstatus).toBe([3 +5m201); +  | + +^ +  30 | expe +ct(res.body.[ +39mdata.id).[ +39mtoBe('placeholder'[3 +9m); +  31 | expe +ct(res.body.[ +39merror).toBeNull( +); +  32 | +}); + + at Object.toBe (src/tes +ts/response.test.js:29:24) + + ΓùÅ Standard Response +Envelope (Issue 19) ΓÇ║ All +routes should return +standard response format + + expect(received).toBe(exp +ected) // Object.is equality + + Expected: 200 + Received: 401 + +   36 | +for +(const route +of routes) { +  37 | +const res += await r +equest(app).ge +t(route); + +> 38 +| expect(res. +status).toBe( +[35m200); +  | + +^ +  39 | ex +pect(res.body) +.toHaveProperty('da +ta'); +  40 | ex +pect(res.body) +.toHaveProperty('me +ta'); +  41 | ex +pect(res.body) +.toHaveProperty('er +ror'); + + at Object.toBe (src/tes +ts/response.test.js:38:26) + + ΓùÅ Standard Response +Envelope (Issue 19) ΓÇ║ +Internal server errors +should return stack trace in +development + + expect(received).toContai +n(expected) // indexOf + + Expected substring: +"Error: Triggered Error" + Received string: +"Triggered Error" + +   56 | +const res += await r +equest(app).ge +t('/debug/error'[3 +9m); +  57 | expe +ct(res.status) +.toBe(500)[33 +m; + +> 58 +| expect(res.[ +39mbody.error. +details).toCon +tain('Error: Triggered +Error'); +  | + +^ +  59 | +}); +  60 | +  61 | +it('Internal server +errors should return +standard error envelope +(e.g. malformed +JSON)', +async () +=> { + + at Object.toContain (sr +c/tests/response.test.js:58:3 +6) + + ΓùÅ Standard Response +Envelope (Issue 19) ΓÇ║ +Internal server errors +should return standard error +envelope (e.g. malformed +JSON) + + expect(received).toBe(exp +ected) // Object.is equality + + Expected: "BAD_REQUEST" + Received: +"INTERNAL_ERROR" + +   67 | +expect(res.status) +[33m.toBe(400) +; +  68 | expe +ct(res.body.[ +39mdata).toBeNull() +; + +> 69 +| expect(res.[ +39mbody.error. +code).toBe([3 +2m'BAD_REQUEST');[ +39m +  | + +^ +  70 | +}); +  71 | +}); +  72 | + + at Object.toBe (src/tes +ts/response.test.js:69:33) + +FAIL src/app.test.js + ΓùÅ Console + + console.log + [dotenv@17.3.1] +injecting env (0) from .env +-- tip: ≡ƒöÉ prevent +committing .env to code: +https://dotenvx.com/precommit + + at _log (node_modules/d +otenv/lib/main.js:139:11) + + console.log + [dotenv@17.3.1] +injecting env (0) from .env +-- tip: ≡ƒöÉ encrypt with +Dotenvx: https://dotenvx.com + + at _log (node_modules/d +otenv/lib/main.js:139:11) + + console.error + Unhandled Error: +TypeError: Cannot convert +undefined or null to object + at +ServerResponse.removeHeader +(node:_http_outgoing:870:30) + at +xPoweredByMiddleware (C:\User +s\pc\Documents\waves\Liquifac +t-backend\node_modules\helmet +\index.cjs:303:7) + at internalNext (C: +\Users\pc\Documents\waves\Liq +uifact-backend\node_modules\h +elmet\index.cjs:529:6) + at xPermittedCrossD +omainPoliciesMiddleware (C:\U +sers\pc\Documents\waves\Liqui +fact-backend\node_modules\hel +met\index.cjs:297:3) + at internalNext (C: +\Users\pc\Documents\waves\Liq +uifact-backend\node_modules\h +elmet\index.cjs:529:6) + at +xFrameOptionsMiddleware (C:\U +sers\pc\Documents\waves\Liqui +fact-backend\node_modules\hel +met\index.cjs:281:3) + at internalNext (C: +\Users\pc\Documents\waves\Liq +uifact-backend\node_modules\h +elmet\index.cjs:529:6) + at +xDownloadOptionsMiddleware (C +:\Users\pc\Documents\waves\Li +quifact-backend\node_modules\ +helmet\index.cjs:261:3) + at internalNext (C: +\Users\pc\Documents\waves\Liq +uifact-backend\node_modules\h +elmet\index.cjs:529:6) + at xDnsPrefetchCont +rolMiddleware (C:\Users\pc\Do +cuments\waves\Liquifact-backe +nd\node_modules\helmet\index. +cjs:254:3) + at internalNext (C: +\Users\pc\Documents\waves\Liq +uifact-backend\node_modules\h +elmet\index.cjs:529:6) + at xContentTypeOpti +onsMiddleware (C:\Users\pc\Do +cuments\waves\Liquifact-backe +nd\node_modules\helmet\index. +cjs:246:3) + at internalNext (C: +\Users\pc\Documents\waves\Liq +uifact-backend\node_modules\h +elmet\index.cjs:529:6) + at strictTransportS +ecurityMiddleware (C:\Users\p +c\Documents\waves\Liquifact-b +ackend\node_modules\helmet\in +dex.cjs:239:3) + at internalNext (C: +\Users\pc\Documents\waves\Liq +uifact-backend\node_modules\h +elmet\index.cjs:529:6) + at +referrerPolicyMiddleware (C:\ +Users\pc\Documents\waves\Liqu +ifact-backend\node_modules\he +lmet\index.cjs:207:3) + at internalNext (C: +\Users\pc\Documents\waves\Liq +uifact-backend\node_modules\h +elmet\index.cjs:529:6) + at +originAgentClusterMiddleware +(C:\Users\pc\Documents\waves\ +Liquifact-backend\node_module +s\helmet\index.cjs:182:3) + at internalNext (C: +\Users\pc\Documents\waves\Liq +uifact-backend\node_modules\h +elmet\index.cjs:529:6) + at crossOriginResou +rcePolicyMiddleware (C:\Users +\pc\Documents\waves\Liquifact +-backend\node_modules\helmet\ +index.cjs:175:3) + at internalNext (C: +\Users\pc\Documents\waves\Liq +uifact-backend\node_modules\h +elmet\index.cjs:529:6) + at crossOriginOpene +rPolicyMiddleware (C:\Users\p +c\Documents\waves\Liquifact-b +ackend\node_modules\helmet\in +dex.cjs:159:3) + at internalNext (C: +\Users\pc\Documents\waves\Liq +uifact-backend\node_modules\h +elmet\index.cjs:529:6) + at crossOriginEmbed +derPolicyMiddleware (C:\Users +\pc\Documents\waves\Liquifact +-backend\node_modules\helmet\ +index.cjs:143:3) + at internalNext (C: +\Users\pc\Documents\waves\Liq +uifact-backend\node_modules\h +elmet\index.cjs:529:6) + at contentSecurityP +olicyMiddleware (C:\Users\pc\ +Documents\waves\Liquifact-bac +kend\node_modules\helmet\inde +x.cjs:124:4) + at internalNext (C: +\Users\pc\Documents\waves\Liq +uifact-backend\node_modules\h +elmet\index.cjs:529:6) + at +helmetMiddleware (C:\Users\pc +\Documents\waves\Liquifact-ba +ckend\node_modules\helmet\ind +ex.cjs:533:6) + at +Layer.handleRequest (C:\Users +\pc\Documents\waves\Liquifact +-backend\node_modules\router\ +lib\layer.js:152:17) + at trimPrefix (C:\U +sers\pc\Documents\waves\Liqui +fact-backend\node_modules\rou +ter\index.js:342:13) + at C:\Users\pc\Docu +ments\waves\Liquifact-backend +\node_modules\router\index.js +:297:9 + at processParams (C +:\Users\pc\Documents\waves\Li +quifact-backend\node_modules\ +router\index.js:582:12) + at next (C:\Users\p +c\Documents\waves\Liquifact-b +ackend\node_modules\router\in +dex.js:291:5) + at Function.handle +(C:\Users\pc\Documents\waves\ +Liquifact-backend\node_module +s\router\index.js:186:3) + at Function.handle +(C:\Users\pc\Documents\waves\ +Liquifact-backend\node_module +s\express\lib\application.js: +177:15) + at handle (C:\Users +\pc\Documents\waves\Liquifact +-backend\src\app.test.js:36:9 +) + at new Promise +() + at invokeApp (C:\Us +ers\pc\Documents\waves\Liquif +act-backend\src\app.test.js:2 +5:10) + at +Object.invokeApp (C:\Users\pc +\Documents\waves\Liquifact-ba +ckend\src\app.test.js:42:28) + at +Promise.finally.completed (C: +\Users\pc\Documents\waves\Liq +uifact-backend\node_modules\j +est-circus\build\jestAdapterI +nit.js:1557:28) + at new Promise +() + at +callAsyncCircusFn (C:\Users\p +c\Documents\waves\Liquifact-b +ackend\node_modules\jest-circ +us\build\jestAdapterInit.js:1 +497:10) + at _callCircusTest +(C:\Users\pc\Documents\waves\ +Liquifact-backend\node_module +s\jest-circus\build\jestAdapt +erInit.js:1007:40) + at +processTicksAndRejections (no +de:internal/process/task_queu +es:105:5) + at _runTest (C:\Use +rs\pc\Documents\waves\Liquifa +ct-backend\node_modules\jest- +circus\build\jestAdapterInit. +js:947:3) + at C:\Users\pc\Docu +ments\waves\Liquifact-backend +\node_modules\jest-circus\bui +ld\jestAdapterInit.js:849:7 + at +_runTestsForDescribeBlock (C: +\Users\pc\Documents\waves\Liq +uifact-backend\node_modules\j +est-circus\build\jestAdapterI +nit.js:862:11) + at +_runTestsForDescribeBlock (C: +\Users\pc\Documents\waves\Liq +uifact-backend\node_modules\j +est-circus\build\jestAdapterI +nit.js:857:11) + at run (C:\Users\pc +\Documents\waves\Liquifact-ba +ckend\node_modules\jest-circu +s\build\jestAdapterInit.js:76 +1:3) + at runAndTransformR +esultsToJestFormat (C:\Users\ +pc\Documents\waves\Liquifact- +backend\node_modules\jest-cir +cus\build\jestAdapterInit.js: +1918:21) + at jestAdapter (C:\ +Users\pc\Documents\waves\Liqu +ifact-backend\node_modules\je +st-circus\build\runner.js:101 +:19) + at runTestInternal +(C:\Users\pc\Documents\waves\ +Liquifact-backend\node_module +s\jest-runner\build\testWorke +r.js:275:16) + at runTest (C:\User +s\pc\Documents\waves\Liquifac +t-backend\node_modules\jest-r +unner\build\testWorker.js:343 +:7) + at Object.worker (C +:\Users\pc\Documents\waves\Li +quifact-backend\node_modules\ +jest-runner\build\testWorker. +js:497:12) + +   31 | +// Log unexpected +errors +  32 | +if (status +=== 500) +{ + +> 33 +| console.[3 +9merror('Unhandled +Error:', +err); +  | + ^ +  34 | } +  35 | +  36 | +problem = +formatProblemDetails({ + + at error (src/middlewar +e/errorHandler.js:33:15) + at Layer.handleError (n +ode_modules/router/lib/layer. +js:116:17) + at trimPrefix (node_mod +ules/router/index.js:340:13) + at node_modules/router/ +index.js:297:9 + at processParams (node_ +modules/router/index.js:582:1 +2) + at next (node_modules/r +outer/index.js:291:5) + at next (src/middleware +/bodySizeLimits.js:177:3) + at Layer.handleError (n +ode_modules/router/lib/layer. +js:116:17) + at trimPrefix (node_mod +ules/router/index.js:340:13) + at node_modules/router/ +index.js:297:9 + at processParams (node_ +modules/router/index.js:582:1 +2) + at next (node_modules/r +outer/index.js:291:5) + at next +(src/app.js:156:5) + at Layer.handleError (n +ode_modules/router/lib/layer. +js:116:17) + at trimPrefix (node_mod +ules/router/index.js:340:13) + at node_modules/router/ +index.js:297:9 + at processParams (node_ +modules/router/index.js:582:1 +2) + at next (node_modules/r +outer/index.js:291:5) + at Layer.handleError (n +ode_modules/router/lib/layer. +js:111:12) + at trimPrefix (node_mod +ules/router/index.js:340:13) + at node_modules/router/ +index.js:297:9 + at processParams (node_ +modules/router/index.js:582:1 +2) + at next (node_modules/r +outer/index.js:291:5) + at Layer.handleError (n +ode_modules/router/lib/layer. +js:111:12) + at trimPrefix (node_mod +ules/router/index.js:340:13) + at node_modules/router/ +index.js:297:9 + at processParams (node_ +modules/router/index.js:582:1 +2) + at next (node_modules/r +outer/index.js:291:5) + at Layer.handleError (n +ode_modules/router/lib/layer. +js:111:12) + at trimPrefix (node_mod +ules/router/index.js:340:13) + at node_modules/router/ +index.js:297:9 + at processParams (node_ +modules/router/index.js:582:1 +2) + at next (node_modules/r +outer/index.js:291:5) + at Layer.handleError (n +ode_modules/router/lib/layer. +js:111:12) + at trimPrefix (node_mod +ules/router/index.js:340:13) + at node_modules/router/ +index.js:297:9 + at processParams (node_ +modules/router/index.js:582:1 +2) + at next (node_modules/r +outer/index.js:291:5) + at Layer.handleError (n +ode_modules/router/lib/layer. +js:111:12) + at trimPrefix (node_mod +ules/router/index.js:340:13) + at node_modules/router/ +index.js:297:9 + at processParams (node_ +modules/router/index.js:582:1 +2) + at next (node_modules/r +outer/index.js:291:5) + at Layer.handleError (n +ode_modules/router/lib/layer. +js:111:12) + at trimPrefix (node_mod +ules/router/index.js:340:13) + at node_modules/router/ +index.js:297:9 + at processParams (node_ +modules/router/index.js:582:1 +2) + at next (node_modules/r +outer/index.js:291:5) + at Layer.handleError (n +ode_modules/router/lib/layer. +js:111:12) + at trimPrefix (node_mod +ules/router/index.js:340:13) + at node_modules/router/ +index.js:297:9 + at processParams (node_ +modules/router/index.js:582:1 +2) + at next (node_modules/r +outer/index.js:291:5) + at Layer.handleRequest +(node_modules/router/lib/laye +r.js:165:5) + at trimPrefix (node_mod +ules/router/index.js:342:13) + at node_modules/router/ +index.js:297:9 + at processParams (node_ +modules/router/index.js:582:1 +2) + at next (node_modules/r +outer/index.js:291:5) + at Function.handle (nod +e_modules/router/index.js:186 +:3) + at Function.handle (nod +e_modules/express/lib/applica +tion.js:177:15) + at handle +(src/app.test.js:36:9) + at invokeApp +(src/app.test.js:25:10) + at Object.invokeApp +(src/app.test.js:42:28) + + console.error + Unhandled Error: +TypeError: Cannot convert +undefined or null to object + at +ServerResponse.removeHeader +(node:_http_outgoing:870:30) + at +xPoweredByMiddleware (C:\User +s\pc\Documents\waves\Liquifac +t-backend\node_modules\helmet +\index.cjs:303:7) + at internalNext (C: +\Users\pc\Documents\waves\Liq +uifact-backend\node_modules\h +elmet\index.cjs:529:6) + at xPermittedCrossD +omainPoliciesMiddleware (C:\U +sers\pc\Documents\waves\Liqui +fact-backend\node_modules\hel +met\index.cjs:297:3) + at internalNext (C: +\Users\pc\Documents\waves\Liq +uifact-backend\node_modules\h +elmet\index.cjs:529:6) + at +xFrameOptionsMiddleware (C:\U +sers\pc\Documents\waves\Liqui +fact-backend\node_modules\hel +met\index.cjs:281:3) + at internalNext (C: +\Users\pc\Documents\waves\Liq +uifact-backend\node_modules\h +elmet\index.cjs:529:6) + at +xDownloadOptionsMiddleware (C +:\Users\pc\Documents\waves\Li +quifact-backend\node_modules\ +helmet\index.cjs:261:3) + at internalNext (C: +\Users\pc\Documents\waves\Liq +uifact-backend\node_modules\h +elmet\index.cjs:529:6) + at xDnsPrefetchCont +rolMiddleware (C:\Users\pc\Do +cuments\waves\Liquifact-backe +nd\node_modules\helmet\index. +cjs:254:3) + at internalNext (C: +\Users\pc\Documents\waves\Liq +uifact-backend\node_modules\h +elmet\index.cjs:529:6) + at xContentTypeOpti +onsMiddleware (C:\Users\pc\Do +cuments\waves\Liquifact-backe +nd\node_modules\helmet\index. +cjs:246:3) + at internalNext (C: +\Users\pc\Documents\waves\Liq +uifact-backend\node_modules\h +elmet\index.cjs:529:6) + at strictTransportS +ecurityMiddleware (C:\Users\p +c\Documents\waves\Liquifact-b +ackend\node_modules\helmet\in +dex.cjs:239:3) + at internalNext (C: +\Users\pc\Documents\waves\Liq +uifact-backend\node_modules\h +elmet\index.cjs:529:6) + at +referrerPolicyMiddleware (C:\ +Users\pc\Documents\waves\Liqu +ifact-backend\node_modules\he +lmet\index.cjs:207:3) + at internalNext (C: +\Users\pc\Documents\waves\Liq +uifact-backend\node_modules\h +elmet\index.cjs:529:6) + at +originAgentClusterMiddleware +(C:\Users\pc\Documents\waves\ +Liquifact-backend\node_module +s\helmet\index.cjs:182:3) + at internalNext (C: +\Users\pc\Documents\waves\Liq +uifact-backend\node_modules\h +elmet\index.cjs:529:6) + at crossOriginResou +rcePolicyMiddleware (C:\Users +\pc\Documents\waves\Liquifact +-backend\node_modules\helmet\ +index.cjs:175:3) + at internalNext (C: +\Users\pc\Documents\waves\Liq +uifact-backend\node_modules\h +elmet\index.cjs:529:6) + at crossOriginOpene +rPolicyMiddleware (C:\Users\p +c\Documents\waves\Liquifact-b +ackend\node_modules\helmet\in +dex.cjs:159:3) + at internalNext (C: +\Users\pc\Documents\waves\Liq +uifact-backend\node_modules\h +elmet\index.cjs:529:6) + at crossOriginEmbed +derPolicyMiddleware (C:\Users +\pc\Documents\waves\Liquifact +-backend\node_modules\helmet\ +index.cjs:143:3) + at internalNext (C: +\Users\pc\Documents\waves\Liq +uifact-backend\node_modules\h +elmet\index.cjs:529:6) + at contentSecurityP +olicyMiddleware (C:\Users\pc\ +Documents\waves\Liquifact-bac +kend\node_modules\helmet\inde +x.cjs:124:4) + at internalNext (C: +\Users\pc\Documents\waves\Liq +uifact-backend\node_modules\h +elmet\index.cjs:529:6) + at +helmetMiddleware (C:\Users\pc +\Documents\waves\Liquifact-ba +ckend\node_modules\helmet\ind +ex.cjs:533:6) + at +Layer.handleRequest (C:\Users +\pc\Documents\waves\Liquifact +-backend\node_modules\router\ +lib\layer.js:152:17) + at trimPrefix (C:\U +sers\pc\Documents\waves\Liqui +fact-backend\node_modules\rou +ter\index.js:342:13) + at C:\Users\pc\Docu +ments\waves\Liquifact-backend +\node_modules\router\index.js +:297:9 + at processParams (C +:\Users\pc\Documents\waves\Li +quifact-backend\node_modules\ +router\index.js:582:12) + at next (C:\Users\p +c\Documents\waves\Liquifact-b +ackend\node_modules\router\in +dex.js:291:5) + at Function.handle +(C:\Users\pc\Documents\waves\ +Liquifact-backend\node_module +s\router\index.js:186:3) + at Function.handle +(C:\Users\pc\Documents\waves\ +Liquifact-backend\node_module +s\express\lib\application.js: +177:15) + at handle (C:\Users +\pc\Documents\waves\Liquifact +-backend\src\app.test.js:36:9 +) + at new Promise +() + at invokeApp (C:\Us +ers\pc\Documents\waves\Liquif +act-backend\src\app.test.js:2 +5:10) + at +Object.invokeApp (C:\Users\pc +\Documents\waves\Liquifact-ba +ckend\src\app.test.js:48:28) + at +Promise.finally.completed (C: +\Users\pc\Documents\waves\Liq +uifact-backend\node_modules\j +est-circus\build\jestAdapterI +nit.js:1557:28) + at new Promise +() + at +callAsyncCircusFn (C:\Users\p +c\Documents\waves\Liquifact-b +ackend\node_modules\jest-circ +us\build\jestAdapterInit.js:1 +497:10) + at _callCircusTest +(C:\Users\pc\Documents\waves\ +Liquifact-backend\node_module +s\jest-circus\build\jestAdapt +erInit.js:1007:40) + at +processTicksAndRejections (no +de:internal/process/task_queu +es:105:5) + at _runTest (C:\Use +rs\pc\Documents\waves\Liquifa +ct-backend\node_modules\jest- +circus\build\jestAdapterInit. +js:947:3) + at C:\Users\pc\Docu +ments\waves\Liquifact-backend +\node_modules\jest-circus\bui +ld\jestAdapterInit.js:849:7 + at +_runTestsForDescribeBlock (C: +\Users\pc\Documents\waves\Liq +uifact-backend\node_modules\j +est-circus\build\jestAdapterI +nit.js:862:11) + at +_runTestsForDescribeBlock (C: +\Users\pc\Documents\waves\Liq +uifact-backend\node_modules\j +est-circus\build\jestAdapterI +nit.js:857:11) + at run (C:\Users\pc +\Documents\waves\Liquifact-ba +ckend\node_modules\jest-circu +s\build\jestAdapterInit.js:76 +1:3) + at runAndTransformR +esultsToJestFormat (C:\Users\ +pc\Documents\waves\Liquifact- +backend\node_modules\jest-cir +cus\build\jestAdapterInit.js: +1918:21) + at jestAdapter (C:\ +Users\pc\Documents\waves\Liqu +ifact-backend\node_modules\je +st-circus\build\runner.js:101 +:19) + at runTestInternal +(C:\Users\pc\Documents\waves\ +Liquifact-backend\node_module +s\jest-runner\build\testWorke +r.js:275:16) + at runTest (C:\User +s\pc\Documents\waves\Liquifac +t-backend\node_modules\jest-r +unner\build\testWorker.js:343 +:7) + at Object.worker (C +:\Users\pc\Documents\waves\Li +quifact-backend\node_modules\ +jest-runner\build\testWorker. +js:497:12) + +   31 | +// Log unexpected +errors +  32 | +if (status +=== 500) +{ + +> 33 +| console.[3 +9merror('Unhandled +Error:', +err); +  | + ^ +  34 | } +  35 | +  36 | +problem = +formatProblemDetails({ + + at error (src/middlewar +e/errorHandler.js:33:15) + at Layer.handleError (n +ode_modules/router/lib/layer. +js:116:17) + at trimPrefix (node_mod +ules/router/index.js:340:13) + at node_modules/router/ +index.js:297:9 + at processParams (node_ +modules/router/index.js:582:1 +2) + at next (node_modules/r +outer/index.js:291:5) + at next (src/middleware +/bodySizeLimits.js:177:3) + at Layer.handleError (n +ode_modules/router/lib/layer. +js:116:17) + at trimPrefix (node_mod +ules/router/index.js:340:13) + at node_modules/router/ +index.js:297:9 + at processParams (node_ +modules/router/index.js:582:1 +2) + at next (node_modules/r +outer/index.js:291:5) + at next +(src/app.js:156:5) + at Layer.handleError (n +ode_modules/router/lib/layer. +js:116:17) + at trimPrefix (node_mod +ules/router/index.js:340:13) + at node_modules/router/ +index.js:297:9 + at processParams (node_ +modules/router/index.js:582:1 +2) + at next (node_modules/r +outer/index.js:291:5) + at Layer.handleError (n +ode_modules/router/lib/layer. +js:111:12) + at trimPrefix (node_mod +ules/router/index.js:340:13) + at node_modules/router/ +index.js:297:9 + at processParams (node_ +modules/router/index.js:582:1 +2) + at next (node_modules/r +outer/index.js:291:5) + at Layer.handleError (n +ode_modules/router/lib/layer. +js:111:12) + at trimPrefix (node_mod +ules/router/index.js:340:13) + at node_modules/router/ +index.js:297:9 + at processParams (node_ +modules/router/index.js:582:1 +2) + at next (node_modules/r +outer/index.js:291:5) + at Layer.handleError (n +ode_modules/router/lib/layer. +js:111:12) + at trimPrefix (node_mod +ules/router/index.js:340:13) + at node_modules/router/ +index.js:297:9 + at processParams (node_ +modules/router/index.js:582:1 +2) + at next (node_modules/r +outer/index.js:291:5) + at Layer.handleError (n +ode_modules/router/lib/layer. +js:111:12) + at trimPrefix (node_mod +ules/router/index.js:340:13) + at node_modules/router/ +index.js:297:9 + at processParams (node_ +modules/router/index.js:582:1 +2) + at next (node_modules/r +outer/index.js:291:5) + at Layer.handleError (n +ode_modules/router/lib/layer. +js:111:12) + at trimPrefix (node_mod +ules/router/index.js:340:13) + at node_modules/router/ +index.js:297:9 + at processParams (node_ +modules/router/index.js:582:1 +2) + at next (node_modules/r +outer/index.js:291:5) + at Layer.handleError (n +ode_modules/router/lib/layer. +js:111:12) + at trimPrefix (node_mod +ules/router/index.js:340:13) + at node_modules/router/ +index.js:297:9 + at processParams (node_ +modules/router/index.js:582:1 +2) + at next (node_modules/r +outer/index.js:291:5) + at Layer.handleError (n +ode_modules/router/lib/layer. +js:111:12) + at trimPrefix (node_mod +ules/router/index.js:340:13) + at node_modules/router/ +index.js:297:9 + at processParams (node_ +modules/router/index.js:582:1 +2) + at next (node_modules/r +outer/index.js:291:5) + at Layer.handleRequest +(node_modules/router/lib/laye +r.js:165:5) + at trimPrefix (node_mod +ules/router/index.js:342:13) + at node_modules/router/ +index.js:297:9 + at processParams (node_ +modules/router/index.js:582:1 +2) + at next (node_modules/r +outer/index.js:291:5) + at Function.handle (nod +e_modules/router/index.js:186 +:3) + at Function.handle (nod +e_modules/express/lib/applica +tion.js:177:15) + at handle +(src/app.test.js:36:9) + at invokeApp +(src/app.test.js:25:10) + at Object.invokeApp +(src/app.test.js:48:28) + + console.error + Unhandled Error: +TypeError: Cannot convert +undefined or null to object + at +ServerResponse.removeHeader +(node:_http_outgoing:870:30) + at +xPoweredByMiddleware (C:\User +s\pc\Documents\waves\Liquifac +t-backend\node_modules\helmet +\index.cjs:303:7) + at internalNext (C: +\Users\pc\Documents\waves\Liq +uifact-backend\node_modules\h +elmet\index.cjs:529:6) + at xPermittedCrossD +omainPoliciesMiddleware (C:\U +sers\pc\Documents\waves\Liqui +fact-backend\node_modules\hel +met\index.cjs:297:3) + at internalNext (C: +\Users\pc\Documents\waves\Liq +uifact-backend\node_modules\h +elmet\index.cjs:529:6) + at +xFrameOptionsMiddleware (C:\U +sers\pc\Documents\waves\Liqui +fact-backend\node_modules\hel +met\index.cjs:281:3) + at internalNext (C: +\Users\pc\Documents\waves\Liq +uifact-backend\node_modules\h +elmet\index.cjs:529:6) + at +xDownloadOptionsMiddleware (C +:\Users\pc\Documents\waves\Li +quifact-backend\node_modules\ +helmet\index.cjs:261:3) + at internalNext (C: +\Users\pc\Documents\waves\Liq +uifact-backend\node_modules\h +elmet\index.cjs:529:6) + at xDnsPrefetchCont +rolMiddleware (C:\Users\pc\Do +cuments\waves\Liquifact-backe +nd\node_modules\helmet\index. +cjs:254:3) + at internalNext (C: +\Users\pc\Documents\waves\Liq +uifact-backend\node_modules\h +elmet\index.cjs:529:6) + at xContentTypeOpti +onsMiddleware (C:\Users\pc\Do +cuments\waves\Liquifact-backe +nd\node_modules\helmet\index. +cjs:246:3) + at internalNext (C: +\Users\pc\Documents\waves\Liq +uifact-backend\node_modules\h +elmet\index.cjs:529:6) + at strictTransportS +ecurityMiddleware (C:\Users\p +c\Documents\waves\Liquifact-b +ackend\node_modules\helmet\in +dex.cjs:239:3) + at internalNext (C: +\Users\pc\Documents\waves\Liq +uifact-backend\node_modules\h +elmet\index.cjs:529:6) + at +referrerPolicyMiddleware (C:\ +Users\pc\Documents\waves\Liqu +ifact-backend\node_modules\he +lmet\index.cjs:207:3) + at internalNext (C: +\Users\pc\Documents\waves\Liq +uifact-backend\node_modules\h +elmet\index.cjs:529:6) + at +originAgentClusterMiddleware +(C:\Users\pc\Documents\waves\ +Liquifact-backend\node_module +s\helmet\index.cjs:182:3) + at internalNext (C: +\Users\pc\Documents\waves\Liq +uifact-backend\node_modules\h +elmet\index.cjs:529:6) + at crossOriginResou +rcePolicyMiddleware (C:\Users +\pc\Documents\waves\Liquifact +-backend\node_modules\helmet\ +index.cjs:175:3) + at internalNext (C: +\Users\pc\Documents\waves\Liq +uifact-backend\node_modules\h +elmet\index.cjs:529:6) + at crossOriginOpene +rPolicyMiddleware (C:\Users\p +c\Documents\waves\Liquifact-b +ackend\node_modules\helmet\in +dex.cjs:159:3) + at internalNext (C: +\Users\pc\Documents\waves\Liq +uifact-backend\node_modules\h +elmet\index.cjs:529:6) + at crossOriginEmbed +derPolicyMiddleware (C:\Users +\pc\Documents\waves\Liquifact +-backend\node_modules\helmet\ +index.cjs:143:3) + at internalNext (C: +\Users\pc\Documents\waves\Liq +uifact-backend\node_modules\h +elmet\index.cjs:529:6) + at contentSecurityP +olicyMiddleware (C:\Users\pc\ +Documents\waves\Liquifact-bac +kend\node_modules\helmet\inde +x.cjs:124:4) + at internalNext (C: +\Users\pc\Documents\waves\Liq +uifact-backend\node_modules\h +elmet\index.cjs:529:6) + at +helmetMiddleware (C:\Users\pc +\Documents\waves\Liquifact-ba +ckend\node_modules\helmet\ind +ex.cjs:533:6) + at +Layer.handleRequest (C:\Users +\pc\Documents\waves\Liquifact +-backend\node_modules\router\ +lib\layer.js:152:17) + at trimPrefix (C:\U +sers\pc\Documents\waves\Liqui +fact-backend\node_modules\rou +ter\index.js:342:13) + at C:\Users\pc\Docu +ments\waves\Liquifact-backend +\node_modules\router\index.js +:297:9 + at processParams (C +:\Users\pc\Documents\waves\Li +quifact-backend\node_modules\ +router\index.js:582:12) + at next (C:\Users\p +c\Documents\waves\Liquifact-b +ackend\node_modules\router\in +dex.js:291:5) + at Function.handle +(C:\Users\pc\Documents\waves\ +Liquifact-backend\node_module +s\router\index.js:186:3) + at Function.handle +(C:\Users\pc\Documents\waves\ +Liquifact-backend\node_module +s\express\lib\application.js: +177:15) + at handle (C:\Users +\pc\Documents\waves\Liquifact +-backend\src\app.test.js:36:9 +) + at new Promise +() + at invokeApp (C:\Us +ers\pc\Documents\waves\Liquif +act-backend\src\app.test.js:2 +5:10) + at +Object.invokeApp (C:\Users\pc +\Documents\waves\Liquifact-ba +ckend\src\app.test.js:53:28) + at +Promise.finally.completed (C: +\Users\pc\Documents\waves\Liq +uifact-backend\node_modules\j +est-circus\build\jestAdapterI +nit.js:1557:28) + at new Promise +() + at +callAsyncCircusFn (C:\Users\p +c\Documents\waves\Liquifact-b +ackend\node_modules\jest-circ +us\build\jestAdapterInit.js:1 +497:10) + at _callCircusTest +(C:\Users\pc\Documents\waves\ +Liquifact-backend\node_module +s\jest-circus\build\jestAdapt +erInit.js:1007:40) + at +processTicksAndRejections (no +de:internal/process/task_queu +es:105:5) + at _runTest (C:\Use +rs\pc\Documents\waves\Liquifa +ct-backend\node_modules\jest- +circus\build\jestAdapterInit. +js:947:3) + at C:\Users\pc\Docu +ments\waves\Liquifact-backend +\node_modules\jest-circus\bui +ld\jestAdapterInit.js:849:7 + at +_runTestsForDescribeBlock (C: +\Users\pc\Documents\waves\Liq +uifact-backend\node_modules\j +est-circus\build\jestAdapterI +nit.js:862:11) + at +_runTestsForDescribeBlock (C: +\Users\pc\Documents\waves\Liq +uifact-backend\node_modules\j +est-circus\build\jestAdapterI +nit.js:857:11) + at run (C:\Users\pc +\Documents\waves\Liquifact-ba +ckend\node_modules\jest-circu +s\build\jestAdapterInit.js:76 +1:3) + at runAndTransformR +esultsToJestFormat (C:\Users\ +pc\Documents\waves\Liquifact- +backend\node_modules\jest-cir +cus\build\jestAdapterInit.js: +1918:21) + at jestAdapter (C:\ +Users\pc\Documents\waves\Liqu +ifact-backend\node_modules\je +st-circus\build\runner.js:101 +:19) + at runTestInternal +(C:\Users\pc\Documents\waves\ +Liquifact-backend\node_module +s\jest-runner\build\testWorke +r.js:275:16) + at runTest (C:\User +s\pc\Documents\waves\Liquifac +t-backend\node_modules\jest-r +unner\build\testWorker.js:343 +:7) + at Object.worker (C +:\Users\pc\Documents\waves\Li +quifact-backend\node_modules\ +jest-runner\build\testWorker. +js:497:12) + +   31 | +// Log unexpected +errors +  32 | +if (status +=== 500) +{ + +> 33 +| console.[3 +9merror('Unhandled +Error:', +err); +  | + ^ +  34 | } +  35 | +  36 | +problem = +formatProblemDetails({ + + at error (src/middlewar +e/errorHandler.js:33:15) + at Layer.handleError (n +ode_modules/router/lib/layer. +js:116:17) + at trimPrefix (node_mod +ules/router/index.js:340:13) + at node_modules/router/ +index.js:297:9 + at processParams (node_ +modules/router/index.js:582:1 +2) + at next (node_modules/r +outer/index.js:291:5) + at next (src/middleware +/bodySizeLimits.js:177:3) + at Layer.handleError (n +ode_modules/router/lib/layer. +js:116:17) + at trimPrefix (node_mod +ules/router/index.js:340:13) + at node_modules/router/ +index.js:297:9 + at processParams (node_ +modules/router/index.js:582:1 +2) + at next (node_modules/r +outer/index.js:291:5) + at next +(src/app.js:156:5) + at Layer.handleError (n +ode_modules/router/lib/layer. +js:116:17) + at trimPrefix (node_mod +ules/router/index.js:340:13) + at node_modules/router/ +index.js:297:9 + at processParams (node_ +modules/router/index.js:582:1 +2) + at next (node_modules/r +outer/index.js:291:5) + at Layer.handleError (n +ode_modules/router/lib/layer. +js:111:12) + at trimPrefix (node_mod +ules/router/index.js:340:13) + at node_modules/router/ +index.js:297:9 + at processParams (node_ +modules/router/index.js:582:1 +2) + at next (node_modules/r +outer/index.js:291:5) + at Layer.handleError (n +ode_modules/router/lib/layer. +js:111:12) + at trimPrefix (node_mod +ules/router/index.js:340:13) + at node_modules/router/ +index.js:297:9 + at processParams (node_ +modules/router/index.js:582:1 +2) + at next (node_modules/r +outer/index.js:291:5) + at Layer.handleError (n +ode_modules/router/lib/layer. +js:111:12) + at trimPrefix (node_mod +ules/router/index.js:340:13) + at node_modules/router/ +index.js:297:9 + at processParams (node_ +modules/router/index.js:582:1 +2) + at next (node_modules/r +outer/index.js:291:5) + at Layer.handleError (n +ode_modules/router/lib/layer. +js:111:12) + at trimPrefix (node_mod +ules/router/index.js:340:13) + at node_modules/router/ +index.js:297:9 + at processParams (node_ +modules/router/index.js:582:1 +2) + at next (node_modules/r +outer/index.js:291:5) + at Layer.handleError (n +ode_modules/router/lib/layer. +js:111:12) + at trimPrefix (node_mod +ules/router/index.js:340:13) + at node_modules/router/ +index.js:297:9 + at processParams (node_ +modules/router/index.js:582:1 +2) + at next (node_modules/r +outer/index.js:291:5) + at Layer.handleError (n +ode_modules/router/lib/layer. +js:111:12) + at trimPrefix (node_mod +ules/router/index.js:340:13) + at node_modules/router/ +index.js:297:9 + at processParams (node_ +modules/router/index.js:582:1 +2) + at next (node_modules/r +outer/index.js:291:5) + at Layer.handleError (n +ode_modules/router/lib/layer. +js:111:12) + at trimPrefix (node_mod +ules/router/index.js:340:13) + at node_modules/router/ +index.js:297:9 + at processParams (node_ +modules/router/index.js:582:1 +2) + at next (node_modules/r +outer/index.js:291:5) + at Layer.handleRequest +(node_modules/router/lib/laye +r.js:165:5) + at trimPrefix (node_mod +ules/router/index.js:342:13) + at node_modules/router/ +index.js:297:9 + at processParams (node_ +modules/router/index.js:582:1 +2) + at next (node_modules/r +outer/index.js:291:5) + at Function.handle (nod +e_modules/router/index.js:186 +:3) + at Function.handle (nod +e_modules/express/lib/applica +tion.js:177:15) + at handle +(src/app.test.js:36:9) + at invokeApp +(src/app.test.js:25:10) + at Object.invokeApp +(src/app.test.js:53:28) + + console.error + Unhandled Error: +TypeError: Cannot convert +undefined or null to object + at +ServerResponse.removeHeader +(node:_http_outgoing:870:30) + at +xPoweredByMiddleware (C:\User +s\pc\Documents\waves\Liquifac +t-backend\node_modules\helmet +\index.cjs:303:7) + at internalNext (C: +\Users\pc\Documents\waves\Liq +uifact-backend\node_modules\h +elmet\index.cjs:529:6) + at xPermittedCrossD +omainPoliciesMiddleware (C:\U +sers\pc\Documents\waves\Liqui +fact-backend\node_modules\hel +met\index.cjs:297:3) + at internalNext (C: +\Users\pc\Documents\waves\Liq +uifact-backend\node_modules\h +elmet\index.cjs:529:6) + at +xFrameOptionsMiddleware (C:\U +sers\pc\Documents\waves\Liqui +fact-backend\node_modules\hel +met\index.cjs:281:3) + at internalNext (C: +\Users\pc\Documents\waves\Liq +uifact-backend\node_modules\h +elmet\index.cjs:529:6) + at +xDownloadOptionsMiddleware (C +:\Users\pc\Documents\waves\Li +quifact-backend\node_modules\ +helmet\index.cjs:261:3) + at internalNext (C: +\Users\pc\Documents\waves\Liq +uifact-backend\node_modules\h +elmet\index.cjs:529:6) + at xDnsPrefetchCont +rolMiddleware (C:\Users\pc\Do +cuments\waves\Liquifact-backe +nd\node_modules\helmet\index. +cjs:254:3) + at internalNext (C: +\Users\pc\Documents\waves\Liq +uifact-backend\node_modules\h +elmet\index.cjs:529:6) + at xContentTypeOpti +onsMiddleware (C:\Users\pc\Do +cuments\waves\Liquifact-backe +nd\node_modules\helmet\index. +cjs:246:3) + at internalNext (C: +\Users\pc\Documents\waves\Liq +uifact-backend\node_modules\h +elmet\index.cjs:529:6) + at strictTransportS +ecurityMiddleware (C:\Users\p +c\Documents\waves\Liquifact-b +ackend\node_modules\helmet\in +dex.cjs:239:3) + at internalNext (C: +\Users\pc\Documents\waves\Liq +uifact-backend\node_modules\h +elmet\index.cjs:529:6) + at +referrerPolicyMiddleware (C:\ +Users\pc\Documents\waves\Liqu +ifact-backend\node_modules\he +lmet\index.cjs:207:3) + at internalNext (C: +\Users\pc\Documents\waves\Liq +uifact-backend\node_modules\h +elmet\index.cjs:529:6) + at +originAgentClusterMiddleware +(C:\Users\pc\Documents\waves\ +Liquifact-backend\node_module +s\helmet\index.cjs:182:3) + at internalNext (C: +\Users\pc\Documents\waves\Liq +uifact-backend\node_modules\h +elmet\index.cjs:529:6) + at crossOriginResou +rcePolicyMiddleware (C:\Users +\pc\Documents\waves\Liquifact +-backend\node_modules\helmet\ +index.cjs:175:3) + at internalNext (C: +\Users\pc\Documents\waves\Liq +uifact-backend\node_modules\h +elmet\index.cjs:529:6) + at crossOriginOpene +rPolicyMiddleware (C:\Users\p +c\Documents\waves\Liquifact-b +ackend\node_modules\helmet\in +dex.cjs:159:3) + at internalNext (C: +\Users\pc\Documents\waves\Liq +uifact-backend\node_modules\h +elmet\index.cjs:529:6) + at crossOriginEmbed +derPolicyMiddleware (C:\Users +\pc\Documents\waves\Liquifact +-backend\node_modules\helmet\ +index.cjs:143:3) + at internalNext (C: +\Users\pc\Documents\waves\Liq +uifact-backend\node_modules\h +elmet\index.cjs:529:6) + at contentSecurityP +olicyMiddleware (C:\Users\pc\ +Documents\waves\Liquifact-bac +kend\node_modules\helmet\inde +x.cjs:124:4) + at internalNext (C: +\Users\pc\Documents\waves\Liq +uifact-backend\node_modules\h +elmet\index.cjs:529:6) + at +helmetMiddleware (C:\Users\pc +\Documents\waves\Liquifact-ba +ckend\node_modules\helmet\ind +ex.cjs:533:6) + at +Layer.handleRequest (C:\Users +\pc\Documents\waves\Liquifact +-backend\node_modules\router\ +lib\layer.js:152:17) + at trimPrefix (C:\U +sers\pc\Documents\waves\Liqui +fact-backend\node_modules\rou +ter\index.js:342:13) + at C:\Users\pc\Docu +ments\waves\Liquifact-backend +\node_modules\router\index.js +:297:9 + at processParams (C +:\Users\pc\Documents\waves\Li +quifact-backend\node_modules\ +router\index.js:582:12) + at next (C:\Users\p +c\Documents\waves\Liquifact-b +ackend\node_modules\router\in +dex.js:291:5) + at Function.handle +(C:\Users\pc\Documents\waves\ +Liquifact-backend\node_module +s\router\index.js:186:3) + at Function.handle +(C:\Users\pc\Documents\waves\ +Liquifact-backend\node_module +s\express\lib\application.js: +177:15) + at handle (C:\Users +\pc\Documents\waves\Liquifact +-backend\src\app.test.js:36:9 +) + at new Promise +() + at invokeApp (C:\Us +ers\pc\Documents\waves\Liquif +act-backend\src\app.test.js:2 +5:10) + at +Object.invokeApp (C:\Users\pc +\Documents\waves\Liquifact-ba +ckend\src\app.test.js:58:28) + at +Promise.finally.completed (C: +\Users\pc\Documents\waves\Liq +uifact-backend\node_modules\j +est-circus\build\jestAdapterI +nit.js:1557:28) + at new Promise +() + at +callAsyncCircusFn (C:\Users\p +c\Documents\waves\Liquifact-b +ackend\node_modules\jest-circ +us\build\jestAdapterInit.js:1 +497:10) + at _callCircusTest +(C:\Users\pc\Documents\waves\ +Liquifact-backend\node_module +s\jest-circus\build\jestAdapt +erInit.js:1007:40) + at +processTicksAndRejections (no +de:internal/process/task_queu +es:105:5) + at _runTest (C:\Use +rs\pc\Documents\waves\Liquifa +ct-backend\node_modules\jest- +circus\build\jestAdapterInit. +js:947:3) + at C:\Users\pc\Docu +ments\waves\Liquifact-backend +\node_modules\jest-circus\bui +ld\jestAdapterInit.js:849:7 + at +_runTestsForDescribeBlock (C: +\Users\pc\Documents\waves\Liq +uifact-backend\node_modules\j +est-circus\build\jestAdapterI +nit.js:862:11) + at +_runTestsForDescribeBlock (C: +\Users\pc\Documents\waves\Liq +uifact-backend\node_modules\j +est-circus\build\jestAdapterI +nit.js:857:11) + at run (C:\Users\pc +\Documents\waves\Liquifact-ba +ckend\node_modules\jest-circu +s\build\jestAdapterInit.js:76 +1:3) + at runAndTransformR +esultsToJestFormat (C:\Users\ +pc\Documents\waves\Liquifact- +backend\node_modules\jest-cir +cus\build\jestAdapterInit.js: +1918:21) + at jestAdapter (C:\ +Users\pc\Documents\waves\Liqu +ifact-backend\node_modules\je +st-circus\build\runner.js:101 +:19) + at runTestInternal +(C:\Users\pc\Documents\waves\ +Liquifact-backend\node_module +s\jest-runner\build\testWorke +r.js:275:16) + at runTest (C:\User +s\pc\Documents\waves\Liquifac +t-backend\node_modules\jest-r +unner\build\testWorker.js:343 +:7) + at Object.worker (C +:\Users\pc\Documents\waves\Li +quifact-backend\node_modules\ +jest-runner\build\testWorker. +js:497:12) + +   31 | +// Log unexpected +errors +  32 | +if (status +=== 500) +{ + +> 33 +| console.[3 +9merror('Unhandled +Error:', +err); +  | + ^ +  34 | } +  35 | +  36 | +problem = +formatProblemDetails({ + + at error (src/middlewar +e/errorHandler.js:33:15) + at Layer.handleError (n +ode_modules/router/lib/layer. +js:116:17) + at trimPrefix (node_mod +ules/router/index.js:340:13) + at node_modules/router/ +index.js:297:9 + at processParams (node_ +modules/router/index.js:582:1 +2) + at next (node_modules/r +outer/index.js:291:5) + at next (src/middleware +/bodySizeLimits.js:177:3) + at Layer.handleError (n +ode_modules/router/lib/layer. +js:116:17) + at trimPrefix (node_mod +ules/router/index.js:340:13) + at node_modules/router/ +index.js:297:9 + at processParams (node_ +modules/router/index.js:582:1 +2) + at next (node_modules/r +outer/index.js:291:5) + at next +(src/app.js:156:5) + at Layer.handleError (n +ode_modules/router/lib/layer. +js:116:17) + at trimPrefix (node_mod +ules/router/index.js:340:13) + at node_modules/router/ +index.js:297:9 + at processParams (node_ +modules/router/index.js:582:1 +2) + at next (node_modules/r +outer/index.js:291:5) + at Layer.handleError (n +ode_modules/router/lib/layer. +js:111:12) + at trimPrefix (node_mod +ules/router/index.js:340:13) + at node_modules/router/ +index.js:297:9 + at processParams (node_ +modules/router/index.js:582:1 +2) + at next (node_modules/r +outer/index.js:291:5) + at Layer.handleError (n +ode_modules/router/lib/layer. +js:111:12) + at trimPrefix (node_mod +ules/router/index.js:340:13) + at node_modules/router/ +index.js:297:9 + at processParams (node_ +modules/router/index.js:582:1 +2) + at next (node_modules/r +outer/index.js:291:5) + at Layer.handleError (n +ode_modules/router/lib/layer. +js:111:12) + at trimPrefix (node_mod +ules/router/index.js:340:13) + at node_modules/router/ +index.js:297:9 + at processParams (node_ +modules/router/index.js:582:1 +2) + at next (node_modules/r +outer/index.js:291:5) + at Layer.handleError (n +ode_modules/router/lib/layer. +js:111:12) + at trimPrefix (node_mod +ules/router/index.js:340:13) + at node_modules/router/ +index.js:297:9 + at processParams (node_ +modules/router/index.js:582:1 +2) + at next (node_modules/r +outer/index.js:291:5) + at Layer.handleError (n +ode_modules/router/lib/layer. +js:111:12) + at trimPrefix (node_mod +ules/router/index.js:340:13) + at node_modules/router/ +index.js:297:9 + at processParams (node_ +modules/router/index.js:582:1 +2) + at next (node_modules/r +outer/index.js:291:5) + at Layer.handleError (n +ode_modules/router/lib/layer. +js:111:12) + at trimPrefix (node_mod +ules/router/index.js:340:13) + at node_modules/router/ +index.js:297:9 + at processParams (node_ +modules/router/index.js:582:1 +2) + at next (node_modules/r +outer/index.js:291:5) + at Layer.handleError (n +ode_modules/router/lib/layer. +js:111:12) + at trimPrefix (node_mod +ules/router/index.js:340:13) + at node_modules/router/ +index.js:297:9 + at processParams (node_ +modules/router/index.js:582:1 +2) + at next (node_modules/r +outer/index.js:291:5) + at Layer.handleRequest +(node_modules/router/lib/laye +r.js:165:5) + at trimPrefix (node_mod +ules/router/index.js:342:13) + at node_modules/router/ +index.js:297:9 + at processParams (node_ +modules/router/index.js:582:1 +2) + at next (node_modules/r +outer/index.js:291:5) + at Function.handle (nod +e_modules/router/index.js:186 +:3) + at Function.handle (nod +e_modules/express/lib/applica +tion.js:177:15) + at handle +(src/app.test.js:36:9) + at invokeApp +(src/app.test.js:25:10) + at Object.invokeApp +(src/app.test.js:58:28) + + ΓùÅ LiquiFact app +integration plus ΓÇ║ +standard success response +structure + + expect(received).toBe(exp +ected) // Object.is equality + + Expected: 200 + Received: 500 + +   41 | +it('standard success +response +structure', +async () +=> { +  42 | +const response += await i +nvokeApp(createApp(),[3 +9m { path: +'/health' +}); + +> 43 +| expect(response[3 +3m.statusCode).[39 +mtoBe(200);[3 +9m +  | + +^ +  44 | expe +ct(response.body[3 +3m.data.status +).toBe('ok'[3 +9m); +  45 | +}); +  46 | + + at Object.toBe +(src/app.test.js:43:33) + + ΓùÅ LiquiFact app +integration plus ΓÇ║ allows +undefined origin +(non-browser) + + expect(received).toBe(exp +ected) // Object.is equality + + Expected: 200 + Received: 500 + +   47 | +it('allows undefined +origin (non-browser)'[3 +3m, async () +=> { +  48 | +const response += await i +nvokeApp(createApp(),[3 +9m { path: '/h +ealth', +origin: undefined +}); + +> 49 +| expect(response[3 +3m.statusCode).[39 +mtoBe(200);[3 +9m +  | + +^ +  50 | +}); +  51 | +  52 | +it('rejects blocked +origins', +async () +=> { + + at Object.toBe +(src/app.test.js:49:33) + + ΓùÅ LiquiFact app +integration plus ΓÇ║ rejects +blocked origins + + expect(received).toBe(exp +ected) // Object.is equality + + Expected: 403 + Received: 500 + +   52 | +it('rejects blocked +origins', +async () +=> { +  53 | +const response += await i +nvokeApp(createApp(),[3 +9m { origin: ' +https://evil.com', +[39m path: +'/health' +}); + +> 54 +| expect(response[3 +3m.statusCode).[39 +mtoBe(403);[3 +9m +  | + +^ +  55 | +}); +  56 | +  57 | +it('trigger 500 error +path', +async () +=> { + + at Object.toBe +(src/app.test.js:54:33) + +FAIL src/__tests__/bodySizeLi +mits.test.js + ΓùÅ Console + + console.log + [dotenv@17.3.1] +injecting env (0) from .env +-- tip: ΓÜÖ∩╕Å suppress all +logs with { quiet: true } + + at _log (node_modules/d +otenv/lib/main.js:139:11) + + console.log + [dotenv@17.3.1] +injecting env (0) from .env +-- tip: ΓÜÖ∩╕Å enable debug +logging with { debug: true } + + at _log (node_modules/d +otenv/lib/main.js:139:11) + + console.log + [dotenv@17.3.1] +injecting env (0) from .env +-- tip: ΓÜí∩╕Å secrets for +agents: +https://dotenvx.com/as2 + + at _log (node_modules/d +otenv/lib/main.js:139:11) + + ΓùÅ createApp() +integration ΓÇ║ GET /health +ΓåÆ 200 with status ok + + expect(received).toBe(exp +ected) // Object.is equality + + Expected: "ok" + Received: undefined + +   198 | + const res += await r +equest(app).ge +t('/health')[ +33m; +  199 | exp +ect(res.status)[33 +m.toBe(200)[3 +3m; + +> +200 | expect(res[33 +m.body.status) +.toBe('ok'[39 +m); +  | + +^ +  201 | +}); +  202 | +  203 | +it('POST /api/invoices +oversized body ΓåÆ +413', +async () +=> { + + at Object.toBe (src/__t +ests__/bodySizeLimits.test.js +:200:29) + +PASS src/__tests__/rateLimit. +test.js + ΓùÅ Console + + console.log + [dotenv@17.3.1] +injecting env (0) from .env +-- tip: ≡ƒöÉ prevent +building .env in docker: +https://dotenvx.com/prebuild + + at _log (node_modules/d +otenv/lib/main.js:139:11) + + console.log + [dotenv@17.3.1] +injecting env (0) from .env +-- tip: ΓÜÖ∩╕Å enable debug +logging with { debug: true } + + at _log (node_modules/d +otenv/lib/main.js:139:11) + + console.log + [dotenv@17.3.1] +injecting env (0) from .env +-- tip: ≡ƒ¢á∩╕Å run +anywhere with `dotenvx run +-- yourcommand` + + at _log (node_modules/d +otenv/lib/main.js:139:11) + +PASS tests/unit/asyncHandler. +test.js + ΓùÅ Console + + console.error + Unhandled Error: +Error: Test error + at C:\Users\pc\Docu +ments\waves\Liquifact-backend +\tests\unit\asyncHandler.test +.js:27:17 + at fn (C:\Users\pc\ +Documents\waves\Liquifact-bac +kend\src\utils\asyncHandler.j +s:10:21) + at +Layer.handleRequest (C:\Users +\pc\Documents\waves\Liquifact +-backend\node_modules\router\ +lib\layer.js:152:17) + at next (C:\Users\p +c\Documents\waves\Liquifact-b +ackend\node_modules\router\li +b\route.js:157:13) + at Route.dispatch ( +C:\Users\pc\Documents\waves\L +iquifact-backend\node_modules +\router\lib\route.js:117:3) + at handle (C:\Users +\pc\Documents\waves\Liquifact +-backend\node_modules\router\ +index.js:435:11) + at +Layer.handleRequest (C:\Users +\pc\Documents\waves\Liquifact +-backend\node_modules\router\ +lib\layer.js:152:17) + at C:\Users\pc\Docu +ments\waves\Liquifact-backend +\node_modules\router\index.js +:295:15 + at processParams (C +:\Users\pc\Documents\waves\Li +quifact-backend\node_modules\ +router\index.js:582:12) + at next (C:\Users\p +c\Documents\waves\Liquifact-b +ackend\node_modules\router\in +dex.js:291:5) + at read (C:\Users\p +c\Documents\waves\Liquifact-b +ackend\node_modules\body-pars +er\lib\read.js:53:5) + at jsonParser (C:\U +sers\pc\Documents\waves\Liqui +fact-backend\node_modules\bod +y-parser\lib\types\json.js:88 +:5) + at +Layer.handleRequest (C:\Users +\pc\Documents\waves\Liquifact +-backend\node_modules\router\ +lib\layer.js:152:17) + at trimPrefix (C:\U +sers\pc\Documents\waves\Liqui +fact-backend\node_modules\rou +ter\index.js:342:13) + at C:\Users\pc\Docu +ments\waves\Liquifact-backend +\node_modules\router\index.js +:297:9 + at processParams (C +:\Users\pc\Documents\waves\Li +quifact-backend\node_modules\ +router\index.js:582:12) + at next (C:\Users\p +c\Documents\waves\Liquifact-b +ackend\node_modules\router\in +dex.js:291:5) + at Function.handle +(C:\Users\pc\Documents\waves\ +Liquifact-backend\node_module +s\router\index.js:186:3) + at Function.handle +(C:\Users\pc\Documents\waves\ +Liquifact-backend\node_module +s\express\lib\application.js: +177:15) + at Server.app (C:\U +sers\pc\Documents\waves\Liqui +fact-backend\node_modules\exp +ress\lib\express.js:38:9) + at Server.emit +(node:events:519:28) + at +parserOnIncoming +(node:_http_server:1186:12) + at HTTPParser.parse +rOnHeadersComplete +(node:_http_common:122:17) + +   31 | +// Log unexpected +errors +  32 | +if (status +=== 500) +{ + +> 33 +| console.[3 +9merror('Unhandled +Error:', +err); +  | + ^ +  34 | } +  35 | +  36 | +problem = +formatProblemDetails({ + + at error (src/middlewar +e/errorHandler.js:33:15) + at Layer.handleError (n +ode_modules/router/lib/layer. +js:116:17) + at trimPrefix (node_mod +ules/router/index.js:340:13) + at node_modules/router/ +index.js:297:9 + at processParams (node_ +modules/router/index.js:582:1 +2) + at next (node_modules/r +outer/index.js:291:5) + at next (node_modules/r +outer/lib/route.js:132:14) + + console.error + Unhandled Error: +Error: Rejected + at C:\Users\pc\Docu +ments\waves\Liquifact-backend +\tests\unit\asyncHandler.test +.js:43:49 + at fn (C:\Users\pc\ +Documents\waves\Liquifact-bac +kend\src\utils\asyncHandler.j +s:10:21) + at +Layer.handleRequest (C:\Users +\pc\Documents\waves\Liquifact +-backend\node_modules\router\ +lib\layer.js:152:17) + at next (C:\Users\p +c\Documents\waves\Liquifact-b +ackend\node_modules\router\li +b\route.js:157:13) + at Route.dispatch ( +C:\Users\pc\Documents\waves\L +iquifact-backend\node_modules +\router\lib\route.js:117:3) + at handle (C:\Users +\pc\Documents\waves\Liquifact +-backend\node_modules\router\ +index.js:435:11) + at +Layer.handleRequest (C:\Users +\pc\Documents\waves\Liquifact +-backend\node_modules\router\ +lib\layer.js:152:17) + at C:\Users\pc\Docu +ments\waves\Liquifact-backend +\node_modules\router\index.js +:295:15 + at processParams (C +:\Users\pc\Documents\waves\Li +quifact-backend\node_modules\ +router\index.js:582:12) + at next (C:\Users\p +c\Documents\waves\Liquifact-b +ackend\node_modules\router\in +dex.js:291:5) + at read (C:\Users\p +c\Documents\waves\Liquifact-b +ackend\node_modules\body-pars +er\lib\read.js:53:5) + at jsonParser (C:\U +sers\pc\Documents\waves\Liqui +fact-backend\node_modules\bod +y-parser\lib\types\json.js:88 +:5) + at +Layer.handleRequest (C:\Users +\pc\Documents\waves\Liquifact +-backend\node_modules\router\ +lib\layer.js:152:17) + at trimPrefix (C:\U +sers\pc\Documents\waves\Liqui +fact-backend\node_modules\rou +ter\index.js:342:13) + at C:\Users\pc\Docu +ments\waves\Liquifact-backend +\node_modules\router\index.js +:297:9 + at processParams (C +:\Users\pc\Documents\waves\Li +quifact-backend\node_modules\ +router\index.js:582:12) + at next (C:\Users\p +c\Documents\waves\Liquifact-b +ackend\node_modules\router\in +dex.js:291:5) + at Function.handle +(C:\Users\pc\Documents\waves\ +Liquifact-backend\node_module +s\router\index.js:186:3) + at Function.handle +(C:\Users\pc\Documents\waves\ +Liquifact-backend\node_module +s\express\lib\application.js: +177:15) + at Server.app (C:\U +sers\pc\Documents\waves\Liqui +fact-backend\node_modules\exp +ress\lib\express.js:38:9) + at Server.emit +(node:events:519:28) + at +parserOnIncoming +(node:_http_server:1186:12) + at HTTPParser.parse +rOnHeadersComplete +(node:_http_common:122:17) + +   31 | +// Log unexpected +errors +  32 | +if (status +=== 500) +{ + +> 33 +| console.[3 +9merror('Unhandled +Error:', +err); +  | + ^ +  34 | } +  35 | +  36 | +problem = +formatProblemDetails({ + + at error (src/middlewar +e/errorHandler.js:33:15) + at Layer.handleError (n +ode_modules/router/lib/layer. +js:116:17) + at trimPrefix (node_mod +ules/router/index.js:340:13) + at node_modules/router/ +index.js:297:9 + at processParams (node_ +modules/router/index.js:582:1 +2) + at next (node_modules/r +outer/index.js:291:5) + at next (node_modules/r +outer/lib/route.js:132:14) + +PASS src/__tests__/deprecatio +n.test.js +PASS +src/__tests__/auth.test.js + ΓùÅ Console + + console.log + [dotenv@17.3.1] +injecting env (0) from .env +-- tip: ≡ƒ¢á∩╕Å run +anywhere with `dotenvx run +-- yourcommand` + + at _log (node_modules/d +otenv/lib/main.js:139:11) + + console.log + [dotenv@17.3.1] +injecting env (0) from .env +-- tip: ≡ƒ¢á∩╕Å run +anywhere with `dotenvx run +-- yourcommand` + + at _log (node_modules/d +otenv/lib/main.js:139:11) + + console.log + [dotenv@17.3.1] +injecting env (0) from .env +-- tip: ΓÜí∩╕Å secrets for +agents: +https://dotenvx.com/as2 + + at _log (node_modules/d +otenv/lib/main.js:139:11) + +PASS +src/services/soroban.test.js +PASS tests/unit/invoice.servi +ce.test.js + ΓùÅ Console + + console.error + Error fetching +invoices: Error: DB Error + at +Function. (C:\User +s\pc\Documents\waves\Liquifac +t-backend\tests\unit\invoice. +service.test.js:36:66) + at C:\Users\pc\Docu +ments\waves\Liquifact-backend +\node_modules\jest-mock\build +\index.js:305:39 + at +Function. (C:\User +s\pc\Documents\waves\Liquifac +t-backend\node_modules\jest-m +ock\build\index.js:312:13) + at +Function.mockConstructor [as +then] (C:\Users\pc\Documents\ +waves\Liquifact-backend\node_ +modules\jest-mock\build\index +.js:57:19) + at +processTicksAndRejections (no +de:internal/process/task_queu +es:105:5) + +   42 | +return +await +query; +  43 | } +catch (error) { + +> 44 +| console. +error('Error fetching +invoices:', +error); +  | + ^ +  45 | +throw +new Error +('Database error while +fetching +invoices'); +  46 | } +  47 | } + + at error (src/services/ +invoice.service.js:44:13) + at Object. ( +tests/unit/invoice.service.te +st.js:38:5) + +PASS tests/unit/queryBuilder. +test.js +PASS src/__tests__/validate.t +est.js +PASS tests/unit/problemDetail +s.test.js +PASS src/config/cors.test.js +PASS +tests/unit/validators.test.js +PASS +tests/unit/AppError.test.js +PASS tests/app.test.js + ΓùÅ Console + + console.error + Unhandled Error: +Error: Boom + at C:\Users\pc\Docu +ments\waves\Liquifact-backend +\tests\app.test.js:20:11 + at fn (C:\Users\pc\ +Documents\waves\Liquifact-bac +kend\src\utils\asyncHandler.j +s:10:21) + at +Layer.handleRequest (C:\Users +\pc\Documents\waves\Liquifact +-backend\node_modules\router\ +lib\layer.js:152:17) + at next (C:\Users\p +c\Documents\waves\Liquifact-b +ackend\node_modules\router\li +b\route.js:157:13) + at Route.dispatch ( +C:\Users\pc\Documents\waves\L +iquifact-backend\node_modules +\router\lib\route.js:117:3) + at handle (C:\Users +\pc\Documents\waves\Liquifact +-backend\node_modules\router\ +index.js:435:11) + at +Layer.handleRequest (C:\Users +\pc\Documents\waves\Liquifact +-backend\node_modules\router\ +lib\layer.js:152:17) + at C:\Users\pc\Docu +ments\waves\Liquifact-backend +\node_modules\router\index.js +:295:15 + at processParams (C +:\Users\pc\Documents\waves\Li +quifact-backend\node_modules\ +router\index.js:582:12) + at next (C:\Users\p +c\Documents\waves\Liquifact-b +ackend\node_modules\router\in +dex.js:291:5) + at read (C:\Users\p +c\Documents\waves\Liquifact-b +ackend\node_modules\body-pars +er\lib\read.js:53:5) + at jsonParser (C:\U +sers\pc\Documents\waves\Liqui +fact-backend\node_modules\bod +y-parser\lib\types\json.js:88 +:5) + at +Layer.handleRequest (C:\Users +\pc\Documents\waves\Liquifact +-backend\node_modules\router\ +lib\layer.js:152:17) + at trimPrefix (C:\U +sers\pc\Documents\waves\Liqui +fact-backend\node_modules\rou +ter\index.js:342:13) + at C:\Users\pc\Docu +ments\waves\Liquifact-backend +\node_modules\router\index.js +:297:9 + at processParams (C +:\Users\pc\Documents\waves\Li +quifact-backend\node_modules\ +router\index.js:582:12) + at next (C:\Users\p +c\Documents\waves\Liquifact-b +ackend\node_modules\router\in +dex.js:291:5) + at Function.handle +(C:\Users\pc\Documents\waves\ +Liquifact-backend\node_module +s\router\index.js:186:3) + at Function.handle +(C:\Users\pc\Documents\waves\ +Liquifact-backend\node_module +s\express\lib\application.js: +177:15) + at Server.app (C:\U +sers\pc\Documents\waves\Liqui +fact-backend\node_modules\exp +ress\lib\express.js:38:9) + at Server.emit +(node:events:519:28) + at +parserOnIncoming +(node:_http_server:1186:12) + at HTTPParser.parse +rOnHeadersComplete +(node:_http_common:122:17) + +   31 | +// Log unexpected +errors +  32 | +if (status +=== 500) +{ + +> 33 +| console.[3 +9merror('Unhandled +Error:', +err); +  | + ^ +  34 | } +  35 | +  36 | +problem = +formatProblemDetails({ + + at error (src/middlewar +e/errorHandler.js:33:15) + at Layer.handleError (n +ode_modules/router/lib/layer. +js:116:17) + at trimPrefix (node_mod +ules/router/index.js:340:13) + at node_modules/router/ +index.js:297:9 + at processParams (node_ +modules/router/index.js:582:1 +2) + at next (node_modules/r +outer/index.js:291:5) + at next (node_modules/r +outer/lib/route.js:132:14) + +PASS src/utils/retry.test.js +---------------------|---------|----------|---------|---------|------------------- +File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s +---------------------|---------|----------|---------|---------|------------------- +All files | 95.03 | 88.18 | 93.84 | 96.12 | + src | 92.85 | 68.75 | 87.5 | 94.87 | + app.js | 96 | 66.66 | 100 | 98.55 | 117 + index.js | 66.66 | 75 | 0 | 66.66 | 16-19 + src/config | 92.59 | 88.88 | 88.88 | 91.66 | + cors.js | 92.59 | 88.88 | 88.88 | 91.66 | 75,92 + src/errors | 100 | 100 | 100 | 100 | + AppError.js | 100 | 100 | 100 | 100 | + src/middleware | 95.32 | 87.09 | 95.23 | 95.32 | + auth.js | 100 | 100 | 100 | 100 | + bodySizeLimits.js | 90.32 | 94.44 | 87.5 | 90.32 | 76,114,147 + deprecation.js | 100 | 42.85 | 100 | 100 | 9-22 + errorHandler.js | 100 | 92.59 | 100 | 100 | 38,42 + rateLimit.js | 100 | 75 | 100 | 100 | 27 + security.js | 100 | 100 | 100 | 100 | + validate.js | 91.66 | 57.14 | 100 | 91.66 | 24,54 + src/schemas | 100 | 100 | 100 | 100 | + apiSchemas.js | 100 | 100 | 100 | 100 | + src/services | 91.83 | 84.37 | 100 | 97.43 | + invoice.service.js | 100 | 100 | 100 | 100 | + soroban.js | 89.74 | 84.37 | 100 | 96.55 | 117 + src/utils | 97.95 | 93.4 | 100 | 97.89 | + asyncHandler.js | 100 | 100 | 100 | 100 | + problemDetails.js | 100 | 100 | 100 | 100 | + queryBuilder.js | 100 | 87.87 | 100 | 100 | 22,24 + responseHelper.js | 100 | 100 | 100 | 100 | + retry.js | 100 | 100 | 100 | 100 | + validators.js | 94.59 | 94.44 | 100 | 94.59 | 45,72 +---------------------|---------|----------|---------|---------|------------------- +Jest: "global" coverage +threshold for functions +(95%) not met: 93.84% + +Summary of all failing tests +FAIL tests/unit/errorHandler. +test.js + ΓùÅ errorHandler +Middleware Unit Tests ΓÇ║ +should handle AppError and +send RFC 7807 response + + expect(jest.fn()).toHaveB +eenCalledWith(...expected) + + Expected: +ObjectContaining {"detail": +"Invalid data", "error": +"Bad Request", "instance": +"/api/v1/test", "status": +400, "title": "Bad Request", +"type": "https://liquifact.co +m/probs/bad-request"} + Received: {"data": null, +"detail": "Invalid data", +"error": {"code": +"INTERNAL_ERROR", "details": +null, "message": "Bad +Request"}, "instance": +"/api/v1/test", "meta": +{"timestamp": +"2026-03-28T17:17:00.798Z", +"version": "0.1.0"}, +"stack": "AppError: Bad +Request + +   26 | +  27 | +test('should handle +AppError and send RFC 7807 +response', () +=> { + +> 28 +| const +error = +new +AppError({ +  | + +^ +  29 | +type: 'https:/ +/liquifact.com/probs/bad-requ +est', +  30 | +title: 'Bad +Request', +  31 | +status: +400, + + at Object. ( +tests/unit/errorHandler.test. +js:28:19) + Number of calls: 1 + at +Object.toHaveBeenCalledWith ( +tests/unit/errorHandler.test. +js:39:31) + + ΓùÅ errorHandler +Middleware Unit Tests ΓÇ║ +should handle generic Error +and fallback to 500 + + expect(jest.fn()).toHaveB +eenCalledWith(...expected) + + Expected: +ObjectContaining {"detail": +"An unexpected error +occurred while processing +your request.", "error": +"Internal Server Error", +"status": 500, "title": +"Internal Server Error"} + Received: {"data": null, +"detail": "Something +exploded", "error": {"code": +"INTERNAL_ERROR", "details": +"Something exploded", +"message": "Internal Server +Error"}, "instance": +"/api/v1/test", "meta": +{"timestamp": +"2026-03-28T17:17:00.815Z", +"version": "0.1.0"}, +"stack": "Error: Something +exploded + +   50 | +  51 | +test('should handle +generic Error and fallback +to 500', () +=> { + +> 52 +| const +error = +new Error +('Something +exploded'); +  | + +^ +  53 | +  54 | erro +rHandler(error, +mockRequest, +mockResponse, +nextFunction); +  55 | + + at Object. ( +tests/unit/errorHandler.test. +js:52:19) + Number of calls: 1 + at +Object.toHaveBeenCalledWith ( +tests/unit/errorHandler.test. +js:57:31) + +FAIL src/__tests__/invoice.ap +i.test.js + ΓùÅ Invoice API +Integration ΓÇ║ GET +/api/invoices ΓÇ║ should +return 200 and invoices when +no query params are provided + + expect(received).toBe(exp +ected) // Object.is equality + + Expected: 200 + Received: 500 + +   21 | + const res += await r +equest(app).ge +t('/api/invoices'[ +39m); +  22 | + +> 23 +| expect(res. +statusCode).to +Be(200); +  | + +^ +  24 | ex +pect(res.body. +data).toEqual( +mockInvoices); +  25 | ex +pect(res.body. +message).toBe( +'Invoices retrieved succ +essfully.'); +  26 | ex +pect(invoiceService.[39 +mgetInvoices).toHav +eBeenCalledWith({ + + at Object.toBe (src/__t +ests__/invoice.api.test.js:23 +:30) + + ΓùÅ Invoice API +Integration ΓÇ║ GET +/api/invoices ΓÇ║ should +handle service errors with +500 + + expect(received).toBe(exp +ected) // Object.is equality + + Expected: "Internal +server error" + Received: {"code": +"INTERNAL_ERROR", "message": +"Internal server error"} + +   106 | +  107 | e +xpect(res.statusCod +e).toBe(500[3 +9m); + +> +108 | expect(res[ +33m.body.error +).toBe('Intern +al server +error'); +  | + +^ +  109 | +}); +  110 | +}); +  111 | +}); + + at Object.toBe (src/__t +ests__/invoice.api.test.js:10 +8:30) + +FAIL tests/integration/errorH +andling.test.js + ΓùÅ API Integration Tests +(RFC 7807) ΓÇ║ GET /health +should return status ok + + expect(received).toBe(exp +ected) // Object.is equality + + Expected: "ok" + Received: undefined + +   36 | +const response += await r +equest(app).ge +t('/health')[ +33m; +  37 | expe +ct(response.status) +.toBe(200 +); + +> 38 +| expect(response[3 +3m.body.status +).toBe('ok'[3 +9m); +  | + +^ +  39 | +}); +  40 | +  41 | +test('GET /api should +return api +info', +async () +=> { + + at Object.toBe (tests/i +ntegration/errorHandling.test +.js:38:34) + + ΓùÅ API Integration Tests +(RFC 7807) ΓÇ║ GET /api +should return api info + + expect(received).toBe(exp +ected) // Object.is equality + + Expected: "LiquiFact API" + Received: undefined + +   42 | +const response += await r +equest(app).ge +t('/api') +; +  43 | expe +ct(response.status) +.toBe(200 +); + +> 44 +| expect(response[3 +3m.body.name) +[33m.toBe('LiquiFac +t API'); +  | + +^ +  45 | +}); +  46 | +  47 | +test('GET +/api/escrow/:invoiceId +should return 200 with +escrow data (requires +auth)', +async () +=> { + + at Object.toBe (tests/i +ntegration/errorHandling.test +.js:44:32) + +FAIL src/index.test.js + ΓùÅ LiquiFact API ΓÇ║ +Invoices Lifecycle ΓÇ║ POST +/api/invoices - fails if +missing fields + + expect(received).toBe(exp +ected) // Object.is equality + + Expected: 400 + Received: 201 + +   56 | + .set( +'Authorization'[33 +m, `Bearer +${token}`) +  57 | +.send({ +amount: +1000 }); + +> 58 +| expect(response +[33m.status).t +oBe(400); +  | + +^ +  59 | +}); +  60 | +  61 | +it('GET /api/invoices - +lists active +invoices', +async () +=> { + + at Object.toBe +(src/index.test.js:58:31) + +FAIL +src/tests/response.test.js + ΓùÅ Standard Response +Envelope (Issue 19) ΓÇ║ POST +/api/invoices should return +201 and standardized success +envelope + + expect(received).toBe(exp +ected) // Object.is equality + + Expected: 201 + Received: 401 + +   27 | +it('POST /api/invoices +should return 201 and +standardized success +envelope', +async () +=> { +  28 | +const res += await r +equest(app).post([ +32m'/api/invoices') +.send({}); + +> 29 +| expect(res.[ +39mstatus).toBe([3 +5m201); +  | + +^ +  30 | expe +ct(res.body.[ +39mdata.id).[ +39mtoBe('placeholder'[3 +9m); +  31 | expe +ct(res.body.[ +39merror).toBeNull( +); +  32 | +}); + + at Object.toBe (src/tes +ts/response.test.js:29:24) + + ΓùÅ Standard Response +Envelope (Issue 19) ΓÇ║ All +routes should return +standard response format + + expect(received).toBe(exp +ected) // Object.is equality + + Expected: 200 + Received: 401 + +   36 | +for +(const route +of routes) { +  37 | +const res += await r +equest(app).ge +t(route); + +> 38 +| expect(res. +status).toBe( +[35m200); +  | + +^ +  39 | ex +pect(res.body) +.toHaveProperty('da +ta'); +  40 | ex +pect(res.body) +.toHaveProperty('me +ta'); +  41 | ex +pect(res.body) +.toHaveProperty('er +ror'); + + at Object.toBe (src/tes +ts/response.test.js:38:26) + + ΓùÅ Standard Response +Envelope (Issue 19) ΓÇ║ +Internal server errors +should return stack trace in +development + + expect(received).toContai +n(expected) // indexOf + + Expected substring: +"Error: Triggered Error" + Received string: +"Triggered Error" + +   56 | +const res += await r +equest(app).ge +t('/debug/error'[3 +9m); +  57 | expe +ct(res.status) +.toBe(500)[33 +m; + +> 58 +| expect(res.[ +39mbody.error. +details).toCon +tain('Error: Triggered +Error'); +  | + +^ +  59 | +}); +  60 | +  61 | +it('Internal server +errors should return +standard error envelope +(e.g. malformed +JSON)', +async () +=> { + + at Object.toContain (sr +c/tests/response.test.js:58:3 +6) + + ΓùÅ Standard Response +Envelope (Issue 19) ΓÇ║ +Internal server errors +should return standard error +envelope (e.g. malformed +JSON) + + expect(received).toBe(exp +ected) // Object.is equality + + Expected: "BAD_REQUEST" + Received: +"INTERNAL_ERROR" + +   67 | +expect(res.status) +[33m.toBe(400) +; +  68 | expe +ct(res.body.[ +39mdata).toBeNull() +; + +> 69 +| expect(res.[ +39mbody.error. +code).toBe([3 +2m'BAD_REQUEST');[ +39m +  | + +^ +  70 | +}); +  71 | +}); +  72 | + + at Object.toBe (src/tes +ts/response.test.js:69:33) + +FAIL src/app.test.js + ΓùÅ LiquiFact app +integration plus ΓÇ║ +standard success response +structure + + expect(received).toBe(exp +ected) // Object.is equality + + Expected: 200 + Received: 500 + +   41 | +it('standard success +response +structure', +async () +=> { +  42 | +const response += await i +nvokeApp(createApp(),[3 +9m { path: +'/health' +}); + +> 43 +| expect(response[3 +3m.statusCode).[39 +mtoBe(200);[3 +9m +  | + +^ +  44 | expe +ct(response.body[3 +3m.data.status +).toBe('ok'[3 +9m); +  45 | +}); +  46 | + + at Object.toBe +(src/app.test.js:43:33) + + ΓùÅ LiquiFact app +integration plus ΓÇ║ allows +undefined origin +(non-browser) + + expect(received).toBe(exp +ected) // Object.is equality + + Expected: 200 + Received: 500 + +   47 | +it('allows undefined +origin (non-browser)'[3 +3m, async () +=> { +  48 | +const response += await i +nvokeApp(createApp(),[3 +9m { path: '/h +ealth', +origin: undefined +}); + +> 49 +| expect(response[3 +3m.statusCode).[39 +mtoBe(200);[3 +9m +  | + +^ +  50 | +}); +  51 | +  52 | +it('rejects blocked +origins', +async () +=> { + + at Object.toBe +(src/app.test.js:49:33) + + ΓùÅ LiquiFact app +integration plus ΓÇ║ rejects +blocked origins + + expect(received).toBe(exp +ected) // Object.is equality + + Expected: 403 + Received: 500 + +   52 | +it('rejects blocked +origins', +async () +=> { +  53 | +const response += await i +nvokeApp(createApp(),[3 +9m { origin: ' +https://evil.com', +[39m path: +'/health' +}); + +> 54 +| expect(response[3 +3m.statusCode).[39 +mtoBe(403);[3 +9m +  | + +^ +  55 | +}); +  56 | +  57 | +it('trigger 500 error +path', +async () +=> { + + at Object.toBe +(src/app.test.js:54:33) + +FAIL src/__tests__/bodySizeLi +mits.test.js + ΓùÅ createApp() +integration ΓÇ║ GET /health +ΓåÆ 200 with status ok + + expect(received).toBe(exp +ected) // Object.is equality + + Expected: "ok" + Received: undefined + +   198 | + const res += await r +equest(app).ge +t('/health')[ +33m; +  199 | exp +ect(res.status)[33 +m.toBe(200)[3 +3m; + +> +200 | expect(res[33 +m.body.status) +.toBe('ok'[39 +m); +  | + +^ +  201 | +}); +  202 | +  203 | +it('POST /api/invoices +oversized body ΓåÆ +413', +async () +=> { + + at Object.toBe (src/__t +ests__/bodySizeLimits.test.js +:200:29) + + +Test Suites: 7 failed, 14 +passed, 21 total +Tests: 15 failed, 145 +passed, 160 total +Snapshots: 0 total +Time: 6.486 s +Ran all test suites. diff --git a/err.log b/err.log new file mode 100644 index 00000000..b022806c --- /dev/null +++ b/err.log @@ -0,0 +1,844 @@ + ● Soroban Integration Wrapper › isTransientError › should identify transient error messages + + TypeError: isTransientError is not a function + +   4 | describe('isTransientError', () => { +  5 | it('should identify transient error messages', () => { + > 6 | expect(isTransientError(new Error('Network timeout'))).toBe(true); +  | ^ +  7 | expect(isTransientError(new Error('Rate limit exceeded (HTTP 429)'))).toBe(true); +  8 | expect(isTransientError(new Error('Server responded with 503'))).toBe(true); +  9 | }); + + at Object.isTransientError (src/services/soroban.test.js:6:14) + + ● Soroban Integration Wrapper › isTransientError › should return false for non-transient errors + + TypeError: isTransientError is not a function + +   10 | +  11 | it('should return false for non-transient errors', () => { + > 12 | expect(isTransientError(new Error('Invalid arguments'))).toBe(false); +  | ^ +  13 | expect(isTransientError(new Error('Contract execution trapped'))).toBe(false); +  14 | expect(isTransientError(new Error('404 Not Found'))).toBe(false); +  15 | }); + + at Object.isTransientError (src/services/soroban.test.js:12:14) + + ● Soroban Integration Wrapper › callSorobanContract › should retry on transient errors using the wrapper + + 503 Service Unavailable + +   29 | attempts++; +  30 | if (attempts < 2) { + > 31 | return Promise.reject(new Error('503 Service Unavailable')); +  | ^ +  32 | } +  33 | return Promise.resolve('recovered'); +  34 | }); + + at src/services/soroban.test.js:31:33 + at operation (src/services/soroban.js:106:20) + at withRetry (src/services/soroban.js:137:10) + at Object.callSorobanContract (src/services/soroban.test.js:37:28) + + + ● CORS configuration helper › parseAllowedOrigins › returns an empty list for missing values + + expect(received).toEqual(expected) // deep equality + + Expected: [] + Received: null + +   24 | +  25 | it('returns an empty list for missing values', () => { + > 26 | expect(parseAllowedOrigins(undefined)).toEqual([]); +  | ^ +  27 | }); +  28 | }); +  29 | + + at Object.toEqual (src/config/cors.test.js:26:46) + + ● CORS configuration helper › getAllowedOriginsFromEnv › uses the explicit allowlist when configured + + TypeError: getAllowedOriginsFromEnv is not a function + +   31 | it('uses the explicit allowlist when configured', () => { +  32 | expect( + > 33 | getAllowedOriginsFromEnv({ +  | ^ +  34 | NODE_ENV: 'production', +  35 | CORS_ALLOWED_ORIGINS: 'https://app.example.com,https://admin.example.com', +  36 | }) + + at Object.getAllowedOriginsFromEnv (src/config/cors.test.js:33:9) + + ● CORS configuration helper › getAllowedOriginsFromEnv › uses development localhost fallback when unset in development + + TypeError: getAllowedOriginsFromEnv is not a function + +   40 | it('uses development localhost fallback when unset in development', () => { +  41 | expect( + > 42 | getAllowedOriginsFromEnv({ +  | ^ +  43 | NODE_ENV: 'development', +  44 | }) +  45 | ).toEqual(getDevelopmentFallbackOrigins()); + + at Object.getAllowedOriginsFromEnv (src/config/cors.test.js:42:9) + + ● CORS configuration helper › getAllowedOriginsFromEnv › fails closed outside development when unset + + TypeError: getAllowedOriginsFromEnv is not a function + +   48 | it('fails closed outside development when unset', () => { +  49 | expect( + > 50 | getAllowedOriginsFromEnv({ +  | ^ +  51 | NODE_ENV: 'production', +  52 | }) +  53 | ).toEqual([]); + + at Object.getAllowedOriginsFromEnv (src/config/cors.test.js:50:9) + + ● CORS configuration helper › createCorsOptions › rejects blocked origins with the dedicated CORS error + + expect(received).toBe(expected) // Object.is equality + + Expected: undefined + Received: "CORS policy: origin \"https://evil.example.com\" is not allowed." + +   76 | +  77 | const [error] = callback.mock.calls[0]; + > 78 | expect(error.message).toBe(CORS_REJECTION_MESSAGE); +  | ^ +  79 | expect(error.status).toBe(403); +  80 | expect(isCorsOriginRejectedError(error)).toBe(true); +  81 | }); + + at Object.toBe (src/config/cors.test.js:78:29) + + ● CORS configuration helper › CORS rejection helpers › creates a 403 rejection error + + TypeError: createCorsRejectionError is not a function + +   84 | describe('CORS rejection helpers', () => { +  85 | it('creates a 403 rejection error', () => { + > 86 | const error = createCorsRejectionError(); +  | ^ +  87 | +  88 | expect(error.message).toBe(CORS_REJECTION_MESSAGE); +  89 | expect(error.status).toBe(403); + + at Object.createCorsRejectionError (src/config/cors.test.js:86:21) + + + ● Test suite failed to run + + Cannot find module 'vitest' from 'src/__tests__/bodySizeLimits.test.js' + +   15 | 'use strict'; +  16 | + > 17 | const { describe, it, expect, beforeEach, beforeAll, vi } = require('vitest'); +  | ^ +  18 | const request = require('supertest'); +  19 | const express = require('express'); +  20 | + + at Resolver._throwModNotFoundError (node_modules/jest-resolve/build/index.js:863:11) + at Object.require (src/__tests__/bodySizeLimits.test.js:17:61) + + + ● Async Handler › should catch async errors + + TypeError: Cannot read properties of undefined (reading 'message') + +   34 | const res = await request(app).get('/fail'); +  35 | expect(res.statusCode).toBe(500); + > 36 | expect(res.body.error.message).toBeDefined(); +  | ^ +  37 | }); +  38 | }); + + at Object.message (tests/app.test.js:36:27) + + + ● asyncHandler utility › should catch async errors and pass to error handler + + expect(received).toBeDefined() + + Received: undefined + +   33 | +  34 | expect(res.statusCode).toBe(500); + > 35 | expect(res.body.error).toBeDefined(); +  | ^ +  36 | expect(res.body.error.message).toBe('Test error'); +  37 | }); +  38 | + + at Object.toBeDefined (tests/unit/asyncHandler.test.js:35:28) + + + ● errorHandler middleware › should return 500 by default + + expect(received).toBeDefined() + + Received: undefined + +   77 | +  78 | expect(res.statusCode).toBe(500); + > 79 | expect(res.body.error).toBeDefined(); +  | ^ +  80 | }); +  81 | +  82 | it('should respect custom statusCode', async () => { + + at Object.toBeDefined (tests/unit/errorHandler.test.js:79:28) + + ● errorHandler middleware › should respect custom statusCode + + expect(received).toBe(expected) // Object.is equality + + Expected: 400 + Received: 500 + +   91 | const res = await request(app).get('/custom'); +  92 | + > 93 | expect(res.statusCode).toBe(400); +  | ^ +  94 | expect(res.body.error.message).toBe('Bad Request'); +  95 | }); +  96 | + + at Object.toBe (tests/unit/errorHandler.test.js:93:28) + + ● errorHandler middleware › should hide stack in production + + TypeError: Cannot read properties of undefined (reading 'message') + +   106 | const res = await request(app).get('/prod-error'); +  107 | + > 108 | expect(res.body.error.message).toBe('Internal server error'); +  | ^ +  109 | expect(res.body.error.stack).toBeUndefined(); +  110 | +  111 | process.env.NODE_ENV = 'test'; // reset + + at Object.message (tests/unit/errorHandler.test.js:108:27) + + + ● Test suite failed to run + + Jest encountered an unexpected token + + Jest failed to parse a file. This happens e.g. when your code or its dependencies use non-standard JavaScript syntax, or when Jest is not configured to support such syntax. + + Out of the box Jest supports Babel, which will be used to transform your files into valid JS based on your Babel configuration. + + By default "node_modules" folder is ignored by transformers. + + Here's what you can do: + • If you are trying to use ECMAScript Modules, see https://jestjs.io/docs/ecmascript-modules for how to enable it. + • If you are trying to use TypeScript, see https://jestjs.io/docs/getting-started#using-typescript + • To have some of your "node_modules" files transformed, you can specify a custom "transformIgnorePatterns" in your config. + • If you need a custom transformation, specify a "transform" option in your config. + • If you simply want to mock your non-JS modules (e.g. binary assets) you can stub them out with the "moduleNameMapper" config option. + + You'll find more details and examples of these config options in the docs: + https://jestjs.io/docs/configuration + For information about custom transformations, see: + https://jestjs.io/docs/code-transformation + + Details: + + SyntaxError: C:\Users\pc\Documents\waves\Liquifact-backend\src\index.js: Unexpected token (8:1) + +   6 |  */ +  7 | + > 8 | * Express app configuration for invoice financing, auth, and Stellar integration. +  | ^ +  9 | * Server startup lives in server.js so this module can be imported cleanly in tests. +  10 | */ +  11 | + +   1 | const request = require('supertest'); +  2 | const jwt = require('jsonwebtoken'); + > 3 | const { app } = require('../index'); +  | ^ +  4 | +  5 | describe('Rate Limiting Middleware', () => { +  6 | const secret = process.env.JWT_SECRET || 'test-secret'; + + at constructor (node_modules/@babel/parser/src/parse-error.ts:95:45) + at Parser.toParseError [as raise] (node_modules/@babel/parser/src/tokenizer/index.ts:1504:19) + at Parser.raise [as unexpected] (node_modules/@babel/parser/src/tokenizer/index.ts:1544:16) + at Parser.unexpected [as parseExprAtom] (node_modules/@babel/parser/src/parser/expression.ts:1358:22) + at Parser.parseExprAtom [as parseExprSubscripts] (node_modules/@babel/parser/src/parser/expression.ts:742:23) + at Parser.parseExprSubscripts [as parseUpdate] (node_modules/@babel/parser/src/parser/expression.ts:721:21) + at Parser.parseUpdate [as parseMaybeUnary] (node_modules/@babel/parser/src/parser/expression.ts:683:23) + at Parser.parseMaybeUnary [as parseMaybeUnaryOrPrivate] (node_modules/@babel/parser/src/parser/expression.ts:417:14) + at Parser.parseMaybeUnaryOrPrivate [as parseExprOps] (node_modules/@babel/parser/src/parser/expression.ts:429:23) + at Parser.parseExprOps [as parseMaybeConditional] (node_modules/@babel/parser/src/parser/expression.ts:384:23) + at Parser.parseMaybeConditional [as parseMaybeAssign] (node_modules/@babel/parser/src/parser/expression.ts:301:21) + at Parser.parseMaybeAssign [as parseExpressionBase] (node_modules/@babel/parser/src/parser/expression.ts:226:23) + at parseExpressionBase (node_modules/@babel/parser/src/parser/expression.ts:217:39) + at Parser.callback [as allowInAnd] (node_modules/@babel/parser/src/parser/expression.ts:3192:16) + at Parser.allowInAnd [as parseExpression] (node_modules/@babel/parser/src/parser/expression.ts:217:17) + at Parser.parseExpression [as parseStatementContent] (node_modules/@babel/parser/src/parser/statement.ts:688:23) + at Parser.parseStatementContent [as parseStatementLike] (node_modules/@babel/parser/src/parser/statement.ts:482:17) + at Parser.parseStatementLike [as parseModuleItem] (node_modules/@babel/parser/src/parser/statement.ts:419:17) + at Parser.parseModuleItem [as parseBlockOrModuleBlockBody] (node_modules/@babel/parser/src/parser/statement.ts:1443:16) + at Parser.parseBlockOrModuleBlockBody [as parseBlockBody] (node_modules/@babel/parser/src/parser/statement.ts:1417:10) + at Parser.parseBlockBody [as parseProgram] (node_modules/@babel/parser/src/parser/statement.ts:229:10) + at Parser.parseProgram [as parseTopLevel] (node_modules/@babel/parser/src/parser/statement.ts:203:25) + at Parser.parseTopLevel [as parse] (node_modules/@babel/parser/src/parser/index.ts:83:25) + at parse (node_modules/@babel/parser/src/index.ts:86:38) + at parser (node_modules/@babel/core/src/parser/index.ts:29:19) + at parser.next () + at normalizeFile (node_modules/@babel/core/src/transformation/normalize-file.ts:50:24) + at normalizeFile.next () + at run (node_modules/@babel/core/src/transformation/index.ts:41:36) + at run.next () + at transform (node_modules/@babel/core/src/transform.ts:29:20) + at transform.next () + at evaluateSync (node_modules/gensync/index.js:251:28) + at sync (node_modules/gensync/index.js:89:14) + at fn (node_modules/@babel/core/src/errors/rewrite-stack-trace.ts:99:14) + at transformSync (node_modules/@babel/core/src/transform.ts:66:52) + at ScriptTransformer.transformSource (node_modules/@jest/transform/build/index.js:415:31) + at ScriptTransformer._transformAndBuildScript (node_modules/@jest/transform/build/index.js:512:40) + at ScriptTransformer.transform (node_modules/@jest/transform/build/index.js:551:19) + at Object.require (src/__tests__/rateLimit.test.js:3:17) + + + ● Test suite failed to run + + Jest encountered an unexpected token + + Jest failed to parse a file. This happens e.g. when your code or its dependencies use non-standard JavaScript syntax, or when Jest is not configured to support such syntax. + + Out of the box Jest supports Babel, which will be used to transform your files into valid JS based on your Babel configuration. + + By default "node_modules" folder is ignored by transformers. + + Here's what you can do: + • If you are trying to use ECMAScript Modules, see https://jestjs.io/docs/ecmascript-modules for how to enable it. + • If you are trying to use TypeScript, see https://jestjs.io/docs/getting-started#using-typescript + • To have some of your "node_modules" files transformed, you can specify a custom "transformIgnorePatterns" in your config. + • If you need a custom transformation, specify a "transform" option in your config. + • If you simply want to mock your non-JS modules (e.g. binary assets) you can stub them out with the "moduleNameMapper" config option. + + You'll find more details and examples of these config options in the docs: + https://jestjs.io/docs/configuration + For information about custom transformations, see: + https://jestjs.io/docs/code-transformation + + Details: + + SyntaxError: C:\Users\pc\Documents\waves\Liquifact-backend\src\app.js: Missing semicolon. (120:4) + +   118 | message: 'Invoice service will list tokenized invoices here.', +  119 | }); + > 120 | })); +  | ^ +  121 | +  122 | // Invoices — POST (create) with strict 512 KB body limit +  123 | app.post('/api/invoices', ...invoiceBodyLimit(), (req, res) => { + +   1 | const request = require('supertest'); + > 2 | const { createApp } = require('../app'); +  | ^ +  3 | const invoiceService = require('../services/invoice.service'); +  4 | +  5 | // Mock the service + + at constructor (node_modules/@babel/parser/src/parse-error.ts:95:45) + at Parser.toParseError [as raise] (node_modules/@babel/parser/src/tokenizer/index.ts:1504:19) + at Parser.raise [as semicolon] (node_modules/@babel/parser/src/parser/util.ts:149:10) + at Parser.semicolon [as parseExpressionStatement] (node_modules/@babel/parser/src/parser/statement.ts:1363:10) + at Parser.parseExpressionStatement [as parseStatementContent] (node_modules/@babel/parser/src/parser/statement.ts:702:19) + at Parser.parseStatementContent [as parseStatementLike] (node_modules/@babel/parser/src/parser/statement.ts:482:17) + at Parser.parseStatementLike [as parseStatementListItem] (node_modules/@babel/parser/src/parser/statement.ts:431:17) + at Parser.parseStatementListItem [as parseBlockOrModuleBlockBody] (node_modules/@babel/parser/src/parser/statement.ts:1444:16) + at Parser.parseBlockOrModuleBlockBody [as parseBlockBody] (node_modules/@babel/parser/src/parser/statement.ts:1417:10) + at Parser.parseBlockBody [as parseBlock] (node_modules/@babel/parser/src/parser/statement.ts:1385:10) + at Parser.parseBlock [as parseFunctionBody] (node_modules/@babel/parser/src/parser/expression.ts:2621:24) + at Parser.parseFunctionBody [as parseFunctionBodyAndFinish] (node_modules/@babel/parser/src/parser/expression.ts:2590:10) + at parseFunctionBodyAndFinish (node_modules/@babel/parser/src/parser/statement.ts:1695:12) + at Parser.callback [as withSmartMixTopicForbiddingContext] (node_modules/@babel/parser/src/parser/expression.ts:3171:14) + at Parser.withSmartMixTopicForbiddingContext [as parseFunction] (node_modules/@babel/parser/src/parser/statement.ts:1693:10) + at Parser.parseFunction [as parseFunctionStatement] (node_modules/@babel/parser/src/parser/statement.ts:1080:17) + at Parser.parseFunctionStatement [as parseStatementContent] (node_modules/@babel/parser/src/parser/statement.ts:525:21) + at Parser.parseStatementContent [as parseStatementLike] (node_modules/@babel/parser/src/parser/statement.ts:482:17) + at Parser.parseStatementLike [as parseModuleItem] (node_modules/@babel/parser/src/parser/statement.ts:419:17) + at Parser.parseModuleItem [as parseBlockOrModuleBlockBody] (node_modules/@babel/parser/src/parser/statement.ts:1443:16) + at Parser.parseBlockOrModuleBlockBody [as parseBlockBody] (node_modules/@babel/parser/src/parser/statement.ts:1417:10) + at Parser.parseBlockBody [as parseProgram] (node_modules/@babel/parser/src/parser/statement.ts:229:10) + at Parser.parseProgram [as parseTopLevel] (node_modules/@babel/parser/src/parser/statement.ts:203:25) + at Parser.parseTopLevel [as parse] (node_modules/@babel/parser/src/parser/index.ts:83:25) + at parse (node_modules/@babel/parser/src/index.ts:86:38) + at parser (node_modules/@babel/core/src/parser/index.ts:29:19) + at parser.next () + at normalizeFile (node_modules/@babel/core/src/transformation/normalize-file.ts:50:24) + at normalizeFile.next () + at run (node_modules/@babel/core/src/transformation/index.ts:41:36) + at run.next () + at transform (node_modules/@babel/core/src/transform.ts:29:20) + at transform.next () + at evaluateSync (node_modules/gensync/index.js:251:28) + at sync (node_modules/gensync/index.js:89:14) + at fn (node_modules/@babel/core/src/errors/rewrite-stack-trace.ts:99:14) + at transformSync (node_modules/@babel/core/src/transform.ts:66:52) + at ScriptTransformer.transformSource (node_modules/@jest/transform/build/index.js:415:31) + at ScriptTransformer._transformAndBuildScript (node_modules/@jest/transform/build/index.js:512:40) + at ScriptTransformer.transform (node_modules/@jest/transform/build/index.js:551:19) + at Object.require (src/__tests__/invoice.api.test.js:2:23) + + + ● Test suite failed to run + + Jest encountered an unexpected token + + Jest failed to parse a file. This happens e.g. when your code or its dependencies use non-standard JavaScript syntax, or when Jest is not configured to support such syntax. + + Out of the box Jest supports Babel, which will be used to transform your files into valid JS based on your Babel configuration. + + By default "node_modules" folder is ignored by transformers. + + Here's what you can do: + • If you are trying to use ECMAScript Modules, see https://jestjs.io/docs/ecmascript-modules for how to enable it. + • If you are trying to use TypeScript, see https://jestjs.io/docs/getting-started#using-typescript + • To have some of your "node_modules" files transformed, you can specify a custom "transformIgnorePatterns" in your config. + • If you need a custom transformation, specify a "transform" option in your config. + • If you simply want to mock your non-JS modules (e.g. binary assets) you can stub them out with the "moduleNameMapper" config option. + + You'll find more details and examples of these config options in the docs: + https://jestjs.io/docs/configuration + For information about custom transformations, see: + https://jestjs.io/docs/code-transformation + + Details: + + SyntaxError: C:\Users\pc\Documents\waves\Liquifact-backend\src\index.js: Unexpected token (8:1) + +   6 |  */ +  7 | + > 8 | * Express app configuration for invoice financing, auth, and Stellar integration. +  | ^ +  9 | * Server startup lives in server.js so this module can be imported cleanly in tests. +  10 | */ +  11 | + +   1 | const request = require('supertest'); +  2 | const jwt = require('jsonwebtoken'); + > 3 | const { app } = require('../index'); +  | ^ +  4 | +  5 | describe('Authentication Middleware', () => { +  6 | const secret = process.env.JWT_SECRET || 'test-secret'; + + at constructor (node_modules/@babel/parser/src/parse-error.ts:95:45) + at Parser.toParseError [as raise] (node_modules/@babel/parser/src/tokenizer/index.ts:1504:19) + at Parser.raise [as unexpected] (node_modules/@babel/parser/src/tokenizer/index.ts:1544:16) + at Parser.unexpected [as parseExprAtom] (node_modules/@babel/parser/src/parser/expression.ts:1358:22) + at Parser.parseExprAtom [as parseExprSubscripts] (node_modules/@babel/parser/src/parser/expression.ts:742:23) + at Parser.parseExprSubscripts [as parseUpdate] (node_modules/@babel/parser/src/parser/expression.ts:721:21) + at Parser.parseUpdate [as parseMaybeUnary] (node_modules/@babel/parser/src/parser/expression.ts:683:23) + at Parser.parseMaybeUnary [as parseMaybeUnaryOrPrivate] (node_modules/@babel/parser/src/parser/expression.ts:417:14) + at Parser.parseMaybeUnaryOrPrivate [as parseExprOps] (node_modules/@babel/parser/src/parser/expression.ts:429:23) + at Parser.parseExprOps [as parseMaybeConditional] (node_modules/@babel/parser/src/parser/expression.ts:384:23) + at Parser.parseMaybeConditional [as parseMaybeAssign] (node_modules/@babel/parser/src/parser/expression.ts:301:21) + at Parser.parseMaybeAssign [as parseExpressionBase] (node_modules/@babel/parser/src/parser/expression.ts:226:23) + at parseExpressionBase (node_modules/@babel/parser/src/parser/expression.ts:217:39) + at Parser.callback [as allowInAnd] (node_modules/@babel/parser/src/parser/expression.ts:3192:16) + at Parser.allowInAnd [as parseExpression] (node_modules/@babel/parser/src/parser/expression.ts:217:17) + at Parser.parseExpression [as parseStatementContent] (node_modules/@babel/parser/src/parser/statement.ts:688:23) + at Parser.parseStatementContent [as parseStatementLike] (node_modules/@babel/parser/src/parser/statement.ts:482:17) + at Parser.parseStatementLike [as parseModuleItem] (node_modules/@babel/parser/src/parser/statement.ts:419:17) + at Parser.parseModuleItem [as parseBlockOrModuleBlockBody] (node_modules/@babel/parser/src/parser/statement.ts:1443:16) + at Parser.parseBlockOrModuleBlockBody [as parseBlockBody] (node_modules/@babel/parser/src/parser/statement.ts:1417:10) + at Parser.parseBlockBody [as parseProgram] (node_modules/@babel/parser/src/parser/statement.ts:229:10) + at Parser.parseProgram [as parseTopLevel] (node_modules/@babel/parser/src/parser/statement.ts:203:25) + at Parser.parseTopLevel [as parse] (node_modules/@babel/parser/src/parser/index.ts:83:25) + at parse (node_modules/@babel/parser/src/index.ts:86:38) + at parser (node_modules/@babel/core/src/parser/index.ts:29:19) + at parser.next () + at normalizeFile (node_modules/@babel/core/src/transformation/normalize-file.ts:50:24) + at normalizeFile.next () + at run (node_modules/@babel/core/src/transformation/index.ts:41:36) + at run.next () + at transform (node_modules/@babel/core/src/transform.ts:29:20) + at transform.next () + at evaluateSync (node_modules/gensync/index.js:251:28) + at sync (node_modules/gensync/index.js:89:14) + at fn (node_modules/@babel/core/src/errors/rewrite-stack-trace.ts:99:14) + at transformSync (node_modules/@babel/core/src/transform.ts:66:52) + at ScriptTransformer.transformSource (node_modules/@jest/transform/build/index.js:415:31) + at ScriptTransformer._transformAndBuildScript (node_modules/@jest/transform/build/index.js:512:40) + at ScriptTransformer.transform (node_modules/@jest/transform/build/index.js:551:19) + at Object.require (src/__tests__/auth.test.js:3:17) + + + ● Test suite failed to run + + Jest encountered an unexpected token + + Jest failed to parse a file. This happens e.g. when your code or its dependencies use non-standard JavaScript syntax, or when Jest is not configured to support such syntax. + + Out of the box Jest supports Babel, which will be used to transform your files into valid JS based on your Babel configuration. + + By default "node_modules" folder is ignored by transformers. + + Here's what you can do: + • If you are trying to use ECMAScript Modules, see https://jestjs.io/docs/ecmascript-modules for how to enable it. + • If you are trying to use TypeScript, see https://jestjs.io/docs/getting-started#using-typescript + • To have some of your "node_modules" files transformed, you can specify a custom "transformIgnorePatterns" in your config. + • If you need a custom transformation, specify a "transform" option in your config. + • If you simply want to mock your non-JS modules (e.g. binary assets) you can stub them out with the "moduleNameMapper" config option. + + You'll find more details and examples of these config options in the docs: + https://jestjs.io/docs/configuration + For information about custom transformations, see: + https://jestjs.io/docs/code-transformation + + Details: + + SyntaxError: C:\Users\pc\Documents\waves\Liquifact-backend\src\index.js: Unexpected token (8:1) + +   6 |  */ +  7 | + > 8 | * Express app configuration for invoice financing, auth, and Stellar integration. +  | ^ +  9 | * Server startup lives in server.js so this module can be imported cleanly in tests. +  10 | */ +  11 | + +   1 | const request = require('supertest'); + > 2 | const app = require('../../src/index'); +  | ^ +  3 | +  4 | describe('API Integration Tests (RFC 7807)', () => { +  5 | test('GET /api/invoices should return 501 Not Implemented with Problem Details', async () => { + + at constructor (node_modules/@babel/parser/src/parse-error.ts:95:45) + at Parser.toParseError [as raise] (node_modules/@babel/parser/src/tokenizer/index.ts:1504:19) + at Parser.raise [as unexpected] (node_modules/@babel/parser/src/tokenizer/index.ts:1544:16) + at Parser.unexpected [as parseExprAtom] (node_modules/@babel/parser/src/parser/expression.ts:1358:22) + at Parser.parseExprAtom [as parseExprSubscripts] (node_modules/@babel/parser/src/parser/expression.ts:742:23) + at Parser.parseExprSubscripts [as parseUpdate] (node_modules/@babel/parser/src/parser/expression.ts:721:21) + at Parser.parseUpdate [as parseMaybeUnary] (node_modules/@babel/parser/src/parser/expression.ts:683:23) + at Parser.parseMaybeUnary [as parseMaybeUnaryOrPrivate] (node_modules/@babel/parser/src/parser/expression.ts:417:14) + at Parser.parseMaybeUnaryOrPrivate [as parseExprOps] (node_modules/@babel/parser/src/parser/expression.ts:429:23) + at Parser.parseExprOps [as parseMaybeConditional] (node_modules/@babel/parser/src/parser/expression.ts:384:23) + at Parser.parseMaybeConditional [as parseMaybeAssign] (node_modules/@babel/parser/src/parser/expression.ts:301:21) + at Parser.parseMaybeAssign [as parseExpressionBase] (node_modules/@babel/parser/src/parser/expression.ts:226:23) + at parseExpressionBase (node_modules/@babel/parser/src/parser/expression.ts:217:39) + at Parser.callback [as allowInAnd] (node_modules/@babel/parser/src/parser/expression.ts:3192:16) + at Parser.allowInAnd [as parseExpression] (node_modules/@babel/parser/src/parser/expression.ts:217:17) + at Parser.parseExpression [as parseStatementContent] (node_modules/@babel/parser/src/parser/statement.ts:688:23) + at Parser.parseStatementContent [as parseStatementLike] (node_modules/@babel/parser/src/parser/statement.ts:482:17) + at Parser.parseStatementLike [as parseModuleItem] (node_modules/@babel/parser/src/parser/statement.ts:419:17) + at Parser.parseModuleItem [as parseBlockOrModuleBlockBody] (node_modules/@babel/parser/src/parser/statement.ts:1443:16) + at Parser.parseBlockOrModuleBlockBody [as parseBlockBody] (node_modules/@babel/parser/src/parser/statement.ts:1417:10) + at Parser.parseBlockBody [as parseProgram] (node_modules/@babel/parser/src/parser/statement.ts:229:10) + at Parser.parseProgram [as parseTopLevel] (node_modules/@babel/parser/src/parser/statement.ts:203:25) + at Parser.parseTopLevel [as parse] (node_modules/@babel/parser/src/parser/index.ts:83:25) + at parse (node_modules/@babel/parser/src/index.ts:86:38) + at parser (node_modules/@babel/core/src/parser/index.ts:29:19) + at parser.next () + at normalizeFile (node_modules/@babel/core/src/transformation/normalize-file.ts:50:24) + at normalizeFile.next () + at run (node_modules/@babel/core/src/transformation/index.ts:41:36) + at run.next () + at transform (node_modules/@babel/core/src/transform.ts:29:20) + at transform.next () + at evaluateSync (node_modules/gensync/index.js:251:28) + at sync (node_modules/gensync/index.js:89:14) + at fn (node_modules/@babel/core/src/errors/rewrite-stack-trace.ts:99:14) + at transformSync (node_modules/@babel/core/src/transform.ts:66:52) + at ScriptTransformer.transformSource (node_modules/@jest/transform/build/index.js:415:31) + at ScriptTransformer._transformAndBuildScript (node_modules/@jest/transform/build/index.js:512:40) + at ScriptTransformer.transform (node_modules/@jest/transform/build/index.js:551:19) + at Object.require (tests/integration/errorHandling.test.js:2:13) + + + ● Test suite failed to run + + Jest encountered an unexpected token + + Jest failed to parse a file. This happens e.g. when your code or its dependencies use non-standard JavaScript syntax, or when Jest is not configured to support such syntax. + + Out of the box Jest supports Babel, which will be used to transform your files into valid JS based on your Babel configuration. + + By default "node_modules" folder is ignored by transformers. + + Here's what you can do: + • If you are trying to use ECMAScript Modules, see https://jestjs.io/docs/ecmascript-modules for how to enable it. + • If you are trying to use TypeScript, see https://jestjs.io/docs/getting-started#using-typescript + • To have some of your "node_modules" files transformed, you can specify a custom "transformIgnorePatterns" in your config. + • If you need a custom transformation, specify a "transform" option in your config. + • If you simply want to mock your non-JS modules (e.g. binary assets) you can stub them out with the "moduleNameMapper" config option. + + You'll find more details and examples of these config options in the docs: + https://jestjs.io/docs/configuration + For information about custom transformations, see: + https://jestjs.io/docs/code-transformation + + Details: + + SyntaxError: C:\Users\pc\Documents\waves\Liquifact-backend\src\index.test.js: Expecting Unicode escape sequence \uXXXX. (59:45) + +   57 | const csp = res.headers['content-security-policy']; +  58 | expect(csp).toBeDefined(); + > 59 | expect(csp).toContain('default-src \\'self\\''); +  | ^ +  60 | expect(csp).toContain('object-src \\'none\\''); +  61 | expect(csp).toContain('frame-src \\'none\\''); +  62 | + + at constructor (node_modules/@babel/parser/src/parse-error.ts:95:45) + at Parser.toParseError [as raise] (node_modules/@babel/parser/src/tokenizer/index.ts:1504:19) + at Parser.raise [as readWord1] (node_modules/@babel/parser/src/tokenizer/index.ts:1440:16) + at Parser.readWord1 [as readWord] (node_modules/@babel/parser/src/tokenizer/index.ts:1466:23) + at Parser.readWord [as getTokenFromCode] (node_modules/@babel/parser/src/tokenizer/index.ts:1054:16) + at Parser.getTokenFromCode [as nextToken] (node_modules/@babel/parser/src/tokenizer/index.ts:279:10) + at Parser.nextToken [as next] (node_modules/@babel/parser/src/tokenizer/index.ts:122:10) + at Parser.next [as parseLiteralAtNode] (node_modules/@babel/parser/src/parser/expression.ts:1699:10) + at Parser.parseLiteralAtNode [as parseLiteral] (node_modules/@babel/parser/src/parser/expression.ts:1705:17) + at Parser.parseLiteral [as parseStringLiteral] (node_modules/@babel/parser/src/parser/expression.ts:1709:17) + at Parser.parseStringLiteral [as parseExprAtom] (node_modules/@babel/parser/src/parser/expression.ts:1158:21) + at Parser.parseExprAtom [as parseExprSubscripts] (node_modules/@babel/parser/src/parser/expression.ts:742:23) + at Parser.parseExprSubscripts [as parseUpdate] (node_modules/@babel/parser/src/parser/expression.ts:721:21) + at Parser.parseUpdate [as parseMaybeUnary] (node_modules/@babel/parser/src/parser/expression.ts:683:23) + at Parser.parseMaybeUnary [as parseMaybeUnaryOrPrivate] (node_modules/@babel/parser/src/parser/expression.ts:417:14) + at Parser.parseMaybeUnaryOrPrivate [as parseExprOps] (node_modules/@babel/parser/src/parser/expression.ts:429:23) + at Parser.parseExprOps [as parseMaybeConditional] (node_modules/@babel/parser/src/parser/expression.ts:384:23) + at Parser.parseMaybeConditional [as parseMaybeAssign] (node_modules/@babel/parser/src/parser/expression.ts:301:21) + at parseMaybeAssign (node_modules/@babel/parser/src/parser/expression.ts:257:12) + at Parser.callback [as allowInAnd] (node_modules/@babel/parser/src/parser/expression.ts:3197:12) + at Parser.allowInAnd [as parseMaybeAssignAllowIn] (node_modules/@babel/parser/src/parser/expression.ts:256:17) + at Parser.parseMaybeAssignAllowIn [as parseMaybeAssignAllowInOrVoidPattern] (node_modules/@babel/parser/src/parser/expression.ts:3311:17) + at Parser.parseMaybeAssignAllowInOrVoidPattern [as parseExprListItem] (node_modules/@babel/parser/src/parser/expression.ts:2793:18) + at Parser.parseExprListItem [as parseCallExpressionArguments] (node_modules/@babel/parser/src/parser/expression.ts:1042:14) + at Parser.parseCallExpressionArguments [as parseCoverCallAndAsyncArrowHead] (node_modules/@babel/parser/src/parser/expression.ts:922:29) + at Parser.parseCoverCallAndAsyncArrowHead [as parseSubscript] (node_modules/@babel/parser/src/parser/expression.ts:804:19) + at Parser.parseSubscript [as parseSubscripts] (node_modules/@babel/parser/src/parser/expression.ts:763:19) + at Parser.parseSubscripts [as parseExprSubscripts] (node_modules/@babel/parser/src/parser/expression.ts:748:17) + at Parser.parseExprSubscripts [as parseUpdate] (node_modules/@babel/parser/src/parser/expression.ts:721:21) + at Parser.parseUpdate [as parseMaybeUnary] (node_modules/@babel/parser/src/parser/expression.ts:683:23) + at Parser.parseMaybeUnary [as parseMaybeUnaryOrPrivate] (node_modules/@babel/parser/src/parser/expression.ts:417:14) + at Parser.parseMaybeUnaryOrPrivate [as parseExprOps] (node_modules/@babel/parser/src/parser/expression.ts:429:23) + at Parser.parseExprOps [as parseMaybeConditional] (node_modules/@babel/parser/src/parser/expression.ts:384:23) + at Parser.parseMaybeConditional [as parseMaybeAssign] (node_modules/@babel/parser/src/parser/expression.ts:301:21) + at Parser.parseMaybeAssign [as parseExpressionBase] (node_modules/@babel/parser/src/parser/expression.ts:226:23) + at parseExpressionBase (node_modules/@babel/parser/src/parser/expression.ts:217:39) + at Parser.callback [as allowInAnd] (node_modules/@babel/parser/src/parser/expression.ts:3192:16) + at Parser.allowInAnd [as parseExpression] (node_modules/@babel/parser/src/parser/expression.ts:217:17) + at Parser.parseExpression [as parseStatementContent] (node_modules/@babel/parser/src/parser/statement.ts:688:23) + at Parser.parseStatementContent [as parseStatementLike] (node_modules/@babel/parser/src/parser/statement.ts:482:17) + at Parser.parseStatementLike [as parseStatementListItem] (node_modules/@babel/parser/src/parser/statement.ts:431:17) + at Parser.parseStatementListItem [as parseBlockOrModuleBlockBody] (node_modules/@babel/parser/src/parser/statement.ts:1444:16) + at Parser.parseBlockOrModuleBlockBody [as parseBlockBody] (node_modules/@babel/parser/src/parser/statement.ts:1417:10) + at Parser.parseBlockBody [as parseBlock] (node_modules/@babel/parser/src/parser/statement.ts:1385:10) + at Parser.parseBlock [as parseFunctionBody] (node_modules/@babel/parser/src/parser/expression.ts:2621:24) + at Parser.parseFunctionBody [as parseFunctionBodyAndFinish] (node_modules/@babel/parser/src/parser/expression.ts:2590:10) + at parseFunctionBodyAndFinish (node_modules/@babel/parser/src/parser/statement.ts:1695:12) + at Parser.callback [as withSmartMixTopicForbiddingContext] (node_modules/@babel/parser/src/parser/expression.ts:3171:14) + at Parser.withSmartMixTopicForbiddingContext [as parseFunction] (node_modules/@babel/parser/src/parser/statement.ts:1693:10) + at Parser.parseFunction [as parseFunctionStatement] (node_modules/@babel/parser/src/parser/statement.ts:1080:17) + at Parser.parseFunctionStatement [as parseStatementContent] (node_modules/@babel/parser/src/parser/statement.ts:525:21) + at Parser.parseStatementContent [as parseStatementLike] (node_modules/@babel/parser/src/parser/statement.ts:482:17) + at Parser.parseStatementLike [as parseModuleItem] (node_modules/@babel/parser/src/parser/statement.ts:419:17) + at Parser.parseModuleItem [as parseBlockOrModuleBlockBody] (node_modules/@babel/parser/src/parser/statement.ts:1443:16) + at Parser.parseBlockOrModuleBlockBody [as parseBlockBody] (node_modules/@babel/parser/src/parser/statement.ts:1417:10) + at Parser.parseBlockBody [as parseProgram] (node_modules/@babel/parser/src/parser/statement.ts:229:10) + at Parser.parseProgram [as parseTopLevel] (node_modules/@babel/parser/src/parser/statement.ts:203:25) + at Parser.parseTopLevel [as parse] (node_modules/@babel/parser/src/parser/index.ts:83:25) + at parse (node_modules/@babel/parser/src/index.ts:86:38) + at parser (node_modules/@babel/core/src/parser/index.ts:29:19) + at parser.next () + at normalizeFile (node_modules/@babel/core/src/transformation/normalize-file.ts:50:24) + at normalizeFile.next () + at run (node_modules/@babel/core/src/transformation/index.ts:41:36) + at run.next () + at transform (node_modules/@babel/core/src/transform.ts:29:20) + at transform.next () + at evaluateSync (node_modules/gensync/index.js:251:28) + at sync (node_modules/gensync/index.js:89:14) + at fn (node_modules/@babel/core/src/errors/rewrite-stack-trace.ts:99:14) + at transformSync (node_modules/@babel/core/src/transform.ts:66:52) + at ScriptTransformer.transformSource (node_modules/@jest/transform/build/index.js:415:31) + at ScriptTransformer._transformAndBuildScript (node_modules/@jest/transform/build/index.js:512:40) + at ScriptTransformer.transform (node_modules/@jest/transform/build/index.js:551:19) + + + ● Test suite failed to run + + Jest encountered an unexpected token + + Jest failed to parse a file. This happens e.g. when your code or its dependencies use non-standard JavaScript syntax, or when Jest is not configured to support such syntax. + + Out of the box Jest supports Babel, which will be used to transform your files into valid JS based on your Babel configuration. + + By default "node_modules" folder is ignored by transformers. + + Here's what you can do: + • If you are trying to use ECMAScript Modules, see https://jestjs.io/docs/ecmascript-modules for how to enable it. + • If you are trying to use TypeScript, see https://jestjs.io/docs/getting-started#using-typescript + • To have some of your "node_modules" files transformed, you can specify a custom "transformIgnorePatterns" in your config. + • If you need a custom transformation, specify a "transform" option in your config. + • If you simply want to mock your non-JS modules (e.g. binary assets) you can stub them out with the "moduleNameMapper" config option. + + You'll find more details and examples of these config options in the docs: + https://jestjs.io/docs/configuration + For information about custom transformations, see: + https://jestjs.io/docs/code-transformation + + Details: + + SyntaxError: C:\Users\pc\Documents\waves\Liquifact-backend\src\app.js: Missing semicolon. (120:4) + +   118 | message: 'Invoice service will list tokenized invoices here.', +  119 | }); + > 120 | })); +  | ^ +  121 | +  122 | // Invoices — POST (create) with strict 512 KB body limit +  123 | app.post('/api/invoices', ...invoiceBodyLimit(), (req, res) => { + +   1 | const cors = require('cors'); +  2 | + > 3 | const { createApp, handleCorsError } = require('./app'); +  | ^ +  4 | const { CORS_REJECTION_MESSAGE } = require('./config/cors'); +  5 | const { createCorsOptions } = require('./config/cors'); +  6 | const invoiceService = require('./services/invoice.service'); + + at constructor (node_modules/@babel/parser/src/parse-error.ts:95:45) + at Parser.toParseError [as raise] (node_modules/@babel/parser/src/tokenizer/index.ts:1504:19) + at Parser.raise [as semicolon] (node_modules/@babel/parser/src/parser/util.ts:149:10) + at Parser.semicolon [as parseExpressionStatement] (node_modules/@babel/parser/src/parser/statement.ts:1363:10) + at Parser.parseExpressionStatement [as parseStatementContent] (node_modules/@babel/parser/src/parser/statement.ts:702:19) + at Parser.parseStatementContent [as parseStatementLike] (node_modules/@babel/parser/src/parser/statement.ts:482:17) + at Parser.parseStatementLike [as parseStatementListItem] (node_modules/@babel/parser/src/parser/statement.ts:431:17) + at Parser.parseStatementListItem [as parseBlockOrModuleBlockBody] (node_modules/@babel/parser/src/parser/statement.ts:1444:16) + at Parser.parseBlockOrModuleBlockBody [as parseBlockBody] (node_modules/@babel/parser/src/parser/statement.ts:1417:10) + at Parser.parseBlockBody [as parseBlock] (node_modules/@babel/parser/src/parser/statement.ts:1385:10) + at Parser.parseBlock [as parseFunctionBody] (node_modules/@babel/parser/src/parser/expression.ts:2621:24) + at Parser.parseFunctionBody [as parseFunctionBodyAndFinish] (node_modules/@babel/parser/src/parser/expression.ts:2590:10) + at parseFunctionBodyAndFinish (node_modules/@babel/parser/src/parser/statement.ts:1695:12) + at Parser.callback [as withSmartMixTopicForbiddingContext] (node_modules/@babel/parser/src/parser/expression.ts:3171:14) + at Parser.withSmartMixTopicForbiddingContext [as parseFunction] (node_modules/@babel/parser/src/parser/statement.ts:1693:10) + at Parser.parseFunction [as parseFunctionStatement] (node_modules/@babel/parser/src/parser/statement.ts:1080:17) + at Parser.parseFunctionStatement [as parseStatementContent] (node_modules/@babel/parser/src/parser/statement.ts:525:21) + at Parser.parseStatementContent [as parseStatementLike] (node_modules/@babel/parser/src/parser/statement.ts:482:17) + at Parser.parseStatementLike [as parseModuleItem] (node_modules/@babel/parser/src/parser/statement.ts:419:17) + at Parser.parseModuleItem [as parseBlockOrModuleBlockBody] (node_modules/@babel/parser/src/parser/statement.ts:1443:16) + at Parser.parseBlockOrModuleBlockBody [as parseBlockBody] (node_modules/@babel/parser/src/parser/statement.ts:1417:10) + at Parser.parseBlockBody [as parseProgram] (node_modules/@babel/parser/src/parser/statement.ts:229:10) + at Parser.parseProgram [as parseTopLevel] (node_modules/@babel/parser/src/parser/statement.ts:203:25) + at Parser.parseTopLevel [as parse] (node_modules/@babel/parser/src/parser/index.ts:83:25) + at parse (node_modules/@babel/parser/src/index.ts:86:38) + at parser (node_modules/@babel/core/src/parser/index.ts:29:19) + at parser.next () + at normalizeFile (node_modules/@babel/core/src/transformation/normalize-file.ts:50:24) + at normalizeFile.next () + at run (node_modules/@babel/core/src/transformation/index.ts:41:36) + at run.next () + at transform (node_modules/@babel/core/src/transform.ts:29:20) + at transform.next () + at evaluateSync (node_modules/gensync/index.js:251:28) + at sync (node_modules/gensync/index.js:89:14) + at fn (node_modules/@babel/core/src/errors/rewrite-stack-trace.ts:99:14) + at transformSync (node_modules/@babel/core/src/transform.ts:66:52) + at ScriptTransformer.transformSource (node_modules/@jest/transform/build/index.js:415:31) + at ScriptTransformer._transformAndBuildScript (node_modules/@jest/transform/build/index.js:512:40) + at ScriptTransformer.transform (node_modules/@jest/transform/build/index.js:551:19) + at Object.require (src/app.test.js:3:40) + + + ● Test suite failed to run + + Jest encountered an unexpected token + + Jest failed to parse a file. This happens e.g. when your code or its dependencies use non-standard JavaScript syntax, or when Jest is not configured to support such syntax. + + Out of the box Jest supports Babel, which will be used to transform your files into valid JS based on your Babel configuration. + + By default "node_modules" folder is ignored by transformers. + + Here's what you can do: + • If you are trying to use ECMAScript Modules, see https://jestjs.io/docs/ecmascript-modules for how to enable it. + • If you are trying to use TypeScript, see https://jestjs.io/docs/getting-started#using-typescript + • To have some of your "node_modules" files transformed, you can specify a custom "transformIgnorePatterns" in your config. + • If you need a custom transformation, specify a "transform" option in your config. + • If you simply want to mock your non-JS modules (e.g. binary assets) you can stub them out with the "moduleNameMapper" config option. + + You'll find more details and examples of these config options in the docs: + https://jestjs.io/docs/configuration + For information about custom transformations, see: + https://jestjs.io/docs/code-transformation + + Details: + + SyntaxError: C:\Users\pc\Documents\waves\Liquifact-backend\src\app.js: Missing semicolon. (120:4) + +   118 | message: 'Invoice service will list tokenized invoices here.', +  119 | }); + > 120 | })); +  | ^ +  121 | +  122 | // Invoices — POST (create) with strict 512 KB body limit +  123 | app.post('/api/invoices', ...invoiceBodyLimit(), (req, res) => { + +   1 | const request = require('supertest'); + > 2 | const app = require('../app'); +  | ^ +  3 | +  4 | describe('Standard Response Envelope (Issue 19)', () => { +  5 | it('Success response should have data, meta, and error=null', async () => { + + at constructor (node_modules/@babel/parser/src/parse-error.ts:95:45) + at Parser.toParseError [as raise] (node_modules/@babel/parser/src/tokenizer/index.ts:1504:19) + at Parser.raise [as semicolon] (node_modules/@babel/parser/src/parser/util.ts:149:10) + at Parser.semicolon [as parseExpressionStatement] (node_modules/@babel/parser/src/parser/statement.ts:1363:10) + at Parser.parseExpressionStatement [as parseStatementContent] (node_modules/@babel/parser/src/parser/statement.ts:702:19) + at Parser.parseStatementContent [as parseStatementLike] (node_modules/@babel/parser/src/parser/statement.ts:482:17) + at Parser.parseStatementLike [as parseStatementListItem] (node_modules/@babel/parser/src/parser/statement.ts:431:17) + at Parser.parseStatementListItem [as parseBlockOrModuleBlockBody] (node_modules/@babel/parser/src/parser/statement.ts:1444:16) + at Parser.parseBlockOrModuleBlockBody [as parseBlockBody] (node_modules/@babel/parser/src/parser/statement.ts:1417:10) + at Parser.parseBlockBody [as parseBlock] (node_modules/@babel/parser/src/parser/statement.ts:1385:10) + at Parser.parseBlock [as parseFunctionBody] (node_modules/@babel/parser/src/parser/expression.ts:2621:24) + at Parser.parseFunctionBody [as parseFunctionBodyAndFinish] (node_modules/@babel/parser/src/parser/expression.ts:2590:10) + at parseFunctionBodyAndFinish (node_modules/@babel/parser/src/parser/statement.ts:1695:12) + at Parser.callback [as withSmartMixTopicForbiddingContext] (node_modules/@babel/parser/src/parser/expression.ts:3171:14) + at Parser.withSmartMixTopicForbiddingContext [as parseFunction] (node_modules/@babel/parser/src/parser/statement.ts:1693:10) + at Parser.parseFunction [as parseFunctionStatement] (node_modules/@babel/parser/src/parser/statement.ts:1080:17) + at Parser.parseFunctionStatement [as parseStatementContent] (node_modules/@babel/parser/src/parser/statement.ts:525:21) + at Parser.parseStatementContent [as parseStatementLike] (node_modules/@babel/parser/src/parser/statement.ts:482:17) + at Parser.parseStatementLike [as parseModuleItem] (node_modules/@babel/parser/src/parser/statement.ts:419:17) + at Parser.parseModuleItem [as parseBlockOrModuleBlockBody] (node_modules/@babel/parser/src/parser/statement.ts:1443:16) + at Parser.parseBlockOrModuleBlockBody [as parseBlockBody] (node_modules/@babel/parser/src/parser/statement.ts:1417:10) + at Parser.parseBlockBody [as parseProgram] (node_modules/@babel/parser/src/parser/statement.ts:229:10) + at Parser.parseProgram [as parseTopLevel] (node_modules/@babel/parser/src/parser/statement.ts:203:25) + at Parser.parseTopLevel [as parse] (node_modules/@babel/parser/src/parser/index.ts:83:25) + at parse (node_modules/@babel/parser/src/index.ts:86:38) + at parser (node_modules/@babel/core/src/parser/index.ts:29:19) + at parser.next () + at normalizeFile (node_modules/@babel/core/src/transformation/normalize-file.ts:50:24) + at normalizeFile.next () + at run (node_modules/@babel/core/src/transformation/index.ts:41:36) + at run.next () + at transform (node_modules/@babel/core/src/transform.ts:29:20) + at transform.next () + at evaluateSync (node_modules/gensync/index.js:251:28) + at sync (node_modules/gensync/index.js:89:14) + at fn (node_modules/@babel/core/src/errors/rewrite-stack-trace.ts:99:14) + at transformSync (node_modules/@babel/core/src/transform.ts:66:52) + at ScriptTransformer.transformSource (node_modules/@jest/transform/build/index.js:415:31) + at ScriptTransformer._transformAndBuildScript (node_modules/@jest/transform/build/index.js:512:40) + at ScriptTransformer.transform (node_modules/@jest/transform/build/index.js:551:19) + at Object.require (src/tests/response.test.js:2:13) diff --git a/fails.txt b/fails.txt new file mode 100644 index 00000000..09132976 --- /dev/null +++ b/fails.txt @@ -0,0 +1,4 @@ + +> backend@1.0.0 test +> jest + diff --git a/fails_stderr.txt b/fails_stderr.txt new file mode 100644 index 00000000..cb9f9e42 Binary files /dev/null and b/fails_stderr.txt differ diff --git a/fails_utf8.txt b/fails_utf8.txt new file mode 100644 index 00000000..9b7f7d48 --- /dev/null +++ b/fails_utf8.txt @@ -0,0 +1,3858 @@ +node.exe : npm warn invalid +config cache=false set in +command line options +At C:\Users\pc\AppData\Roamin +g\npm\npm.ps1:24 char:5 ++ & "node$exe" "$basedir +/node_modules/npm/bin/npm-cli +.js" $args ++ ~~~~~~~~~~~~~~~~~~~~~~~ +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +~~~~~~~~~~ + + CategoryInfo + : NotSpecified: (npm war + n invali...nd line optio + ns:String) [], RemoteExc +eption + + FullyQualifiedErrorId + : NativeCommandError + +npm warn invalid config Must +be valid filesystem path + +> backend@1.0.0 test +> jest + +FAIL tests/app.test.js + ΓùÅ Console + + console.error + Unhandled Error: +Error: Boom + at C:\Users\pc\Docu +ments\waves\Liquifact-backend +\tests\app.test.js:20:11 + at fn (C:\Users\pc\ +Documents\waves\Liquifact-bac +kend\src\utils\asyncHandler.j +s:10:21) + at +Layer.handleRequest (C:\Users +\pc\Documents\waves\Liquifact +-backend\node_modules\router\ +lib\layer.js:152:17) + at next (C:\Users\p +c\Documents\waves\Liquifact-b +ackend\node_modules\router\li +b\route.js:157:13) + at Route.dispatch ( +C:\Users\pc\Documents\waves\L +iquifact-backend\node_modules +\router\lib\route.js:117:3) + at handle (C:\Users +\pc\Documents\waves\Liquifact +-backend\node_modules\router\ +index.js:435:11) + at +Layer.handleRequest (C:\Users +\pc\Documents\waves\Liquifact +-backend\node_modules\router\ +lib\layer.js:152:17) + at C:\Users\pc\Docu +ments\waves\Liquifact-backend +\node_modules\router\index.js +:295:15 + at processParams (C +:\Users\pc\Documents\waves\Li +quifact-backend\node_modules\ +router\index.js:582:12) + at next (C:\Users\p +c\Documents\waves\Liquifact-b +ackend\node_modules\router\in +dex.js:291:5) + at read (C:\Users\p +c\Documents\waves\Liquifact-b +ackend\node_modules\body-pars +er\lib\read.js:53:5) + at jsonParser (C:\U +sers\pc\Documents\waves\Liqui +fact-backend\node_modules\bod +y-parser\lib\types\json.js:88 +:5) + at +Layer.handleRequest (C:\Users +\pc\Documents\waves\Liquifact +-backend\node_modules\router\ +lib\layer.js:152:17) + at trimPrefix (C:\U +sers\pc\Documents\waves\Liqui +fact-backend\node_modules\rou +ter\index.js:342:13) + at C:\Users\pc\Docu +ments\waves\Liquifact-backend +\node_modules\router\index.js +:297:9 + at processParams (C +:\Users\pc\Documents\waves\Li +quifact-backend\node_modules\ +router\index.js:582:12) + at next (C:\Users\p +c\Documents\waves\Liquifact-b +ackend\node_modules\router\in +dex.js:291:5) + at Function.handle +(C:\Users\pc\Documents\waves\ +Liquifact-backend\node_module +s\router\index.js:186:3) + at Function.handle +(C:\Users\pc\Documents\waves\ +Liquifact-backend\node_module +s\express\lib\application.js: +177:15) + at Server.app (C:\U +sers\pc\Documents\waves\Liqui +fact-backend\node_modules\exp +ress\lib\express.js:38:9) + at Server.emit +(node:events:519:28) + at +parserOnIncoming +(node:_http_server:1186:12) + at HTTPParser.parse +rOnHeadersComplete +(node:_http_common:122:17) + +   25 | } +else { +  26 | +// If it's an unknown +error, provide a fallback +500 status (or use +err.status/statusCode if +available) + +> 27 +| console. +error('Unhandled +Error:', +err); +  | + ^ +  28 | +  29 | +// Some libraries use +status or statusCode +properties (like +http-errors) +  30 | +const status += +err.status +|| +err.statusCode +|| +500; + + at error (src/middlewar +e/errorHandler.js:27:13) + at Layer.handleError (n +ode_modules/router/lib/layer. +js:116:17) + at trimPrefix (node_mod +ules/router/index.js:340:13) + at node_modules/router/ +index.js:297:9 + at processParams (node_ +modules/router/index.js:582:1 +2) + at next (node_modules/r +outer/index.js:291:5) + at next (node_modules/r +outer/lib/route.js:132:14) + + ΓùÅ Async Handler ΓÇ║ +should catch async errors + + expect(received).toBe(exp +ected) // Object.is equality + + Expected: "Boom" + Received: "An unexpected +error occurred while +processing your request." + +   35 | +expect(res.statusCo +de).toBe(500[ +39m); +  36 | expe +ct(res.body.[ +39mtitle).toBe([32 +m'Internal Server +Error'); + +> 37 +| expect(res.[ +39mbody.detail)[33 +m.toBe('Boom') +; +  | + +^ +  38 | +}); +  39 | +}); + + at Object.toBe +(tests/app.test.js:37:29) + +FAIL tests/unit/asyncHandler. +test.js + ΓùÅ Console + + console.error + Unhandled Error: +Error: Test error + at C:\Users\pc\Docu +ments\waves\Liquifact-backend +\tests\unit\asyncHandler.test +.js:27:17 + at fn (C:\Users\pc\ +Documents\waves\Liquifact-bac +kend\src\utils\asyncHandler.j +s:10:21) + at +Layer.handleRequest (C:\Users +\pc\Documents\waves\Liquifact +-backend\node_modules\router\ +lib\layer.js:152:17) + at next (C:\Users\p +c\Documents\waves\Liquifact-b +ackend\node_modules\router\li +b\route.js:157:13) + at Route.dispatch ( +C:\Users\pc\Documents\waves\L +iquifact-backend\node_modules +\router\lib\route.js:117:3) + at handle (C:\Users +\pc\Documents\waves\Liquifact +-backend\node_modules\router\ +index.js:435:11) + at +Layer.handleRequest (C:\Users +\pc\Documents\waves\Liquifact +-backend\node_modules\router\ +lib\layer.js:152:17) + at C:\Users\pc\Docu +ments\waves\Liquifact-backend +\node_modules\router\index.js +:295:15 + at processParams (C +:\Users\pc\Documents\waves\Li +quifact-backend\node_modules\ +router\index.js:582:12) + at next (C:\Users\p +c\Documents\waves\Liquifact-b +ackend\node_modules\router\in +dex.js:291:5) + at read (C:\Users\p +c\Documents\waves\Liquifact-b +ackend\node_modules\body-pars +er\lib\read.js:53:5) + at jsonParser (C:\U +sers\pc\Documents\waves\Liqui +fact-backend\node_modules\bod +y-parser\lib\types\json.js:88 +:5) + at +Layer.handleRequest (C:\Users +\pc\Documents\waves\Liquifact +-backend\node_modules\router\ +lib\layer.js:152:17) + at trimPrefix (C:\U +sers\pc\Documents\waves\Liqui +fact-backend\node_modules\rou +ter\index.js:342:13) + at C:\Users\pc\Docu +ments\waves\Liquifact-backend +\node_modules\router\index.js +:297:9 + at processParams (C +:\Users\pc\Documents\waves\Li +quifact-backend\node_modules\ +router\index.js:582:12) + at next (C:\Users\p +c\Documents\waves\Liquifact-b +ackend\node_modules\router\in +dex.js:291:5) + at Function.handle +(C:\Users\pc\Documents\waves\ +Liquifact-backend\node_module +s\router\index.js:186:3) + at Function.handle +(C:\Users\pc\Documents\waves\ +Liquifact-backend\node_module +s\express\lib\application.js: +177:15) + at Server.app (C:\U +sers\pc\Documents\waves\Liqui +fact-backend\node_modules\exp +ress\lib\express.js:38:9) + at Server.emit +(node:events:519:28) + at +parserOnIncoming +(node:_http_server:1186:12) + at HTTPParser.parse +rOnHeadersComplete +(node:_http_common:122:17) + +   25 | } +else { +  26 | +// If it's an unknown +error, provide a fallback +500 status (or use +err.status/statusCode if +available) + +> 27 +| console. +error('Unhandled +Error:', +err); +  | + ^ +  28 | +  29 | +// Some libraries use +status or statusCode +properties (like +http-errors) +  30 | +const status += +err.status +|| +err.statusCode +|| +500; + + at error (src/middlewar +e/errorHandler.js:27:13) + at Layer.handleError (n +ode_modules/router/lib/layer. +js:116:17) + at trimPrefix (node_mod +ules/router/index.js:340:13) + at node_modules/router/ +index.js:297:9 + at processParams (node_ +modules/router/index.js:582:1 +2) + at next (node_modules/r +outer/index.js:291:5) + at next (node_modules/r +outer/lib/route.js:132:14) + + console.error + Unhandled Error: +Error: Rejected + at C:\Users\pc\Docu +ments\waves\Liquifact-backend +\tests\unit\asyncHandler.test +.js:43:49 + at fn (C:\Users\pc\ +Documents\waves\Liquifact-bac +kend\src\utils\asyncHandler.j +s:10:21) + at +Layer.handleRequest (C:\Users +\pc\Documents\waves\Liquifact +-backend\node_modules\router\ +lib\layer.js:152:17) + at next (C:\Users\p +c\Documents\waves\Liquifact-b +ackend\node_modules\router\li +b\route.js:157:13) + at Route.dispatch ( +C:\Users\pc\Documents\waves\L +iquifact-backend\node_modules +\router\lib\route.js:117:3) + at handle (C:\Users +\pc\Documents\waves\Liquifact +-backend\node_modules\router\ +index.js:435:11) + at +Layer.handleRequest (C:\Users +\pc\Documents\waves\Liquifact +-backend\node_modules\router\ +lib\layer.js:152:17) + at C:\Users\pc\Docu +ments\waves\Liquifact-backend +\node_modules\router\index.js +:295:15 + at processParams (C +:\Users\pc\Documents\waves\Li +quifact-backend\node_modules\ +router\index.js:582:12) + at next (C:\Users\p +c\Documents\waves\Liquifact-b +ackend\node_modules\router\in +dex.js:291:5) + at read (C:\Users\p +c\Documents\waves\Liquifact-b +ackend\node_modules\body-pars +er\lib\read.js:53:5) + at jsonParser (C:\U +sers\pc\Documents\waves\Liqui +fact-backend\node_modules\bod +y-parser\lib\types\json.js:88 +:5) + at +Layer.handleRequest (C:\Users +\pc\Documents\waves\Liquifact +-backend\node_modules\router\ +lib\layer.js:152:17) + at trimPrefix (C:\U +sers\pc\Documents\waves\Liqui +fact-backend\node_modules\rou +ter\index.js:342:13) + at C:\Users\pc\Docu +ments\waves\Liquifact-backend +\node_modules\router\index.js +:297:9 + at processParams (C +:\Users\pc\Documents\waves\Li +quifact-backend\node_modules\ +router\index.js:582:12) + at next (C:\Users\p +c\Documents\waves\Liquifact-b +ackend\node_modules\router\in +dex.js:291:5) + at Function.handle +(C:\Users\pc\Documents\waves\ +Liquifact-backend\node_module +s\router\index.js:186:3) + at Function.handle +(C:\Users\pc\Documents\waves\ +Liquifact-backend\node_module +s\express\lib\application.js: +177:15) + at Server.app (C:\U +sers\pc\Documents\waves\Liqui +fact-backend\node_modules\exp +ress\lib\express.js:38:9) + at Server.emit +(node:events:519:28) + at +parserOnIncoming +(node:_http_server:1186:12) + at HTTPParser.parse +rOnHeadersComplete +(node:_http_common:122:17) + +   25 | } +else { +  26 | +// If it's an unknown +error, provide a fallback +500 status (or use +err.status/statusCode if +available) + +> 27 +| console. +error('Unhandled +Error:', +err); +  | + ^ +  28 | +  29 | +// Some libraries use +status or statusCode +properties (like +http-errors) +  30 | +const status += +err.status +|| +err.statusCode +|| +500; + + at error (src/middlewar +e/errorHandler.js:27:13) + at Layer.handleError (n +ode_modules/router/lib/layer. +js:116:17) + at trimPrefix (node_mod +ules/router/index.js:340:13) + at node_modules/router/ +index.js:297:9 + at processParams (node_ +modules/router/index.js:582:1 +2) + at next (node_modules/r +outer/index.js:291:5) + at next (node_modules/r +outer/lib/route.js:132:14) + + ΓùÅ asyncHandler utility +ΓÇ║ should catch async +errors and pass to error +handler + + expect(received).toBe(exp +ected) // Object.is equality + + Expected: "Test error" + Received: "An unexpected +error occurred while +processing your request." + +   34 | +expect(res.statusCo +de).toBe(500[ +39m); +  35 | expe +ct(res.body.[ +39mtitle).toBe([32 +m'Internal Server +Error'); + +> 36 +| expect(res.[ +39mbody.detail)[33 +m.toBe('Test +error'); +  | + +^ +  37 | +}); +  38 | +  39 | +it('should handle +rejected +promises', +async () +=> { + + at Object.toBe (tests/u +nit/asyncHandler.test.js:36:2 +9) + +FAIL +src/tests/response.test.js + ΓùÅ Console + + console.log + [dotenv@17.3.1] +injecting env (0) from .env +-- tip: ≡ƒöÉ prevent +committing .env to code: +https://dotenvx.com/precommit + + at _log (node_modules/d +otenv/lib/main.js:139:11) + + ΓùÅ Standard Response +Envelope (Issue 19) ΓÇ║ +Success response should have +data, meta, and error=null + + TypeError: app.address +is not a function + +   4 | +describe('Standard +Response Envelope (Issue +19)', () +=> { +  5 | +it('Success response +should have data, meta, and +error=null', +async () +=> { + +> 6 +| const +res = +await request(app) +[33m.get( +'/health'); +  | + +^ +  7 | expec +t(res.status). +toBe(200) +; +  8 | expec +t(res.body).[ +39mtoHaveProperty('data' +); +  9 | expec +t(res.body).[ +39mtoHaveProperty('meta' +); + + at Test.serverAddress ( +node_modules/supertest/lib/te +st.js:61:22) + at new Test (node_modul +es/supertest/lib/test.js:49:1 +4) + at +Object.obj. [as +get] (node_modules/supertest/ +index.js:40:18) + at Object.get (src/test +s/response.test.js:6:36) + + ΓùÅ Standard Response +Envelope (Issue 19) ΓÇ║ +Error response should have +data=null, meta, and error +object + + TypeError: app.address +is not a function + +   15 | +  16 | +it('Error response +should have data=null, meta, +and error +object', +async () +=> { + +> 17 +| const +res = +await request(app) +[33m.get( +'/not-found-route') +; +  | + +^ +  18 | expe +ct(res.status) +.toBe(404)[33 +m; +  19 | expe +ct(res.body). +[39mtoHaveProperty('data +'); +  20 | expe +ct(res.body.[ +39mdata).toBeNull() +; + + at Test.serverAddress ( +node_modules/supertest/lib/te +st.js:61:22) + at new Test (node_modul +es/supertest/lib/test.js:49:1 +4) + at +Object.obj. [as +get] (node_modules/supertest/ +index.js:40:18) + at Object.get (src/test +s/response.test.js:17:36) + + ΓùÅ Standard Response +Envelope (Issue 19) ΓÇ║ POST +/api/invoices should return +201 and standardized success +envelope + + TypeError: app.address +is not a function + +   26 | +  27 | +it('POST /api/invoices +should return 201 and +standardized success +envelope', +async () +=> { + +> 28 +| const +res = +await request(app) +[33m.post('/api/inv +oices').send({ +}); +  | + +^ +  29 | expe +ct(res.status) +.toBe(201)[33 +m; +  30 | expe +ct(res.body.[ +39mdata.id).[ +39mtoBe('placeholder'[3 +9m); +  31 | expe +ct(res.body.[ +39merror).toBeNull( +); + + at Test.serverAddress ( +node_modules/supertest/lib/te +st.js:61:22) + at new Test (node_modul +es/supertest/lib/test.js:49:1 +4) + at +Object.obj. [as +post] (node_modules/supertest +/index.js:40:18) + at Object.post (src/tes +ts/response.test.js:28:36) + + ΓùÅ Standard Response +Envelope (Issue 19) ΓÇ║ All +routes should return +standard response format + + TypeError: app.address +is not a function + +   35 | +const routes += +['/api', +'/api/invoices'[33 +m, '/api/escrow/123 +']; +  36 | +for +(const route +of routes) { + +> 37 +| const +res = +await request(app) +[33m.get(route +); +  | + +^ +  38 | ex +pect(res.status)[3 +3m.toBe(200)[ +33m; +  39 | ex +pect(res.body) +.toHaveProperty('da +ta'); +  40 | ex +pect(res.body) +.toHaveProperty('me +ta'); + + at Test.serverAddress ( +node_modules/supertest/lib/te +st.js:61:22) + at new Test (node_modul +es/supertest/lib/test.js:49:1 +4) + at +Object.obj. [as +get] (node_modules/supertest/ +index.js:40:18) + at Object.get (src/test +s/response.test.js:37:38) + + ΓùÅ Standard Response +Envelope (Issue 19) ΓÇ║ GET +/debug/error should return +500 and standardized +internal error + + TypeError: app.address +is not a function + +   46 | +it('GET /debug/error +should return 500 and +standardized internal +error', +async () +=> { +  47 | proc +ess.env. +[33mNODE_ENV += 'production' +; + +> 48 +| const +res = +await request(app) +[33m.get( +'/debug/error');[3 +9m +  | + +^ +  49 | expe +ct(res.status) +.toBe(500)[33 +m; +  50 | expe +ct(res.body.[ +39merror.message)[ +33m.toBe('Internal +Server +Error'); +  51 | expe +ct(res.body.[ +39merror.details)[ +33m.toBeNull();[39 +m + + at Test.serverAddress ( +node_modules/supertest/lib/te +st.js:61:22) + at new Test (node_modul +es/supertest/lib/test.js:49:1 +4) + at +Object.obj. [as +get] (node_modules/supertest/ +index.js:40:18) + at Object.get (src/test +s/response.test.js:48:36) + + ΓùÅ Standard Response +Envelope (Issue 19) ΓÇ║ +Internal server errors +should return stack trace in +development + + TypeError: app.address +is not a function + +   54 | +it('Internal server +errors should return stack +trace in +development', +async () +=> { +  55 | proc +ess.env. +[33mNODE_ENV += 'development +'; + +> 56 +| const +res = +await request(app) +[33m.get( +'/debug/error');[3 +9m +  | + +^ +  57 | expe +ct(res.status) +.toBe(500)[33 +m; +  58 | expe +ct(res.body.[ +39merror.details)[ +33m.toContain('Erro +r: Triggered +Error'); +  59 | +}); + + at Test.serverAddress ( +node_modules/supertest/lib/te +st.js:61:22) + at new Test (node_modul +es/supertest/lib/test.js:49:1 +4) + at +Object.obj. [as +get] (node_modules/supertest/ +index.js:40:18) + at Object.get (src/test +s/response.test.js:56:36) + + ΓùÅ Standard Response +Envelope (Issue 19) ΓÇ║ +Internal server errors +should return standard error +envelope (e.g. malformed +JSON) + + TypeError: app.address +is not a function + +   61 | +it('Internal server +errors should return +standard error envelope +(e.g. malformed +JSON)', +async () +=> { +  62 | +const res += await +request(app) + +> 63 +| .post( +'/api/invoices') +  | +^ +  64 | [ +33m.set(' +Content-Type', + +'application/json') +  65 | [ +33m.send('{"invalid +": json}'); +// Malformed JSON +  66 | + + at Test.serverAddress ( +node_modules/supertest/lib/te +st.js:61:22) + at new Test (node_modul +es/supertest/lib/test.js:49:1 +4) + at +Object.obj. [as +post] (node_modules/supertest +/index.js:40:18) + at Object.post (src/tes +ts/response.test.js:63:8) + +FAIL src/app.test.js + ΓùÅ Console + + console.log + [dotenv@17.3.1] +injecting env (0) from .env +-- tip: ≡ƒöÉ prevent +building .env in docker: +https://dotenvx.com/prebuild + + at _log (node_modules/d +otenv/lib/main.js:139:11) + + console.error + Unhandled Error: +TypeError: Cannot read +properties of undefined +(reading 'remoteAddress') + at getSocketAddr (C +:\Users\pc\Documents\waves\Li +quifact-backend\node_modules\ +forwarded\index.js:49:22) + at forwarded (C:\Us +ers\pc\Documents\waves\Liquif +act-backend\node_modules\forw +arded\index.js:31:20) + at alladdrs (C:\Use +rs\pc\Documents\waves\Liquifa +ct-backend\node_modules\proxy +-addr\index.js:57:15) + at proxyaddr (C:\Us +ers\pc\Documents\waves\Liquif +act-backend\node_modules\prox +y-addr\index.js:231:15) + at +IncomingMessage.ip (C:\Users\ +pc\Documents\waves\Liquifact- +backend\node_modules\express\ +lib\request.js:329:10) + at Object.ip [as +keyGenerator] (C:\Users\pc\Do +cuments\waves\Liquifact-backe +nd\src\middleware\rateLimit.j +s:27:66) + at C:\Users\pc\Docu +ments\waves\Liquifact-backend +\node_modules\express-rate-li +mit\dist\index.cjs:849:32 + at +processTicksAndRejections (no +de:internal/process/task_queu +es:105:5) + at C:\Users\pc\Docu +ments\waves\Liquifact-backend +\node_modules\express-rate-li +mit\dist\index.cjs:830:5 + +   25 | } +else { +  26 | +// If it's an unknown +error, provide a fallback +500 status (or use +err.status/statusCode if +available) + +> 27 +| console. +error('Unhandled +Error:', +err); +  | + ^ +  28 | +  29 | +// Some libraries use +status or statusCode +properties (like +http-errors) +  30 | +const status += +err.status +|| +err.statusCode +|| +500; + + at error (src/middlewar +e/errorHandler.js:27:13) + at Layer.handleError (n +ode_modules/router/lib/layer. +js:116:17) + at trimPrefix (node_mod +ules/router/index.js:340:13) + at node_modules/router/ +index.js:297:9 + at processParams (node_ +modules/router/index.js:582:1 +2) + at next (node_modules/r +outer/index.js:291:5) + at next (src/middleware +/bodySizeLimits.js:177:3) + at Layer.handleError (n +ode_modules/router/lib/layer. +js:116:17) + at trimPrefix (node_mod +ules/router/index.js:340:13) + at node_modules/router/ +index.js:297:9 + at processParams (node_ +modules/router/index.js:582:1 +2) + at next (node_modules/r +outer/index.js:291:5) + at next +(src/app.js:176:5) + at Layer.handleError (n +ode_modules/router/lib/layer. +js:116:17) + at trimPrefix (node_mod +ules/router/index.js:340:13) + at node_modules/router/ +index.js:297:9 + at processParams (node_ +modules/router/index.js:582:1 +2) + at next (node_modules/r +outer/index.js:291:5) + at Layer.handleError (n +ode_modules/router/lib/layer. +js:111:12) + at trimPrefix (node_mod +ules/router/index.js:340:13) + at node_modules/router/ +index.js:297:9 + at processParams (node_ +modules/router/index.js:582:1 +2) + at next (node_modules/r +outer/index.js:291:5) + at node_modules/express +-rate-limit/dist/index.cjs:83 +0:5 + + console.error + Unhandled Error: +TypeError: Cannot read +properties of undefined +(reading 'remoteAddress') + at getSocketAddr (C +:\Users\pc\Documents\waves\Li +quifact-backend\node_modules\ +forwarded\index.js:49:22) + at forwarded (C:\Us +ers\pc\Documents\waves\Liquif +act-backend\node_modules\forw +arded\index.js:31:20) + at alladdrs (C:\Use +rs\pc\Documents\waves\Liquifa +ct-backend\node_modules\proxy +-addr\index.js:57:15) + at proxyaddr (C:\Us +ers\pc\Documents\waves\Liquif +act-backend\node_modules\prox +y-addr\index.js:231:15) + at +IncomingMessage.ip (C:\Users\ +pc\Documents\waves\Liquifact- +backend\node_modules\express\ +lib\request.js:329:10) + at Object.ip [as +keyGenerator] (C:\Users\pc\Do +cuments\waves\Liquifact-backe +nd\src\middleware\rateLimit.j +s:27:66) + at C:\Users\pc\Docu +ments\waves\Liquifact-backend +\node_modules\express-rate-li +mit\dist\index.cjs:849:32 + at +processTicksAndRejections (no +de:internal/process/task_queu +es:105:5) + at C:\Users\pc\Docu +ments\waves\Liquifact-backend +\node_modules\express-rate-li +mit\dist\index.cjs:830:5 + +   25 | } +else { +  26 | +// If it's an unknown +error, provide a fallback +500 status (or use +err.status/statusCode if +available) + +> 27 +| console. +error('Unhandled +Error:', +err); +  | + ^ +  28 | +  29 | +// Some libraries use +status or statusCode +properties (like +http-errors) +  30 | +const status += +err.status +|| +err.statusCode +|| +500; + + at error (src/middlewar +e/errorHandler.js:27:13) + at Layer.handleError (n +ode_modules/router/lib/layer. +js:116:17) + at trimPrefix (node_mod +ules/router/index.js:340:13) + at node_modules/router/ +index.js:297:9 + at processParams (node_ +modules/router/index.js:582:1 +2) + at next (node_modules/r +outer/index.js:291:5) + at next (src/middleware +/bodySizeLimits.js:177:3) + at Layer.handleError (n +ode_modules/router/lib/layer. +js:116:17) + at trimPrefix (node_mod +ules/router/index.js:340:13) + at node_modules/router/ +index.js:297:9 + at processParams (node_ +modules/router/index.js:582:1 +2) + at next (node_modules/r +outer/index.js:291:5) + at next +(src/app.js:176:5) + at Layer.handleError (n +ode_modules/router/lib/layer. +js:116:17) + at trimPrefix (node_mod +ules/router/index.js:340:13) + at node_modules/router/ +index.js:297:9 + at processParams (node_ +modules/router/index.js:582:1 +2) + at next (node_modules/r +outer/index.js:291:5) + at Layer.handleError (n +ode_modules/router/lib/layer. +js:111:12) + at trimPrefix (node_mod +ules/router/index.js:340:13) + at node_modules/router/ +index.js:297:9 + at processParams (node_ +modules/router/index.js:582:1 +2) + at next (node_modules/r +outer/index.js:291:5) + at node_modules/express +-rate-limit/dist/index.cjs:83 +0:5 + + console.error + Unhandled Error: +TypeError: Cannot read +properties of undefined +(reading 'remoteAddress') + at getSocketAddr (C +:\Users\pc\Documents\waves\Li +quifact-backend\node_modules\ +forwarded\index.js:49:22) + at forwarded (C:\Us +ers\pc\Documents\waves\Liquif +act-backend\node_modules\forw +arded\index.js:31:20) + at alladdrs (C:\Use +rs\pc\Documents\waves\Liquifa +ct-backend\node_modules\proxy +-addr\index.js:57:15) + at proxyaddr (C:\Us +ers\pc\Documents\waves\Liquif +act-backend\node_modules\prox +y-addr\index.js:231:15) + at +IncomingMessage.ip (C:\Users\ +pc\Documents\waves\Liquifact- +backend\node_modules\express\ +lib\request.js:329:10) + at Object.ip [as +keyGenerator] (C:\Users\pc\Do +cuments\waves\Liquifact-backe +nd\src\middleware\rateLimit.j +s:27:66) + at C:\Users\pc\Docu +ments\waves\Liquifact-backend +\node_modules\express-rate-li +mit\dist\index.cjs:849:32 + at +processTicksAndRejections (no +de:internal/process/task_queu +es:105:5) + at C:\Users\pc\Docu +ments\waves\Liquifact-backend +\node_modules\express-rate-li +mit\dist\index.cjs:830:5 + +   25 | } +else { +  26 | +// If it's an unknown +error, provide a fallback +500 status (or use +err.status/statusCode if +available) + +> 27 +| console. +error('Unhandled +Error:', +err); +  | + ^ +  28 | +  29 | +// Some libraries use +status or statusCode +properties (like +http-errors) +  30 | +const status += +err.status +|| +err.statusCode +|| +500; + + at error (src/middlewar +e/errorHandler.js:27:13) + at Layer.handleError (n +ode_modules/router/lib/layer. +js:116:17) + at trimPrefix (node_mod +ules/router/index.js:340:13) + at node_modules/router/ +index.js:297:9 + at processParams (node_ +modules/router/index.js:582:1 +2) + at next (node_modules/r +outer/index.js:291:5) + at next (src/middleware +/bodySizeLimits.js:177:3) + at Layer.handleError (n +ode_modules/router/lib/layer. +js:116:17) + at trimPrefix (node_mod +ules/router/index.js:340:13) + at node_modules/router/ +index.js:297:9 + at processParams (node_ +modules/router/index.js:582:1 +2) + at next (node_modules/r +outer/index.js:291:5) + at next +(src/app.js:176:5) + at Layer.handleError (n +ode_modules/router/lib/layer. +js:116:17) + at trimPrefix (node_mod +ules/router/index.js:340:13) + at node_modules/router/ +index.js:297:9 + at processParams (node_ +modules/router/index.js:582:1 +2) + at next (node_modules/r +outer/index.js:291:5) + at Layer.handleError (n +ode_modules/router/lib/layer. +js:111:12) + at trimPrefix (node_mod +ules/router/index.js:340:13) + at node_modules/router/ +index.js:297:9 + at processParams (node_ +modules/router/index.js:582:1 +2) + at next (node_modules/r +outer/index.js:291:5) + at node_modules/express +-rate-limit/dist/index.cjs:83 +0:5 + + console.error + Unhandled Error: +TypeError: Cannot read +properties of undefined +(reading 'remoteAddress') + at getSocketAddr (C +:\Users\pc\Documents\waves\Li +quifact-backend\node_modules\ +forwarded\index.js:49:22) + at forwarded (C:\Us +ers\pc\Documents\waves\Liquif +act-backend\node_modules\forw +arded\index.js:31:20) + at alladdrs (C:\Use +rs\pc\Documents\waves\Liquifa +ct-backend\node_modules\proxy +-addr\index.js:57:15) + at proxyaddr (C:\Us +ers\pc\Documents\waves\Liquif +act-backend\node_modules\prox +y-addr\index.js:231:15) + at +IncomingMessage.ip (C:\Users\ +pc\Documents\waves\Liquifact- +backend\node_modules\express\ +lib\request.js:329:10) + at Object.ip [as +keyGenerator] (C:\Users\pc\Do +cuments\waves\Liquifact-backe +nd\src\middleware\rateLimit.j +s:27:66) + at C:\Users\pc\Docu +ments\waves\Liquifact-backend +\node_modules\express-rate-li +mit\dist\index.cjs:849:32 + at +processTicksAndRejections (no +de:internal/process/task_queu +es:105:5) + at C:\Users\pc\Docu +ments\waves\Liquifact-backend +\node_modules\express-rate-li +mit\dist\index.cjs:830:5 + +   25 | } +else { +  26 | +// If it's an unknown +error, provide a fallback +500 status (or use +err.status/statusCode if +available) + +> 27 +| console. +error('Unhandled +Error:', +err); +  | + ^ +  28 | +  29 | +// Some libraries use +status or statusCode +properties (like +http-errors) +  30 | +const status += +err.status +|| +err.statusCode +|| +500; + + at error (src/middlewar +e/errorHandler.js:27:13) + at Layer.handleError (n +ode_modules/router/lib/layer. +js:116:17) + at trimPrefix (node_mod +ules/router/index.js:340:13) + at node_modules/router/ +index.js:297:9 + at processParams (node_ +modules/router/index.js:582:1 +2) + at next (node_modules/r +outer/index.js:291:5) + at next (src/middleware +/bodySizeLimits.js:177:3) + at Layer.handleError (n +ode_modules/router/lib/layer. +js:116:17) + at trimPrefix (node_mod +ules/router/index.js:340:13) + at node_modules/router/ +index.js:297:9 + at processParams (node_ +modules/router/index.js:582:1 +2) + at next (node_modules/r +outer/index.js:291:5) + at next +(src/app.js:176:5) + at Layer.handleError (n +ode_modules/router/lib/layer. +js:116:17) + at trimPrefix (node_mod +ules/router/index.js:340:13) + at node_modules/router/ +index.js:297:9 + at processParams (node_ +modules/router/index.js:582:1 +2) + at next (node_modules/r +outer/index.js:291:5) + at Layer.handleError (n +ode_modules/router/lib/layer. +js:111:12) + at trimPrefix (node_mod +ules/router/index.js:340:13) + at node_modules/router/ +index.js:297:9 + at processParams (node_ +modules/router/index.js:582:1 +2) + at next (node_modules/r +outer/index.js:291:5) + at node_modules/express +-rate-limit/dist/index.cjs:83 +0:5 + + console.error + Unhandled Error: +TypeError: Cannot read +properties of undefined +(reading 'remoteAddress') + at getSocketAddr (C +:\Users\pc\Documents\waves\Li +quifact-backend\node_modules\ +forwarded\index.js:49:22) + at forwarded (C:\Us +ers\pc\Documents\waves\Liquif +act-backend\node_modules\forw +arded\index.js:31:20) + at alladdrs (C:\Use +rs\pc\Documents\waves\Liquifa +ct-backend\node_modules\proxy +-addr\index.js:57:15) + at proxyaddr (C:\Us +ers\pc\Documents\waves\Liquif +act-backend\node_modules\prox +y-addr\index.js:231:15) + at +IncomingMessage.ip (C:\Users\ +pc\Documents\waves\Liquifact- +backend\node_modules\express\ +lib\request.js:329:10) + at Object.ip [as +keyGenerator] (C:\Users\pc\Do +cuments\waves\Liquifact-backe +nd\src\middleware\rateLimit.j +s:27:66) + at C:\Users\pc\Docu +ments\waves\Liquifact-backend +\node_modules\express-rate-li +mit\dist\index.cjs:849:32 + at +processTicksAndRejections (no +de:internal/process/task_queu +es:105:5) + at C:\Users\pc\Docu +ments\waves\Liquifact-backend +\node_modules\express-rate-li +mit\dist\index.cjs:830:5 + +   25 | } +else { +  26 | +// If it's an unknown +error, provide a fallback +500 status (or use +err.status/statusCode if +available) + +> 27 +| console. +error('Unhandled +Error:', +err); +  | + ^ +  28 | +  29 | +// Some libraries use +status or statusCode +properties (like +http-errors) +  30 | +const status += +err.status +|| +err.statusCode +|| +500; + + at error (src/middlewar +e/errorHandler.js:27:13) + at Layer.handleError (n +ode_modules/router/lib/layer. +js:116:17) + at trimPrefix (node_mod +ules/router/index.js:340:13) + at node_modules/router/ +index.js:297:9 + at processParams (node_ +modules/router/index.js:582:1 +2) + at next (node_modules/r +outer/index.js:291:5) + at next (src/middleware +/bodySizeLimits.js:177:3) + at Layer.handleError (n +ode_modules/router/lib/layer. +js:116:17) + at trimPrefix (node_mod +ules/router/index.js:340:13) + at node_modules/router/ +index.js:297:9 + at processParams (node_ +modules/router/index.js:582:1 +2) + at next (node_modules/r +outer/index.js:291:5) + at next +(src/app.js:176:5) + at Layer.handleError (n +ode_modules/router/lib/layer. +js:116:17) + at trimPrefix (node_mod +ules/router/index.js:340:13) + at node_modules/router/ +index.js:297:9 + at processParams (node_ +modules/router/index.js:582:1 +2) + at next (node_modules/r +outer/index.js:291:5) + at Layer.handleError (n +ode_modules/router/lib/layer. +js:111:12) + at trimPrefix (node_mod +ules/router/index.js:340:13) + at node_modules/router/ +index.js:297:9 + at processParams (node_ +modules/router/index.js:582:1 +2) + at next (node_modules/r +outer/index.js:291:5) + at node_modules/express +-rate-limit/dist/index.cjs:83 +0:5 + + console.error + Unhandled Error: +TypeError: Cannot read +properties of undefined +(reading 'remoteAddress') + at getSocketAddr (C +:\Users\pc\Documents\waves\Li +quifact-backend\node_modules\ +forwarded\index.js:49:22) + at forwarded (C:\Us +ers\pc\Documents\waves\Liquif +act-backend\node_modules\forw +arded\index.js:31:20) + at alladdrs (C:\Use +rs\pc\Documents\waves\Liquifa +ct-backend\node_modules\proxy +-addr\index.js:57:15) + at proxyaddr (C:\Us +ers\pc\Documents\waves\Liquif +act-backend\node_modules\prox +y-addr\index.js:231:15) + at +IncomingMessage.ip (C:\Users\ +pc\Documents\waves\Liquifact- +backend\node_modules\express\ +lib\request.js:329:10) + at Object.ip [as +keyGenerator] (C:\Users\pc\Do +cuments\waves\Liquifact-backe +nd\src\middleware\rateLimit.j +s:27:66) + at C:\Users\pc\Docu +ments\waves\Liquifact-backend +\node_modules\express-rate-li +mit\dist\index.cjs:849:32 + at +processTicksAndRejections (no +de:internal/process/task_queu +es:105:5) + at C:\Users\pc\Docu +ments\waves\Liquifact-backend +\node_modules\express-rate-li +mit\dist\index.cjs:830:5 + +   25 | } +else { +  26 | +// If it's an unknown +error, provide a fallback +500 status (or use +err.status/statusCode if +available) + +> 27 +| console. +error('Unhandled +Error:', +err); +  | + ^ +  28 | +  29 | +// Some libraries use +status or statusCode +properties (like +http-errors) +  30 | +const status += +err.status +|| +err.statusCode +|| +500; + + at error (src/middlewar +e/errorHandler.js:27:13) + at Layer.handleError (n +ode_modules/router/lib/layer. +js:116:17) + at trimPrefix (node_mod +ules/router/index.js:340:13) + at node_modules/router/ +index.js:297:9 + at processParams (node_ +modules/router/index.js:582:1 +2) + at next (node_modules/r +outer/index.js:291:5) + at next (src/middleware +/bodySizeLimits.js:177:3) + at Layer.handleError (n +ode_modules/router/lib/layer. +js:116:17) + at trimPrefix (node_mod +ules/router/index.js:340:13) + at node_modules/router/ +index.js:297:9 + at processParams (node_ +modules/router/index.js:582:1 +2) + at next (node_modules/r +outer/index.js:291:5) + at next +(src/app.js:176:5) + at Layer.handleError (n +ode_modules/router/lib/layer. +js:116:17) + at trimPrefix (node_mod +ules/router/index.js:340:13) + at node_modules/router/ +index.js:297:9 + at processParams (node_ +modules/router/index.js:582:1 +2) + at next (node_modules/r +outer/index.js:291:5) + at Layer.handleError (n +ode_modules/router/lib/layer. +js:111:12) + at trimPrefix (node_mod +ules/router/index.js:340:13) + at node_modules/router/ +index.js:297:9 + at processParams (node_ +modules/router/index.js:582:1 +2) + at next (node_modules/r +outer/index.js:291:5) + at node_modules/express +-rate-limit/dist/index.cjs:83 +0:5 + + console.error + Unhandled Error: +TypeError: Cannot read +properties of undefined +(reading 'remoteAddress') + at getSocketAddr (C +:\Users\pc\Documents\waves\Li +quifact-backend\node_modules\ +forwarded\index.js:49:22) + at forwarded (C:\Us +ers\pc\Documents\waves\Liquif +act-backend\node_modules\forw +arded\index.js:31:20) + at alladdrs (C:\Use +rs\pc\Documents\waves\Liquifa +ct-backend\node_modules\proxy +-addr\index.js:57:15) + at proxyaddr (C:\Us +ers\pc\Documents\waves\Liquif +act-backend\node_modules\prox +y-addr\index.js:231:15) + at +IncomingMessage.ip (C:\Users\ +pc\Documents\waves\Liquifact- +backend\node_modules\express\ +lib\request.js:329:10) + at Object.ip [as +keyGenerator] (C:\Users\pc\Do +cuments\waves\Liquifact-backe +nd\src\middleware\rateLimit.j +s:27:66) + at C:\Users\pc\Docu +ments\waves\Liquifact-backend +\node_modules\express-rate-li +mit\dist\index.cjs:849:32 + at +processTicksAndRejections (no +de:internal/process/task_queu +es:105:5) + at C:\Users\pc\Docu +ments\waves\Liquifact-backend +\node_modules\express-rate-li +mit\dist\index.cjs:830:5 + +   25 | } +else { +  26 | +// If it's an unknown +error, provide a fallback +500 status (or use +err.status/statusCode if +available) + +> 27 +| console. +error('Unhandled +Error:', +err); +  | + ^ +  28 | +  29 | +// Some libraries use +status or statusCode +properties (like +http-errors) +  30 | +const status += +err.status +|| +err.statusCode +|| +500; + + at error (src/middlewar +e/errorHandler.js:27:13) + at Layer.handleError (n +ode_modules/router/lib/layer. +js:116:17) + at trimPrefix (node_mod +ules/router/index.js:340:13) + at node_modules/router/ +index.js:297:9 + at processParams (node_ +modules/router/index.js:582:1 +2) + at next (node_modules/r +outer/index.js:291:5) + at next (src/middleware +/bodySizeLimits.js:177:3) + at Layer.handleError (n +ode_modules/router/lib/layer. +js:116:17) + at trimPrefix (node_mod +ules/router/index.js:340:13) + at node_modules/router/ +index.js:297:9 + at processParams (node_ +modules/router/index.js:582:1 +2) + at next (node_modules/r +outer/index.js:291:5) + at next +(src/app.js:176:5) + at Layer.handleError (n +ode_modules/router/lib/layer. +js:116:17) + at trimPrefix (node_mod +ules/router/index.js:340:13) + at node_modules/router/ +index.js:297:9 + at processParams (node_ +modules/router/index.js:582:1 +2) + at next (node_modules/r +outer/index.js:291:5) + at Layer.handleError (n +ode_modules/router/lib/layer. +js:111:12) + at trimPrefix (node_mod +ules/router/index.js:340:13) + at node_modules/router/ +index.js:297:9 + at processParams (node_ +modules/router/index.js:582:1 +2) + at next (node_modules/r +outer/index.js:291:5) + at node_modules/express +-rate-limit/dist/index.cjs:83 +0:5 + + console.error + Unhandled Error: +TypeError: Cannot read +properties of undefined +(reading 'remoteAddress') + at getSocketAddr (C +:\Users\pc\Documents\waves\Li +quifact-backend\node_modules\ +forwarded\index.js:49:22) + at forwarded (C:\Us +ers\pc\Documents\waves\Liquif +act-backend\node_modules\forw +arded\index.js:31:20) + at alladdrs (C:\Use +rs\pc\Documents\waves\Liquifa +ct-backend\node_modules\proxy +-addr\index.js:57:15) + at proxyaddr (C:\Us +ers\pc\Documents\waves\Liquif +act-backend\node_modules\prox +y-addr\index.js:231:15) + at +IncomingMessage.ip (C:\Users\ +pc\Documents\waves\Liquifact- +backend\node_modules\express\ +lib\request.js:329:10) + at Object.ip [as +keyGenerator] (C:\Users\pc\Do +cuments\waves\Liquifact-backe +nd\src\middleware\rateLimit.j +s:27:66) + at C:\Users\pc\Docu +ments\waves\Liquifact-backend +\node_modules\express-rate-li +mit\dist\index.cjs:849:32 + at +processTicksAndRejections (no +de:internal/process/task_queu +es:105:5) + at C:\Users\pc\Docu +ments\waves\Liquifact-backend +\node_modules\express-rate-li +mit\dist\index.cjs:830:5 + +   25 | } +else { +  26 | +// If it's an unknown +error, provide a fallback +500 status (or use +err.status/statusCode if +available) + +> 27 +| console. +error('Unhandled +Error:', +err); +  | + ^ +  28 | +  29 | +// Some libraries use +status or statusCode +properties (like +http-errors) +  30 | +const status += +err.status +|| +err.statusCode +|| +500; + + at error (src/middlewar +e/errorHandler.js:27:13) + at Layer.handleError (n +ode_modules/router/lib/layer. +js:116:17) + at trimPrefix (node_mod +ules/router/index.js:340:13) + at node_modules/router/ +index.js:297:9 + at processParams (node_ +modules/router/index.js:582:1 +2) + at next (node_modules/r +outer/index.js:291:5) + at next (src/middleware +/bodySizeLimits.js:177:3) + at Layer.handleError (n +ode_modules/router/lib/layer. +js:116:17) + at trimPrefix (node_mod +ules/router/index.js:340:13) + at node_modules/router/ +index.js:297:9 + at processParams (node_ +modules/router/index.js:582:1 +2) + at next (node_modules/r +outer/index.js:291:5) + at next +(src/app.js:176:5) + at Layer.handleError (n +ode_modules/router/lib/layer. +js:116:17) + at trimPrefix (node_mod +ules/router/index.js:340:13) + at node_modules/router/ +index.js:297:9 + at processParams (node_ +modules/router/index.js:582:1 +2) + at next (node_modules/r +outer/index.js:291:5) + at Layer.handleError (n +ode_modules/router/lib/layer. +js:111:12) + at trimPrefix (node_mod +ules/router/index.js:340:13) + at node_modules/router/ +index.js:297:9 + at processParams (node_ +modules/router/index.js:582:1 +2) + at next (node_modules/r +outer/index.js:291:5) + at node_modules/express +-rate-limit/dist/index.cjs:83 +0:5 + + ΓùÅ LiquiFact app +integration ΓÇ║ allows +configured origins for +standard requests + + expect(received).toBe(exp +ected) // Object.is equality + + Expected: 200 + Received: 500 + +   164 | + }); +  165 | + +> +166 | expect(res +ponse.statusCode)[ +33m.toBe(200) +[33m; +  | + +^ +  167 | + expect(response.he +aders['access-control-al +low-origin']). +toBe( +  168 | + 'https://app.example. +com' +  169 | + ); + + at toBe +(src/app.test.js:166:37) + at Object. +(src/app.test.js:155:5) + + ΓùÅ LiquiFact app +integration ΓÇ║ allows +requests without an origin +header + + expect(received).toBe(exp +ected) // Object.is equality + + Expected: 200 + Received: 500 + +   210 | + }); +  211 | + +> +212 | expect(res +ponse.statusCode)[ +33m.toBe(200) +[33m; +  | + +^ +  213 | + expect(response.he +aders['access-control-al +low-origin']). +toBeUndefined(); +  214 | } +  215 | +); + + at toBe +(src/app.test.js:212:37) + at Object. +(src/app.test.js:202:5) + + ΓùÅ LiquiFact app +integration ΓÇ║ allows +localhost origins by default +in development + + expect(received).toBe(exp +ected) // Object.is equality + + Expected: 200 + Received: 500 + +   228 | + }); +  229 | + +> +230 | expect(res +ponse.statusCode)[ +33m.toBe(200) +[33m; +  | + +^ +  231 | + expect(response.he +aders['access-control-al +low-origin']). +toBe( +  232 | + 'http://localhost:300 +0' +  233 | + ); + + at toBe +(src/app.test.js:230:37) + at Object. +(src/app.test.js:219:5) + + ΓùÅ LiquiFact app +integration ΓÇ║ returns API +metadata from /api + + expect(received).toBe(exp +ected) // Object.is equality + + Expected: 200 + Received: 500 + +   261 | + }); +  262 | + +> +263 | expect(respons +e.statusCode). +toBe(200) +; +  | + +^ +  264 | exp +ect(response.body) +[33m.toEqual({ +  265 | +name: +'LiquiFact +API', +  266 | +description: +'Global Invoice +Liquidity Network on +Stellar', + + at Object.toBe +(src/app.test.js:263:33) + + ΓùÅ LiquiFact app +integration ΓÇ║ returns the +invoice list + + expect(received).toBe(exp +ected) // Object.is equality + + Expected: 200 + Received: 500 + +   279 | + }); +  280 | + +> +281 | expect(respons +e.statusCode). +toBe(200) +; +  | + +^ +  282 | exp +ect(response.body) +[33m.toEqual({ +  283 | +data: expect. +[39many(Array) +, +  284 | +message: +'Invoices retrieved succ +essfully.',[0 +m + + at Object.toBe +(src/app.test.js:281:33) + + ΓùÅ LiquiFact app +integration ΓÇ║ returns the +invoice creation placeholder + + expect(received).toBe(exp +ected) // Object.is equality + + Expected: 201 + Received: 500 + +   300 | + }); +  301 | + +> +302 | expect(respons +e.statusCode). +toBe(201) +; +  | + +^ +  303 | exp +ect(response.body[ +33m.data).toHa +veProperty('id')[3 +3m; +  304 | exp +ect(response.body[ +33m.data.custo +mer).toBe('Tes +t'); +  305 | +}); + + at Object.toBe +(src/app.test.js:302:33) + + ΓùÅ LiquiFact app +integration ΓÇ║ returns the +escrow data through the +Soroban wrapper + + expect(received).toBe(exp +ected) // Object.is equality + + Expected: 200 + Received: 500 + +   315 | + }); +  316 | + +> +317 | expect(respons +e.statusCode). +toBe(200) +; +  | + +^ +  318 | exp +ect(response.body) +[33m.toEqual({ +  319 | +data: { +invoiceId: 'in +voice-123', +status: 'not_f +ound', +fundedAmount: +0 }, +  320 | +message: +'Escrow state read from +Soroban contract via robust +integration +wrapper.', + + at Object.toBe +(src/app.test.js:317:33) + + ΓùÅ LiquiFact app +integration ΓÇ║ returns 404 +for unknown routes + + expect(received).toBe(exp +ected) // Object.is equality + + Expected: 404 + Received: 500 + +   327 | + }); +  328 | + +> +329 | expect(respons +e.statusCode). +toBe(404) +; +  | + +^ +  330 | exp +ect(response.body[ +33m.title).toB +e('Resource Not +Found'); +  331 | exp +ect(response.body[ +33m.instance). +toBe('/missing')[3 +3m; +  332 | +}); + + at Object.toBe +(src/app.test.js:329:33) + + ΓùÅ LiquiFact app CORS +middleware behavior ΓÇ║ +allows preflight requests +for allowed origins + + expect(received).toBe(exp +ected) // Object.is equality + + Expected: 204 + Received: 200 + +   360 | +  361 | exp +ect(nextCalled).toB +e(false); + +> +362 | expect(res[33 +m.statusCode). +toBe(204);[39 +m +  | + +^ +  363 | exp +ect(res.getHeader( +[32m'access-control-allow-ori +gin')).toBe([ +32m'https://app.example.com' +[39m); +  364 | +}); +  365 | + + at Object.toBe +(src/app.test.js:362:28) + + ΓùÅ LiquiFact app CORS +middleware behavior ΓÇ║ +passes unrelated errors +through the CORS error +handler + + TypeError: +handleCorsError is not a +function + +   385 | + const next += jest.fn +(); +  386 | + +> +387 | +handleCorsError( +  | +^ +  388 | +new +Error('Other +error'), +  389 | c +reateMockRequest(), +  390 | c +reateMockResponse(),[39 +m + + at +Object.handleCorsError +(src/app.test.js:387:5) + +PASS src/__tests__/rateLimit. +test.js + ΓùÅ Console + + console.log + [dotenv@17.3.1] +injecting env (0) from .env +-- tip: ≡ƒöÉ prevent +committing .env to code: +https://dotenvx.com/precommit + + at _log (node_modules/d +otenv/lib/main.js:139:11) + + console.log + [dotenv@17.3.1] +injecting env (0) from .env +-- tip: ΓÜí∩╕Å secrets for +agents: +https://dotenvx.com/as2 + + at _log (node_modules/d +otenv/lib/main.js:139:11) + +FAIL src/__tests__/invoice.ap +i.test.js + ΓùÅ Console + + console.log + [dotenv@17.3.1] +injecting env (0) from .env +-- tip: ΓÜÖ∩╕Å load +multiple .env files with { +path: ['.env.local', '.env'] +} + + at _log (node_modules/d +otenv/lib/main.js:139:11) + + console.error + Response validation +failed: [ + { + expected: 'string', + code: +'invalid_type', + path: [ 'data', 0, +'status' ], + message: 'Invalid +input: expected string, +received undefined' + }, + { + expected: 'string', + code: +'invalid_type', + path: [ 'data', 1, +'status' ], + message: 'Invalid +input: expected string, +received undefined' + } + ] + +   48 | + } catch +(error) { +  49 | + if (error +instanceof +ZodError) { + +> 50 +| co +nsole.error('R +esponse validation +failed:', erro +r.issues);[39 +m +  | + +^ +  51 | + return +originalJson.call( +[36mthis.statu +s(500), +{ error: +'Internal server error: +Response validation +failed' }); +  52 | + } +  53 | + // In rare +cases where another error +happens, just throw + + at +ServerResponse.error [as +json] (src/middleware/validat +e.js:50:29) + at json +(src/app.js:80:18) + + ΓùÅ Invoice API +Integration ΓÇ║ GET +/api/invoices ΓÇ║ should +return 200 and invoices when +no query params are provided + + expect(received).toBe(exp +ected) // Object.is equality + + Expected: 200 + Received: 500 + +   21 | + const res += await r +equest(app).ge +t('/api/invoices'[ +39m); +  22 | + +> 23 +| expect(res. +statusCode).to +Be(200); +  | + +^ +  24 | ex +pect(res.body. +data).toEqual( +mockInvoices); +  25 | ex +pect(res.body. +message).toBe( +'Invoices retrieved succ +essfully.'); +  26 | ex +pect(invoiceService.[39 +mgetInvoices).toHav +eBeenCalledWith({ + + at Object.toBe (src/__t +ests__/invoice.api.test.js:23 +:30) + +PASS tests/unit/errorHandler. +test.js +PASS src/__tests__/deprecatio +n.test.js +PASS +tests/unit/validators.test.js +FAIL src/index.test.js + ΓùÅ Console + + console.log + [dotenv@17.3.1] +injecting env (0) from .env +-- tip: ΓÜÖ∩╕Å specify +custom .env file path with { +path: '/custom/path/.env' } + + at _log (node_modules/d +otenv/lib/main.js:139:11) + + console.log + [dotenv@17.3.1] +injecting env (0) from .env +-- tip: ≡ƒöÉ encrypt with +Dotenvx: https://dotenvx.com + + at _log (node_modules/d +otenv/lib/main.js:139:11) + + console.warn + LiquiFact API running +at http://localhost:3001 + +   16 | +const startServer += () => { +  17 | +const server += app.lis +ten(PORT, + () => { + +> 18 +| console. +warn(`LiquiFact API +running at http://localhost:$ +{PORT}`); +  | + ^ +  19 | +}); +  20 | +return +server; +  21 | +}; + + at warn +(src/index.js:18:13) + at Function.cb +(src/index.test.js:239:19) + at listen +(src/index.js:17:22) + at Object.startServer +(src/index.test.js:243:22) + + ΓùÅ LiquiFact API ΓÇ║ +Invoices Lifecycle ΓÇ║ POST +/api/invoices - fails if +missing fields + + expect(received).toBe(exp +ected) // Object.is equality + + Expected: 400 + Received: 201 + +   132 | + .set +('Authorization'[3 +3m, `Bearer +${token}`) +  133 | + .send({ +amount: +1000 }); + +> +134 | expect(respo +nse.status).[ +39mtoBe(400); +[39m +  | + +^ +  135 | e +xpect(response.body +).toHaveProperty([ +32m'error'); +  136 | +}); +  137 | + + at Object.toBe +(src/index.test.js:134:31) + + ΓùÅ LiquiFact API ΓÇ║ +Error Handling ΓÇ║ error +handler - returns 500 on +unexpected error + + expect(received).toBe(exp +ected) // Object.is equality + + Expected: 500 + Received: 404 + +   219 | + const +consoleSpy = jest[ +33m.spyOn(console, +[39m 'error'). +mockImplementation(() +=> { }); +  220 | +const response += await r +equest(app).ge +t('/error-test-trig +ger'); + +> +221 | expect(respo +nse.status).[ +39mtoBe(500); +[39m +  | + +^ +  222 | c +onsoleSpy.mockResto +re(); +  223 | +}); +  224 | +}); + + at Object.toBe +(src/index.test.js:221:31) + +PASS src/__tests__/bodySizeLi +mits.test.js + ΓùÅ Console + + console.log + [dotenv@17.3.1] +injecting env (0) from .env +-- tip: ΓÜÖ∩╕Å write to +custom object with { +processEnv: myObject } + + at _log (node_modules/d +otenv/lib/main.js:139:11) + + console.log + [dotenv@17.3.1] +injecting env (0) from .env +-- tip: ≡ƒ¢í∩╕Å auth for +agents: https://vestauth.com + + at _log (node_modules/d +otenv/lib/main.js:139:11) + +PASS tests/unit/queryBuilder. +test.js +PASS src/__tests__/validate.t +est.js +PASS +src/__tests__/auth.test.js + ΓùÅ Console + + console.log + [dotenv@17.3.1] +injecting env (0) from .env +-- tip: ≡ƒöÉ prevent +committing .env to code: +https://dotenvx.com/precommit + + at _log (node_modules/d +otenv/lib/main.js:139:11) + + console.log + [dotenv@17.3.1] +injecting env (0) from .env +-- tip: ≡ƒ¢í∩╕Å auth for +agents: https://vestauth.com + + at _log (node_modules/d +otenv/lib/main.js:139:11) + +PASS tests/unit/invoice.servi +ce.test.js + ΓùÅ Console + + console.error + Error fetching +invoices: Error: DB Error + at +Function. (C:\User +s\pc\Documents\waves\Liquifac +t-backend\tests\unit\invoice. +service.test.js:36:66) + at C:\Users\pc\Docu +ments\waves\Liquifact-backend +\node_modules\jest-mock\build +\index.js:305:39 + at +Function. (C:\User +s\pc\Documents\waves\Liquifac +t-backend\node_modules\jest-m +ock\build\index.js:312:13) + at +Function.mockConstructor [as +then] (C:\Users\pc\Documents\ +waves\Liquifact-backend\node_ +modules\jest-mock\build\index +.js:57:19) + at +processTicksAndRejections (no +de:internal/process/task_queu +es:105:5) + +   42 | +return +await +query; +  43 | } +catch (error) { + +> 44 +| console. +error('Error fetching +invoices:', +error); +  | + ^ +  45 | +throw +new Error +('Database error while +fetching +invoices'); +  46 | } +  47 | } + + at error (src/services/ +invoice.service.js:44:13) + at Object. ( +tests/unit/invoice.service.te +st.js:38:5) + +PASS +src/services/soroban.test.js +PASS src/config/cors.test.js +PASS +tests/unit/AppError.test.js +PASS tests/unit/problemDetail +s.test.js +PASS tests/integration/errorH +andling.test.js + ΓùÅ Console + + console.log + [dotenv@17.3.1] +injecting env (0) from .env +-- tip: ≡ƒöÉ prevent +committing .env to code: +https://dotenvx.com/precommit + + at _log (node_modules/d +otenv/lib/main.js:139:11) + + console.log + [dotenv@17.3.1] +injecting env (0) from .env +-- tip: ΓÜÖ∩╕Å write to +custom object with { +processEnv: myObject } + + at _log (node_modules/d +otenv/lib/main.js:139:11) + +PASS src/utils/retry.test.js + +Summary of all failing tests +FAIL tests/app.test.js + ΓùÅ Async Handler ΓÇ║ +should catch async errors + + expect(received).toBe(exp +ected) // Object.is equality + + Expected: "Boom" + Received: "An unexpected +error occurred while +processing your request." + +   35 | +expect(res.statusCo +de).toBe(500[ +39m); +  36 | expe +ct(res.body.[ +39mtitle).toBe([32 +m'Internal Server +Error'); + +> 37 +| expect(res.[ +39mbody.detail)[33 +m.toBe('Boom') +; +  | + +^ +  38 | +}); +  39 | +}); + + at Object.toBe +(tests/app.test.js:37:29) + +FAIL tests/unit/asyncHandler. +test.js + ΓùÅ asyncHandler utility +ΓÇ║ should catch async +errors and pass to error +handler + + expect(received).toBe(exp +ected) // Object.is equality + + Expected: "Test error" + Received: "An unexpected +error occurred while +processing your request." + +   34 | +expect(res.statusCo +de).toBe(500[ +39m); +  35 | expe +ct(res.body.[ +39mtitle).toBe([32 +m'Internal Server +Error'); + +> 36 +| expect(res.[ +39mbody.detail)[33 +m.toBe('Test +error'); +  | + +^ +  37 | +}); +  38 | +  39 | +it('should handle +rejected +promises', +async () +=> { + + at Object.toBe (tests/u +nit/asyncHandler.test.js:36:2 +9) + +FAIL +src/tests/response.test.js + ΓùÅ Standard Response +Envelope (Issue 19) ΓÇ║ +Success response should have +data, meta, and error=null + + TypeError: app.address +is not a function + +   4 | +describe('Standard +Response Envelope (Issue +19)', () +=> { +  5 | +it('Success response +should have data, meta, and +error=null', +async () +=> { + +> 6 +| const +res = +await request(app) +[33m.get( +'/health'); +  | + +^ +  7 | expec +t(res.status). +toBe(200) +; +  8 | expec +t(res.body).[ +39mtoHaveProperty('data' +); +  9 | expec +t(res.body).[ +39mtoHaveProperty('meta' +); + + at Test.serverAddress ( +node_modules/supertest/lib/te +st.js:61:22) + at new Test (node_modul +es/supertest/lib/test.js:49:1 +4) + at +Object.obj. [as +get] (node_modules/supertest/ +index.js:40:18) + at Object.get (src/test +s/response.test.js:6:36) + + ΓùÅ Standard Response +Envelope (Issue 19) ΓÇ║ +Error response should have +data=null, meta, and error +object + + TypeError: app.address +is not a function + +   15 | +  16 | +it('Error response +should have data=null, meta, +and error +object', +async () +=> { + +> 17 +| const +res = +await request(app) +[33m.get( +'/not-found-route') +; +  | + +^ +  18 | expe +ct(res.status) +.toBe(404)[33 +m; +  19 | expe +ct(res.body). +[39mtoHaveProperty('data +'); +  20 | expe +ct(res.body.[ +39mdata).toBeNull() +; + + at Test.serverAddress ( +node_modules/supertest/lib/te +st.js:61:22) + at new Test (node_modul +es/supertest/lib/test.js:49:1 +4) + at +Object.obj. [as +get] (node_modules/supertest/ +index.js:40:18) + at Object.get (src/test +s/response.test.js:17:36) + + ΓùÅ Standard Response +Envelope (Issue 19) ΓÇ║ POST +/api/invoices should return +201 and standardized success +envelope + + TypeError: app.address +is not a function + +   26 | +  27 | +it('POST /api/invoices +should return 201 and +standardized success +envelope', +async () +=> { + +> 28 +| const +res = +await request(app) +[33m.post('/api/inv +oices').send({ +}); +  | + +^ +  29 | expe +ct(res.status) +.toBe(201)[33 +m; +  30 | expe +ct(res.body.[ +39mdata.id).[ +39mtoBe('placeholder'[3 +9m); +  31 | expe +ct(res.body.[ +39merror).toBeNull( +); + + at Test.serverAddress ( +node_modules/supertest/lib/te +st.js:61:22) + at new Test (node_modul +es/supertest/lib/test.js:49:1 +4) + at +Object.obj. [as +post] (node_modules/supertest +/index.js:40:18) + at Object.post (src/tes +ts/response.test.js:28:36) + + ΓùÅ Standard Response +Envelope (Issue 19) ΓÇ║ All +routes should return +standard response format + + TypeError: app.address +is not a function + +   35 | +const routes += +['/api', +'/api/invoices'[33 +m, '/api/escrow/123 +']; +  36 | +for +(const route +of routes) { + +> 37 +| const +res = +await request(app) +[33m.get(route +); +  | + +^ +  38 | ex +pect(res.status)[3 +3m.toBe(200)[ +33m; +  39 | ex +pect(res.body) +.toHaveProperty('da +ta'); +  40 | ex +pect(res.body) +.toHaveProperty('me +ta'); + + at Test.serverAddress ( +node_modules/supertest/lib/te +st.js:61:22) + at new Test (node_modul +es/supertest/lib/test.js:49:1 +4) + at +Object.obj. [as +get] (node_modules/supertest/ +index.js:40:18) + at Object.get (src/test +s/response.test.js:37:38) + + ΓùÅ Standard Response +Envelope (Issue 19) ΓÇ║ GET +/debug/error should return +500 and standardized +internal error + + TypeError: app.address +is not a function + +   46 | +it('GET /debug/error +should return 500 and +standardized internal +error', +async () +=> { +  47 | proc +ess.env. +[33mNODE_ENV += 'production' +; + +> 48 +| const +res = +await request(app) +[33m.get( +'/debug/error');[3 +9m +  | + +^ +  49 | expe +ct(res.status) +.toBe(500)[33 +m; +  50 | expe +ct(res.body.[ +39merror.message)[ +33m.toBe('Internal +Server +Error'); +  51 | expe +ct(res.body.[ +39merror.details)[ +33m.toBeNull();[39 +m + + at Test.serverAddress ( +node_modules/supertest/lib/te +st.js:61:22) + at new Test (node_modul +es/supertest/lib/test.js:49:1 +4) + at +Object.obj. [as +get] (node_modules/supertest/ +index.js:40:18) + at Object.get (src/test +s/response.test.js:48:36) + + ΓùÅ Standard Response +Envelope (Issue 19) ΓÇ║ +Internal server errors +should return stack trace in +development + + TypeError: app.address +is not a function + +   54 | +it('Internal server +errors should return stack +trace in +development', +async () +=> { +  55 | proc +ess.env. +[33mNODE_ENV += 'development +'; + +> 56 +| const +res = +await request(app) +[33m.get( +'/debug/error');[3 +9m +  | + +^ +  57 | expe +ct(res.status) +.toBe(500)[33 +m; +  58 | expe +ct(res.body.[ +39merror.details)[ +33m.toContain('Erro +r: Triggered +Error'); +  59 | +}); + + at Test.serverAddress ( +node_modules/supertest/lib/te +st.js:61:22) + at new Test (node_modul +es/supertest/lib/test.js:49:1 +4) + at +Object.obj. [as +get] (node_modules/supertest/ +index.js:40:18) + at Object.get (src/test +s/response.test.js:56:36) + + ΓùÅ Standard Response +Envelope (Issue 19) ΓÇ║ +Internal server errors +should return standard error +envelope (e.g. malformed +JSON) + + TypeError: app.address +is not a function + +   61 | +it('Internal server +errors should return +standard error envelope +(e.g. malformed +JSON)', +async () +=> { +  62 | +const res += await +request(app) + +> 63 +| .post( +'/api/invoices') +  | +^ +  64 | [ +33m.set(' +Content-Type', + +'application/json') +  65 | [ +33m.send('{"invalid +": json}'); +// Malformed JSON +  66 | + + at Test.serverAddress ( +node_modules/supertest/lib/te +st.js:61:22) + at new Test (node_modul +es/supertest/lib/test.js:49:1 +4) + at +Object.obj. [as +post] (node_modules/supertest +/index.js:40:18) + at Object.post (src/tes +ts/response.test.js:63:8) + +FAIL src/app.test.js + ΓùÅ LiquiFact app +integration ΓÇ║ allows +configured origins for +standard requests + + expect(received).toBe(exp +ected) // Object.is equality + + Expected: 200 + Received: 500 + +   164 | + }); +  165 | + +> +166 | expect(res +ponse.statusCode)[ +33m.toBe(200) +[33m; +  | + +^ +  167 | + expect(response.he +aders['access-control-al +low-origin']). +toBe( +  168 | + 'https://app.example. +com' +  169 | + ); + + at toBe +(src/app.test.js:166:37) + at Object. +(src/app.test.js:155:5) + + ΓùÅ LiquiFact app +integration ΓÇ║ allows +requests without an origin +header + + expect(received).toBe(exp +ected) // Object.is equality + + Expected: 200 + Received: 500 + +   210 | + }); +  211 | + +> +212 | expect(res +ponse.statusCode)[ +33m.toBe(200) +[33m; +  | + +^ +  213 | + expect(response.he +aders['access-control-al +low-origin']). +toBeUndefined(); +  214 | } +  215 | +); + + at toBe +(src/app.test.js:212:37) + at Object. +(src/app.test.js:202:5) + + ΓùÅ LiquiFact app +integration ΓÇ║ allows +localhost origins by default +in development + + expect(received).toBe(exp +ected) // Object.is equality + + Expected: 200 + Received: 500 + +   228 | + }); +  229 | + +> +230 | expect(res +ponse.statusCode)[ +33m.toBe(200) +[33m; +  | + +^ +  231 | + expect(response.he +aders['access-control-al +low-origin']). +toBe( +  232 | + 'http://localhost:300 +0' +  233 | + ); + + at toBe +(src/app.test.js:230:37) + at Object. +(src/app.test.js:219:5) + + ΓùÅ LiquiFact app +integration ΓÇ║ returns API +metadata from /api + + expect(received).toBe(exp +ected) // Object.is equality + + Expected: 200 + Received: 500 + +   261 | + }); +  262 | + +> +263 | expect(respons +e.statusCode). +toBe(200) +; +  | + +^ +  264 | exp +ect(response.body) +[33m.toEqual({ +  265 | +name: +'LiquiFact +API', +  266 | +description: +'Global Invoice +Liquidity Network on +Stellar', + + at Object.toBe +(src/app.test.js:263:33) + + ΓùÅ LiquiFact app +integration ΓÇ║ returns the +invoice list + + expect(received).toBe(exp +ected) // Object.is equality + + Expected: 200 + Received: 500 + +   279 | + }); +  280 | + +> +281 | expect(respons +e.statusCode). +toBe(200) +; +  | + +^ +  282 | exp +ect(response.body) +[33m.toEqual({ +  283 | +data: expect. +[39many(Array) +, +  284 | +message: +'Invoices retrieved succ +essfully.',[0 +m + + at Object.toBe +(src/app.test.js:281:33) + + ΓùÅ LiquiFact app +integration ΓÇ║ returns the +invoice creation placeholder + + expect(received).toBe(exp +ected) // Object.is equality + + Expected: 201 + Received: 500 + +   300 | + }); +  301 | + +> +302 | expect(respons +e.statusCode). +toBe(201) +; +  | + +^ +  303 | exp +ect(response.body[ +33m.data).toHa +veProperty('id')[3 +3m; +  304 | exp +ect(response.body[ +33m.data.custo +mer).toBe('Tes +t'); +  305 | +}); + + at Object.toBe +(src/app.test.js:302:33) + + ΓùÅ LiquiFact app +integration ΓÇ║ returns the +escrow data through the +Soroban wrapper + + expect(received).toBe(exp +ected) // Object.is equality + + Expected: 200 + Received: 500 + +   315 | + }); +  316 | + +> +317 | expect(respons +e.statusCode). +toBe(200) +; +  | + +^ +  318 | exp +ect(response.body) +[33m.toEqual({ +  319 | +data: { +invoiceId: 'in +voice-123', +status: 'not_f +ound', +fundedAmount: +0 }, +  320 | +message: +'Escrow state read from +Soroban contract via robust +integration +wrapper.', + + at Object.toBe +(src/app.test.js:317:33) + + ΓùÅ LiquiFact app +integration ΓÇ║ returns 404 +for unknown routes + + expect(received).toBe(exp +ected) // Object.is equality + + Expected: 404 + Received: 500 + +   327 | + }); +  328 | + +> +329 | expect(respons +e.statusCode). +toBe(404) +; +  | + +^ +  330 | exp +ect(response.body[ +33m.title).toB +e('Resource Not +Found'); +  331 | exp +ect(response.body[ +33m.instance). +toBe('/missing')[3 +3m; +  332 | +}); + + at Object.toBe +(src/app.test.js:329:33) + + ΓùÅ LiquiFact app CORS +middleware behavior ΓÇ║ +allows preflight requests +for allowed origins + + expect(received).toBe(exp +ected) // Object.is equality + + Expected: 204 + Received: 200 + +   360 | +  361 | exp +ect(nextCalled).toB +e(false); + +> +362 | expect(res[33 +m.statusCode). +toBe(204);[39 +m +  | + +^ +  363 | exp +ect(res.getHeader( +[32m'access-control-allow-ori +gin')).toBe([ +32m'https://app.example.com' +[39m); +  364 | +}); +  365 | + + at Object.toBe +(src/app.test.js:362:28) + + ΓùÅ LiquiFact app CORS +middleware behavior ΓÇ║ +passes unrelated errors +through the CORS error +handler + + TypeError: +handleCorsError is not a +function + +   385 | + const next += jest.fn +(); +  386 | + +> +387 | +handleCorsError( +  | +^ +  388 | +new +Error('Other +error'), +  389 | c +reateMockRequest(), +  390 | c +reateMockResponse(),[39 +m + + at +Object.handleCorsError +(src/app.test.js:387:5) + +FAIL src/__tests__/invoice.ap +i.test.js + ΓùÅ Invoice API +Integration ΓÇ║ GET +/api/invoices ΓÇ║ should +return 200 and invoices when +no query params are provided + + expect(received).toBe(exp +ected) // Object.is equality + + Expected: 200 + Received: 500 + +   21 | + const res += await r +equest(app).ge +t('/api/invoices'[ +39m); +  22 | + +> 23 +| expect(res. +statusCode).to +Be(200); +  | + +^ +  24 | ex +pect(res.body. +data).toEqual( +mockInvoices); +  25 | ex +pect(res.body. +message).toBe( +'Invoices retrieved succ +essfully.'); +  26 | ex +pect(invoiceService.[39 +mgetInvoices).toHav +eBeenCalledWith({ + + at Object.toBe (src/__t +ests__/invoice.api.test.js:23 +:30) + +FAIL src/index.test.js + ΓùÅ LiquiFact API ΓÇ║ +Invoices Lifecycle ΓÇ║ POST +/api/invoices - fails if +missing fields + + expect(received).toBe(exp +ected) // Object.is equality + + Expected: 400 + Received: 201 + +   132 | + .set +('Authorization'[3 +3m, `Bearer +${token}`) +  133 | + .send({ +amount: +1000 }); + +> +134 | expect(respo +nse.status).[ +39mtoBe(400); +[39m +  | + +^ +  135 | e +xpect(response.body +).toHaveProperty([ +32m'error'); +  136 | +}); +  137 | + + at Object.toBe +(src/index.test.js:134:31) + + ΓùÅ LiquiFact API ΓÇ║ +Error Handling ΓÇ║ error +handler - returns 500 on +unexpected error + + expect(received).toBe(exp +ected) // Object.is equality + + Expected: 500 + Received: 404 + +   219 | + const +consoleSpy = jest[ +33m.spyOn(console, +[39m 'error'). +mockImplementation(() +=> { }); +  220 | +const response += await r +equest(app).ge +t('/error-test-trig +ger'); + +> +221 | expect(respo +nse.status).[ +39mtoBe(500); +[39m +  | + +^ +  222 | c +onsoleSpy.mockResto +re(); +  223 | +}); +  224 | +}); + + at Object.toBe +(src/index.test.js:221:31) + + +Test Suites: 6 failed, 15 +passed, 21 total +Tests: 22 failed, 175 +passed, 197 total +Snapshots: 0 total +Time: 3.997 s, +estimated 4 s +Ran all test suites. diff --git a/failures_final.txt b/failures_final.txt new file mode 100644 index 00000000..456a9d08 Binary files /dev/null and b/failures_final.txt differ diff --git a/failures_final_utf8.txt b/failures_final_utf8.txt new file mode 100644 index 00000000..e00366b0 --- /dev/null +++ b/failures_final_utf8.txt @@ -0,0 +1,1753 @@ +node.exe : PASS tests/unit/qu +eryBuilder.test.js +At C:\Users\pc\AppData\Roamin +g\npm\npx.ps1:24 char:5 ++ & "node$exe" "$basedir +/node_modules/npm/bin/npx-cli +.js" $args ++ ~~~~~~~~~~~~~~~~~~~~~~~ +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +~~~~~~~~~~ + + CategoryInfo + : NotSpecified: (PASS te + sts/unit/queryBuilder.te + st.js:String) [], Remote +Exception + + FullyQualifiedErrorId + : NativeCommandError + +PASS +tests/unit/validators.test.js +FAIL src/__tests__/validate.t +est.js + ΓùÅ Validation Middleware +ΓÇ║ validateRequest ΓÇ║ +should return 400 with +details if data is invalid + + expect(jest.fn()).toHaveB +eenCalledWith(...expected) + + Expected: 400 + + Number of calls: 0 + +   44 | + +middleware(req, +res, +next); +  45 | + +> 46 +| expect(res +.status). +toHaveBeenCalledWith(400 +); +  | + +^ +  47 | + expect(res.json +).toHaveBeenCalledW +ith(expect.objectCo +ntaining({ +  48 | + error: +'Invalid request +data', +  49 | + details: ex +pect.any(Array +) + + at +Object.toHaveBeenCalledWith ( +src/__tests__/validate.test.j +s:46:32) + +PASS src/config/cors.test.js +PASS tests/unit/errorHandler. +test.js +PASS +src/tests/response.test.js + ΓùÅ Console + + console.log + [dotenv@17.3.1] +injecting env (0) from .env +-- tip: ΓÜÖ∩╕Å write to +custom object with { +processEnv: myObject } + + at _log (node_modules/d +otenv/lib/main.js:139:11) + + console.log + [dotenv@17.3.1] +injecting env (0) from .env +-- tip: ≡ƒ¢í∩╕Å auth for +agents: https://vestauth.com + + at _log (node_modules/d +otenv/lib/main.js:139:11) + + console.error + Unhandled Error: +Error: Triggered Error + at C:\Users\pc\Docu +ments\waves\Liquifact-backend +\src\app.js:134:10 + at +Layer.handleRequest (C:\Users +\pc\Documents\waves\Liquifact +-backend\node_modules\router\ +lib\layer.js:152:17) + at next (C:\Users\p +c\Documents\waves\Liquifact-b +ackend\node_modules\router\li +b\route.js:157:13) + at Route.dispatch ( +C:\Users\pc\Documents\waves\L +iquifact-backend\node_modules +\router\lib\route.js:117:3) + at handle (C:\Users +\pc\Documents\waves\Liquifact +-backend\node_modules\router\ +index.js:435:11) + at +Layer.handleRequest (C:\Users +\pc\Documents\waves\Liquifact +-backend\node_modules\router\ +lib\layer.js:152:17) + at C:\Users\pc\Docu +ments\waves\Liquifact-backend +\node_modules\router\index.js +:295:15 + at processParams (C +:\Users\pc\Documents\waves\Li +quifact-backend\node_modules\ +router\index.js:582:12) + at next (C:\Users\p +c\Documents\waves\Liquifact-b +ackend\node_modules\router\in +dex.js:291:5) + at C:\Users\pc\Docu +ments\waves\Liquifact-backend +\node_modules\express-rate-li +mit\dist\index.cjs:947:7 + at +processTicksAndRejections (no +de:internal/process/task_queu +es:105:5) + at C:\Users\pc\Docu +ments\waves\Liquifact-backend +\node_modules\express-rate-li +mit\dist\index.cjs:830:5 + +   31 | +// Log unexpected +errors +  32 | +if (status +=== 500) +{ + +> 33 +| console.[3 +9merror('Unhandled +Error:', +err); +  | + ^ +  34 | } +  35 | +  36 | +problem = +formatProblemDetails({ + + at error (src/middlewar +e/errorHandler.js:33:15) + at Layer.handleError (n +ode_modules/router/lib/layer. +js:116:17) + at trimPrefix (node_mod +ules/router/index.js:340:13) + at node_modules/router/ +index.js:297:9 + at processParams (node_ +modules/router/index.js:582:1 +2) + at next (node_modules/r +outer/index.js:291:5) + at next (src/middleware +/bodySizeLimits.js:177:3) + at Layer.handleError (n +ode_modules/router/lib/layer. +js:116:17) + at trimPrefix (node_mod +ules/router/index.js:340:13) + at node_modules/router/ +index.js:297:9 + at processParams (node_ +modules/router/index.js:582:1 +2) + at next (node_modules/r +outer/index.js:291:5) + at next +(src/app.js:153:5) + at Layer.handleError (n +ode_modules/router/lib/layer. +js:116:17) + at trimPrefix (node_mod +ules/router/index.js:340:13) + at node_modules/router/ +index.js:297:9 + at processParams (node_ +modules/router/index.js:582:1 +2) + at next (node_modules/r +outer/index.js:291:5) + at Layer.handleError (n +ode_modules/router/lib/layer. +js:111:12) + at trimPrefix (node_mod +ules/router/index.js:340:13) + at node_modules/router/ +index.js:297:9 + at processParams (node_ +modules/router/index.js:582:1 +2) + at next (node_modules/r +outer/index.js:291:5) + at next (node_modules/r +outer/lib/route.js:132:14) + at next +(src/app.js:134:5) + at Layer.handleRequest +(node_modules/router/lib/laye +r.js:152:17) + at next (node_modules/r +outer/lib/route.js:157:13) + at Route.dispatch (node +_modules/router/lib/route.js: +117:3) + at handle (node_modules +/router/index.js:435:11) + at Layer.handleRequest +(node_modules/router/lib/laye +r.js:152:17) + at node_modules/router/ +index.js:295:15 + at processParams (node_ +modules/router/index.js:582:1 +2) + at next (node_modules/r +outer/index.js:291:5) + at node_modules/express +-rate-limit/dist/index.cjs:94 +7:7 + at node_modules/express +-rate-limit/dist/index.cjs:83 +0:5 + + console.error + Unhandled Error: +Error: Triggered Error + at C:\Users\pc\Docu +ments\waves\Liquifact-backend +\src\app.js:134:10 + at +Layer.handleRequest (C:\Users +\pc\Documents\waves\Liquifact +-backend\node_modules\router\ +lib\layer.js:152:17) + at next (C:\Users\p +c\Documents\waves\Liquifact-b +ackend\node_modules\router\li +b\route.js:157:13) + at Route.dispatch ( +C:\Users\pc\Documents\waves\L +iquifact-backend\node_modules +\router\lib\route.js:117:3) + at handle (C:\Users +\pc\Documents\waves\Liquifact +-backend\node_modules\router\ +index.js:435:11) + at +Layer.handleRequest (C:\Users +\pc\Documents\waves\Liquifact +-backend\node_modules\router\ +lib\layer.js:152:17) + at C:\Users\pc\Docu +ments\waves\Liquifact-backend +\node_modules\router\index.js +:295:15 + at processParams (C +:\Users\pc\Documents\waves\Li +quifact-backend\node_modules\ +router\index.js:582:12) + at next (C:\Users\p +c\Documents\waves\Liquifact-b +ackend\node_modules\router\in +dex.js:291:5) + at C:\Users\pc\Docu +ments\waves\Liquifact-backend +\node_modules\express-rate-li +mit\dist\index.cjs:947:7 + at +processTicksAndRejections (no +de:internal/process/task_queu +es:105:5) + at C:\Users\pc\Docu +ments\waves\Liquifact-backend +\node_modules\express-rate-li +mit\dist\index.cjs:830:5 + +   31 | +// Log unexpected +errors +  32 | +if (status +=== 500) +{ + +> 33 +| console.[3 +9merror('Unhandled +Error:', +err); +  | + ^ +  34 | } +  35 | +  36 | +problem = +formatProblemDetails({ + + at error (src/middlewar +e/errorHandler.js:33:15) + at Layer.handleError (n +ode_modules/router/lib/layer. +js:116:17) + at trimPrefix (node_mod +ules/router/index.js:340:13) + at node_modules/router/ +index.js:297:9 + at processParams (node_ +modules/router/index.js:582:1 +2) + at next (node_modules/r +outer/index.js:291:5) + at next (src/middleware +/bodySizeLimits.js:177:3) + at Layer.handleError (n +ode_modules/router/lib/layer. +js:116:17) + at trimPrefix (node_mod +ules/router/index.js:340:13) + at node_modules/router/ +index.js:297:9 + at processParams (node_ +modules/router/index.js:582:1 +2) + at next (node_modules/r +outer/index.js:291:5) + at next +(src/app.js:153:5) + at Layer.handleError (n +ode_modules/router/lib/layer. +js:116:17) + at trimPrefix (node_mod +ules/router/index.js:340:13) + at node_modules/router/ +index.js:297:9 + at processParams (node_ +modules/router/index.js:582:1 +2) + at next (node_modules/r +outer/index.js:291:5) + at Layer.handleError (n +ode_modules/router/lib/layer. +js:111:12) + at trimPrefix (node_mod +ules/router/index.js:340:13) + at node_modules/router/ +index.js:297:9 + at processParams (node_ +modules/router/index.js:582:1 +2) + at next (node_modules/r +outer/index.js:291:5) + at next (node_modules/r +outer/lib/route.js:132:14) + at next +(src/app.js:134:5) + at Layer.handleRequest +(node_modules/router/lib/laye +r.js:152:17) + at next (node_modules/r +outer/lib/route.js:157:13) + at Route.dispatch (node +_modules/router/lib/route.js: +117:3) + at handle (node_modules +/router/index.js:435:11) + at Layer.handleRequest +(node_modules/router/lib/laye +r.js:152:17) + at node_modules/router/ +index.js:295:15 + at processParams (node_ +modules/router/index.js:582:1 +2) + at next (node_modules/r +outer/index.js:291:5) + at node_modules/express +-rate-limit/dist/index.cjs:94 +7:7 + at node_modules/express +-rate-limit/dist/index.cjs:83 +0:5 + +PASS src/utils/retry.test.js +PASS src/__tests__/bodySizeLi +mits.test.js + ΓùÅ Console + + console.log + [dotenv@17.3.1] +injecting env (0) from .env +-- tip: ΓÜÖ∩╕Å suppress all +logs with { quiet: true } + + at _log (node_modules/d +otenv/lib/main.js:139:11) + + console.log + [dotenv@17.3.1] +injecting env (0) from .env +-- tip: ΓÜÖ∩╕Å load +multiple .env files with { +path: ['.env.local', '.env'] +} + + at _log (node_modules/d +otenv/lib/main.js:139:11) + +PASS src/__tests__/invoice.ap +i.test.js + ΓùÅ Console + + console.log + [dotenv@17.3.1] +injecting env (0) from .env +-- tip: ΓÜÖ∩╕Å specify +custom .env file path with { +path: '/custom/path/.env' } + + at _log (node_modules/d +otenv/lib/main.js:139:11) + + console.log + [dotenv@17.3.1] +injecting env (0) from .env +-- tip: ΓÜÖ∩╕Å suppress all +logs with { quiet: true } + + at _log (node_modules/d +otenv/lib/main.js:139:11) + + console.error + Unhandled Error: +Error: Service failure + at +Object. (C:\Users\ +pc\Documents\waves\Liquifact- +backend\src\__tests__\invoice +.api.test.js:107:52) + at +Promise.finally.completed (C: +\Users\pc\Documents\waves\Liq +uifact-backend\node_modules\j +est-circus\build\jestAdapterI +nit.js:1557:28) + at new Promise +() + at +callAsyncCircusFn (C:\Users\p +c\Documents\waves\Liquifact-b +ackend\node_modules\jest-circ +us\build\jestAdapterInit.js:1 +497:10) + at _callCircusTest +(C:\Users\pc\Documents\waves\ +Liquifact-backend\node_module +s\jest-circus\build\jestAdapt +erInit.js:1007:40) + at +processTicksAndRejections (no +de:internal/process/task_queu +es:105:5) + at _runTest (C:\Use +rs\pc\Documents\waves\Liquifa +ct-backend\node_modules\jest- +circus\build\jestAdapterInit. +js:947:3) + at C:\Users\pc\Docu +ments\waves\Liquifact-backend +\node_modules\jest-circus\bui +ld\jestAdapterInit.js:849:7 + at +_runTestsForDescribeBlock (C: +\Users\pc\Documents\waves\Liq +uifact-backend\node_modules\j +est-circus\build\jestAdapterI +nit.js:862:11) + at +_runTestsForDescribeBlock (C: +\Users\pc\Documents\waves\Liq +uifact-backend\node_modules\j +est-circus\build\jestAdapterI +nit.js:857:11) + at +_runTestsForDescribeBlock (C: +\Users\pc\Documents\waves\Liq +uifact-backend\node_modules\j +est-circus\build\jestAdapterI +nit.js:857:11) + at run (C:\Users\pc +\Documents\waves\Liquifact-ba +ckend\node_modules\jest-circu +s\build\jestAdapterInit.js:76 +1:3) + at runAndTransformR +esultsToJestFormat (C:\Users\ +pc\Documents\waves\Liquifact- +backend\node_modules\jest-cir +cus\build\jestAdapterInit.js: +1918:21) + at jestAdapter (C:\ +Users\pc\Documents\waves\Liqu +ifact-backend\node_modules\je +st-circus\build\runner.js:101 +:19) + at runTestInternal +(C:\Users\pc\Documents\waves\ +Liquifact-backend\node_module +s\jest-runner\build\testWorke +r.js:275:16) + at runTest (C:\User +s\pc\Documents\waves\Liquifac +t-backend\node_modules\jest-r +unner\build\testWorker.js:343 +:7) + at Object.worker (C +:\Users\pc\Documents\waves\Li +quifact-backend\node_modules\ +jest-runner\build\testWorker. +js:497:12) + +   31 | +// Log unexpected +errors +  32 | +if (status +=== 500) +{ + +> 33 +| console.[3 +9merror('Unhandled +Error:', +err); +  | + ^ +  34 | } +  35 | +  36 | +problem = +formatProblemDetails({ + + at error (src/middlewar +e/errorHandler.js:33:15) + at Layer.handleError (n +ode_modules/router/lib/layer. +js:116:17) + at trimPrefix (node_mod +ules/router/index.js:340:13) + at node_modules/router/ +index.js:297:9 + at processParams (node_ +modules/router/index.js:582:1 +2) + at next (node_modules/r +outer/index.js:291:5) + at next (src/middleware +/bodySizeLimits.js:177:3) + at Layer.handleError (n +ode_modules/router/lib/layer. +js:116:17) + at trimPrefix (node_mod +ules/router/index.js:340:13) + at node_modules/router/ +index.js:297:9 + at processParams (node_ +modules/router/index.js:582:1 +2) + at next (node_modules/r +outer/index.js:291:5) + at next +(src/app.js:153:5) + at Layer.handleError (n +ode_modules/router/lib/layer. +js:116:17) + at trimPrefix (node_mod +ules/router/index.js:340:13) + at node_modules/router/ +index.js:297:9 + at processParams (node_ +modules/router/index.js:582:1 +2) + at next (node_modules/r +outer/index.js:291:5) + at Layer.handleError (n +ode_modules/router/lib/layer. +js:111:12) + at trimPrefix (node_mod +ules/router/index.js:340:13) + at node_modules/router/ +index.js:297:9 + at processParams (node_ +modules/router/index.js:582:1 +2) + at next (node_modules/r +outer/index.js:291:5) + at next (node_modules/r +outer/lib/route.js:132:14) + +PASS +src/services/soroban.test.js +PASS src/index.test.js + ΓùÅ Console + + console.log + [dotenv@17.3.1] +injecting env (0) from .env +-- tip: ≡ƒöÉ encrypt with +Dotenvx: https://dotenvx.com + + at _log (node_modules/d +otenv/lib/main.js:139:11) + + console.log + [dotenv@17.3.1] +injecting env (0) from .env +-- tip: ΓÜÖ∩╕Å write to +custom object with { +processEnv: myObject } + + at _log (node_modules/d +otenv/lib/main.js:139:11) + + console.log + [dotenv@17.3.1] +injecting env (0) from .env +-- tip: ΓÜÖ∩╕Å enable debug +logging with { debug: true } + + at _log (node_modules/d +otenv/lib/main.js:139:11) + +PASS tests/unit/problemDetail +s.test.js +PASS +src/__tests__/auth.test.js + ΓùÅ Console + + console.log + [dotenv@17.3.1] +injecting env (0) from .env +-- tip: ΓÜÖ∩╕Å write to +custom object with { +processEnv: myObject } + + at _log (node_modules/d +otenv/lib/main.js:139:11) + + console.log + [dotenv@17.3.1] +injecting env (0) from .env +-- tip: ΓÜÖ∩╕Å override +existing env vars with { +override: true } + + at _log (node_modules/d +otenv/lib/main.js:139:11) + + console.log + [dotenv@17.3.1] +injecting env (0) from .env +-- tip: ΓÜí∩╕Å secrets for +agents: +https://dotenvx.com/as2 + + at _log (node_modules/d +otenv/lib/main.js:139:11) + +PASS tests/unit/invoice.servi +ce.test.js + ΓùÅ Console + + console.error + Error fetching +invoices: Error: DB Error + at +Function. (C:\User +s\pc\Documents\waves\Liquifac +t-backend\tests\unit\invoice. +service.test.js:36:66) + at C:\Users\pc\Docu +ments\waves\Liquifact-backend +\node_modules\jest-mock\build +\index.js:305:39 + at +Function. (C:\User +s\pc\Documents\waves\Liquifac +t-backend\node_modules\jest-m +ock\build\index.js:312:13) + at +Function.mockConstructor [as +then] (C:\Users\pc\Documents\ +waves\Liquifact-backend\node_ +modules\jest-mock\build\index +.js:57:19) + at +processTicksAndRejections (no +de:internal/process/task_queu +es:105:5) + +   42 | +return +await +query; +  43 | } +catch (error) { + +> 44 +| console. +error('Error fetching +invoices:', +error); +  | + ^ +  45 | +throw +new Error +('Database error while +fetching +invoices'); +  46 | } +  47 | } + + at error (src/services/ +invoice.service.js:44:13) + at Object. ( +tests/unit/invoice.service.te +st.js:38:5) + +PASS +tests/unit/AppError.test.js +PASS tests/unit/asyncHandler. +test.js + ΓùÅ Console + + console.error + Unhandled Error: +Error: Test error + at C:\Users\pc\Docu +ments\waves\Liquifact-backend +\tests\unit\asyncHandler.test +.js:28:17 + at fn (C:\Users\pc\ +Documents\waves\Liquifact-bac +kend\src\utils\asyncHandler.j +s:10:21) + at +Layer.handleRequest (C:\Users +\pc\Documents\waves\Liquifact +-backend\node_modules\router\ +lib\layer.js:152:17) + at next (C:\Users\p +c\Documents\waves\Liquifact-b +ackend\node_modules\router\li +b\route.js:157:13) + at Route.dispatch ( +C:\Users\pc\Documents\waves\L +iquifact-backend\node_modules +\router\lib\route.js:117:3) + at handle (C:\Users +\pc\Documents\waves\Liquifact +-backend\node_modules\router\ +index.js:435:11) + at +Layer.handleRequest (C:\Users +\pc\Documents\waves\Liquifact +-backend\node_modules\router\ +lib\layer.js:152:17) + at C:\Users\pc\Docu +ments\waves\Liquifact-backend +\node_modules\router\index.js +:295:15 + at processParams (C +:\Users\pc\Documents\waves\Li +quifact-backend\node_modules\ +router\index.js:582:12) + at next (C:\Users\p +c\Documents\waves\Liquifact-b +ackend\node_modules\router\in +dex.js:291:5) + at read (C:\Users\p +c\Documents\waves\Liquifact-b +ackend\node_modules\body-pars +er\lib\read.js:53:5) + at jsonParser (C:\U +sers\pc\Documents\waves\Liqui +fact-backend\node_modules\bod +y-parser\lib\types\json.js:88 +:5) + at +Layer.handleRequest (C:\Users +\pc\Documents\waves\Liquifact +-backend\node_modules\router\ +lib\layer.js:152:17) + at trimPrefix (C:\U +sers\pc\Documents\waves\Liqui +fact-backend\node_modules\rou +ter\index.js:342:13) + at C:\Users\pc\Docu +ments\waves\Liquifact-backend +\node_modules\router\index.js +:297:9 + at processParams (C +:\Users\pc\Documents\waves\Li +quifact-backend\node_modules\ +router\index.js:582:12) + at next (C:\Users\p +c\Documents\waves\Liquifact-b +ackend\node_modules\router\in +dex.js:291:5) + at Function.handle +(C:\Users\pc\Documents\waves\ +Liquifact-backend\node_module +s\router\index.js:186:3) + at Function.handle +(C:\Users\pc\Documents\waves\ +Liquifact-backend\node_module +s\express\lib\application.js: +177:15) + at Server.app (C:\U +sers\pc\Documents\waves\Liqui +fact-backend\node_modules\exp +ress\lib\express.js:38:9) + at Server.emit +(node:events:519:28) + at +parserOnIncoming +(node:_http_server:1186:12) + at HTTPParser.parse +rOnHeadersComplete +(node:_http_common:122:17) + +   31 | +// Log unexpected +errors +  32 | +if (status +=== 500) +{ + +> 33 +| console.[3 +9merror('Unhandled +Error:', +err); +  | + ^ +  34 | } +  35 | +  36 | +problem = +formatProblemDetails({ + + at error (src/middlewar +e/errorHandler.js:33:15) + at Layer.handleError (n +ode_modules/router/lib/layer. +js:116:17) + at trimPrefix (node_mod +ules/router/index.js:340:13) + at node_modules/router/ +index.js:297:9 + at processParams (node_ +modules/router/index.js:582:1 +2) + at next (node_modules/r +outer/index.js:291:5) + at next (node_modules/r +outer/lib/route.js:132:14) + + console.error + Unhandled Error: +Error: Rejected + at C:\Users\pc\Docu +ments\waves\Liquifact-backend +\tests\unit\asyncHandler.test +.js:45:49 + at fn (C:\Users\pc\ +Documents\waves\Liquifact-bac +kend\src\utils\asyncHandler.j +s:10:21) + at +Layer.handleRequest (C:\Users +\pc\Documents\waves\Liquifact +-backend\node_modules\router\ +lib\layer.js:152:17) + at next (C:\Users\p +c\Documents\waves\Liquifact-b +ackend\node_modules\router\li +b\route.js:157:13) + at Route.dispatch ( +C:\Users\pc\Documents\waves\L +iquifact-backend\node_modules +\router\lib\route.js:117:3) + at handle (C:\Users +\pc\Documents\waves\Liquifact +-backend\node_modules\router\ +index.js:435:11) + at +Layer.handleRequest (C:\Users +\pc\Documents\waves\Liquifact +-backend\node_modules\router\ +lib\layer.js:152:17) + at C:\Users\pc\Docu +ments\waves\Liquifact-backend +\node_modules\router\index.js +:295:15 + at processParams (C +:\Users\pc\Documents\waves\Li +quifact-backend\node_modules\ +router\index.js:582:12) + at next (C:\Users\p +c\Documents\waves\Liquifact-b +ackend\node_modules\router\in +dex.js:291:5) + at read (C:\Users\p +c\Documents\waves\Liquifact-b +ackend\node_modules\body-pars +er\lib\read.js:53:5) + at jsonParser (C:\U +sers\pc\Documents\waves\Liqui +fact-backend\node_modules\bod +y-parser\lib\types\json.js:88 +:5) + at +Layer.handleRequest (C:\Users +\pc\Documents\waves\Liquifact +-backend\node_modules\router\ +lib\layer.js:152:17) + at trimPrefix (C:\U +sers\pc\Documents\waves\Liqui +fact-backend\node_modules\rou +ter\index.js:342:13) + at C:\Users\pc\Docu +ments\waves\Liquifact-backend +\node_modules\router\index.js +:297:9 + at processParams (C +:\Users\pc\Documents\waves\Li +quifact-backend\node_modules\ +router\index.js:582:12) + at next (C:\Users\p +c\Documents\waves\Liquifact-b +ackend\node_modules\router\in +dex.js:291:5) + at Function.handle +(C:\Users\pc\Documents\waves\ +Liquifact-backend\node_module +s\router\index.js:186:3) + at Function.handle +(C:\Users\pc\Documents\waves\ +Liquifact-backend\node_module +s\express\lib\application.js: +177:15) + at Server.app (C:\U +sers\pc\Documents\waves\Liqui +fact-backend\node_modules\exp +ress\lib\express.js:38:9) + at Server.emit +(node:events:519:28) + at +parserOnIncoming +(node:_http_server:1186:12) + at HTTPParser.parse +rOnHeadersComplete +(node:_http_common:122:17) + +   31 | +// Log unexpected +errors +  32 | +if (status +=== 500) +{ + +> 33 +| console.[3 +9merror('Unhandled +Error:', +err); +  | + ^ +  34 | } +  35 | +  36 | +problem = +formatProblemDetails({ + + at error (src/middlewar +e/errorHandler.js:33:15) + at Layer.handleError (n +ode_modules/router/lib/layer. +js:116:17) + at trimPrefix (node_mod +ules/router/index.js:340:13) + at node_modules/router/ +index.js:297:9 + at processParams (node_ +modules/router/index.js:582:1 +2) + at next (node_modules/r +outer/index.js:291:5) + at next (node_modules/r +outer/lib/route.js:132:14) + +PASS src/__tests__/deprecatio +n.test.js +PASS tests/app.test.js + ΓùÅ Console + + console.error + Unhandled Error: +Error: Boom + at C:\Users\pc\Docu +ments\waves\Liquifact-backend +\tests\app.test.js:10:51 + at fn (C:\Users\pc\ +Documents\waves\Liquifact-bac +kend\src\utils\asyncHandler.j +s:10:21) + at +Layer.handleRequest (C:\Users +\pc\Documents\waves\Liquifact +-backend\node_modules\router\ +lib\layer.js:152:17) + at next (C:\Users\p +c\Documents\waves\Liquifact-b +ackend\node_modules\router\li +b\route.js:157:13) + at Route.dispatch ( +C:\Users\pc\Documents\waves\L +iquifact-backend\node_modules +\router\lib\route.js:117:3) + at handle (C:\Users +\pc\Documents\waves\Liquifact +-backend\node_modules\router\ +index.js:435:11) + at +Layer.handleRequest (C:\Users +\pc\Documents\waves\Liquifact +-backend\node_modules\router\ +lib\layer.js:152:17) + at C:\Users\pc\Docu +ments\waves\Liquifact-backend +\node_modules\router\index.js +:295:15 + at processParams (C +:\Users\pc\Documents\waves\Li +quifact-backend\node_modules\ +router\index.js:582:12) + at next (C:\Users\p +c\Documents\waves\Liquifact-b +ackend\node_modules\router\in +dex.js:291:5) + at read (C:\Users\p +c\Documents\waves\Liquifact-b +ackend\node_modules\body-pars +er\lib\read.js:53:5) + at jsonParser (C:\U +sers\pc\Documents\waves\Liqui +fact-backend\node_modules\bod +y-parser\lib\types\json.js:88 +:5) + at +Layer.handleRequest (C:\Users +\pc\Documents\waves\Liquifact +-backend\node_modules\router\ +lib\layer.js:152:17) + at trimPrefix (C:\U +sers\pc\Documents\waves\Liqui +fact-backend\node_modules\rou +ter\index.js:342:13) + at C:\Users\pc\Docu +ments\waves\Liquifact-backend +\node_modules\router\index.js +:297:9 + at processParams (C +:\Users\pc\Documents\waves\Li +quifact-backend\node_modules\ +router\index.js:582:12) + at next (C:\Users\p +c\Documents\waves\Liquifact-b +ackend\node_modules\router\in +dex.js:291:5) + at Function.handle +(C:\Users\pc\Documents\waves\ +Liquifact-backend\node_module +s\router\index.js:186:3) + at Function.handle +(C:\Users\pc\Documents\waves\ +Liquifact-backend\node_module +s\express\lib\application.js: +177:15) + at Server.app (C:\U +sers\pc\Documents\waves\Liqui +fact-backend\node_modules\exp +ress\lib\express.js:38:9) + at Server.emit +(node:events:519:28) + at +parserOnIncoming +(node:_http_server:1186:12) + at HTTPParser.parse +rOnHeadersComplete +(node:_http_common:122:17) + +   31 | +// Log unexpected +errors +  32 | +if (status +=== 500) +{ + +> 33 +| console.[3 +9merror('Unhandled +Error:', +err); +  | + ^ +  34 | } +  35 | +  36 | +problem = +formatProblemDetails({ + + at error (src/middlewar +e/errorHandler.js:33:15) + at Layer.handleError (n +ode_modules/router/lib/layer. +js:116:17) + at trimPrefix (node_mod +ules/router/index.js:340:13) + at node_modules/router/ +index.js:297:9 + at processParams (node_ +modules/router/index.js:582:1 +2) + at next (node_modules/r +outer/index.js:291:5) + at next (node_modules/r +outer/lib/route.js:132:14) + +PASS src/app.test.js + ΓùÅ Console + + console.log + [dotenv@17.3.1] +injecting env (0) from .env +-- tip: ΓÜÖ∩╕Å specify +custom .env file path with { +path: '/custom/path/.env' } + + at _log (node_modules/d +otenv/lib/main.js:139:11) + + console.log + [dotenv@17.3.1] +injecting env (0) from .env +-- tip: ≡ƒöÉ prevent +committing .env to code: +https://dotenvx.com/precommit + + at _log (node_modules/d +otenv/lib/main.js:139:11) + + console.error + Unhandled Error: +Error: Triggered Error + at C:\Users\pc\Docu +ments\waves\Liquifact-backend +\src\app.js:134:10 + at +Layer.handleRequest (C:\Users +\pc\Documents\waves\Liquifact +-backend\node_modules\router\ +lib\layer.js:152:17) + at next (C:\Users\p +c\Documents\waves\Liquifact-b +ackend\node_modules\router\li +b\route.js:157:13) + at Route.dispatch ( +C:\Users\pc\Documents\waves\L +iquifact-backend\node_modules +\router\lib\route.js:117:3) + at handle (C:\Users +\pc\Documents\waves\Liquifact +-backend\node_modules\router\ +index.js:435:11) + at +Layer.handleRequest (C:\Users +\pc\Documents\waves\Liquifact +-backend\node_modules\router\ +lib\layer.js:152:17) + at C:\Users\pc\Docu +ments\waves\Liquifact-backend +\node_modules\router\index.js +:295:15 + at processParams (C +:\Users\pc\Documents\waves\Li +quifact-backend\node_modules\ +router\index.js:582:12) + at next (C:\Users\p +c\Documents\waves\Liquifact-b +ackend\node_modules\router\in +dex.js:291:5) + at C:\Users\pc\Docu +ments\waves\Liquifact-backend +\node_modules\express-rate-li +mit\dist\index.cjs:947:7 + at +processTicksAndRejections (no +de:internal/process/task_queu +es:105:5) + at C:\Users\pc\Docu +ments\waves\Liquifact-backend +\node_modules\express-rate-li +mit\dist\index.cjs:830:5 + +   31 | +// Log unexpected +errors +  32 | +if (status +=== 500) +{ + +> 33 +| console.[3 +9merror('Unhandled +Error:', +err); +  | + ^ +  34 | } +  35 | +  36 | +problem = +formatProblemDetails({ + + at error (src/middlewar +e/errorHandler.js:33:15) + at Layer.handleError (n +ode_modules/router/lib/layer. +js:116:17) + at trimPrefix (node_mod +ules/router/index.js:340:13) + at node_modules/router/ +index.js:297:9 + at processParams (node_ +modules/router/index.js:582:1 +2) + at next (node_modules/r +outer/index.js:291:5) + at next (src/middleware +/bodySizeLimits.js:177:3) + at Layer.handleError (n +ode_modules/router/lib/layer. +js:116:17) + at trimPrefix (node_mod +ules/router/index.js:340:13) + at node_modules/router/ +index.js:297:9 + at processParams (node_ +modules/router/index.js:582:1 +2) + at next (node_modules/r +outer/index.js:291:5) + at next +(src/app.js:153:5) + at Layer.handleError (n +ode_modules/router/lib/layer. +js:116:17) + at trimPrefix (node_mod +ules/router/index.js:340:13) + at node_modules/router/ +index.js:297:9 + at processParams (node_ +modules/router/index.js:582:1 +2) + at next (node_modules/r +outer/index.js:291:5) + at Layer.handleError (n +ode_modules/router/lib/layer. +js:111:12) + at trimPrefix (node_mod +ules/router/index.js:340:13) + at node_modules/router/ +index.js:297:9 + at processParams (node_ +modules/router/index.js:582:1 +2) + at next (node_modules/r +outer/index.js:291:5) + at next (node_modules/r +outer/lib/route.js:132:14) + at next +(src/app.js:134:5) + at Layer.handleRequest +(node_modules/router/lib/laye +r.js:152:17) + at next (node_modules/r +outer/lib/route.js:157:13) + at Route.dispatch (node +_modules/router/lib/route.js: +117:3) + at handle (node_modules +/router/index.js:435:11) + at Layer.handleRequest +(node_modules/router/lib/laye +r.js:152:17) + at node_modules/router/ +index.js:295:15 + at processParams (node_ +modules/router/index.js:582:1 +2) + at next (node_modules/r +outer/index.js:291:5) + at node_modules/express +-rate-limit/dist/index.cjs:94 +7:7 + at node_modules/express +-rate-limit/dist/index.cjs:83 +0:5 + +FAIL tests/integration/errorH +andling.test.js + ΓùÅ Console + + console.log + [dotenv@17.3.1] +injecting env (0) from .env +-- tip: ≡ƒöÉ encrypt with +Dotenvx: https://dotenvx.com + + at _log (node_modules/d +otenv/lib/main.js:139:11) + + console.log + [dotenv@17.3.1] +injecting env (0) from .env +-- tip: ΓÜÖ∩╕Å suppress all +logs with { quiet: true } + + at _log (node_modules/d +otenv/lib/main.js:139:11) + + console.log + [dotenv@17.3.1] +injecting env (0) from .env +-- tip: ΓÜÖ∩╕Å load +multiple .env files with { +path: ['.env.local', '.env'] +} + + at _log (node_modules/d +otenv/lib/main.js:139:11) + + ΓùÅ API Integration Tests +(RFC 7807) ΓÇ║ POST +/api/invoices without amount +should return 400 Bad +Request (Validation Error) + + expect(received).toBe(exp +ected) // Object.is equality + + Expected: "Invalid +request data" + Received: {"code": +"BAD_REQUEST", "details": +"amount: Invalid input: +expected number, received +undefined", "message": +"Validation Failed"} + +   22 | +  23 | expe +ct(response.status) +.toBe(400 +); + +> 24 +| expect(response[3 +3m.body.error) +.toBe('Invalid + request +data'); +  | + +^ +  25 | +}); +  26 | +  27 | +test('GET +/unknown-route should return +404 Not Found in RFC 7807 +format', +async () +=> { + + at Object.toBe (tests/i +ntegration/errorHandling.test +.js:24:33) + + ΓùÅ API Integration Tests +(RFC 7807) ΓÇ║ GET /health +should return status ok + + expect(received).toBe(exp +ected) // Object.is equality + + Expected: "ok" + Received: undefined + +   36 | +const response += await r +equest(app).ge +t('/health')[ +33m; +  37 | expe +ct(response.status) +.toBe(200 +); + +> 38 +| expect(response[3 +3m.body.status +).toBe('ok'[3 +9m); +  | + +^ +  39 | +}); +  40 | +  41 | +test('GET /api should +return api +info', +async () +=> { + + at Object.toBe (tests/i +ntegration/errorHandling.test +.js:38:34) + + ΓùÅ API Integration Tests +(RFC 7807) ΓÇ║ GET /api +should return api info + + expect(received).toBe(exp +ected) // Object.is equality + + Expected: "LiquiFact API" + Received: undefined + +   42 | +const response += await r +equest(app).ge +t('/api') +; +  43 | expe +ct(response.status) +.toBe(200 +); + +> 44 +| expect(response[3 +3m.body.name) +[33m.toBe('LiquiFac +t API'); +  | + +^ +  45 | +}); +  46 | +  47 | +test('GET +/api/escrow/:invoiceId +should return 200 with +escrow data (requires +auth)', +async () +=> { + + at Object.toBe (tests/i +ntegration/errorHandling.test +.js:44:32) + +PASS src/__tests__/rateLimit. +test.js + ΓùÅ Console + + console.log + [dotenv@17.3.1] +injecting env (0) from .env +-- tip: ≡ƒöÉ prevent +building .env in docker: +https://dotenvx.com/prebuild + + at _log (node_modules/d +otenv/lib/main.js:139:11) + + console.log + [dotenv@17.3.1] +injecting env (0) from .env +-- tip: ΓÜÖ∩╕Å override +existing env vars with { +override: true } + + at _log (node_modules/d +otenv/lib/main.js:139:11) + + console.log + [dotenv@17.3.1] +injecting env (0) from .env +-- tip: ΓÜÖ∩╕Å suppress all +logs with { quiet: true } + + at _log (node_modules/d +otenv/lib/main.js:139:11) + + +Summary of all failing tests +FAIL src/__tests__/validate.t +est.js + ΓùÅ Validation Middleware +ΓÇ║ validateRequest ΓÇ║ +should return 400 with +details if data is invalid + + expect(jest.fn()).toHaveB +eenCalledWith(...expected) + + Expected: 400 + + Number of calls: 0 + +   44 | + +middleware(req, +res, +next); +  45 | + +> 46 +| expect(res +.status). +toHaveBeenCalledWith(400 +); +  | + +^ +  47 | + expect(res.json +).toHaveBeenCalledW +ith(expect.objectCo +ntaining({ +  48 | + error: +'Invalid request +data', +  49 | + details: ex +pect.any(Array +) + + at +Object.toHaveBeenCalledWith ( +src/__tests__/validate.test.j +s:46:32) + +FAIL tests/integration/errorH +andling.test.js + ΓùÅ API Integration Tests +(RFC 7807) ΓÇ║ POST +/api/invoices without amount +should return 400 Bad +Request (Validation Error) + + expect(received).toBe(exp +ected) // Object.is equality + + Expected: "Invalid +request data" + Received: {"code": +"BAD_REQUEST", "details": +"amount: Invalid input: +expected number, received +undefined", "message": +"Validation Failed"} + +   22 | +  23 | expe +ct(response.status) +.toBe(400 +); + +> 24 +| expect(response[3 +3m.body.error) +.toBe('Invalid + request +data'); +  | + +^ +  25 | +}); +  26 | +  27 | +test('GET +/unknown-route should return +404 Not Found in RFC 7807 +format', +async () +=> { + + at Object.toBe (tests/i +ntegration/errorHandling.test +.js:24:33) + + ΓùÅ API Integration Tests +(RFC 7807) ΓÇ║ GET /health +should return status ok + + expect(received).toBe(exp +ected) // Object.is equality + + Expected: "ok" + Received: undefined + +   36 | +const response += await r +equest(app).ge +t('/health')[ +33m; +  37 | expe +ct(response.status) +.toBe(200 +); + +> 38 +| expect(response[3 +3m.body.status +).toBe('ok'[3 +9m); +  | + +^ +  39 | +}); +  40 | +  41 | +test('GET /api should +return api +info', +async () +=> { + + at Object.toBe (tests/i +ntegration/errorHandling.test +.js:38:34) + + ΓùÅ API Integration Tests +(RFC 7807) ΓÇ║ GET /api +should return api info + + expect(received).toBe(exp +ected) // Object.is equality + + Expected: "LiquiFact API" + Received: undefined + +   42 | +const response += await r +equest(app).ge +t('/api') +; +  43 | expe +ct(response.status) +.toBe(200 +); + +> 44 +| expect(response[3 +3m.body.name) +[33m.toBe('LiquiFac +t API'); +  | + +^ +  45 | +}); +  46 | +  47 | +test('GET +/api/escrow/:invoiceId +should return 200 with +escrow data (requires +auth)', +async () +=> { + + at Object.toBe (tests/i +ntegration/errorHandling.test +.js:44:32) + + +Test Suites: 2 failed, 19 +passed, 21 total +Tests: 4 failed, 148 +passed, 152 total +Snapshots: 0 total +Time: 8.061 s +Ran all test suites. diff --git a/full_test_output.txt b/full_test_output.txt new file mode 100644 index 00000000..63f33ce9 Binary files /dev/null and b/full_test_output.txt differ diff --git a/full_test_results.json b/full_test_results.json new file mode 100644 index 00000000..b43ee7dc Binary files /dev/null and b/full_test_results.json differ diff --git a/full_test_utf8.txt b/full_test_utf8.txt new file mode 100644 index 00000000..bb21a00c --- /dev/null +++ b/full_test_utf8.txt @@ -0,0 +1,2385 @@ +node.exe : npm warn invalid +config cache=false set in +command line options +At C:\Users\pc\AppData\Roamin +g\npm\npm.ps1:24 char:5 ++ & "node$exe" "$basedir +/node_modules/npm/bin/npm-cli +.js" $args ++ ~~~~~~~~~~~~~~~~~~~~~~~ +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +~~~~~~~~~~ + + CategoryInfo + : NotSpecified: (npm war + n invali...nd line optio + ns:String) [], RemoteExc +eption + + FullyQualifiedErrorId + : NativeCommandError + +npm warn invalid config Must +be valid filesystem path + +> backend@1.0.0 test:coverage +> jest --coverage + +FAIL tests/unit/errorHandler. +test.js + ΓùÅ errorHandler +Middleware Unit Tests ΓÇ║ +should handle AppError and +send RFC 7807 response + + expect(jest.fn()).toHaveB +eenCalledWith(...expected) + + Expected: +ObjectContaining {"detail": +"Invalid data", "error": +"Bad Request", "instance": +"/api/v1/test", "status": +400, "title": "Bad Request", +"type": "https://liquifact.co +m/probs/bad-request"} + Received: {"data": null, +"detail": "Invalid data", +"error": {"code": +"BAD_REQUEST", "details": +"Invalid data", "message": +"Bad Request"}, "instance": +"/api/v1/test", "meta": +{"timestamp": +"2026-03-28T17:37:30.938Z", +"version": "0.1.0"}, +"stack": "AppError: Bad +Request + +   26 | +  27 | +test('should handle +AppError and send RFC 7807 +response', () +=> { + +> 28 +| const +error = +new +AppError({ +  | + +^ +  29 | +type: 'https:/ +/liquifact.com/probs/bad-requ +est', +  30 | +title: 'Bad +Request', +  31 | +status: +400, + + at Object. ( +tests/unit/errorHandler.test. +js:28:19) + Number of calls: 1 + at +Object.toHaveBeenCalledWith ( +tests/unit/errorHandler.test. +js:39:31) + + ΓùÅ errorHandler +Middleware Unit Tests ΓÇ║ +should handle generic Error +and fallback to 500 + + expect(jest.fn()).toHaveB +eenCalledWith(...expected) + + Expected: +ObjectContaining {"detail": +"An unexpected error +occurred while processing +your request.", "error": +"Internal Server Error", +"status": 500, "title": +"Internal Server Error"} + Received: {"data": null, +"detail": "Error: Something +exploded", "error": {"code": +"INTERNAL_ERROR", "details": +"Error: Something exploded", +"message": "Internal Server +Error"}, "instance": +"/api/v1/test", "meta": +{"timestamp": +"2026-03-28T17:37:30.953Z", +"version": "0.1.0"}, +"stack": "Error: Something +exploded + +   50 | +  51 | +test('should handle +generic Error and fallback +to 500', () +=> { + +> 52 +| const +error = +new Error +('Something +exploded'); +  | + +^ +  53 | +  54 | erro +rHandler(error, +mockRequest, +mockResponse, +nextFunction); +  55 | + + at Object. ( +tests/unit/errorHandler.test. +js:52:19) + Number of calls: 1 + at +Object.toHaveBeenCalledWith ( +tests/unit/errorHandler.test. +js:57:31) + +FAIL src/__tests__/validate.t +est.js + ΓùÅ Validation Middleware +ΓÇ║ validateRequest ΓÇ║ +should return 400 with +details if data is invalid + + TypeError: Cannot read +properties of undefined +(reading 'map') + +   16 | + title: +'Validation +Failed', +  17 | + status: +400, + +> 18 +| +detail: error. +errors.map(e +=> +`${e.path.join('.')}: ${ +e.message}`).j +oin(', +'), +  | + +^ +  19 | + instance: r +eq.originalUrl +, +  20 | + })); +  21 | +} + + at map (src/middleware/ +validate.js:18:38) + at Object.middleware (s +rc/__tests__/validate.test.js +:44:13) + +FAIL tests/unit/asyncHandler. +test.js + ΓùÅ Console + + console.error + Unhandled Error: +Error: Test error + at C:\Users\pc\Docu +ments\waves\Liquifact-backend +\tests\unit\asyncHandler.test +.js:27:17 + at fn (C:\Users\pc\ +Documents\waves\Liquifact-bac +kend\src\utils\asyncHandler.j +s:10:21) + at +Layer.handleRequest (C:\Users +\pc\Documents\waves\Liquifact +-backend\node_modules\router\ +lib\layer.js:152:17) + at next (C:\Users\p +c\Documents\waves\Liquifact-b +ackend\node_modules\router\li +b\route.js:157:13) + at Route.dispatch ( +C:\Users\pc\Documents\waves\L +iquifact-backend\node_modules +\router\lib\route.js:117:3) + at handle (C:\Users +\pc\Documents\waves\Liquifact +-backend\node_modules\router\ +index.js:435:11) + at +Layer.handleRequest (C:\Users +\pc\Documents\waves\Liquifact +-backend\node_modules\router\ +lib\layer.js:152:17) + at C:\Users\pc\Docu +ments\waves\Liquifact-backend +\node_modules\router\index.js +:295:15 + at processParams (C +:\Users\pc\Documents\waves\Li +quifact-backend\node_modules\ +router\index.js:582:12) + at next (C:\Users\p +c\Documents\waves\Liquifact-b +ackend\node_modules\router\in +dex.js:291:5) + at read (C:\Users\p +c\Documents\waves\Liquifact-b +ackend\node_modules\body-pars +er\lib\read.js:53:5) + at jsonParser (C:\U +sers\pc\Documents\waves\Liqui +fact-backend\node_modules\bod +y-parser\lib\types\json.js:88 +:5) + at +Layer.handleRequest (C:\Users +\pc\Documents\waves\Liquifact +-backend\node_modules\router\ +lib\layer.js:152:17) + at trimPrefix (C:\U +sers\pc\Documents\waves\Liqui +fact-backend\node_modules\rou +ter\index.js:342:13) + at C:\Users\pc\Docu +ments\waves\Liquifact-backend +\node_modules\router\index.js +:297:9 + at processParams (C +:\Users\pc\Documents\waves\Li +quifact-backend\node_modules\ +router\index.js:582:12) + at next (C:\Users\p +c\Documents\waves\Liquifact-b +ackend\node_modules\router\in +dex.js:291:5) + at Function.handle +(C:\Users\pc\Documents\waves\ +Liquifact-backend\node_module +s\router\index.js:186:3) + at Function.handle +(C:\Users\pc\Documents\waves\ +Liquifact-backend\node_module +s\express\lib\application.js: +177:15) + at Server.app (C:\U +sers\pc\Documents\waves\Liqui +fact-backend\node_modules\exp +ress\lib\express.js:38:9) + at Server.emit +(node:events:519:28) + at +parserOnIncoming +(node:_http_server:1186:12) + at HTTPParser.parse +rOnHeadersComplete +(node:_http_common:122:17) + +   31 | +// Log unexpected +errors +  32 | +if (status +=== 500) +{ + +> 33 +| console.[3 +9merror('Unhandled +Error:', +err); +  | + ^ +  34 | } +  35 | +  36 | +problem = +formatProblemDetails({ + + at error (src/middlewar +e/errorHandler.js:33:15) + at Layer.handleError (n +ode_modules/router/lib/layer. +js:116:17) + at trimPrefix (node_mod +ules/router/index.js:340:13) + at node_modules/router/ +index.js:297:9 + at processParams (node_ +modules/router/index.js:582:1 +2) + at next (node_modules/r +outer/index.js:291:5) + at next (node_modules/r +outer/lib/route.js:132:14) + + console.error + Unhandled Error: +Error: Rejected + at C:\Users\pc\Docu +ments\waves\Liquifact-backend +\tests\unit\asyncHandler.test +.js:43:49 + at fn (C:\Users\pc\ +Documents\waves\Liquifact-bac +kend\src\utils\asyncHandler.j +s:10:21) + at +Layer.handleRequest (C:\Users +\pc\Documents\waves\Liquifact +-backend\node_modules\router\ +lib\layer.js:152:17) + at next (C:\Users\p +c\Documents\waves\Liquifact-b +ackend\node_modules\router\li +b\route.js:157:13) + at Route.dispatch ( +C:\Users\pc\Documents\waves\L +iquifact-backend\node_modules +\router\lib\route.js:117:3) + at handle (C:\Users +\pc\Documents\waves\Liquifact +-backend\node_modules\router\ +index.js:435:11) + at +Layer.handleRequest (C:\Users +\pc\Documents\waves\Liquifact +-backend\node_modules\router\ +lib\layer.js:152:17) + at C:\Users\pc\Docu +ments\waves\Liquifact-backend +\node_modules\router\index.js +:295:15 + at processParams (C +:\Users\pc\Documents\waves\Li +quifact-backend\node_modules\ +router\index.js:582:12) + at next (C:\Users\p +c\Documents\waves\Liquifact-b +ackend\node_modules\router\in +dex.js:291:5) + at read (C:\Users\p +c\Documents\waves\Liquifact-b +ackend\node_modules\body-pars +er\lib\read.js:53:5) + at jsonParser (C:\U +sers\pc\Documents\waves\Liqui +fact-backend\node_modules\bod +y-parser\lib\types\json.js:88 +:5) + at +Layer.handleRequest (C:\Users +\pc\Documents\waves\Liquifact +-backend\node_modules\router\ +lib\layer.js:152:17) + at trimPrefix (C:\U +sers\pc\Documents\waves\Liqui +fact-backend\node_modules\rou +ter\index.js:342:13) + at C:\Users\pc\Docu +ments\waves\Liquifact-backend +\node_modules\router\index.js +:297:9 + at processParams (C +:\Users\pc\Documents\waves\Li +quifact-backend\node_modules\ +router\index.js:582:12) + at next (C:\Users\p +c\Documents\waves\Liquifact-b +ackend\node_modules\router\in +dex.js:291:5) + at Function.handle +(C:\Users\pc\Documents\waves\ +Liquifact-backend\node_module +s\router\index.js:186:3) + at Function.handle +(C:\Users\pc\Documents\waves\ +Liquifact-backend\node_module +s\express\lib\application.js: +177:15) + at Server.app (C:\U +sers\pc\Documents\waves\Liqui +fact-backend\node_modules\exp +ress\lib\express.js:38:9) + at Server.emit +(node:events:519:28) + at +parserOnIncoming +(node:_http_server:1186:12) + at HTTPParser.parse +rOnHeadersComplete +(node:_http_common:122:17) + +   31 | +// Log unexpected +errors +  32 | +if (status +=== 500) +{ + +> 33 +| console.[3 +9merror('Unhandled +Error:', +err); +  | + ^ +  34 | } +  35 | +  36 | +problem = +formatProblemDetails({ + + at error (src/middlewar +e/errorHandler.js:33:15) + at Layer.handleError (n +ode_modules/router/lib/layer. +js:116:17) + at trimPrefix (node_mod +ules/router/index.js:340:13) + at node_modules/router/ +index.js:297:9 + at processParams (node_ +modules/router/index.js:582:1 +2) + at next (node_modules/r +outer/index.js:291:5) + at next (node_modules/r +outer/lib/route.js:132:14) + + ΓùÅ asyncHandler utility +ΓÇ║ should catch async +errors and pass to error +handler + + expect(received).toBe(exp +ected) // Object.is equality + + Expected: "Test error" + Received: "Error: Test +error" + +   34 | +expect(res.statusCo +de).toBe(500[ +39m); +  35 | expe +ct(res.body.[ +39mtitle).toBe([32 +m'Internal Server +Error'); + +> 36 +| expect(res.[ +39mbody.detail)[33 +m.toBe('Test +error'); +  | + +^ +  37 | +}); +  38 | +  39 | +it('should handle +rejected +promises', +async () +=> { + + at Object.toBe (tests/u +nit/asyncHandler.test.js:36:2 +9) + +PASS +src/__tests__/auth.test.js + ΓùÅ Console + + console.log + [dotenv@17.3.1] +injecting env (0) from .env +-- tip: ΓÜÖ∩╕Å load +multiple .env files with { +path: ['.env.local', '.env'] +} + + at _log (node_modules/d +otenv/lib/main.js:139:11) + + console.log + [dotenv@17.3.1] +injecting env (0) from .env +-- tip: ΓÜÖ∩╕Å specify +custom .env file path with { +path: '/custom/path/.env' } + + at _log (node_modules/d +otenv/lib/main.js:139:11) + + console.log + [dotenv@17.3.1] +injecting env (0) from .env +-- tip: ΓÜÖ∩╕Å specify +custom .env file path with { +path: '/custom/path/.env' } + + at _log (node_modules/d +otenv/lib/main.js:139:11) + +PASS +src/tests/response.test.js + ΓùÅ Console + + console.log + [dotenv@17.3.1] +injecting env (0) from .env +-- tip: ΓÜÖ∩╕Å load +multiple .env files with { +path: ['.env.local', '.env'] +} + + at _log (node_modules/d +otenv/lib/main.js:139:11) + + console.log + [dotenv@17.3.1] +injecting env (0) from .env +-- tip: ≡ƒ¢í∩╕Å auth for +agents: https://vestauth.com + + at _log (node_modules/d +otenv/lib/main.js:139:11) + + console.error + Unhandled Error: +Error: Triggered Error + at C:\Users\pc\Docu +ments\waves\Liquifact-backend +\src\app.js:134:10 + at +Layer.handleRequest (C:\Users +\pc\Documents\waves\Liquifact +-backend\node_modules\router\ +lib\layer.js:152:17) + at next (C:\Users\p +c\Documents\waves\Liquifact-b +ackend\node_modules\router\li +b\route.js:157:13) + at Route.dispatch ( +C:\Users\pc\Documents\waves\L +iquifact-backend\node_modules +\router\lib\route.js:117:3) + at handle (C:\Users +\pc\Documents\waves\Liquifact +-backend\node_modules\router\ +index.js:435:11) + at +Layer.handleRequest (C:\Users +\pc\Documents\waves\Liquifact +-backend\node_modules\router\ +lib\layer.js:152:17) + at C:\Users\pc\Docu +ments\waves\Liquifact-backend +\node_modules\router\index.js +:295:15 + at processParams (C +:\Users\pc\Documents\waves\Li +quifact-backend\node_modules\ +router\index.js:582:12) + at next (C:\Users\p +c\Documents\waves\Liquifact-b +ackend\node_modules\router\in +dex.js:291:5) + at C:\Users\pc\Docu +ments\waves\Liquifact-backend +\node_modules\express-rate-li +mit\dist\index.cjs:947:7 + at +processTicksAndRejections (no +de:internal/process/task_queu +es:105:5) + at C:\Users\pc\Docu +ments\waves\Liquifact-backend +\node_modules\express-rate-li +mit\dist\index.cjs:830:5 + +   31 | +// Log unexpected +errors +  32 | +if (status +=== 500) +{ + +> 33 +| console.[3 +9merror('Unhandled +Error:', +err); +  | + ^ +  34 | } +  35 | +  36 | +problem = +formatProblemDetails({ + + at error (src/middlewar +e/errorHandler.js:33:15) + at Layer.handleError (n +ode_modules/router/lib/layer. +js:116:17) + at trimPrefix (node_mod +ules/router/index.js:340:13) + at node_modules/router/ +index.js:297:9 + at processParams (node_ +modules/router/index.js:582:1 +2) + at next (node_modules/r +outer/index.js:291:5) + at next (src/middleware +/bodySizeLimits.js:177:3) + at Layer.handleError (n +ode_modules/router/lib/layer. +js:116:17) + at trimPrefix (node_mod +ules/router/index.js:340:13) + at node_modules/router/ +index.js:297:9 + at processParams (node_ +modules/router/index.js:582:1 +2) + at next (node_modules/r +outer/index.js:291:5) + at next +(src/app.js:149:5) + at Layer.handleError (n +ode_modules/router/lib/layer. +js:116:17) + at trimPrefix (node_mod +ules/router/index.js:340:13) + at node_modules/router/ +index.js:297:9 + at processParams (node_ +modules/router/index.js:582:1 +2) + at next (node_modules/r +outer/index.js:291:5) + at Layer.handleError (n +ode_modules/router/lib/layer. +js:111:12) + at trimPrefix (node_mod +ules/router/index.js:340:13) + at node_modules/router/ +index.js:297:9 + at processParams (node_ +modules/router/index.js:582:1 +2) + at next (node_modules/r +outer/index.js:291:5) + at next (node_modules/r +outer/lib/route.js:132:14) + at next +(src/app.js:134:5) + at Layer.handleRequest +(node_modules/router/lib/laye +r.js:152:17) + at next (node_modules/r +outer/lib/route.js:157:13) + at Route.dispatch (node +_modules/router/lib/route.js: +117:3) + at handle (node_modules +/router/index.js:435:11) + at Layer.handleRequest +(node_modules/router/lib/laye +r.js:152:17) + at node_modules/router/ +index.js:295:15 + at processParams (node_ +modules/router/index.js:582:1 +2) + at next (node_modules/r +outer/index.js:291:5) + at node_modules/express +-rate-limit/dist/index.cjs:94 +7:7 + at node_modules/express +-rate-limit/dist/index.cjs:83 +0:5 + + console.error + Unhandled Error: +Error: Triggered Error + at C:\Users\pc\Docu +ments\waves\Liquifact-backend +\src\app.js:134:10 + at +Layer.handleRequest (C:\Users +\pc\Documents\waves\Liquifact +-backend\node_modules\router\ +lib\layer.js:152:17) + at next (C:\Users\p +c\Documents\waves\Liquifact-b +ackend\node_modules\router\li +b\route.js:157:13) + at Route.dispatch ( +C:\Users\pc\Documents\waves\L +iquifact-backend\node_modules +\router\lib\route.js:117:3) + at handle (C:\Users +\pc\Documents\waves\Liquifact +-backend\node_modules\router\ +index.js:435:11) + at +Layer.handleRequest (C:\Users +\pc\Documents\waves\Liquifact +-backend\node_modules\router\ +lib\layer.js:152:17) + at C:\Users\pc\Docu +ments\waves\Liquifact-backend +\node_modules\router\index.js +:295:15 + at processParams (C +:\Users\pc\Documents\waves\Li +quifact-backend\node_modules\ +router\index.js:582:12) + at next (C:\Users\p +c\Documents\waves\Liquifact-b +ackend\node_modules\router\in +dex.js:291:5) + at C:\Users\pc\Docu +ments\waves\Liquifact-backend +\node_modules\express-rate-li +mit\dist\index.cjs:947:7 + at +processTicksAndRejections (no +de:internal/process/task_queu +es:105:5) + at C:\Users\pc\Docu +ments\waves\Liquifact-backend +\node_modules\express-rate-li +mit\dist\index.cjs:830:5 + +   31 | +// Log unexpected +errors +  32 | +if (status +=== 500) +{ + +> 33 +| console.[3 +9merror('Unhandled +Error:', +err); +  | + ^ +  34 | } +  35 | +  36 | +problem = +formatProblemDetails({ + + at error (src/middlewar +e/errorHandler.js:33:15) + at Layer.handleError (n +ode_modules/router/lib/layer. +js:116:17) + at trimPrefix (node_mod +ules/router/index.js:340:13) + at node_modules/router/ +index.js:297:9 + at processParams (node_ +modules/router/index.js:582:1 +2) + at next (node_modules/r +outer/index.js:291:5) + at next (src/middleware +/bodySizeLimits.js:177:3) + at Layer.handleError (n +ode_modules/router/lib/layer. +js:116:17) + at trimPrefix (node_mod +ules/router/index.js:340:13) + at node_modules/router/ +index.js:297:9 + at processParams (node_ +modules/router/index.js:582:1 +2) + at next (node_modules/r +outer/index.js:291:5) + at next +(src/app.js:149:5) + at Layer.handleError (n +ode_modules/router/lib/layer. +js:116:17) + at trimPrefix (node_mod +ules/router/index.js:340:13) + at node_modules/router/ +index.js:297:9 + at processParams (node_ +modules/router/index.js:582:1 +2) + at next (node_modules/r +outer/index.js:291:5) + at Layer.handleError (n +ode_modules/router/lib/layer. +js:111:12) + at trimPrefix (node_mod +ules/router/index.js:340:13) + at node_modules/router/ +index.js:297:9 + at processParams (node_ +modules/router/index.js:582:1 +2) + at next (node_modules/r +outer/index.js:291:5) + at next (node_modules/r +outer/lib/route.js:132:14) + at next +(src/app.js:134:5) + at Layer.handleRequest +(node_modules/router/lib/laye +r.js:152:17) + at next (node_modules/r +outer/lib/route.js:157:13) + at Route.dispatch (node +_modules/router/lib/route.js: +117:3) + at handle (node_modules +/router/index.js:435:11) + at Layer.handleRequest +(node_modules/router/lib/laye +r.js:152:17) + at node_modules/router/ +index.js:295:15 + at processParams (node_ +modules/router/index.js:582:1 +2) + at next (node_modules/r +outer/index.js:291:5) + at node_modules/express +-rate-limit/dist/index.cjs:94 +7:7 + at node_modules/express +-rate-limit/dist/index.cjs:83 +0:5 + +FAIL src/index.test.js + ΓùÅ Console + + console.log + [dotenv@17.3.1] +injecting env (0) from .env +-- tip: ΓÜÖ∩╕Å override +existing env vars with { +override: true } + + at _log (node_modules/d +otenv/lib/main.js:139:11) + + console.log + [dotenv@17.3.1] +injecting env (0) from .env +-- tip: ≡ƒñû agentic secret +storage: +https://dotenvx.com/as2 + + at _log (node_modules/d +otenv/lib/main.js:139:11) + + console.log + [dotenv@17.3.1] +injecting env (0) from .env +-- tip: ΓÜÖ∩╕Å specify +custom .env file path with { +path: '/custom/path/.env' } + + at _log (node_modules/d +otenv/lib/main.js:139:11) + + ΓùÅ LiquiFact API ΓÇ║ +Invoices Lifecycle ΓÇ║ POST +/api/invoices - fails if +missing fields + + expect(received).toBe(exp +ected) // Object.is equality + + Expected: 400 + Received: 201 + +   56 | + .set( +'Authorization'[33 +m, `Bearer +${token}`) +  57 | +.send({ +amount: +1000 }); + +> 58 +| expect(response +[33m.status).t +oBe(400); +  | + +^ +  59 | +}); +  60 | +  61 | +it('GET /api/invoices - +lists active +invoices', +async () +=> { + + at Object.toBe +(src/index.test.js:58:31) + +FAIL tests/integration/errorH +andling.test.js + ΓùÅ Console + + console.log + [dotenv@17.3.1] +injecting env (0) from .env +-- tip: ΓÜí∩╕Å secrets for +agents: +https://dotenvx.com/as2 + + at _log (node_modules/d +otenv/lib/main.js:139:11) + + console.log + [dotenv@17.3.1] +injecting env (0) from .env +-- tip: ΓÜÖ∩╕Å enable debug +logging with { debug: true } + + at _log (node_modules/d +otenv/lib/main.js:139:11) + + console.log + [dotenv@17.3.1] +injecting env (0) from .env +-- tip: ΓÜí∩╕Å secrets for +agents: +https://dotenvx.com/as2 + + at _log (node_modules/d +otenv/lib/main.js:139:11) + + console.error + Unhandled Error: +TypeError: Cannot read +properties of undefined +(reading 'map') + at map (C:\Users\pc +\Documents\waves\Liquifact-ba +ckend\src\middleware\validate +.js:18:38) + at +Layer.handleRequest (C:\Users +\pc\Documents\waves\Liquifact +-backend\node_modules\router\ +lib\layer.js:152:17) + at next (C:\Users\p +c\Documents\waves\Liquifact-b +ackend\node_modules\router\li +b\route.js:157:13) + at next (C:\Users\p +c\Documents\waves\Liquifact-b +ackend\src\middleware\auth.js +:45:5) + at C:\Users\pc\Docu +ments\waves\Liquifact-backend +\node_modules\jsonwebtoken\ve +rify.js:261:12 + at getSecret (C:\Us +ers\pc\Documents\waves\Liquif +act-backend\node_modules\json +webtoken\verify.js:97:14) + at +Object.module.exports [as +verify] (C:\Users\pc\Document +s\waves\Liquifact-backend\nod +e_modules\jsonwebtoken\verify +.js:101:10) + at verify (C:\Users +\pc\Documents\waves\Liquifact +-backend\src\middleware\auth. +js:35:7) + at +Layer.handleRequest (C:\Users +\pc\Documents\waves\Liquifact +-backend\node_modules\router\ +lib\layer.js:152:17) + at next (C:\Users\p +c\Documents\waves\Liquifact-b +ackend\node_modules\router\li +b\route.js:157:13) + at C:\Users\pc\Docu +ments\waves\Liquifact-backend +\node_modules\express-rate-li +mit\dist\index.cjs:947:7 + at +processTicksAndRejections (no +de:internal/process/task_queu +es:105:5) + at C:\Users\pc\Docu +ments\waves\Liquifact-backend +\node_modules\express-rate-li +mit\dist\index.cjs:830:5 + +   31 | +// Log unexpected +errors +  32 | +if (status +=== 500) +{ + +> 33 +| console.[3 +9merror('Unhandled +Error:', +err); +  | + ^ +  34 | } +  35 | +  36 | +problem = +formatProblemDetails({ + + at error (src/middlewar +e/errorHandler.js:33:15) + at Layer.handleError (n +ode_modules/router/lib/layer. +js:116:17) + at trimPrefix (node_mod +ules/router/index.js:340:13) + at node_modules/router/ +index.js:297:9 + at processParams (node_ +modules/router/index.js:582:1 +2) + at next (node_modules/r +outer/index.js:291:5) + at next (src/middleware +/bodySizeLimits.js:177:3) + at Layer.handleError (n +ode_modules/router/lib/layer. +js:116:17) + at trimPrefix (node_mod +ules/router/index.js:340:13) + at node_modules/router/ +index.js:297:9 + at processParams (node_ +modules/router/index.js:582:1 +2) + at next (node_modules/r +outer/index.js:291:5) + at next +(src/app.js:149:5) + at Layer.handleError (n +ode_modules/router/lib/layer. +js:116:17) + at trimPrefix (node_mod +ules/router/index.js:340:13) + at node_modules/router/ +index.js:297:9 + at processParams (node_ +modules/router/index.js:582:1 +2) + at next (node_modules/r +outer/index.js:291:5) + at Layer.handleError (n +ode_modules/router/lib/layer. +js:111:12) + at trimPrefix (node_mod +ules/router/index.js:340:13) + at node_modules/router/ +index.js:297:9 + at processParams (node_ +modules/router/index.js:582:1 +2) + at next (node_modules/r +outer/index.js:291:5) + at next (node_modules/r +outer/lib/route.js:132:14) + at Layer.handleError (n +ode_modules/router/lib/layer. +js:111:12) + at next (node_modules/r +outer/lib/route.js:155:13) + at Layer.handleError (n +ode_modules/router/lib/layer. +js:111:12) + at next (node_modules/r +outer/lib/route.js:155:13) + at Layer.handleRequest +(node_modules/router/lib/laye +r.js:165:5) + at next (node_modules/r +outer/lib/route.js:157:13) + at next +(src/middleware/auth.js:45:5) + at node_modules/jsonweb +token/verify.js:261:12 + at getSecret (node_modu +les/jsonwebtoken/verify.js:97 +:14) + at +Object.module.exports [as +verify] (node_modules/jsonweb +token/verify.js:101:10) + at verify +(src/middleware/auth.js:35:7) + at Layer.handleRequest +(node_modules/router/lib/laye +r.js:152:17) + at next (node_modules/r +outer/lib/route.js:157:13) + at node_modules/express +-rate-limit/dist/index.cjs:94 +7:7 + at node_modules/express +-rate-limit/dist/index.cjs:83 +0:5 + + ΓùÅ API Integration Tests +(RFC 7807) ΓÇ║ POST +/api/invoices without amount +should return 400 Bad +Request (Validation Error) + + expect(received).toBe(exp +ected) // Object.is equality + + Expected: 400 + Received: 500 + +   21 | + .send({ +customer: +'Test' +}); // +Missing 'amount' +  22 | + +> 23 +| expect(response[3 +3m.status).toB +e(400); +  | + +^ +  24 | expe +ct(response.body[3 +3m.error).toBe +('Invalid request +data'); +  25 | +}); +  26 | + + at Object.toBe (tests/i +ntegration/errorHandling.test +.js:23:29) + + ΓùÅ API Integration Tests +(RFC 7807) ΓÇ║ GET /health +should return status ok + + expect(received).toBe(exp +ected) // Object.is equality + + Expected: "ok" + Received: undefined + +   36 | +const response += await r +equest(app).ge +t('/health')[ +33m; +  37 | expe +ct(response.status) +.toBe(200 +); + +> 38 +| expect(response[3 +3m.body.status +).toBe('ok'[3 +9m); +  | + +^ +  39 | +}); +  40 | +  41 | +test('GET /api should +return api +info', +async () +=> { + + at Object.toBe (tests/i +ntegration/errorHandling.test +.js:38:34) + + ΓùÅ API Integration Tests +(RFC 7807) ΓÇ║ GET /api +should return api info + + expect(received).toBe(exp +ected) // Object.is equality + + Expected: "LiquiFact API" + Received: undefined + +   42 | +const response += await r +equest(app).ge +t('/api') +; +  43 | expe +ct(response.status) +.toBe(200 +); + +> 44 +| expect(response[3 +3m.body.name) +[33m.toBe('LiquiFac +t API'); +  | + +^ +  45 | +}); +  46 | +  47 | +test('GET +/api/escrow/:invoiceId +should return 200 with +escrow data (requires +auth)', +async () +=> { + + at Object.toBe (tests/i +ntegration/errorHandling.test +.js:44:32) + +PASS src/__tests__/invoice.ap +i.test.js + ΓùÅ Console + + console.log + [dotenv@17.3.1] +injecting env (0) from .env +-- tip: ΓÜÖ∩╕Å enable debug +logging with { debug: true } + + at _log (node_modules/d +otenv/lib/main.js:139:11) + + console.log + [dotenv@17.3.1] +injecting env (0) from .env +-- tip: ≡ƒñû agentic secret +storage: +https://dotenvx.com/as2 + + at _log (node_modules/d +otenv/lib/main.js:139:11) + + console.error + Unhandled Error: +Error: Service failure + at +Object. (C:\Users\ +pc\Documents\waves\Liquifact- +backend\src\__tests__\invoice +.api.test.js:107:52) + at +Promise.finally.completed (C: +\Users\pc\Documents\waves\Liq +uifact-backend\node_modules\j +est-circus\build\jestAdapterI +nit.js:1557:28) + at new Promise +() + at +callAsyncCircusFn (C:\Users\p +c\Documents\waves\Liquifact-b +ackend\node_modules\jest-circ +us\build\jestAdapterInit.js:1 +497:10) + at _callCircusTest +(C:\Users\pc\Documents\waves\ +Liquifact-backend\node_module +s\jest-circus\build\jestAdapt +erInit.js:1007:40) + at +processTicksAndRejections (no +de:internal/process/task_queu +es:105:5) + at _runTest (C:\Use +rs\pc\Documents\waves\Liquifa +ct-backend\node_modules\jest- +circus\build\jestAdapterInit. +js:947:3) + at C:\Users\pc\Docu +ments\waves\Liquifact-backend +\node_modules\jest-circus\bui +ld\jestAdapterInit.js:849:7 + at +_runTestsForDescribeBlock (C: +\Users\pc\Documents\waves\Liq +uifact-backend\node_modules\j +est-circus\build\jestAdapterI +nit.js:862:11) + at +_runTestsForDescribeBlock (C: +\Users\pc\Documents\waves\Liq +uifact-backend\node_modules\j +est-circus\build\jestAdapterI +nit.js:857:11) + at +_runTestsForDescribeBlock (C: +\Users\pc\Documents\waves\Liq +uifact-backend\node_modules\j +est-circus\build\jestAdapterI +nit.js:857:11) + at run (C:\Users\pc +\Documents\waves\Liquifact-ba +ckend\node_modules\jest-circu +s\build\jestAdapterInit.js:76 +1:3) + at runAndTransformR +esultsToJestFormat (C:\Users\ +pc\Documents\waves\Liquifact- +backend\node_modules\jest-cir +cus\build\jestAdapterInit.js: +1918:21) + at jestAdapter (C:\ +Users\pc\Documents\waves\Liqu +ifact-backend\node_modules\je +st-circus\build\runner.js:101 +:19) + at runTestInternal +(C:\Users\pc\Documents\waves\ +Liquifact-backend\node_module +s\jest-runner\build\testWorke +r.js:275:16) + at runTest (C:\User +s\pc\Documents\waves\Liquifac +t-backend\node_modules\jest-r +unner\build\testWorker.js:343 +:7) + at Object.worker (C +:\Users\pc\Documents\waves\Li +quifact-backend\node_modules\ +jest-runner\build\testWorker. +js:497:12) + +   31 | +// Log unexpected +errors +  32 | +if (status +=== 500) +{ + +> 33 +| console.[3 +9merror('Unhandled +Error:', +err); +  | + ^ +  34 | } +  35 | +  36 | +problem = +formatProblemDetails({ + + at error (src/middlewar +e/errorHandler.js:33:15) + at Layer.handleError (n +ode_modules/router/lib/layer. +js:116:17) + at trimPrefix (node_mod +ules/router/index.js:340:13) + at node_modules/router/ +index.js:297:9 + at processParams (node_ +modules/router/index.js:582:1 +2) + at next (node_modules/r +outer/index.js:291:5) + at next (src/middleware +/bodySizeLimits.js:177:3) + at Layer.handleError (n +ode_modules/router/lib/layer. +js:116:17) + at trimPrefix (node_mod +ules/router/index.js:340:13) + at node_modules/router/ +index.js:297:9 + at processParams (node_ +modules/router/index.js:582:1 +2) + at next (node_modules/r +outer/index.js:291:5) + at next +(src/app.js:149:5) + at Layer.handleError (n +ode_modules/router/lib/layer. +js:116:17) + at trimPrefix (node_mod +ules/router/index.js:340:13) + at node_modules/router/ +index.js:297:9 + at processParams (node_ +modules/router/index.js:582:1 +2) + at next (node_modules/r +outer/index.js:291:5) + at Layer.handleError (n +ode_modules/router/lib/layer. +js:111:12) + at trimPrefix (node_mod +ules/router/index.js:340:13) + at node_modules/router/ +index.js:297:9 + at processParams (node_ +modules/router/index.js:582:1 +2) + at next (node_modules/r +outer/index.js:291:5) + at next (node_modules/r +outer/lib/route.js:132:14) + +PASS src/config/cors.test.js +PASS tests/unit/invoice.servi +ce.test.js + ΓùÅ Console + + console.error + Error fetching +invoices: Error: DB Error + at +Function. (C:\User +s\pc\Documents\waves\Liquifac +t-backend\tests\unit\invoice. +service.test.js:36:66) + at C:\Users\pc\Docu +ments\waves\Liquifact-backend +\node_modules\jest-mock\build +\index.js:305:39 + at +Function. (C:\User +s\pc\Documents\waves\Liquifac +t-backend\node_modules\jest-m +ock\build\index.js:312:13) + at +Function.mockConstructor [as +then] (C:\Users\pc\Documents\ +waves\Liquifact-backend\node_ +modules\jest-mock\build\index +.js:57:19) + at +processTicksAndRejections (no +de:internal/process/task_queu +es:105:5) + +   42 | +return +await +query; +  43 | } +catch (error) { + +> 44 +| console. +error('Error fetching +invoices:', +error); +  | + ^ +  45 | +throw +new Error +('Database error while +fetching +invoices'); +  46 | } +  47 | } + + at error (src/services/ +invoice.service.js:44:13) + at Object. ( +tests/unit/invoice.service.te +st.js:38:5) + +PASS src/__tests__/deprecatio +n.test.js +PASS tests/app.test.js + ΓùÅ Console + + console.error + Unhandled Error: +Error: Boom + at C:\Users\pc\Docu +ments\waves\Liquifact-backend +\tests\app.test.js:10:51 + at fn (C:\Users\pc\ +Documents\waves\Liquifact-bac +kend\src\utils\asyncHandler.j +s:10:21) + at +Layer.handleRequest (C:\Users +\pc\Documents\waves\Liquifact +-backend\node_modules\router\ +lib\layer.js:152:17) + at next (C:\Users\p +c\Documents\waves\Liquifact-b +ackend\node_modules\router\li +b\route.js:157:13) + at Route.dispatch ( +C:\Users\pc\Documents\waves\L +iquifact-backend\node_modules +\router\lib\route.js:117:3) + at handle (C:\Users +\pc\Documents\waves\Liquifact +-backend\node_modules\router\ +index.js:435:11) + at +Layer.handleRequest (C:\Users +\pc\Documents\waves\Liquifact +-backend\node_modules\router\ +lib\layer.js:152:17) + at C:\Users\pc\Docu +ments\waves\Liquifact-backend +\node_modules\router\index.js +:295:15 + at processParams (C +:\Users\pc\Documents\waves\Li +quifact-backend\node_modules\ +router\index.js:582:12) + at next (C:\Users\p +c\Documents\waves\Liquifact-b +ackend\node_modules\router\in +dex.js:291:5) + at read (C:\Users\p +c\Documents\waves\Liquifact-b +ackend\node_modules\body-pars +er\lib\read.js:53:5) + at jsonParser (C:\U +sers\pc\Documents\waves\Liqui +fact-backend\node_modules\bod +y-parser\lib\types\json.js:88 +:5) + at +Layer.handleRequest (C:\Users +\pc\Documents\waves\Liquifact +-backend\node_modules\router\ +lib\layer.js:152:17) + at trimPrefix (C:\U +sers\pc\Documents\waves\Liqui +fact-backend\node_modules\rou +ter\index.js:342:13) + at C:\Users\pc\Docu +ments\waves\Liquifact-backend +\node_modules\router\index.js +:297:9 + at processParams (C +:\Users\pc\Documents\waves\Li +quifact-backend\node_modules\ +router\index.js:582:12) + at next (C:\Users\p +c\Documents\waves\Liquifact-b +ackend\node_modules\router\in +dex.js:291:5) + at Function.handle +(C:\Users\pc\Documents\waves\ +Liquifact-backend\node_module +s\router\index.js:186:3) + at Function.handle +(C:\Users\pc\Documents\waves\ +Liquifact-backend\node_module +s\express\lib\application.js: +177:15) + at Server.app (C:\U +sers\pc\Documents\waves\Liqui +fact-backend\node_modules\exp +ress\lib\express.js:38:9) + at Server.emit +(node:events:519:28) + at +parserOnIncoming +(node:_http_server:1186:12) + at HTTPParser.parse +rOnHeadersComplete +(node:_http_common:122:17) + +   31 | +// Log unexpected +errors +  32 | +if (status +=== 500) +{ + +> 33 +| console.[3 +9merror('Unhandled +Error:', +err); +  | + ^ +  34 | } +  35 | +  36 | +problem = +formatProblemDetails({ + + at error (src/middlewar +e/errorHandler.js:33:15) + at Layer.handleError (n +ode_modules/router/lib/layer. +js:116:17) + at trimPrefix (node_mod +ules/router/index.js:340:13) + at node_modules/router/ +index.js:297:9 + at processParams (node_ +modules/router/index.js:582:1 +2) + at next (node_modules/r +outer/index.js:291:5) + at next (node_modules/r +outer/lib/route.js:132:14) + +PASS +tests/unit/AppError.test.js +PASS +tests/unit/validators.test.js +PASS +src/services/soroban.test.js +PASS tests/unit/queryBuilder. +test.js +PASS src/app.test.js + ΓùÅ Console + + console.log + [dotenv@17.3.1] +injecting env (0) from .env +-- tip: ≡ƒ¢á∩╕Å run +anywhere with `dotenvx run +-- yourcommand` + + at _log (node_modules/d +otenv/lib/main.js:139:11) + + console.log + [dotenv@17.3.1] +injecting env (0) from .env +-- tip: ΓÜÖ∩╕Å suppress all +logs with { quiet: true } + + at _log (node_modules/d +otenv/lib/main.js:139:11) + + console.error + Unhandled Error: +Error: Triggered Error + at C:\Users\pc\Docu +ments\waves\Liquifact-backend +\src\app.js:134:10 + at +Layer.handleRequest (C:\Users +\pc\Documents\waves\Liquifact +-backend\node_modules\router\ +lib\layer.js:152:17) + at next (C:\Users\p +c\Documents\waves\Liquifact-b +ackend\node_modules\router\li +b\route.js:157:13) + at Route.dispatch ( +C:\Users\pc\Documents\waves\L +iquifact-backend\node_modules +\router\lib\route.js:117:3) + at handle (C:\Users +\pc\Documents\waves\Liquifact +-backend\node_modules\router\ +index.js:435:11) + at +Layer.handleRequest (C:\Users +\pc\Documents\waves\Liquifact +-backend\node_modules\router\ +lib\layer.js:152:17) + at C:\Users\pc\Docu +ments\waves\Liquifact-backend +\node_modules\router\index.js +:295:15 + at processParams (C +:\Users\pc\Documents\waves\Li +quifact-backend\node_modules\ +router\index.js:582:12) + at next (C:\Users\p +c\Documents\waves\Liquifact-b +ackend\node_modules\router\in +dex.js:291:5) + at C:\Users\pc\Docu +ments\waves\Liquifact-backend +\node_modules\express-rate-li +mit\dist\index.cjs:947:7 + at +processTicksAndRejections (no +de:internal/process/task_queu +es:105:5) + at C:\Users\pc\Docu +ments\waves\Liquifact-backend +\node_modules\express-rate-li +mit\dist\index.cjs:830:5 + +   31 | +// Log unexpected +errors +  32 | +if (status +=== 500) +{ + +> 33 +| console.[3 +9merror('Unhandled +Error:', +err); +  | + ^ +  34 | } +  35 | +  36 | +problem = +formatProblemDetails({ + + at error (src/middlewar +e/errorHandler.js:33:15) + at Layer.handleError (n +ode_modules/router/lib/layer. +js:116:17) + at trimPrefix (node_mod +ules/router/index.js:340:13) + at node_modules/router/ +index.js:297:9 + at processParams (node_ +modules/router/index.js:582:1 +2) + at next (node_modules/r +outer/index.js:291:5) + at next (src/middleware +/bodySizeLimits.js:177:3) + at Layer.handleError (n +ode_modules/router/lib/layer. +js:116:17) + at trimPrefix (node_mod +ules/router/index.js:340:13) + at node_modules/router/ +index.js:297:9 + at processParams (node_ +modules/router/index.js:582:1 +2) + at next (node_modules/r +outer/index.js:291:5) + at next +(src/app.js:149:5) + at Layer.handleError (n +ode_modules/router/lib/layer. +js:116:17) + at trimPrefix (node_mod +ules/router/index.js:340:13) + at node_modules/router/ +index.js:297:9 + at processParams (node_ +modules/router/index.js:582:1 +2) + at next (node_modules/r +outer/index.js:291:5) + at Layer.handleError (n +ode_modules/router/lib/layer. +js:111:12) + at trimPrefix (node_mod +ules/router/index.js:340:13) + at node_modules/router/ +index.js:297:9 + at processParams (node_ +modules/router/index.js:582:1 +2) + at next (node_modules/r +outer/index.js:291:5) + at next (node_modules/r +outer/lib/route.js:132:14) + at next +(src/app.js:134:5) + at Layer.handleRequest +(node_modules/router/lib/laye +r.js:152:17) + at next (node_modules/r +outer/lib/route.js:157:13) + at Route.dispatch (node +_modules/router/lib/route.js: +117:3) + at handle (node_modules +/router/index.js:435:11) + at Layer.handleRequest +(node_modules/router/lib/laye +r.js:152:17) + at node_modules/router/ +index.js:295:15 + at processParams (node_ +modules/router/index.js:582:1 +2) + at next (node_modules/r +outer/index.js:291:5) + at node_modules/express +-rate-limit/dist/index.cjs:94 +7:7 + at node_modules/express +-rate-limit/dist/index.cjs:83 +0:5 + +PASS src/__tests__/bodySizeLi +mits.test.js + ΓùÅ Console + + console.log + [dotenv@17.3.1] +injecting env (0) from .env +-- tip: ΓÜí∩╕Å secrets for +agents: +https://dotenvx.com/as2 + + at _log (node_modules/d +otenv/lib/main.js:139:11) + + console.log + [dotenv@17.3.1] +injecting env (0) from .env +-- tip: ≡ƒöÉ prevent +committing .env to code: +https://dotenvx.com/precommit + + at _log (node_modules/d +otenv/lib/main.js:139:11) + +PASS src/__tests__/rateLimit. +test.js + ΓùÅ Console + + console.log + [dotenv@17.3.1] +injecting env (0) from .env +-- tip: ≡ƒñû agentic secret +storage: +https://dotenvx.com/as2 + + at _log (node_modules/d +otenv/lib/main.js:139:11) + + console.log + [dotenv@17.3.1] +injecting env (0) from .env +-- tip: ΓÜÖ∩╕Å write to +custom object with { +processEnv: myObject } + + at _log (node_modules/d +otenv/lib/main.js:139:11) + + console.log + [dotenv@17.3.1] +injecting env (0) from .env +-- tip: ≡ƒ¢í∩╕Å auth for +agents: https://vestauth.com + + at _log (node_modules/d +otenv/lib/main.js:139:11) + +PASS tests/unit/problemDetail +s.test.js +PASS src/utils/retry.test.js +---------------------|---------|----------|---------|---------|------------------- +File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s +---------------------|---------|----------|---------|---------|------------------- +All files | 95.98 | 88.84 | 95.31 | 97.15 | + src | 98.68 | 78.57 | 100 | 98.59 | + app.js | 98.59 | 80 | 100 | 98.48 | 110 + index.js | 100 | 75 | 100 | 100 | 20 + src/config | 92.59 | 88.88 | 88.88 | 91.66 | + cors.js | 92.59 | 88.88 | 88.88 | 91.66 | 75,93 + src/errors | 100 | 100 | 100 | 100 | + AppError.js | 100 | 100 | 100 | 100 | + src/middleware | 95.28 | 89.1 | 90.9 | 95.19 | + auth.js | 100 | 100 | 100 | 100 | + bodySizeLimits.js | 90.32 | 94.44 | 87.5 | 90.32 | 76,114,147 + deprecation.js | 100 | 42.85 | 100 | 100 | 9-22 + errorHandler.js | 100 | 93.93 | 100 | 100 | 38,42 + rateLimit.js | 100 | 75 | 100 | 100 | 27 + security.js | 100 | 100 | 100 | 100 | + validate.js | 91.3 | 77.77 | 83.33 | 90.47 | 18-22 + src/schemas | 100 | 100 | 100 | 100 | + apiSchemas.js | 100 | 100 | 100 | 100 | + src/services | 87.75 | 75 | 100 | 97.43 | + invoice.service.js | 100 | 100 | 100 | 100 | + soroban.js | 84.61 | 75 | 100 | 96.55 | 117 + src/utils | 98.97 | 94.5 | 100 | 98.94 | + asyncHandler.js | 100 | 100 | 100 | 100 | + problemDetails.js | 100 | 100 | 100 | 100 | + queryBuilder.js | 100 | 87.87 | 100 | 100 | 22,24 + responseHelper.js | 100 | 100 | 100 | 100 | + retry.js | 100 | 100 | 100 | 100 | + validators.js | 97.29 | 97.22 | 100 | 97.29 | 45 +---------------------|---------|----------|---------|---------|------------------- + +Summary of all failing tests +FAIL tests/unit/errorHandler. +test.js + ΓùÅ errorHandler +Middleware Unit Tests ΓÇ║ +should handle AppError and +send RFC 7807 response + + expect(jest.fn()).toHaveB +eenCalledWith(...expected) + + Expected: +ObjectContaining {"detail": +"Invalid data", "error": +"Bad Request", "instance": +"/api/v1/test", "status": +400, "title": "Bad Request", +"type": "https://liquifact.co +m/probs/bad-request"} + Received: {"data": null, +"detail": "Invalid data", +"error": {"code": +"BAD_REQUEST", "details": +"Invalid data", "message": +"Bad Request"}, "instance": +"/api/v1/test", "meta": +{"timestamp": +"2026-03-28T17:37:30.938Z", +"version": "0.1.0"}, +"stack": "AppError: Bad +Request + +   26 | +  27 | +test('should handle +AppError and send RFC 7807 +response', () +=> { + +> 28 +| const +error = +new +AppError({ +  | + +^ +  29 | +type: 'https:/ +/liquifact.com/probs/bad-requ +est', +  30 | +title: 'Bad +Request', +  31 | +status: +400, + + at Object. ( +tests/unit/errorHandler.test. +js:28:19) + Number of calls: 1 + at +Object.toHaveBeenCalledWith ( +tests/unit/errorHandler.test. +js:39:31) + + ΓùÅ errorHandler +Middleware Unit Tests ΓÇ║ +should handle generic Error +and fallback to 500 + + expect(jest.fn()).toHaveB +eenCalledWith(...expected) + + Expected: +ObjectContaining {"detail": +"An unexpected error +occurred while processing +your request.", "error": +"Internal Server Error", +"status": 500, "title": +"Internal Server Error"} + Received: {"data": null, +"detail": "Error: Something +exploded", "error": {"code": +"INTERNAL_ERROR", "details": +"Error: Something exploded", +"message": "Internal Server +Error"}, "instance": +"/api/v1/test", "meta": +{"timestamp": +"2026-03-28T17:37:30.953Z", +"version": "0.1.0"}, +"stack": "Error: Something +exploded + +   50 | +  51 | +test('should handle +generic Error and fallback +to 500', () +=> { + +> 52 +| const +error = +new Error +('Something +exploded'); +  | + +^ +  53 | +  54 | erro +rHandler(error, +mockRequest, +mockResponse, +nextFunction); +  55 | + + at Object. ( +tests/unit/errorHandler.test. +js:52:19) + Number of calls: 1 + at +Object.toHaveBeenCalledWith ( +tests/unit/errorHandler.test. +js:57:31) + +FAIL src/__tests__/validate.t +est.js + ΓùÅ Validation Middleware +ΓÇ║ validateRequest ΓÇ║ +should return 400 with +details if data is invalid + + TypeError: Cannot read +properties of undefined +(reading 'map') + +   16 | + title: +'Validation +Failed', +  17 | + status: +400, + +> 18 +| +detail: error. +errors.map(e +=> +`${e.path.join('.')}: ${ +e.message}`).j +oin(', +'), +  | + +^ +  19 | + instance: r +eq.originalUrl +, +  20 | + })); +  21 | +} + + at map (src/middleware/ +validate.js:18:38) + at Object.middleware (s +rc/__tests__/validate.test.js +:44:13) + +FAIL tests/unit/asyncHandler. +test.js + ΓùÅ asyncHandler utility +ΓÇ║ should catch async +errors and pass to error +handler + + expect(received).toBe(exp +ected) // Object.is equality + + Expected: "Test error" + Received: "Error: Test +error" + +   34 | +expect(res.statusCo +de).toBe(500[ +39m); +  35 | expe +ct(res.body.[ +39mtitle).toBe([32 +m'Internal Server +Error'); + +> 36 +| expect(res.[ +39mbody.detail)[33 +m.toBe('Test +error'); +  | + +^ +  37 | +}); +  38 | +  39 | +it('should handle +rejected +promises', +async () +=> { + + at Object.toBe (tests/u +nit/asyncHandler.test.js:36:2 +9) + +FAIL src/index.test.js + ΓùÅ LiquiFact API ΓÇ║ +Invoices Lifecycle ΓÇ║ POST +/api/invoices - fails if +missing fields + + expect(received).toBe(exp +ected) // Object.is equality + + Expected: 400 + Received: 201 + +   56 | + .set( +'Authorization'[33 +m, `Bearer +${token}`) +  57 | +.send({ +amount: +1000 }); + +> 58 +| expect(response +[33m.status).t +oBe(400); +  | + +^ +  59 | +}); +  60 | +  61 | +it('GET /api/invoices - +lists active +invoices', +async () +=> { + + at Object.toBe +(src/index.test.js:58:31) + +FAIL tests/integration/errorH +andling.test.js + ΓùÅ API Integration Tests +(RFC 7807) ΓÇ║ POST +/api/invoices without amount +should return 400 Bad +Request (Validation Error) + + expect(received).toBe(exp +ected) // Object.is equality + + Expected: 400 + Received: 500 + +   21 | + .send({ +customer: +'Test' +}); // +Missing 'amount' +  22 | + +> 23 +| expect(response[3 +3m.status).toB +e(400); +  | + +^ +  24 | expe +ct(response.body[3 +3m.error).toBe +('Invalid request +data'); +  25 | +}); +  26 | + + at Object.toBe (tests/i +ntegration/errorHandling.test +.js:23:29) + + ΓùÅ API Integration Tests +(RFC 7807) ΓÇ║ GET /health +should return status ok + + expect(received).toBe(exp +ected) // Object.is equality + + Expected: "ok" + Received: undefined + +   36 | +const response += await r +equest(app).ge +t('/health')[ +33m; +  37 | expe +ct(response.status) +.toBe(200 +); + +> 38 +| expect(response[3 +3m.body.status +).toBe('ok'[3 +9m); +  | + +^ +  39 | +}); +  40 | +  41 | +test('GET /api should +return api +info', +async () +=> { + + at Object.toBe (tests/i +ntegration/errorHandling.test +.js:38:34) + + ΓùÅ API Integration Tests +(RFC 7807) ΓÇ║ GET /api +should return api info + + expect(received).toBe(exp +ected) // Object.is equality + + Expected: "LiquiFact API" + Received: undefined + +   42 | +const response += await r +equest(app).ge +t('/api') +; +  43 | expe +ct(response.status) +.toBe(200 +); + +> 44 +| expect(response[3 +3m.body.name) +[33m.toBe('LiquiFac +t API'); +  | + +^ +  45 | +}); +  46 | +  47 | +test('GET +/api/escrow/:invoiceId +should return 200 with +escrow data (requires +auth)', +async () +=> { + + at Object.toBe (tests/i +ntegration/errorHandling.test +.js:44:32) + + +Test Suites: 5 failed, 16 +passed, 21 total +Tests: 8 failed, 144 +passed, 152 total +Snapshots: 0 total +Time: 3.552 s +Ran all test suites. diff --git a/invoice_fail.txt b/invoice_fail.txt new file mode 100644 index 00000000..4a5cf531 Binary files /dev/null and b/invoice_fail.txt differ diff --git a/invoice_fail_utf8.txt b/invoice_fail_utf8.txt new file mode 100644 index 00000000..013587d9 --- /dev/null +++ b/invoice_fail_utf8.txt @@ -0,0 +1,177 @@ + console.log + [dotenv@17.3.1] injecting env (0) from .env -- tip: ΓÜÖ∩╕Å write to custom object with { processEnv: myObject } + + at _log (node_modules/dotenv/lib/main.js:139:11) + + console.log + [dotenv@17.3.1] injecting env (0) from .env -- tip: ΓÜÖ∩╕Å specify custom .env file path with { path: '/custom/path/.env' } + + at _log (node_modules/dotenv/lib/main.js:139:11) + + console.error + Response validation failed: [ + { + expected: 'string', + code: 'invalid_type', + path: [ 'data', 0, 'status' ], + message: 'Invalid input: expected string, received undefined' + }, + { + expected: 'string', + code: 'invalid_type', + path: [ 'data', 1, 'status' ], + message: 'Invalid input: expected string, received undefined' + } + ] + +   42 | /* istanbul ignore next */ +  43 | if (error instanceof ZodError) { + > 44 | console.error('Response validation failed:', error.issues); +  | ^ +  45 | return originalJson.call(this.status(500), { error: 'Internal server error: Response validation failed' }); +  46 | } +  47 | // In rare cases where another error happens, just throw + + at ServerResponse.error [as json] (src/middleware/validate.js:44:25) + at json (src/app.js:81:18) + +node.exe : FAIL src/__tests__ +/invoice.api.test.js +At C:\Users\pc\AppData\Roamin +g\npm\npx.ps1:24 char:5 ++ & "node$exe" "$basedir +/node_modules/npm/bin/npx-cli +.js" $args ++ ~~~~~~~~~~~~~~~~~~~~~~~ +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +~~~~~~~~~~ + + CategoryInfo + : NotSpecified: (FAIL sr + c/__tests__/invoice.api. + test.js:String) [], Remo +teException + + FullyQualifiedErrorId + : NativeCommandError + + Invoice API Integration + GET /api/invoices + ├ù should return 200 +and invoices when no query +params are provided (74 ms) + ΓêÜ should filter by +status (16 ms) + ΓêÜ should filter by +SME ID (11 ms) + ΓêÜ should filter by +date range (11 ms) + ΓêÜ should apply +sorting (10 ms) + ΓêÜ should reject +invalid status with 400 (12 +ms) + ΓêÜ should reject +invalid date format with 400 +(9 ms) + ΓêÜ should reject +multiple invalid inputs with +400 (9 ms) + ├ù should handle +service errors with 500 (15 +ms) + + ΓùÅ Invoice API +Integration ΓÇ║ GET +/api/invoices ΓÇ║ should +return 200 and invoices when +no query params are provided + + expect(received).toBe(exp +ected) // Object.is equality + + Expected: 200 + Received: 500 + +   21 | + const res += await r +equest(app).ge +t('/api/invoices'[ +39m); +  22 | + +> 23 +| expect(res. +statusCode).to +Be(200); +  | + +^ +  24 | ex +pect(res.body. +data).toEqual( +mockInvoices); +  25 | ex +pect(res.body. +message).toBe( +'Invoices retrieved succ +essfully.'); +  26 | ex +pect(invoiceService.[39 +mgetInvoices).toHav +eBeenCalledWith({ + + at Object.toBe (src/__t +ests__/invoice.api.test.js:23 +:30) + + ΓùÅ Invoice API +Integration ΓÇ║ GET +/api/invoices ΓÇ║ should +handle service errors with +500 + + expect(received).toBe(exp +ected) // Object.is equality + + Expected: "Internal +server error" + Received: {"code": +"INTERNAL_ERROR", "message": +"Internal server error"} + +   106 | +  107 | e +xpect(res.statusCod +e).toBe(500[3 +9m); + +> +108 | expect(res[ +33m.body.error +).toBe('Intern +al server +error'); +  | + +^ +  109 | +}); +  110 | +}); +  111 | +}); + + at Object.toBe (src/__t +ests__/invoice.api.test.js:10 +8:30) + +Test Suites: 1 failed, 1 +total +Tests: 2 failed, 7 +passed, 9 total +Snapshots: 0 total +Time: 1.957 s, +estimated 3 s +Ran all test suites matching +src/__tests__/invoice.api.tes +t.js. diff --git a/jest-results.json b/jest-results.json new file mode 100644 index 00000000..2167f3e9 Binary files /dev/null and b/jest-results.json differ diff --git a/node_modules/.bin/acorn.cmd b/node_modules/.bin/acorn.cmd new file mode 100644 index 00000000..f38017c4 --- /dev/null +++ b/node_modules/.bin/acorn.cmd @@ -0,0 +1,17 @@ +@ECHO off +GOTO start +:find_dp0 +SET dp0=%~dp0 +EXIT /b +:start +SETLOCAL +CALL :find_dp0 + +IF EXIST "%dp0%\node.exe" ( + SET "_prog=%dp0%\node.exe" +) ELSE ( + SET "_prog=node" + SET PATHEXT=%PATHEXT:;.JS;=;% +) + +endLocal & goto #_undefined_# 2>NUL || title %COMSPEC% & "%_prog%" "%dp0%\..\acorn\bin\acorn" %* diff --git a/node_modules/.bin/acorn.ps1 b/node_modules/.bin/acorn.ps1 new file mode 100644 index 00000000..6f6dcddf --- /dev/null +++ b/node_modules/.bin/acorn.ps1 @@ -0,0 +1,28 @@ +#!/usr/bin/env pwsh +$basedir=Split-Path $MyInvocation.MyCommand.Definition -Parent + +$exe="" +if ($PSVersionTable.PSVersion -lt "6.0" -or $IsWindows) { + # Fix case when both the Windows and Linux builds of Node + # are installed in the same directory + $exe=".exe" +} +$ret=0 +if (Test-Path "$basedir/node$exe") { + # Support pipeline input + if ($MyInvocation.ExpectingInput) { + $input | & "$basedir/node$exe" "$basedir/../acorn/bin/acorn" $args + } else { + & "$basedir/node$exe" "$basedir/../acorn/bin/acorn" $args + } + $ret=$LASTEXITCODE +} else { + # Support pipeline input + if ($MyInvocation.ExpectingInput) { + $input | & "node$exe" "$basedir/../acorn/bin/acorn" $args + } else { + & "node$exe" "$basedir/../acorn/bin/acorn" $args + } + $ret=$LASTEXITCODE +} +exit $ret diff --git a/node_modules/.bin/acorn~HEAD b/node_modules/.bin/acorn~HEAD new file mode 100644 index 00000000..679bd163 --- /dev/null +++ b/node_modules/.bin/acorn~HEAD @@ -0,0 +1,16 @@ +#!/bin/sh +basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')") + +case `uname` in + *CYGWIN*|*MINGW*|*MSYS*) + if command -v cygpath > /dev/null 2>&1; then + basedir=`cygpath -w "$basedir"` + fi + ;; +esac + +if [ -x "$basedir/node" ]; then + exec "$basedir/node" "$basedir/../acorn/bin/acorn" "$@" +else + exec node "$basedir/../acorn/bin/acorn" "$@" +fi diff --git a/node_modules/.bin/baseline-browser-mapping.cmd b/node_modules/.bin/baseline-browser-mapping.cmd new file mode 100644 index 00000000..d4f491f5 --- /dev/null +++ b/node_modules/.bin/baseline-browser-mapping.cmd @@ -0,0 +1,17 @@ +@ECHO off +GOTO start +:find_dp0 +SET dp0=%~dp0 +EXIT /b +:start +SETLOCAL +CALL :find_dp0 + +IF EXIST "%dp0%\node.exe" ( + SET "_prog=%dp0%\node.exe" +) ELSE ( + SET "_prog=node" + SET PATHEXT=%PATHEXT:;.JS;=;% +) + +endLocal & goto #_undefined_# 2>NUL || title %COMSPEC% & "%_prog%" "%dp0%\..\baseline-browser-mapping\dist\cli.cjs" %* diff --git a/node_modules/.bin/baseline-browser-mapping.ps1 b/node_modules/.bin/baseline-browser-mapping.ps1 new file mode 100644 index 00000000..049fe744 --- /dev/null +++ b/node_modules/.bin/baseline-browser-mapping.ps1 @@ -0,0 +1,28 @@ +#!/usr/bin/env pwsh +$basedir=Split-Path $MyInvocation.MyCommand.Definition -Parent + +$exe="" +if ($PSVersionTable.PSVersion -lt "6.0" -or $IsWindows) { + # Fix case when both the Windows and Linux builds of Node + # are installed in the same directory + $exe=".exe" +} +$ret=0 +if (Test-Path "$basedir/node$exe") { + # Support pipeline input + if ($MyInvocation.ExpectingInput) { + $input | & "$basedir/node$exe" "$basedir/../baseline-browser-mapping/dist/cli.cjs" $args + } else { + & "$basedir/node$exe" "$basedir/../baseline-browser-mapping/dist/cli.cjs" $args + } + $ret=$LASTEXITCODE +} else { + # Support pipeline input + if ($MyInvocation.ExpectingInput) { + $input | & "node$exe" "$basedir/../baseline-browser-mapping/dist/cli.cjs" $args + } else { + & "node$exe" "$basedir/../baseline-browser-mapping/dist/cli.cjs" $args + } + $ret=$LASTEXITCODE +} +exit $ret diff --git a/node_modules/.bin/baseline-browser-mapping~HEAD b/node_modules/.bin/baseline-browser-mapping~HEAD new file mode 100644 index 00000000..7e4dd08b --- /dev/null +++ b/node_modules/.bin/baseline-browser-mapping~HEAD @@ -0,0 +1,16 @@ +#!/bin/sh +basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')") + +case `uname` in + *CYGWIN*|*MINGW*|*MSYS*) + if command -v cygpath > /dev/null 2>&1; then + basedir=`cygpath -w "$basedir"` + fi + ;; +esac + +if [ -x "$basedir/node" ]; then + exec "$basedir/node" "$basedir/../baseline-browser-mapping/dist/cli.cjs" "$@" +else + exec node "$basedir/../baseline-browser-mapping/dist/cli.cjs" "$@" +fi diff --git a/node_modules/.bin/browserslist.cmd b/node_modules/.bin/browserslist.cmd new file mode 100644 index 00000000..e2a0d3f9 --- /dev/null +++ b/node_modules/.bin/browserslist.cmd @@ -0,0 +1,17 @@ +@ECHO off +GOTO start +:find_dp0 +SET dp0=%~dp0 +EXIT /b +:start +SETLOCAL +CALL :find_dp0 + +IF EXIST "%dp0%\node.exe" ( + SET "_prog=%dp0%\node.exe" +) ELSE ( + SET "_prog=node" + SET PATHEXT=%PATHEXT:;.JS;=;% +) + +endLocal & goto #_undefined_# 2>NUL || title %COMSPEC% & "%_prog%" "%dp0%\..\browserslist\cli.js" %* diff --git a/node_modules/.bin/browserslist.ps1 b/node_modules/.bin/browserslist.ps1 new file mode 100644 index 00000000..01e10a08 --- /dev/null +++ b/node_modules/.bin/browserslist.ps1 @@ -0,0 +1,28 @@ +#!/usr/bin/env pwsh +$basedir=Split-Path $MyInvocation.MyCommand.Definition -Parent + +$exe="" +if ($PSVersionTable.PSVersion -lt "6.0" -or $IsWindows) { + # Fix case when both the Windows and Linux builds of Node + # are installed in the same directory + $exe=".exe" +} +$ret=0 +if (Test-Path "$basedir/node$exe") { + # Support pipeline input + if ($MyInvocation.ExpectingInput) { + $input | & "$basedir/node$exe" "$basedir/../browserslist/cli.js" $args + } else { + & "$basedir/node$exe" "$basedir/../browserslist/cli.js" $args + } + $ret=$LASTEXITCODE +} else { + # Support pipeline input + if ($MyInvocation.ExpectingInput) { + $input | & "node$exe" "$basedir/../browserslist/cli.js" $args + } else { + & "node$exe" "$basedir/../browserslist/cli.js" $args + } + $ret=$LASTEXITCODE +} +exit $ret diff --git a/node_modules/.bin/browserslist~HEAD b/node_modules/.bin/browserslist~HEAD new file mode 100644 index 00000000..60e71ad8 --- /dev/null +++ b/node_modules/.bin/browserslist~HEAD @@ -0,0 +1,16 @@ +#!/bin/sh +basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')") + +case `uname` in + *CYGWIN*|*MINGW*|*MSYS*) + if command -v cygpath > /dev/null 2>&1; then + basedir=`cygpath -w "$basedir"` + fi + ;; +esac + +if [ -x "$basedir/node" ]; then + exec "$basedir/node" "$basedir/../browserslist/cli.js" "$@" +else + exec node "$basedir/../browserslist/cli.js" "$@" +fi diff --git a/node_modules/.bin/eslint.cmd b/node_modules/.bin/eslint.cmd new file mode 100644 index 00000000..2f7264f2 --- /dev/null +++ b/node_modules/.bin/eslint.cmd @@ -0,0 +1,17 @@ +@ECHO off +GOTO start +:find_dp0 +SET dp0=%~dp0 +EXIT /b +:start +SETLOCAL +CALL :find_dp0 + +IF EXIST "%dp0%\node.exe" ( + SET "_prog=%dp0%\node.exe" +) ELSE ( + SET "_prog=node" + SET PATHEXT=%PATHEXT:;.JS;=;% +) + +endLocal & goto #_undefined_# 2>NUL || title %COMSPEC% & "%_prog%" "%dp0%\..\eslint\bin\eslint.js" %* diff --git a/node_modules/.bin/eslint.ps1 b/node_modules/.bin/eslint.ps1 new file mode 100644 index 00000000..155bec49 --- /dev/null +++ b/node_modules/.bin/eslint.ps1 @@ -0,0 +1,28 @@ +#!/usr/bin/env pwsh +$basedir=Split-Path $MyInvocation.MyCommand.Definition -Parent + +$exe="" +if ($PSVersionTable.PSVersion -lt "6.0" -or $IsWindows) { + # Fix case when both the Windows and Linux builds of Node + # are installed in the same directory + $exe=".exe" +} +$ret=0 +if (Test-Path "$basedir/node$exe") { + # Support pipeline input + if ($MyInvocation.ExpectingInput) { + $input | & "$basedir/node$exe" "$basedir/../eslint/bin/eslint.js" $args + } else { + & "$basedir/node$exe" "$basedir/../eslint/bin/eslint.js" $args + } + $ret=$LASTEXITCODE +} else { + # Support pipeline input + if ($MyInvocation.ExpectingInput) { + $input | & "node$exe" "$basedir/../eslint/bin/eslint.js" $args + } else { + & "node$exe" "$basedir/../eslint/bin/eslint.js" $args + } + $ret=$LASTEXITCODE +} +exit $ret diff --git a/node_modules/.bin/eslint~HEAD b/node_modules/.bin/eslint~HEAD new file mode 100644 index 00000000..d450ee1f --- /dev/null +++ b/node_modules/.bin/eslint~HEAD @@ -0,0 +1,16 @@ +#!/bin/sh +basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')") + +case `uname` in + *CYGWIN*|*MINGW*|*MSYS*) + if command -v cygpath > /dev/null 2>&1; then + basedir=`cygpath -w "$basedir"` + fi + ;; +esac + +if [ -x "$basedir/node" ]; then + exec "$basedir/node" "$basedir/../eslint/bin/eslint.js" "$@" +else + exec node "$basedir/../eslint/bin/eslint.js" "$@" +fi diff --git a/node_modules/.bin/esparse.cmd b/node_modules/.bin/esparse.cmd new file mode 100644 index 00000000..77d1a423 --- /dev/null +++ b/node_modules/.bin/esparse.cmd @@ -0,0 +1,17 @@ +@ECHO off +GOTO start +:find_dp0 +SET dp0=%~dp0 +EXIT /b +:start +SETLOCAL +CALL :find_dp0 + +IF EXIST "%dp0%\node.exe" ( + SET "_prog=%dp0%\node.exe" +) ELSE ( + SET "_prog=node" + SET PATHEXT=%PATHEXT:;.JS;=;% +) + +endLocal & goto #_undefined_# 2>NUL || title %COMSPEC% & "%_prog%" "%dp0%\..\esprima\bin\esparse.js" %* diff --git a/node_modules/.bin/esparse.ps1 b/node_modules/.bin/esparse.ps1 new file mode 100644 index 00000000..f19ed730 --- /dev/null +++ b/node_modules/.bin/esparse.ps1 @@ -0,0 +1,28 @@ +#!/usr/bin/env pwsh +$basedir=Split-Path $MyInvocation.MyCommand.Definition -Parent + +$exe="" +if ($PSVersionTable.PSVersion -lt "6.0" -or $IsWindows) { + # Fix case when both the Windows and Linux builds of Node + # are installed in the same directory + $exe=".exe" +} +$ret=0 +if (Test-Path "$basedir/node$exe") { + # Support pipeline input + if ($MyInvocation.ExpectingInput) { + $input | & "$basedir/node$exe" "$basedir/../esprima/bin/esparse.js" $args + } else { + & "$basedir/node$exe" "$basedir/../esprima/bin/esparse.js" $args + } + $ret=$LASTEXITCODE +} else { + # Support pipeline input + if ($MyInvocation.ExpectingInput) { + $input | & "node$exe" "$basedir/../esprima/bin/esparse.js" $args + } else { + & "node$exe" "$basedir/../esprima/bin/esparse.js" $args + } + $ret=$LASTEXITCODE +} +exit $ret diff --git a/node_modules/.bin/esparse~HEAD b/node_modules/.bin/esparse~HEAD new file mode 100644 index 00000000..601762ce --- /dev/null +++ b/node_modules/.bin/esparse~HEAD @@ -0,0 +1,16 @@ +#!/bin/sh +basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')") + +case `uname` in + *CYGWIN*|*MINGW*|*MSYS*) + if command -v cygpath > /dev/null 2>&1; then + basedir=`cygpath -w "$basedir"` + fi + ;; +esac + +if [ -x "$basedir/node" ]; then + exec "$basedir/node" "$basedir/../esprima/bin/esparse.js" "$@" +else + exec node "$basedir/../esprima/bin/esparse.js" "$@" +fi diff --git a/node_modules/.bin/esvalidate.cmd b/node_modules/.bin/esvalidate.cmd new file mode 100644 index 00000000..085b5424 --- /dev/null +++ b/node_modules/.bin/esvalidate.cmd @@ -0,0 +1,17 @@ +@ECHO off +GOTO start +:find_dp0 +SET dp0=%~dp0 +EXIT /b +:start +SETLOCAL +CALL :find_dp0 + +IF EXIST "%dp0%\node.exe" ( + SET "_prog=%dp0%\node.exe" +) ELSE ( + SET "_prog=node" + SET PATHEXT=%PATHEXT:;.JS;=;% +) + +endLocal & goto #_undefined_# 2>NUL || title %COMSPEC% & "%_prog%" "%dp0%\..\esprima\bin\esvalidate.js" %* diff --git a/node_modules/.bin/esvalidate.ps1 b/node_modules/.bin/esvalidate.ps1 new file mode 100644 index 00000000..23699d11 --- /dev/null +++ b/node_modules/.bin/esvalidate.ps1 @@ -0,0 +1,28 @@ +#!/usr/bin/env pwsh +$basedir=Split-Path $MyInvocation.MyCommand.Definition -Parent + +$exe="" +if ($PSVersionTable.PSVersion -lt "6.0" -or $IsWindows) { + # Fix case when both the Windows and Linux builds of Node + # are installed in the same directory + $exe=".exe" +} +$ret=0 +if (Test-Path "$basedir/node$exe") { + # Support pipeline input + if ($MyInvocation.ExpectingInput) { + $input | & "$basedir/node$exe" "$basedir/../esprima/bin/esvalidate.js" $args + } else { + & "$basedir/node$exe" "$basedir/../esprima/bin/esvalidate.js" $args + } + $ret=$LASTEXITCODE +} else { + # Support pipeline input + if ($MyInvocation.ExpectingInput) { + $input | & "node$exe" "$basedir/../esprima/bin/esvalidate.js" $args + } else { + & "node$exe" "$basedir/../esprima/bin/esvalidate.js" $args + } + $ret=$LASTEXITCODE +} +exit $ret diff --git a/node_modules/.bin/esvalidate~HEAD b/node_modules/.bin/esvalidate~HEAD new file mode 100644 index 00000000..e2fee1f1 --- /dev/null +++ b/node_modules/.bin/esvalidate~HEAD @@ -0,0 +1,16 @@ +#!/bin/sh +basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')") + +case `uname` in + *CYGWIN*|*MINGW*|*MSYS*) + if command -v cygpath > /dev/null 2>&1; then + basedir=`cygpath -w "$basedir"` + fi + ;; +esac + +if [ -x "$basedir/node" ]; then + exec "$basedir/node" "$basedir/../esprima/bin/esvalidate.js" "$@" +else + exec node "$basedir/../esprima/bin/esvalidate.js" "$@" +fi diff --git a/node_modules/.bin/glob.cmd b/node_modules/.bin/glob.cmd new file mode 100644 index 00000000..2acbf75e --- /dev/null +++ b/node_modules/.bin/glob.cmd @@ -0,0 +1,17 @@ +@ECHO off +GOTO start +:find_dp0 +SET dp0=%~dp0 +EXIT /b +:start +SETLOCAL +CALL :find_dp0 + +IF EXIST "%dp0%\node.exe" ( + SET "_prog=%dp0%\node.exe" +) ELSE ( + SET "_prog=node" + SET PATHEXT=%PATHEXT:;.JS;=;% +) + +endLocal & goto #_undefined_# 2>NUL || title %COMSPEC% & "%_prog%" "%dp0%\..\glob\dist\esm\bin.mjs" %* diff --git a/node_modules/.bin/glob.ps1 b/node_modules/.bin/glob.ps1 new file mode 100644 index 00000000..71ac2b20 --- /dev/null +++ b/node_modules/.bin/glob.ps1 @@ -0,0 +1,28 @@ +#!/usr/bin/env pwsh +$basedir=Split-Path $MyInvocation.MyCommand.Definition -Parent + +$exe="" +if ($PSVersionTable.PSVersion -lt "6.0" -or $IsWindows) { + # Fix case when both the Windows and Linux builds of Node + # are installed in the same directory + $exe=".exe" +} +$ret=0 +if (Test-Path "$basedir/node$exe") { + # Support pipeline input + if ($MyInvocation.ExpectingInput) { + $input | & "$basedir/node$exe" "$basedir/../glob/dist/esm/bin.mjs" $args + } else { + & "$basedir/node$exe" "$basedir/../glob/dist/esm/bin.mjs" $args + } + $ret=$LASTEXITCODE +} else { + # Support pipeline input + if ($MyInvocation.ExpectingInput) { + $input | & "node$exe" "$basedir/../glob/dist/esm/bin.mjs" $args + } else { + & "node$exe" "$basedir/../glob/dist/esm/bin.mjs" $args + } + $ret=$LASTEXITCODE +} +exit $ret diff --git a/node_modules/.bin/glob~HEAD b/node_modules/.bin/glob~HEAD new file mode 100644 index 00000000..6fbc4bb8 --- /dev/null +++ b/node_modules/.bin/glob~HEAD @@ -0,0 +1,16 @@ +#!/bin/sh +basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')") + +case `uname` in + *CYGWIN*|*MINGW*|*MSYS*) + if command -v cygpath > /dev/null 2>&1; then + basedir=`cygpath -w "$basedir"` + fi + ;; +esac + +if [ -x "$basedir/node" ]; then + exec "$basedir/node" "$basedir/../glob/dist/esm/bin.mjs" "$@" +else + exec node "$basedir/../glob/dist/esm/bin.mjs" "$@" +fi diff --git a/node_modules/.bin/import-local-fixture.cmd b/node_modules/.bin/import-local-fixture.cmd new file mode 100644 index 00000000..53ee97f5 --- /dev/null +++ b/node_modules/.bin/import-local-fixture.cmd @@ -0,0 +1,17 @@ +@ECHO off +GOTO start +:find_dp0 +SET dp0=%~dp0 +EXIT /b +:start +SETLOCAL +CALL :find_dp0 + +IF EXIST "%dp0%\node.exe" ( + SET "_prog=%dp0%\node.exe" +) ELSE ( + SET "_prog=node" + SET PATHEXT=%PATHEXT:;.JS;=;% +) + +endLocal & goto #_undefined_# 2>NUL || title %COMSPEC% & "%_prog%" "%dp0%\..\import-local\fixtures\cli.js" %* diff --git a/node_modules/.bin/import-local-fixture.ps1 b/node_modules/.bin/import-local-fixture.ps1 new file mode 100644 index 00000000..01ef7842 --- /dev/null +++ b/node_modules/.bin/import-local-fixture.ps1 @@ -0,0 +1,28 @@ +#!/usr/bin/env pwsh +$basedir=Split-Path $MyInvocation.MyCommand.Definition -Parent + +$exe="" +if ($PSVersionTable.PSVersion -lt "6.0" -or $IsWindows) { + # Fix case when both the Windows and Linux builds of Node + # are installed in the same directory + $exe=".exe" +} +$ret=0 +if (Test-Path "$basedir/node$exe") { + # Support pipeline input + if ($MyInvocation.ExpectingInput) { + $input | & "$basedir/node$exe" "$basedir/../import-local/fixtures/cli.js" $args + } else { + & "$basedir/node$exe" "$basedir/../import-local/fixtures/cli.js" $args + } + $ret=$LASTEXITCODE +} else { + # Support pipeline input + if ($MyInvocation.ExpectingInput) { + $input | & "node$exe" "$basedir/../import-local/fixtures/cli.js" $args + } else { + & "node$exe" "$basedir/../import-local/fixtures/cli.js" $args + } + $ret=$LASTEXITCODE +} +exit $ret diff --git a/node_modules/.bin/import-local-fixture~HEAD b/node_modules/.bin/import-local-fixture~HEAD new file mode 100644 index 00000000..3a654413 --- /dev/null +++ b/node_modules/.bin/import-local-fixture~HEAD @@ -0,0 +1,16 @@ +#!/bin/sh +basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')") + +case `uname` in + *CYGWIN*|*MINGW*|*MSYS*) + if command -v cygpath > /dev/null 2>&1; then + basedir=`cygpath -w "$basedir"` + fi + ;; +esac + +if [ -x "$basedir/node" ]; then + exec "$basedir/node" "$basedir/../import-local/fixtures/cli.js" "$@" +else + exec node "$basedir/../import-local/fixtures/cli.js" "$@" +fi diff --git a/node_modules/.bin/jest.cmd b/node_modules/.bin/jest.cmd new file mode 100644 index 00000000..b7b7db07 --- /dev/null +++ b/node_modules/.bin/jest.cmd @@ -0,0 +1,17 @@ +@ECHO off +GOTO start +:find_dp0 +SET dp0=%~dp0 +EXIT /b +:start +SETLOCAL +CALL :find_dp0 + +IF EXIST "%dp0%\node.exe" ( + SET "_prog=%dp0%\node.exe" +) ELSE ( + SET "_prog=node" + SET PATHEXT=%PATHEXT:;.JS;=;% +) + +endLocal & goto #_undefined_# 2>NUL || title %COMSPEC% & "%_prog%" "%dp0%\..\jest\bin\jest.js" %* diff --git a/node_modules/.bin/jest.ps1 b/node_modules/.bin/jest.ps1 new file mode 100644 index 00000000..78a25637 --- /dev/null +++ b/node_modules/.bin/jest.ps1 @@ -0,0 +1,28 @@ +#!/usr/bin/env pwsh +$basedir=Split-Path $MyInvocation.MyCommand.Definition -Parent + +$exe="" +if ($PSVersionTable.PSVersion -lt "6.0" -or $IsWindows) { + # Fix case when both the Windows and Linux builds of Node + # are installed in the same directory + $exe=".exe" +} +$ret=0 +if (Test-Path "$basedir/node$exe") { + # Support pipeline input + if ($MyInvocation.ExpectingInput) { + $input | & "$basedir/node$exe" "$basedir/../jest/bin/jest.js" $args + } else { + & "$basedir/node$exe" "$basedir/../jest/bin/jest.js" $args + } + $ret=$LASTEXITCODE +} else { + # Support pipeline input + if ($MyInvocation.ExpectingInput) { + $input | & "node$exe" "$basedir/../jest/bin/jest.js" $args + } else { + & "node$exe" "$basedir/../jest/bin/jest.js" $args + } + $ret=$LASTEXITCODE +} +exit $ret diff --git a/node_modules/.bin/jest~HEAD b/node_modules/.bin/jest~HEAD new file mode 100644 index 00000000..61b6f565 --- /dev/null +++ b/node_modules/.bin/jest~HEAD @@ -0,0 +1,16 @@ +#!/bin/sh +basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')") + +case `uname` in + *CYGWIN*|*MINGW*|*MSYS*) + if command -v cygpath > /dev/null 2>&1; then + basedir=`cygpath -w "$basedir"` + fi + ;; +esac + +if [ -x "$basedir/node" ]; then + exec "$basedir/node" "$basedir/../jest/bin/jest.js" "$@" +else + exec node "$basedir/../jest/bin/jest.js" "$@" +fi diff --git a/node_modules/.bin/js-yaml.cmd b/node_modules/.bin/js-yaml.cmd new file mode 100644 index 00000000..7154987a --- /dev/null +++ b/node_modules/.bin/js-yaml.cmd @@ -0,0 +1,17 @@ +@ECHO off +GOTO start +:find_dp0 +SET dp0=%~dp0 +EXIT /b +:start +SETLOCAL +CALL :find_dp0 + +IF EXIST "%dp0%\node.exe" ( + SET "_prog=%dp0%\node.exe" +) ELSE ( + SET "_prog=node" + SET PATHEXT=%PATHEXT:;.JS;=;% +) + +endLocal & goto #_undefined_# 2>NUL || title %COMSPEC% & "%_prog%" "%dp0%\..\js-yaml\bin\js-yaml.js" %* diff --git a/node_modules/.bin/js-yaml.ps1 b/node_modules/.bin/js-yaml.ps1 new file mode 100644 index 00000000..2acfc61c --- /dev/null +++ b/node_modules/.bin/js-yaml.ps1 @@ -0,0 +1,28 @@ +#!/usr/bin/env pwsh +$basedir=Split-Path $MyInvocation.MyCommand.Definition -Parent + +$exe="" +if ($PSVersionTable.PSVersion -lt "6.0" -or $IsWindows) { + # Fix case when both the Windows and Linux builds of Node + # are installed in the same directory + $exe=".exe" +} +$ret=0 +if (Test-Path "$basedir/node$exe") { + # Support pipeline input + if ($MyInvocation.ExpectingInput) { + $input | & "$basedir/node$exe" "$basedir/../js-yaml/bin/js-yaml.js" $args + } else { + & "$basedir/node$exe" "$basedir/../js-yaml/bin/js-yaml.js" $args + } + $ret=$LASTEXITCODE +} else { + # Support pipeline input + if ($MyInvocation.ExpectingInput) { + $input | & "node$exe" "$basedir/../js-yaml/bin/js-yaml.js" $args + } else { + & "node$exe" "$basedir/../js-yaml/bin/js-yaml.js" $args + } + $ret=$LASTEXITCODE +} +exit $ret diff --git a/node_modules/.bin/js-yaml~HEAD b/node_modules/.bin/js-yaml~HEAD new file mode 100644 index 00000000..82416ef1 --- /dev/null +++ b/node_modules/.bin/js-yaml~HEAD @@ -0,0 +1,16 @@ +#!/bin/sh +basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')") + +case `uname` in + *CYGWIN*|*MINGW*|*MSYS*) + if command -v cygpath > /dev/null 2>&1; then + basedir=`cygpath -w "$basedir"` + fi + ;; +esac + +if [ -x "$basedir/node" ]; then + exec "$basedir/node" "$basedir/../js-yaml/bin/js-yaml.js" "$@" +else + exec node "$basedir/../js-yaml/bin/js-yaml.js" "$@" +fi diff --git a/node_modules/.bin/jsesc.cmd b/node_modules/.bin/jsesc.cmd new file mode 100644 index 00000000..7ff98f0e --- /dev/null +++ b/node_modules/.bin/jsesc.cmd @@ -0,0 +1,17 @@ +@ECHO off +GOTO start +:find_dp0 +SET dp0=%~dp0 +EXIT /b +:start +SETLOCAL +CALL :find_dp0 + +IF EXIST "%dp0%\node.exe" ( + SET "_prog=%dp0%\node.exe" +) ELSE ( + SET "_prog=node" + SET PATHEXT=%PATHEXT:;.JS;=;% +) + +endLocal & goto #_undefined_# 2>NUL || title %COMSPEC% & "%_prog%" "%dp0%\..\jsesc\bin\jsesc" %* diff --git a/node_modules/.bin/jsesc.ps1 b/node_modules/.bin/jsesc.ps1 new file mode 100644 index 00000000..6007e022 --- /dev/null +++ b/node_modules/.bin/jsesc.ps1 @@ -0,0 +1,28 @@ +#!/usr/bin/env pwsh +$basedir=Split-Path $MyInvocation.MyCommand.Definition -Parent + +$exe="" +if ($PSVersionTable.PSVersion -lt "6.0" -or $IsWindows) { + # Fix case when both the Windows and Linux builds of Node + # are installed in the same directory + $exe=".exe" +} +$ret=0 +if (Test-Path "$basedir/node$exe") { + # Support pipeline input + if ($MyInvocation.ExpectingInput) { + $input | & "$basedir/node$exe" "$basedir/../jsesc/bin/jsesc" $args + } else { + & "$basedir/node$exe" "$basedir/../jsesc/bin/jsesc" $args + } + $ret=$LASTEXITCODE +} else { + # Support pipeline input + if ($MyInvocation.ExpectingInput) { + $input | & "node$exe" "$basedir/../jsesc/bin/jsesc" $args + } else { + & "node$exe" "$basedir/../jsesc/bin/jsesc" $args + } + $ret=$LASTEXITCODE +} +exit $ret diff --git a/node_modules/.bin/jsesc~HEAD b/node_modules/.bin/jsesc~HEAD new file mode 100644 index 00000000..879c4133 --- /dev/null +++ b/node_modules/.bin/jsesc~HEAD @@ -0,0 +1,16 @@ +#!/bin/sh +basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')") + +case `uname` in + *CYGWIN*|*MINGW*|*MSYS*) + if command -v cygpath > /dev/null 2>&1; then + basedir=`cygpath -w "$basedir"` + fi + ;; +esac + +if [ -x "$basedir/node" ]; then + exec "$basedir/node" "$basedir/../jsesc/bin/jsesc" "$@" +else + exec node "$basedir/../jsesc/bin/jsesc" "$@" +fi diff --git a/node_modules/.bin/json5.cmd b/node_modules/.bin/json5.cmd new file mode 100644 index 00000000..d9924813 --- /dev/null +++ b/node_modules/.bin/json5.cmd @@ -0,0 +1,17 @@ +@ECHO off +GOTO start +:find_dp0 +SET dp0=%~dp0 +EXIT /b +:start +SETLOCAL +CALL :find_dp0 + +IF EXIST "%dp0%\node.exe" ( + SET "_prog=%dp0%\node.exe" +) ELSE ( + SET "_prog=node" + SET PATHEXT=%PATHEXT:;.JS;=;% +) + +endLocal & goto #_undefined_# 2>NUL || title %COMSPEC% & "%_prog%" "%dp0%\..\json5\lib\cli.js" %* diff --git a/node_modules/.bin/json5.ps1 b/node_modules/.bin/json5.ps1 new file mode 100644 index 00000000..8700ddbe --- /dev/null +++ b/node_modules/.bin/json5.ps1 @@ -0,0 +1,28 @@ +#!/usr/bin/env pwsh +$basedir=Split-Path $MyInvocation.MyCommand.Definition -Parent + +$exe="" +if ($PSVersionTable.PSVersion -lt "6.0" -or $IsWindows) { + # Fix case when both the Windows and Linux builds of Node + # are installed in the same directory + $exe=".exe" +} +$ret=0 +if (Test-Path "$basedir/node$exe") { + # Support pipeline input + if ($MyInvocation.ExpectingInput) { + $input | & "$basedir/node$exe" "$basedir/../json5/lib/cli.js" $args + } else { + & "$basedir/node$exe" "$basedir/../json5/lib/cli.js" $args + } + $ret=$LASTEXITCODE +} else { + # Support pipeline input + if ($MyInvocation.ExpectingInput) { + $input | & "node$exe" "$basedir/../json5/lib/cli.js" $args + } else { + & "node$exe" "$basedir/../json5/lib/cli.js" $args + } + $ret=$LASTEXITCODE +} +exit $ret diff --git a/node_modules/.bin/json5~HEAD b/node_modules/.bin/json5~HEAD new file mode 100644 index 00000000..abf72a4e --- /dev/null +++ b/node_modules/.bin/json5~HEAD @@ -0,0 +1,16 @@ +#!/bin/sh +basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')") + +case `uname` in + *CYGWIN*|*MINGW*|*MSYS*) + if command -v cygpath > /dev/null 2>&1; then + basedir=`cygpath -w "$basedir"` + fi + ;; +esac + +if [ -x "$basedir/node" ]; then + exec "$basedir/node" "$basedir/../json5/lib/cli.js" "$@" +else + exec node "$basedir/../json5/lib/cli.js" "$@" +fi diff --git a/node_modules/.bin/mime.cmd b/node_modules/.bin/mime.cmd new file mode 100644 index 00000000..a9e48f1e --- /dev/null +++ b/node_modules/.bin/mime.cmd @@ -0,0 +1,17 @@ +@ECHO off +GOTO start +:find_dp0 +SET dp0=%~dp0 +EXIT /b +:start +SETLOCAL +CALL :find_dp0 + +IF EXIST "%dp0%\node.exe" ( + SET "_prog=%dp0%\node.exe" +) ELSE ( + SET "_prog=node" + SET PATHEXT=%PATHEXT:;.JS;=;% +) + +endLocal & goto #_undefined_# 2>NUL || title %COMSPEC% & "%_prog%" "%dp0%\..\mime\cli.js" %* diff --git a/node_modules/.bin/mime.ps1 b/node_modules/.bin/mime.ps1 new file mode 100644 index 00000000..2222f40b --- /dev/null +++ b/node_modules/.bin/mime.ps1 @@ -0,0 +1,28 @@ +#!/usr/bin/env pwsh +$basedir=Split-Path $MyInvocation.MyCommand.Definition -Parent + +$exe="" +if ($PSVersionTable.PSVersion -lt "6.0" -or $IsWindows) { + # Fix case when both the Windows and Linux builds of Node + # are installed in the same directory + $exe=".exe" +} +$ret=0 +if (Test-Path "$basedir/node$exe") { + # Support pipeline input + if ($MyInvocation.ExpectingInput) { + $input | & "$basedir/node$exe" "$basedir/../mime/cli.js" $args + } else { + & "$basedir/node$exe" "$basedir/../mime/cli.js" $args + } + $ret=$LASTEXITCODE +} else { + # Support pipeline input + if ($MyInvocation.ExpectingInput) { + $input | & "node$exe" "$basedir/../mime/cli.js" $args + } else { + & "node$exe" "$basedir/../mime/cli.js" $args + } + $ret=$LASTEXITCODE +} +exit $ret diff --git a/node_modules/.bin/mime~HEAD b/node_modules/.bin/mime~HEAD new file mode 100644 index 00000000..7751de3c --- /dev/null +++ b/node_modules/.bin/mime~HEAD @@ -0,0 +1,16 @@ +#!/bin/sh +basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')") + +case `uname` in + *CYGWIN*|*MINGW*|*MSYS*) + if command -v cygpath > /dev/null 2>&1; then + basedir=`cygpath -w "$basedir"` + fi + ;; +esac + +if [ -x "$basedir/node" ]; then + exec "$basedir/node" "$basedir/../mime/cli.js" "$@" +else + exec node "$basedir/../mime/cli.js" "$@" +fi diff --git a/node_modules/.bin/napi-postinstall.cmd b/node_modules/.bin/napi-postinstall.cmd new file mode 100644 index 00000000..d88df20f --- /dev/null +++ b/node_modules/.bin/napi-postinstall.cmd @@ -0,0 +1,17 @@ +@ECHO off +GOTO start +:find_dp0 +SET dp0=%~dp0 +EXIT /b +:start +SETLOCAL +CALL :find_dp0 + +IF EXIST "%dp0%\node.exe" ( + SET "_prog=%dp0%\node.exe" +) ELSE ( + SET "_prog=node" + SET PATHEXT=%PATHEXT:;.JS;=;% +) + +endLocal & goto #_undefined_# 2>NUL || title %COMSPEC% & "%_prog%" "%dp0%\..\napi-postinstall\lib\cli.js" %* diff --git a/node_modules/.bin/napi-postinstall.ps1 b/node_modules/.bin/napi-postinstall.ps1 new file mode 100644 index 00000000..f61ca7d1 --- /dev/null +++ b/node_modules/.bin/napi-postinstall.ps1 @@ -0,0 +1,28 @@ +#!/usr/bin/env pwsh +$basedir=Split-Path $MyInvocation.MyCommand.Definition -Parent + +$exe="" +if ($PSVersionTable.PSVersion -lt "6.0" -or $IsWindows) { + # Fix case when both the Windows and Linux builds of Node + # are installed in the same directory + $exe=".exe" +} +$ret=0 +if (Test-Path "$basedir/node$exe") { + # Support pipeline input + if ($MyInvocation.ExpectingInput) { + $input | & "$basedir/node$exe" "$basedir/../napi-postinstall/lib/cli.js" $args + } else { + & "$basedir/node$exe" "$basedir/../napi-postinstall/lib/cli.js" $args + } + $ret=$LASTEXITCODE +} else { + # Support pipeline input + if ($MyInvocation.ExpectingInput) { + $input | & "node$exe" "$basedir/../napi-postinstall/lib/cli.js" $args + } else { + & "node$exe" "$basedir/../napi-postinstall/lib/cli.js" $args + } + $ret=$LASTEXITCODE +} +exit $ret diff --git a/node_modules/.bin/napi-postinstall~HEAD b/node_modules/.bin/napi-postinstall~HEAD new file mode 100644 index 00000000..985cc4c7 --- /dev/null +++ b/node_modules/.bin/napi-postinstall~HEAD @@ -0,0 +1,16 @@ +#!/bin/sh +basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')") + +case `uname` in + *CYGWIN*|*MINGW*|*MSYS*) + if command -v cygpath > /dev/null 2>&1; then + basedir=`cygpath -w "$basedir"` + fi + ;; +esac + +if [ -x "$basedir/node" ]; then + exec "$basedir/node" "$basedir/../napi-postinstall/lib/cli.js" "$@" +else + exec node "$basedir/../napi-postinstall/lib/cli.js" "$@" +fi diff --git a/node_modules/.bin/node-which.cmd b/node_modules/.bin/node-which.cmd new file mode 100644 index 00000000..7eeb3164 --- /dev/null +++ b/node_modules/.bin/node-which.cmd @@ -0,0 +1,17 @@ +@ECHO off +GOTO start +:find_dp0 +SET dp0=%~dp0 +EXIT /b +:start +SETLOCAL +CALL :find_dp0 + +IF EXIST "%dp0%\node.exe" ( + SET "_prog=%dp0%\node.exe" +) ELSE ( + SET "_prog=node" + SET PATHEXT=%PATHEXT:;.JS;=;% +) + +endLocal & goto #_undefined_# 2>NUL || title %COMSPEC% & "%_prog%" "%dp0%\..\which\bin\node-which" %* diff --git a/node_modules/.bin/node-which.ps1 b/node_modules/.bin/node-which.ps1 new file mode 100644 index 00000000..cfb09e84 --- /dev/null +++ b/node_modules/.bin/node-which.ps1 @@ -0,0 +1,28 @@ +#!/usr/bin/env pwsh +$basedir=Split-Path $MyInvocation.MyCommand.Definition -Parent + +$exe="" +if ($PSVersionTable.PSVersion -lt "6.0" -or $IsWindows) { + # Fix case when both the Windows and Linux builds of Node + # are installed in the same directory + $exe=".exe" +} +$ret=0 +if (Test-Path "$basedir/node$exe") { + # Support pipeline input + if ($MyInvocation.ExpectingInput) { + $input | & "$basedir/node$exe" "$basedir/../which/bin/node-which" $args + } else { + & "$basedir/node$exe" "$basedir/../which/bin/node-which" $args + } + $ret=$LASTEXITCODE +} else { + # Support pipeline input + if ($MyInvocation.ExpectingInput) { + $input | & "node$exe" "$basedir/../which/bin/node-which" $args + } else { + & "node$exe" "$basedir/../which/bin/node-which" $args + } + $ret=$LASTEXITCODE +} +exit $ret diff --git a/node_modules/.bin/node-which~HEAD b/node_modules/.bin/node-which~HEAD new file mode 100644 index 00000000..b49b03f7 --- /dev/null +++ b/node_modules/.bin/node-which~HEAD @@ -0,0 +1,16 @@ +#!/bin/sh +basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')") + +case `uname` in + *CYGWIN*|*MINGW*|*MSYS*) + if command -v cygpath > /dev/null 2>&1; then + basedir=`cygpath -w "$basedir"` + fi + ;; +esac + +if [ -x "$basedir/node" ]; then + exec "$basedir/node" "$basedir/../which/bin/node-which" "$@" +else + exec node "$basedir/../which/bin/node-which" "$@" +fi diff --git a/node_modules/.bin/parser.cmd b/node_modules/.bin/parser.cmd new file mode 100644 index 00000000..a8a20405 --- /dev/null +++ b/node_modules/.bin/parser.cmd @@ -0,0 +1,17 @@ +@ECHO off +GOTO start +:find_dp0 +SET dp0=%~dp0 +EXIT /b +:start +SETLOCAL +CALL :find_dp0 + +IF EXIST "%dp0%\node.exe" ( + SET "_prog=%dp0%\node.exe" +) ELSE ( + SET "_prog=node" + SET PATHEXT=%PATHEXT:;.JS;=;% +) + +endLocal & goto #_undefined_# 2>NUL || title %COMSPEC% & "%_prog%" "%dp0%\..\@babel\parser\bin\babel-parser.js" %* diff --git a/node_modules/.bin/parser.ps1 b/node_modules/.bin/parser.ps1 new file mode 100644 index 00000000..8926517b --- /dev/null +++ b/node_modules/.bin/parser.ps1 @@ -0,0 +1,28 @@ +#!/usr/bin/env pwsh +$basedir=Split-Path $MyInvocation.MyCommand.Definition -Parent + +$exe="" +if ($PSVersionTable.PSVersion -lt "6.0" -or $IsWindows) { + # Fix case when both the Windows and Linux builds of Node + # are installed in the same directory + $exe=".exe" +} +$ret=0 +if (Test-Path "$basedir/node$exe") { + # Support pipeline input + if ($MyInvocation.ExpectingInput) { + $input | & "$basedir/node$exe" "$basedir/../@babel/parser/bin/babel-parser.js" $args + } else { + & "$basedir/node$exe" "$basedir/../@babel/parser/bin/babel-parser.js" $args + } + $ret=$LASTEXITCODE +} else { + # Support pipeline input + if ($MyInvocation.ExpectingInput) { + $input | & "node$exe" "$basedir/../@babel/parser/bin/babel-parser.js" $args + } else { + & "node$exe" "$basedir/../@babel/parser/bin/babel-parser.js" $args + } + $ret=$LASTEXITCODE +} +exit $ret diff --git a/node_modules/.bin/parser~HEAD b/node_modules/.bin/parser~HEAD new file mode 100644 index 00000000..7696ad41 --- /dev/null +++ b/node_modules/.bin/parser~HEAD @@ -0,0 +1,16 @@ +#!/bin/sh +basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')") + +case `uname` in + *CYGWIN*|*MINGW*|*MSYS*) + if command -v cygpath > /dev/null 2>&1; then + basedir=`cygpath -w "$basedir"` + fi + ;; +esac + +if [ -x "$basedir/node" ]; then + exec "$basedir/node" "$basedir/../@babel/parser/bin/babel-parser.js" "$@" +else + exec node "$basedir/../@babel/parser/bin/babel-parser.js" "$@" +fi diff --git a/node_modules/.bin/regexp-tree.cmd b/node_modules/.bin/regexp-tree.cmd new file mode 100644 index 00000000..5e9bbda4 --- /dev/null +++ b/node_modules/.bin/regexp-tree.cmd @@ -0,0 +1,17 @@ +@ECHO off +GOTO start +:find_dp0 +SET dp0=%~dp0 +EXIT /b +:start +SETLOCAL +CALL :find_dp0 + +IF EXIST "%dp0%\node.exe" ( + SET "_prog=%dp0%\node.exe" +) ELSE ( + SET "_prog=node" + SET PATHEXT=%PATHEXT:;.JS;=;% +) + +endLocal & goto #_undefined_# 2>NUL || title %COMSPEC% & "%_prog%" "%dp0%\..\regexp-tree\bin\regexp-tree" %* diff --git a/node_modules/.bin/regexp-tree.ps1 b/node_modules/.bin/regexp-tree.ps1 new file mode 100644 index 00000000..afc76394 --- /dev/null +++ b/node_modules/.bin/regexp-tree.ps1 @@ -0,0 +1,28 @@ +#!/usr/bin/env pwsh +$basedir=Split-Path $MyInvocation.MyCommand.Definition -Parent + +$exe="" +if ($PSVersionTable.PSVersion -lt "6.0" -or $IsWindows) { + # Fix case when both the Windows and Linux builds of Node + # are installed in the same directory + $exe=".exe" +} +$ret=0 +if (Test-Path "$basedir/node$exe") { + # Support pipeline input + if ($MyInvocation.ExpectingInput) { + $input | & "$basedir/node$exe" "$basedir/../regexp-tree/bin/regexp-tree" $args + } else { + & "$basedir/node$exe" "$basedir/../regexp-tree/bin/regexp-tree" $args + } + $ret=$LASTEXITCODE +} else { + # Support pipeline input + if ($MyInvocation.ExpectingInput) { + $input | & "node$exe" "$basedir/../regexp-tree/bin/regexp-tree" $args + } else { + & "node$exe" "$basedir/../regexp-tree/bin/regexp-tree" $args + } + $ret=$LASTEXITCODE +} +exit $ret diff --git a/node_modules/.bin/regexp-tree~HEAD b/node_modules/.bin/regexp-tree~HEAD new file mode 100644 index 00000000..e8956074 --- /dev/null +++ b/node_modules/.bin/regexp-tree~HEAD @@ -0,0 +1,16 @@ +#!/bin/sh +basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')") + +case `uname` in + *CYGWIN*|*MINGW*|*MSYS*) + if command -v cygpath > /dev/null 2>&1; then + basedir=`cygpath -w "$basedir"` + fi + ;; +esac + +if [ -x "$basedir/node" ]; then + exec "$basedir/node" "$basedir/../regexp-tree/bin/regexp-tree" "$@" +else + exec node "$basedir/../regexp-tree/bin/regexp-tree" "$@" +fi diff --git a/node_modules/.bin/semver.cmd b/node_modules/.bin/semver.cmd new file mode 100644 index 00000000..7d4c104a --- /dev/null +++ b/node_modules/.bin/semver.cmd @@ -0,0 +1,17 @@ +@ECHO off +GOTO start +:find_dp0 +SET dp0=%~dp0 +EXIT /b +:start +SETLOCAL +CALL :find_dp0 + +IF EXIST "%dp0%\node.exe" ( + SET "_prog=%dp0%\node.exe" +) ELSE ( + SET "_prog=node" + SET PATHEXT=%PATHEXT:;.JS;=;% +) + +endLocal & goto #_undefined_# 2>NUL || title %COMSPEC% & "%_prog%" "%dp0%\..\semver\bin\semver.js" %* diff --git a/node_modules/.bin/semver.ps1 b/node_modules/.bin/semver.ps1 new file mode 100644 index 00000000..314717ad --- /dev/null +++ b/node_modules/.bin/semver.ps1 @@ -0,0 +1,28 @@ +#!/usr/bin/env pwsh +$basedir=Split-Path $MyInvocation.MyCommand.Definition -Parent + +$exe="" +if ($PSVersionTable.PSVersion -lt "6.0" -or $IsWindows) { + # Fix case when both the Windows and Linux builds of Node + # are installed in the same directory + $exe=".exe" +} +$ret=0 +if (Test-Path "$basedir/node$exe") { + # Support pipeline input + if ($MyInvocation.ExpectingInput) { + $input | & "$basedir/node$exe" "$basedir/../semver/bin/semver.js" $args + } else { + & "$basedir/node$exe" "$basedir/../semver/bin/semver.js" $args + } + $ret=$LASTEXITCODE +} else { + # Support pipeline input + if ($MyInvocation.ExpectingInput) { + $input | & "node$exe" "$basedir/../semver/bin/semver.js" $args + } else { + & "node$exe" "$basedir/../semver/bin/semver.js" $args + } + $ret=$LASTEXITCODE +} +exit $ret diff --git a/node_modules/.bin/semver~HEAD b/node_modules/.bin/semver~HEAD new file mode 100644 index 00000000..97c53279 --- /dev/null +++ b/node_modules/.bin/semver~HEAD @@ -0,0 +1,16 @@ +#!/bin/sh +basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')") + +case `uname` in + *CYGWIN*|*MINGW*|*MSYS*) + if command -v cygpath > /dev/null 2>&1; then + basedir=`cygpath -w "$basedir"` + fi + ;; +esac + +if [ -x "$basedir/node" ]; then + exec "$basedir/node" "$basedir/../semver/bin/semver.js" "$@" +else + exec node "$basedir/../semver/bin/semver.js" "$@" +fi diff --git a/node_modules/.bin/update-browserslist-db.cmd b/node_modules/.bin/update-browserslist-db.cmd new file mode 100644 index 00000000..d5176c73 --- /dev/null +++ b/node_modules/.bin/update-browserslist-db.cmd @@ -0,0 +1,17 @@ +@ECHO off +GOTO start +:find_dp0 +SET dp0=%~dp0 +EXIT /b +:start +SETLOCAL +CALL :find_dp0 + +IF EXIST "%dp0%\node.exe" ( + SET "_prog=%dp0%\node.exe" +) ELSE ( + SET "_prog=node" + SET PATHEXT=%PATHEXT:;.JS;=;% +) + +endLocal & goto #_undefined_# 2>NUL || title %COMSPEC% & "%_prog%" "%dp0%\..\update-browserslist-db\cli.js" %* diff --git a/node_modules/.bin/update-browserslist-db.ps1 b/node_modules/.bin/update-browserslist-db.ps1 new file mode 100644 index 00000000..7abdf26d --- /dev/null +++ b/node_modules/.bin/update-browserslist-db.ps1 @@ -0,0 +1,28 @@ +#!/usr/bin/env pwsh +$basedir=Split-Path $MyInvocation.MyCommand.Definition -Parent + +$exe="" +if ($PSVersionTable.PSVersion -lt "6.0" -or $IsWindows) { + # Fix case when both the Windows and Linux builds of Node + # are installed in the same directory + $exe=".exe" +} +$ret=0 +if (Test-Path "$basedir/node$exe") { + # Support pipeline input + if ($MyInvocation.ExpectingInput) { + $input | & "$basedir/node$exe" "$basedir/../update-browserslist-db/cli.js" $args + } else { + & "$basedir/node$exe" "$basedir/../update-browserslist-db/cli.js" $args + } + $ret=$LASTEXITCODE +} else { + # Support pipeline input + if ($MyInvocation.ExpectingInput) { + $input | & "node$exe" "$basedir/../update-browserslist-db/cli.js" $args + } else { + & "node$exe" "$basedir/../update-browserslist-db/cli.js" $args + } + $ret=$LASTEXITCODE +} +exit $ret diff --git a/node_modules/.bin/update-browserslist-db~HEAD b/node_modules/.bin/update-browserslist-db~HEAD new file mode 100644 index 00000000..cced63c4 --- /dev/null +++ b/node_modules/.bin/update-browserslist-db~HEAD @@ -0,0 +1,16 @@ +#!/bin/sh +basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')") + +case `uname` in + *CYGWIN*|*MINGW*|*MSYS*) + if command -v cygpath > /dev/null 2>&1; then + basedir=`cygpath -w "$basedir"` + fi + ;; +esac + +if [ -x "$basedir/node" ]; then + exec "$basedir/node" "$basedir/../update-browserslist-db/cli.js" "$@" +else + exec node "$basedir/../update-browserslist-db/cli.js" "$@" +fi diff --git a/node_modules/.package-lock.json b/node_modules/.package-lock.json index c2e23b54..079f3252 100644 --- a/node_modules/.package-lock.json +++ b/node_modules/.package-lock.json @@ -6,8 +6,6 @@ "packages": { "node_modules/@babel/code-frame": { "version": "7.29.0", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.29.0.tgz", - "integrity": "sha512-9NhCeYjq9+3uxgdtp20LSiJXJvN0FeCtNGpJxuMFZ1Kv3cWUNb6DOhJwUvcVCzKGR66cw4njwM6hrJLqgOwbcw==", "dev": true, "license": "MIT", "dependencies": { @@ -21,51 +19,19 @@ }, "node_modules/@babel/code-frame/node_modules/js-tokens": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", "dev": true, "license": "MIT" }, "node_modules/@babel/compat-data": { "version": "7.29.0", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.29.0.tgz", - "integrity": "sha512-T1NCJqT/j9+cn8fvkt7jtwbLBfLC/1y1c7NtCeXFRgzGTsafi68MRv8yzkYSapBnFA6L3U2VSc02ciDzoAJhJg==", "dev": true, "license": "MIT", - "dependencies": { - "@babel/code-frame": "^7.29.0", - "@babel/generator": "^7.29.0", - "@babel/helper-compilation-targets": "^7.28.6", - "@babel/helper-module-transforms": "^7.28.6", - "@babel/helpers": "^7.28.6", - "@babel/parser": "^7.29.0", - "@babel/template": "^7.28.6", - "@babel/traverse": "^7.29.0", - "@babel/types": "^7.29.0", - "@jridgewell/remapping": "^2.3.5", - "convert-source-map": "^2.0.0", - "debug": "^4.1.0", - "gensync": "^1.0.0-beta.2", - "json5": "^2.2.3", - "semver": "^6.3.1" - }, "engines": { "node": ">=6.9.0" } }, - "node_modules/@babel/compat-data/node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "dev": true, - "bin": { - "semver": "bin/semver.js" - } - }, "node_modules/@babel/core": { "version": "7.29.0", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.29.0.tgz", - "integrity": "sha512-CGOfOJqWjg2qW/Mb6zNsDm+u5vFQ8DxXfbM09z69p5Z6+mE1ikP2jUXw+j42Pf1XTYED2Rni5f95npYeuwMDQA==", "dev": true, "license": "MIT", "dependencies": { @@ -95,8 +61,6 @@ }, "node_modules/@babel/core/node_modules/semver": { "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", "dev": true, "license": "ISC", "bin": { @@ -105,8 +69,6 @@ }, "node_modules/@babel/generator": { "version": "7.29.1", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.29.1.tgz", - "integrity": "sha512-qsaF+9Qcm2Qv8SRIMMscAvG4O3lJ0F1GuMo5HR/Bp02LopNgnZBC/EkbevHFeGs4ls/oPz9v+Bsmzbkbe+0dUw==", "dev": true, "license": "MIT", "dependencies": { @@ -122,8 +84,6 @@ }, "node_modules/@babel/helper-compilation-targets": { "version": "7.28.6", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.28.6.tgz", - "integrity": "sha512-JYtls3hqi15fcx5GaSNL7SCTJ2MNmjrkHXg4FSpOA/grxK8KwyZ5bubHsCq8FXCkua6xhuaaBit+3b7+VZRfcA==", "dev": true, "license": "MIT", "dependencies": { @@ -139,8 +99,6 @@ }, "node_modules/@babel/helper-compilation-targets/node_modules/lru-cache": { "version": "5.1.1", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", - "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", "dev": true, "license": "ISC", "dependencies": { @@ -149,8 +107,6 @@ }, "node_modules/@babel/helper-compilation-targets/node_modules/semver": { "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", "dev": true, "license": "ISC", "bin": { @@ -159,8 +115,6 @@ }, "node_modules/@babel/helper-globals": { "version": "7.28.0", - "resolved": "https://registry.npmjs.org/@babel/helper-globals/-/helper-globals-7.28.0.tgz", - "integrity": "sha512-+W6cISkXFa1jXsDEdYA8HeevQT/FULhxzR99pxphltZcVaugps53THCeiWA8SguxxpSp3gKPiuYfSWopkLQ4hw==", "dev": true, "license": "MIT", "engines": { @@ -169,8 +123,6 @@ }, "node_modules/@babel/helper-module-imports": { "version": "7.28.6", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.28.6.tgz", - "integrity": "sha512-l5XkZK7r7wa9LucGw9LwZyyCUscb4x37JWTPz7swwFE/0FMQAGpiWUZn8u9DzkSBWEcK25jmvubfpw2dnAMdbw==", "dev": true, "license": "MIT", "dependencies": { @@ -183,8 +135,6 @@ }, "node_modules/@babel/helper-module-transforms": { "version": "7.28.6", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.28.6.tgz", - "integrity": "sha512-67oXFAYr2cDLDVGLXTEABjdBJZ6drElUSI7WKp70NrpyISso3plG9SAGEF6y7zbha/wOzUByWWTJvEDVNIUGcA==", "dev": true, "license": "MIT", "dependencies": { @@ -201,8 +151,6 @@ }, "node_modules/@babel/helper-plugin-utils": { "version": "7.28.6", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.28.6.tgz", - "integrity": "sha512-S9gzZ/bz83GRysI7gAD4wPT/AI3uCnY+9xn+Mx/KPs2JwHJIz1W8PZkg2cqyt3RNOBM8ejcXhV6y8Og7ly/Dug==", "dev": true, "license": "MIT", "engines": { @@ -227,8 +175,6 @@ }, "node_modules/@babel/helper-validator-option": { "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.27.1.tgz", - "integrity": "sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg==", "dev": true, "license": "MIT", "engines": { @@ -237,8 +183,6 @@ }, "node_modules/@babel/helpers": { "version": "7.29.2", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.29.2.tgz", - "integrity": "sha512-HoGuUs4sCZNezVEKdVcwqmZN8GoHirLUcLaYVNBK2J0DadGtdcqgr3BCbvH8+XUo4NGjNl3VOtSjEKNzqfFgKw==", "dev": true, "license": "MIT", "dependencies": { @@ -265,8 +209,6 @@ }, "node_modules/@babel/plugin-syntax-async-generators": { "version": "7.8.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz", - "integrity": "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==", "dev": true, "license": "MIT", "dependencies": { @@ -278,8 +220,6 @@ }, "node_modules/@babel/plugin-syntax-bigint": { "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-bigint/-/plugin-syntax-bigint-7.8.3.tgz", - "integrity": "sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg==", "dev": true, "license": "MIT", "dependencies": { @@ -291,8 +231,6 @@ }, "node_modules/@babel/plugin-syntax-class-properties": { "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz", - "integrity": "sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==", "dev": true, "license": "MIT", "dependencies": { @@ -304,8 +242,6 @@ }, "node_modules/@babel/plugin-syntax-class-static-block": { "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-static-block/-/plugin-syntax-class-static-block-7.14.5.tgz", - "integrity": "sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw==", "dev": true, "license": "MIT", "dependencies": { @@ -320,8 +256,6 @@ }, "node_modules/@babel/plugin-syntax-import-attributes": { "version": "7.28.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.28.6.tgz", - "integrity": "sha512-jiLC0ma9XkQT3TKJ9uYvlakm66Pamywo+qwL+oL8HJOvc6TWdZXVfhqJr8CCzbSGUAbDOzlGHJC1U+vRfLQDvw==", "dev": true, "license": "MIT", "dependencies": { @@ -336,8 +270,6 @@ }, "node_modules/@babel/plugin-syntax-import-meta": { "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz", - "integrity": "sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==", "dev": true, "license": "MIT", "dependencies": { @@ -349,8 +281,6 @@ }, "node_modules/@babel/plugin-syntax-json-strings": { "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz", - "integrity": "sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==", "dev": true, "license": "MIT", "dependencies": { @@ -362,8 +292,6 @@ }, "node_modules/@babel/plugin-syntax-jsx": { "version": "7.28.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.28.6.tgz", - "integrity": "sha512-wgEmr06G6sIpqr8YDwA2dSRTE3bJ+V0IfpzfSY3Lfgd7YWOaAdlykvJi13ZKBt8cZHfgH1IXN+CL656W3uUa4w==", "dev": true, "license": "MIT", "dependencies": { @@ -378,8 +306,6 @@ }, "node_modules/@babel/plugin-syntax-logical-assignment-operators": { "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz", - "integrity": "sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==", "dev": true, "license": "MIT", "dependencies": { @@ -391,8 +317,6 @@ }, "node_modules/@babel/plugin-syntax-nullish-coalescing-operator": { "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz", - "integrity": "sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==", "dev": true, "license": "MIT", "dependencies": { @@ -404,8 +328,6 @@ }, "node_modules/@babel/plugin-syntax-numeric-separator": { "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz", - "integrity": "sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==", "dev": true, "license": "MIT", "dependencies": { @@ -417,8 +339,6 @@ }, "node_modules/@babel/plugin-syntax-object-rest-spread": { "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz", - "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==", "dev": true, "license": "MIT", "dependencies": { @@ -430,8 +350,6 @@ }, "node_modules/@babel/plugin-syntax-optional-catch-binding": { "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz", - "integrity": "sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==", "dev": true, "license": "MIT", "dependencies": { @@ -443,8 +361,6 @@ }, "node_modules/@babel/plugin-syntax-optional-chaining": { "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz", - "integrity": "sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==", "dev": true, "license": "MIT", "dependencies": { @@ -456,8 +372,6 @@ }, "node_modules/@babel/plugin-syntax-private-property-in-object": { "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-private-property-in-object/-/plugin-syntax-private-property-in-object-7.14.5.tgz", - "integrity": "sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg==", "dev": true, "license": "MIT", "dependencies": { @@ -472,8 +386,6 @@ }, "node_modules/@babel/plugin-syntax-top-level-await": { "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz", - "integrity": "sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==", "dev": true, "license": "MIT", "dependencies": { @@ -488,8 +400,6 @@ }, "node_modules/@babel/plugin-syntax-typescript": { "version": "7.28.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.28.6.tgz", - "integrity": "sha512-+nDNmQye7nlnuuHDboPbGm00Vqg3oO8niRRL27/4LYHUsHYh0zJ1xWOz0uRwNFmM1Avzk8wZbc6rdiYhomzv/A==", "dev": true, "license": "MIT", "dependencies": { @@ -504,8 +414,6 @@ }, "node_modules/@babel/template": { "version": "7.28.6", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.28.6.tgz", - "integrity": "sha512-YA6Ma2KsCdGb+WC6UpBVFJGXL58MDA6oyONbjyF/+5sBgxY/dwkhLogbMT2GXXyU84/IhRw/2D1Os1B/giz+BQ==", "dev": true, "license": "MIT", "dependencies": { @@ -519,8 +427,6 @@ }, "node_modules/@babel/traverse": { "version": "7.29.0", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.29.0.tgz", - "integrity": "sha512-4HPiQr0X7+waHfyXPZpWPfWL/J7dcN1mx9gL6WdQVMbPnF3+ZhSMs8tCxN7oHddJE9fhNE7+lxdnlyemKfJRuA==", "dev": true, "license": "MIT", "dependencies": { @@ -601,8 +507,6 @@ }, "node_modules/@eslint/config-array": { "version": "0.21.2", - "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.21.2.tgz", - "integrity": "sha512-nJl2KGTlrf9GjLimgIru+V/mzgSK0ABCDQRvxw5BjURL7WfH5uoWmizbH7QB6MmnMBd8cIC9uceWnezL1VZWWw==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -616,8 +520,6 @@ }, "node_modules/@eslint/config-helpers": { "version": "0.4.2", - "resolved": "https://registry.npmjs.org/@eslint/config-helpers/-/config-helpers-0.4.2.tgz", - "integrity": "sha512-gBrxN88gOIf3R7ja5K9slwNayVcZgK6SOUORm2uBzTeIEfeVaIhOpCtTox3P6R7o2jLFwLFTLnC7kU/RGcYEgw==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -629,8 +531,6 @@ }, "node_modules/@eslint/core": { "version": "0.17.0", - "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.17.0.tgz", - "integrity": "sha512-yL/sLrpmtDaFEiUj1osRP4TI2MDz1AddJL+jZ7KSqvBuliN4xqYY54IfdN8qD8Toa6g1iloph1fxQNkjOxrrpQ==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -642,8 +542,6 @@ }, "node_modules/@eslint/eslintrc": { "version": "3.3.5", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.3.5.tgz", - "integrity": "sha512-4IlJx0X0qftVsN5E+/vGujTRIFtwuLbNsVUe7TO6zYPDR1O6nFwvwhIKEKSrl6dZchmYBITazxKoUYOjdtjlRg==", "dev": true, "license": "MIT", "dependencies": { @@ -666,15 +564,11 @@ }, "node_modules/@eslint/eslintrc/node_modules/argparse": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", "dev": true, "license": "Python-2.0" }, "node_modules/@eslint/eslintrc/node_modules/globals": { "version": "14.0.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-14.0.0.tgz", - "integrity": "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==", "dev": true, "license": "MIT", "engines": { @@ -686,8 +580,6 @@ }, "node_modules/@eslint/eslintrc/node_modules/js-yaml": { "version": "4.1.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.1.tgz", - "integrity": "sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==", "dev": true, "license": "MIT", "dependencies": { @@ -699,8 +591,6 @@ }, "node_modules/@eslint/js": { "version": "9.39.4", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.39.4.tgz", - "integrity": "sha512-nE7DEIchvtiFTwBw4Lfbu59PG+kCofhjsKaCWzxTpt4lfRjRMqG6uMBzKXuEcyXhOHoUp9riAm7/aWYGhXZ9cw==", "dev": true, "license": "MIT", "engines": { @@ -712,8 +602,6 @@ }, "node_modules/@eslint/object-schema": { "version": "2.1.7", - "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-2.1.7.tgz", - "integrity": "sha512-VtAOaymWVfZcmZbp6E2mympDIHvyjXs/12LqWYjVw6qjrfF+VK+fyG33kChz3nnK+SU5/NeHOqrTEHS8sXO3OA==", "dev": true, "license": "Apache-2.0", "engines": { @@ -722,8 +610,6 @@ }, "node_modules/@eslint/plugin-kit": { "version": "0.4.1", - "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.4.1.tgz", - "integrity": "sha512-43/qtrDUokr7LJqoF2c3+RInu/t4zfrpYdoSDfYyhg52rwLV6TnOvdG4fXm7IkSB3wErkcmJS9iEhjVtOSEjjA==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -796,8 +682,6 @@ }, "node_modules/@istanbuljs/load-nyc-config": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", - "integrity": "sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==", "dev": true, "license": "ISC", "dependencies": { @@ -813,8 +697,6 @@ }, "node_modules/@istanbuljs/load-nyc-config/node_modules/find-up": { "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", "dev": true, "license": "MIT", "dependencies": { @@ -827,8 +709,6 @@ }, "node_modules/@istanbuljs/load-nyc-config/node_modules/locate-path": { "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", "dev": true, "license": "MIT", "dependencies": { @@ -840,8 +720,6 @@ }, "node_modules/@istanbuljs/load-nyc-config/node_modules/p-limit": { "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", "dev": true, "license": "MIT", "dependencies": { @@ -856,8 +734,6 @@ }, "node_modules/@istanbuljs/load-nyc-config/node_modules/p-locate": { "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", "dev": true, "license": "MIT", "dependencies": { @@ -877,8 +753,6 @@ }, "node_modules/@jest/console": { "version": "30.3.0", - "resolved": "https://registry.npmjs.org/@jest/console/-/console-30.3.0.tgz", - "integrity": "sha512-PAwCvFJ4696XP2qZj+LAn1BWjZaJ6RjG6c7/lkMaUJnkyMS34ucuIsfqYvfskVNvUI27R/u4P1HMYFnlVXG/Ww==", "dev": true, "license": "MIT", "dependencies": { @@ -895,8 +769,6 @@ }, "node_modules/@jest/core": { "version": "30.3.0", - "resolved": "https://registry.npmjs.org/@jest/core/-/core-30.3.0.tgz", - "integrity": "sha512-U5mVPsBxLSO6xYbf+tgkymLx+iAhvZX43/xI1+ej2ZOPnPdkdO1CzDmFKh2mZBn2s4XZixszHeQnzp1gm/DIxw==", "dev": true, "license": "MIT", "dependencies": { @@ -942,8 +814,6 @@ }, "node_modules/@jest/diff-sequences": { "version": "30.3.0", - "resolved": "https://registry.npmjs.org/@jest/diff-sequences/-/diff-sequences-30.3.0.tgz", - "integrity": "sha512-cG51MVnLq1ecVUaQ3fr6YuuAOitHK1S4WUJHnsPFE/quQr33ADUx1FfrTCpMCRxvy0Yr9BThKpDjSlcTi91tMA==", "dev": true, "license": "MIT", "engines": { @@ -952,8 +822,6 @@ }, "node_modules/@jest/environment": { "version": "30.3.0", - "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-30.3.0.tgz", - "integrity": "sha512-SlLSF4Be735yQXyh2+mctBOzNDx5s5uLv88/j8Qn1wH679PDcwy67+YdADn8NJnGjzlXtN62asGH/T4vWOkfaw==", "dev": true, "license": "MIT", "dependencies": { @@ -968,8 +836,6 @@ }, "node_modules/@jest/expect": { "version": "30.3.0", - "resolved": "https://registry.npmjs.org/@jest/expect/-/expect-30.3.0.tgz", - "integrity": "sha512-76Nlh4xJxk2D/9URCn3wFi98d2hb19uWE1idLsTt2ywhvdOldbw3S570hBgn25P4ICUZ/cBjybrBex2g17IDbg==", "dev": true, "license": "MIT", "dependencies": { @@ -982,8 +848,6 @@ }, "node_modules/@jest/expect-utils": { "version": "30.3.0", - "resolved": "https://registry.npmjs.org/@jest/expect-utils/-/expect-utils-30.3.0.tgz", - "integrity": "sha512-j0+W5iQQ8hBh7tHZkTQv3q2Fh/M7Je72cIsYqC4OaktgtO7v1So9UTjp6uPBHIaB6beoF/RRsCgMJKvti0wADA==", "dev": true, "license": "MIT", "dependencies": { @@ -995,8 +859,6 @@ }, "node_modules/@jest/fake-timers": { "version": "30.3.0", - "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-30.3.0.tgz", - "integrity": "sha512-WUQDs8SOP9URStX1DzhD425CqbN/HxUYCTwVrT8sTVBfMvFqYt/s61EK5T05qnHu0po6RitXIvP9otZxYDzTGQ==", "dev": true, "license": "MIT", "dependencies": { @@ -1013,8 +875,6 @@ }, "node_modules/@jest/get-type": { "version": "30.1.0", - "resolved": "https://registry.npmjs.org/@jest/get-type/-/get-type-30.1.0.tgz", - "integrity": "sha512-eMbZE2hUnx1WV0pmURZY9XoXPkUYjpc55mb0CrhtdWLtzMQPFvu/rZkTLZFTsdaVQa+Tr4eWAteqcUzoawq/uA==", "dev": true, "license": "MIT", "engines": { @@ -1023,8 +883,6 @@ }, "node_modules/@jest/globals": { "version": "30.3.0", - "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-30.3.0.tgz", - "integrity": "sha512-+owLCBBdfpgL3HU+BD5etr1SvbXpSitJK0is1kiYjJxAAJggYMRQz5hSdd5pq1sSggfxPbw2ld71pt4x5wwViA==", "dev": true, "license": "MIT", "dependencies": { @@ -1039,8 +897,6 @@ }, "node_modules/@jest/pattern": { "version": "30.0.1", - "resolved": "https://registry.npmjs.org/@jest/pattern/-/pattern-30.0.1.tgz", - "integrity": "sha512-gWp7NfQW27LaBQz3TITS8L7ZCQ0TLvtmI//4OwlQRx4rnWxcPNIYjxZpDcN4+UlGxgm3jS5QPz8IPTCkb59wZA==", "dev": true, "license": "MIT", "dependencies": { @@ -1053,8 +909,6 @@ }, "node_modules/@jest/reporters": { "version": "30.3.0", - "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-30.3.0.tgz", - "integrity": "sha512-a09z89S+PkQnL055bVj8+pe2Caed2PBOaczHcXCykW5ngxX9EWx/1uAwncxc/HiU0oZqfwseMjyhxgRjS49qPw==", "dev": true, "license": "MIT", "dependencies": { @@ -1096,15 +950,11 @@ }, "node_modules/@jest/reporters/node_modules/@bcoe/v8-coverage": { "version": "0.2.3", - "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz", - "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==", "dev": true, "license": "MIT" }, "node_modules/@jest/schemas": { "version": "30.0.5", - "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-30.0.5.tgz", - "integrity": "sha512-DmdYgtezMkh3cpU8/1uyXakv3tJRcmcXxBOcO0tbaozPwpmh4YMsnWrQm9ZmZMfa5ocbxzbFk6O4bDPEc/iAnA==", "dev": true, "license": "MIT", "dependencies": { @@ -1116,8 +966,6 @@ }, "node_modules/@jest/snapshot-utils": { "version": "30.3.0", - "resolved": "https://registry.npmjs.org/@jest/snapshot-utils/-/snapshot-utils-30.3.0.tgz", - "integrity": "sha512-ORbRN9sf5PP82v3FXNSwmO1OTDR2vzR2YTaR+E3VkSBZ8zadQE6IqYdYEeFH1NIkeB2HIGdF02dapb6K0Mj05g==", "dev": true, "license": "MIT", "dependencies": { @@ -1132,8 +980,6 @@ }, "node_modules/@jest/source-map": { "version": "30.0.1", - "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-30.0.1.tgz", - "integrity": "sha512-MIRWMUUR3sdbP36oyNyhbThLHyJ2eEDClPCiHVbrYAe5g3CHRArIVpBw7cdSB5fr+ofSfIb2Tnsw8iEHL0PYQg==", "dev": true, "license": "MIT", "dependencies": { @@ -1147,8 +993,6 @@ }, "node_modules/@jest/test-result": { "version": "30.3.0", - "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-30.3.0.tgz", - "integrity": "sha512-e/52nJGuD74AKTSe0P4y5wFRlaXP0qmrS17rqOMHeSwm278VyNyXE3gFO/4DTGF9w+65ra3lo3VKj0LBrzmgdQ==", "dev": true, "license": "MIT", "dependencies": { @@ -1163,8 +1007,6 @@ }, "node_modules/@jest/test-sequencer": { "version": "30.3.0", - "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-30.3.0.tgz", - "integrity": "sha512-dgbWy9b8QDlQeRZcv7LNF+/jFiiYHTKho1xirauZ7kVwY7avjFF6uTT0RqlgudB5OuIPagFdVtfFMosjVbk1eA==", "dev": true, "license": "MIT", "dependencies": { @@ -1179,8 +1021,6 @@ }, "node_modules/@jest/transform": { "version": "30.3.0", - "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-30.3.0.tgz", - "integrity": "sha512-TLKY33fSLVd/lKB2YI1pH69ijyUblO/BQvCj566YvnwuzoTNr648iE0j22vRvVNk2HsPwByPxATg3MleS3gf5A==", "dev": true, "license": "MIT", "dependencies": { @@ -1205,8 +1045,6 @@ }, "node_modules/@jest/types": { "version": "30.3.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-30.3.0.tgz", - "integrity": "sha512-JHm87k7bA33hpBngtU8h6UBub/fqqA9uXfw+21j5Hmk7ooPHlboRNxHq0JcMtC+n8VJGP1mcfnD3Mk+XKe1oSw==", "dev": true, "license": "MIT", "dependencies": { @@ -1233,8 +1071,6 @@ }, "node_modules/@jridgewell/remapping": { "version": "2.3.5", - "resolved": "https://registry.npmjs.org/@jridgewell/remapping/-/remapping-2.3.5.tgz", - "integrity": "sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==", "dev": true, "license": "MIT", "dependencies": { @@ -1294,8 +1130,6 @@ }, "node_modules/@pkgr/core": { "version": "0.2.9", - "resolved": "https://registry.npmjs.org/@pkgr/core/-/core-0.2.9.tgz", - "integrity": "sha512-QNqXyfVS2wm9hweSYD2O7F0G06uurj9kZ96TRQE5Y9hU7+tgdZwIkbAKc5Ocy1HxEY2kuDQa6cQ1WRs/O5LFKA==", "dev": true, "license": "MIT", "engines": { @@ -1307,15 +1141,11 @@ }, "node_modules/@sinclair/typebox": { "version": "0.34.48", - "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.34.48.tgz", - "integrity": "sha512-kKJTNuK3AQOrgjjotVxMrCn1sUJwM76wMszfq1kdU4uYVJjvEWuFQ6HgvLt4Xz3fSmZlTOxJ/Ie13KnIcWQXFA==", "dev": true, "license": "MIT" }, "node_modules/@sinonjs/commons": { "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-3.0.1.tgz", - "integrity": "sha512-K3mCHKQ9sVh8o1C9cxkwxaOmXoAMlDxC1mYyHrjqOWEcBjYr76t96zL2zlj5dUGZ3HSw240X1qgH3Mjf1yJWpQ==", "dev": true, "license": "BSD-3-Clause", "dependencies": { @@ -1324,8 +1154,6 @@ }, "node_modules/@sinonjs/fake-timers": { "version": "15.1.1", - "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-15.1.1.tgz", - "integrity": "sha512-cO5W33JgAPbOh07tvZjUOJ7oWhtaqGHiZw+11DPbyqh2kHTBc3eF/CjJDeQ4205RLQsX6rxCuYOroFQwl7JDRw==", "dev": true, "license": "BSD-3-Clause", "dependencies": { @@ -1334,8 +1162,6 @@ }, "node_modules/@types/babel__core": { "version": "7.20.5", - "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz", - "integrity": "sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==", "dev": true, "license": "MIT", "dependencies": { @@ -1348,8 +1174,6 @@ }, "node_modules/@types/babel__generator": { "version": "7.27.0", - "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.27.0.tgz", - "integrity": "sha512-ufFd2Xi92OAVPYsy+P4n7/U7e68fex0+Ee8gSG9KX7eo084CWiQ4sdxktvdl0bOPupXtVJPY19zk6EwWqUQ8lg==", "dev": true, "license": "MIT", "dependencies": { @@ -1358,8 +1182,6 @@ }, "node_modules/@types/babel__template": { "version": "7.4.4", - "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.4.tgz", - "integrity": "sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==", "dev": true, "license": "MIT", "dependencies": { @@ -1369,8 +1191,6 @@ }, "node_modules/@types/babel__traverse": { "version": "7.28.0", - "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.28.0.tgz", - "integrity": "sha512-8PvcXf70gTDZBgt9ptxJ8elBeBjcLOAcOtoO/mPJjtji1+CdGbHgm77om1GrsPxsiE+uXIpNSK64UYaIwQXd4Q==", "dev": true, "license": "MIT", "dependencies": { @@ -1384,15 +1204,11 @@ }, "node_modules/@types/istanbul-lib-coverage": { "version": "2.0.6", - "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.6.tgz", - "integrity": "sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w==", "dev": true, "license": "MIT" }, "node_modules/@types/istanbul-lib-report": { "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.3.tgz", - "integrity": "sha512-NQn7AHQnk/RSLOxrBbGyJM/aVQ+pjj5HCgasFxc0K/KhoATfQ/47AyUl15I2yBUpihjmas+a+VJBOqecrFH+uA==", "dev": true, "license": "MIT", "dependencies": { @@ -1401,8 +1217,6 @@ }, "node_modules/@types/istanbul-reports": { "version": "3.0.4", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.4.tgz", - "integrity": "sha512-pk2B1NWalF9toCRu6gjBzR69syFjP4Od8WRAX+0mmf9lAjCRicLOWc+ZrxZHx/0XRjotgkF9t6iaMJ+aXcOdZQ==", "dev": true, "license": "MIT", "dependencies": { @@ -1411,15 +1225,11 @@ }, "node_modules/@types/json-schema": { "version": "7.0.15", - "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", - "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", "dev": true, "license": "MIT" }, "node_modules/@types/node": { "version": "25.5.0", - "resolved": "https://registry.npmjs.org/@types/node/-/node-25.5.0.tgz", - "integrity": "sha512-jp2P3tQMSxWugkCUKLRPVUpGaL5MVFwF8RDuSRztfwgN1wmqJeMSbKlnEtQqU8UrhTmzEmZdu2I6v2dpp7XIxw==", "dev": true, "license": "MIT", "dependencies": { @@ -1428,15 +1238,11 @@ }, "node_modules/@types/stack-utils": { "version": "2.0.3", - "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.3.tgz", - "integrity": "sha512-9aEbYZ3TbYMznPdcdr3SmIrLXwC/AKZXQeCf9Pgao5CKb8CyHuEX5jzWPTkvregvhRJHcpRO6BFoGW9ycaOkYw==", "dev": true, "license": "MIT" }, "node_modules/@types/yargs": { "version": "17.0.35", - "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.35.tgz", - "integrity": "sha512-qUHkeCyQFxMXg79wQfTtfndEC+N9ZZg76HJftDJp+qH2tV7Gj4OJi7l+PiWwJ+pWtW8GwSmqsDj/oymhrTWXjg==", "dev": true, "license": "MIT", "dependencies": { @@ -1445,8 +1251,6 @@ }, "node_modules/@types/yargs-parser": { "version": "21.0.3", - "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-21.0.3.tgz", - "integrity": "sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ==", "dev": true, "license": "MIT" }, @@ -1464,15 +1268,11 @@ }, "node_modules/@ungap/structured-clone": { "version": "1.3.0", - "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.3.0.tgz", - "integrity": "sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g==", "dev": true, "license": "ISC" }, "node_modules/@unrs/resolver-binding-linux-x64-gnu": { "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-x64-gnu/-/resolver-binding-linux-x64-gnu-1.11.1.tgz", - "integrity": "sha512-C3ZAHugKgovV5YvAMsxhq0gtXuwESUKc5MhEtjBpLoHPLYM+iuwSj3lflFwK3DPm68660rZ7G8BMcwSro7hD5w==", "cpu": [ "x64" ], @@ -1485,8 +1285,6 @@ }, "node_modules/@unrs/resolver-binding-linux-x64-musl": { "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-x64-musl/-/resolver-binding-linux-x64-musl-1.11.1.tgz", - "integrity": "sha512-rV0YSoyhK2nZ4vEswT/QwqzqQXw5I6CjoaYMOX0TqBlWhojUf8P94mvI7nuJTeaCkkds3QE4+zS8Ko+GdXuZtA==", "cpu": [ "x64" ], @@ -1497,6 +1295,18 @@ "linux" ] }, + "node_modules/@unrs/resolver-binding-win32-x64-msvc": { + "version": "1.11.1", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, "node_modules/accepts": { "version": "2.0.0", "license": "MIT", @@ -1529,8 +1339,6 @@ }, "node_modules/ajv": { "version": "6.14.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.14.0.tgz", - "integrity": "sha512-IWrosm/yrn43eiKqkfkHis7QioDleaXQHdDVPKg0FSwwd/DuvyX79TZnFOnYpB7dcsFAMmtFztZuXPDvSePkFw==", "dev": true, "license": "MIT", "dependencies": { @@ -1546,8 +1354,6 @@ }, "node_modules/ansi-escapes": { "version": "4.3.2", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", - "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", "dev": true, "license": "MIT", "dependencies": { @@ -1587,8 +1393,6 @@ }, "node_modules/anymatch": { "version": "3.1.3", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", - "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", "dev": true, "license": "ISC", "dependencies": { @@ -1601,8 +1405,6 @@ }, "node_modules/anymatch/node_modules/picomatch": { "version": "2.3.2", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.2.tgz", - "integrity": "sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA==", "dev": true, "license": "MIT", "engines": { @@ -1622,8 +1424,6 @@ }, "node_modules/argparse": { "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", "dev": true, "license": "MIT", "dependencies": { @@ -1642,8 +1442,6 @@ }, "node_modules/babel-jest": { "version": "30.3.0", - "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-30.3.0.tgz", - "integrity": "sha512-gRpauEU2KRrCox5Z296aeVHR4jQ98BCnu0IO332D/xpHNOsIH/bgSRk9k6GbKIbBw8vFeN6ctuu6tV8WOyVfYQ==", "dev": true, "license": "MIT", "dependencies": { @@ -1664,8 +1462,6 @@ }, "node_modules/babel-plugin-istanbul": { "version": "7.0.1", - "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-7.0.1.tgz", - "integrity": "sha512-D8Z6Qm8jCvVXtIRkBnqNHX0zJ37rQcFJ9u8WOS6tkYOsRdHBzypCstaxWiu5ZIlqQtviRYbgnRLSoCEvjqcqbA==", "dev": true, "license": "BSD-3-Clause", "workspaces": [ @@ -1684,9 +1480,6 @@ }, "node_modules/babel-plugin-istanbul/node_modules/glob": { "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", - "deprecated": "Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me", "dev": true, "license": "ISC", "dependencies": { @@ -1706,8 +1499,6 @@ }, "node_modules/babel-plugin-istanbul/node_modules/test-exclude": { "version": "6.0.0", - "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", - "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==", "dev": true, "license": "ISC", "dependencies": { @@ -1721,8 +1512,6 @@ }, "node_modules/babel-plugin-jest-hoist": { "version": "30.3.0", - "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-30.3.0.tgz", - "integrity": "sha512-+TRkByhsws6sfPjVaitzadk1I0F5sPvOVUH5tyTSzhePpsGIVrdeunHSw/C36QeocS95OOk8lunc4rlu5Anwsg==", "dev": true, "license": "MIT", "dependencies": { @@ -1734,8 +1523,6 @@ }, "node_modules/babel-preset-current-node-syntax": { "version": "1.2.0", - "resolved": "https://registry.npmjs.org/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.2.0.tgz", - "integrity": "sha512-E/VlAEzRrsLEb2+dv8yp3bo4scof3l9nR4lrld+Iy5NyVqgVYUJnDAmunkhPMisRI32Qc4iRiz425d8vM++2fg==", "dev": true, "license": "MIT", "dependencies": { @@ -1761,8 +1548,6 @@ }, "node_modules/babel-preset-jest": { "version": "30.3.0", - "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-30.3.0.tgz", - "integrity": "sha512-6ZcUbWHC+dMz2vfzdNwi87Z1gQsLNK2uLuK1Q89R11xdvejcivlYYwDlEv0FHX3VwEXpbBQ9uufB/MUNpZGfhQ==", "dev": true, "license": "MIT", "dependencies": { @@ -1783,8 +1568,6 @@ }, "node_modules/baseline-browser-mapping": { "version": "2.10.10", - "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.10.10.tgz", - "integrity": "sha512-sUoJ3IMxx4AyRqO4MLeHlnGDkyXRoUG0/AI9fjK+vS72ekpV0yWVY7O0BVjmBcRtkNcsAO2QDZ4tdKKGoI6YaQ==", "dev": true, "license": "Apache-2.0", "bin": { @@ -1818,8 +1601,6 @@ }, "node_modules/brace-expansion": { "version": "1.1.12", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", - "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", "dev": true, "license": "MIT", "dependencies": { @@ -1829,8 +1610,6 @@ }, "node_modules/browserslist": { "version": "4.28.1", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.28.1.tgz", - "integrity": "sha512-ZC5Bd0LgJXgwGqUknZY/vkUQ04r8NXnJZ3yYi4vDmSiZmC/pdSN0NbNRPxZpbtO4uAfDUAFffO8IZoM3Gj8IkA==", "dev": true, "funding": [ { @@ -1863,8 +1642,6 @@ }, "node_modules/bser": { "version": "2.1.1", - "resolved": "https://registry.npmjs.org/bser/-/bser-2.1.1.tgz", - "integrity": "sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -1873,13 +1650,10 @@ }, "node_modules/buffer-equal-constant-time": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz", - "integrity": "sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA==" + "license": "BSD-3-Clause" }, "node_modules/buffer-from": { "version": "1.1.2", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", - "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", "dev": true, "license": "MIT" }, @@ -1917,8 +1691,6 @@ }, "node_modules/callsites": { "version": "3.1.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", - "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", "dev": true, "license": "MIT", "engines": { @@ -1927,8 +1699,6 @@ }, "node_modules/camelcase": { "version": "5.3.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", "dev": true, "license": "MIT", "engines": { @@ -1937,8 +1707,6 @@ }, "node_modules/caniuse-lite": { "version": "1.0.30001781", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001781.tgz", - "integrity": "sha512-RdwNCyMsNBftLjW6w01z8bKEvT6e/5tpPVEgtn22TiLGlstHOVecsX2KHFkD5e/vRnIE4EGzpuIODb3mtswtkw==", "dev": true, "funding": [ { @@ -1958,8 +1726,6 @@ }, "node_modules/chalk": { "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "dev": true, "license": "MIT", "dependencies": { @@ -1975,8 +1741,6 @@ }, "node_modules/char-regex": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/char-regex/-/char-regex-1.0.2.tgz", - "integrity": "sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==", "dev": true, "license": "MIT", "engines": { @@ -1985,8 +1749,6 @@ }, "node_modules/ci-info": { "version": "4.4.0", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-4.4.0.tgz", - "integrity": "sha512-77PSwercCZU2Fc4sX94eF8k8Pxte6JAwL4/ICZLFjJLqegs7kCuAsqqj/70NQF6TvDpgFjkubQB2FW2ZZddvQg==", "dev": true, "funding": [ { @@ -2001,15 +1763,11 @@ }, "node_modules/cjs-module-lexer": { "version": "2.2.0", - "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-2.2.0.tgz", - "integrity": "sha512-4bHTS2YuzUvtoLjdy+98ykbNB5jS0+07EvFNXerqZQJ89F7DI6ET7OQo/HJuW6K0aVsKA9hj9/RVb2kQVOrPDQ==", "dev": true, "license": "MIT" }, "node_modules/cliui": { "version": "8.0.1", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", - "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", "dev": true, "license": "ISC", "dependencies": { @@ -2023,8 +1781,6 @@ }, "node_modules/cliui/node_modules/ansi-regex": { "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", "dev": true, "license": "MIT", "engines": { @@ -2033,15 +1789,11 @@ }, "node_modules/cliui/node_modules/emoji-regex": { "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", "dev": true, "license": "MIT" }, "node_modules/cliui/node_modules/string-width": { "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", "dev": true, "license": "MIT", "dependencies": { @@ -2055,8 +1807,6 @@ }, "node_modules/cliui/node_modules/strip-ansi": { "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", "dev": true, "license": "MIT", "dependencies": { @@ -2068,8 +1818,6 @@ }, "node_modules/cliui/node_modules/wrap-ansi": { "version": "7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", "dev": true, "license": "MIT", "dependencies": { @@ -2086,8 +1834,6 @@ }, "node_modules/co": { "version": "4.6.0", - "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", - "integrity": "sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ==", "dev": true, "license": "MIT", "engines": { @@ -2097,8 +1843,6 @@ }, "node_modules/collect-v8-coverage": { "version": "1.0.3", - "resolved": "https://registry.npmjs.org/collect-v8-coverage/-/collect-v8-coverage-1.0.3.tgz", - "integrity": "sha512-1L5aqIkwPfiodaMgQunkF1zRhNqifHBmtbbbxcr6yVxxBnliw4TDOW6NxpO8DJLgJ16OT+Y4ztZqP6p/FtXnAw==", "dev": true, "license": "MIT" }, @@ -2147,8 +1891,6 @@ }, "node_modules/concat-map": { "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", "dev": true, "license": "MIT" }, @@ -2172,8 +1914,6 @@ }, "node_modules/convert-source-map": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", - "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", "dev": true, "license": "MIT" }, @@ -2241,8 +1981,6 @@ }, "node_modules/dedent": { "version": "1.7.2", - "resolved": "https://registry.npmjs.org/dedent/-/dedent-1.7.2.tgz", - "integrity": "sha512-WzMx3mW98SN+zn3hgemf4OzdmyNhhhKz5Ay0pUfQiMQ3e1g+xmTJWp/pKdwKVXhdSkAEGIIzqeuWrL3mV/AXbA==", "dev": true, "license": "MIT", "peerDependencies": { @@ -2261,8 +1999,6 @@ }, "node_modules/deepmerge": { "version": "4.3.1", - "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz", - "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==", "dev": true, "license": "MIT", "engines": { @@ -2286,8 +2022,6 @@ }, "node_modules/detect-newline": { "version": "3.1.0", - "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz", - "integrity": "sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==", "dev": true, "license": "MIT", "engines": { @@ -2332,8 +2066,7 @@ }, "node_modules/ecdsa-sig-formatter": { "version": "1.0.11", - "resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz", - "integrity": "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==", + "license": "Apache-2.0", "dependencies": { "safe-buffer": "^5.0.1" } @@ -2344,15 +2077,11 @@ }, "node_modules/electron-to-chromium": { "version": "1.5.322", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.322.tgz", - "integrity": "sha512-vFU34OcrvMcH66T+dYC3G4nURmgfDVewMIu6Q2urXpumAPSMmzvcn04KVVV8Opikq8Vs5nUbO/8laNhNRqSzYw==", "dev": true, "license": "ISC" }, "node_modules/emittery": { "version": "0.13.1", - "resolved": "https://registry.npmjs.org/emittery/-/emittery-0.13.1.tgz", - "integrity": "sha512-DeWwawk6r5yR9jFgnDKYt4sLS0LmHJJi3ZOnb5/JdbYwj3nW+FxQnHIjhBKz8YLC7oRNPVM9NQ47I3CVx34eqQ==", "dev": true, "license": "MIT", "engines": { @@ -2376,8 +2105,6 @@ }, "node_modules/error-ex": { "version": "1.3.4", - "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.4.tgz", - "integrity": "sha512-sqQamAnR14VgCr1A618A3sGrygcpK+HEbenA/HiEAkkUwcZIIB/tgWqHFxWgOyDh4nB4JCRimh79dR5Ywc9MDQ==", "dev": true, "license": "MIT", "dependencies": { @@ -2424,8 +2151,6 @@ }, "node_modules/escalade": { "version": "3.2.0", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", - "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", "dev": true, "license": "MIT", "engines": { @@ -2449,8 +2174,6 @@ }, "node_modules/eslint": { "version": "9.39.4", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.39.4.tgz", - "integrity": "sha512-XoMjdBOwe/esVgEvLmNsD3IRHkm7fbKIUGvrleloJXUZgDHig2IPWNniv+GwjyJXzuNqVjlr5+4yVUZjycJwfQ==", "dev": true, "license": "MIT", "dependencies": { @@ -2546,8 +2269,6 @@ }, "node_modules/eslint-scope": { "version": "8.4.0", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.4.0.tgz", - "integrity": "sha512-sNXOfKCn74rt8RICKMvJS7XKV/Xk9kA7DyJr8mJik3S7Cwgy3qlkkmyS2uQB3jiJg6VNdZd/pDBJu0nvG2NlTg==", "dev": true, "license": "BSD-2-Clause", "dependencies": { @@ -2590,8 +2311,6 @@ }, "node_modules/esprima": { "version": "4.0.1", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", "dev": true, "license": "BSD-2-Clause", "bin": { @@ -2615,8 +2334,6 @@ }, "node_modules/esrecurse": { "version": "4.3.0", - "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", - "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", "dev": true, "license": "BSD-2-Clause", "dependencies": { @@ -2651,8 +2368,6 @@ }, "node_modules/execa": { "version": "5.1.1", - "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", - "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", "dev": true, "license": "MIT", "dependencies": { @@ -2675,15 +2390,11 @@ }, "node_modules/execa/node_modules/signal-exit": { "version": "3.0.7", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", - "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", "dev": true, "license": "ISC" }, "node_modules/exit-x": { "version": "0.2.2", - "resolved": "https://registry.npmjs.org/exit-x/-/exit-x-0.2.2.tgz", - "integrity": "sha512-+I6B/IkJc1o/2tiURyz/ivu/O0nKNEArIUB5O7zBrlDVJr22SCLH3xTeEry428LvFhRzIA1g8izguxJ/gbNcVQ==", "dev": true, "license": "MIT", "engines": { @@ -2692,8 +2403,6 @@ }, "node_modules/expect": { "version": "30.3.0", - "resolved": "https://registry.npmjs.org/expect/-/expect-30.3.0.tgz", - "integrity": "sha512-1zQrciTiQfRdo7qJM1uG4navm8DayFa2TgCSRlzUyNkhcJ6XUZF3hjnpkyr3VhAqPH7i/9GkG7Tv5abz6fqz0Q==", "dev": true, "license": "MIT", "dependencies": { @@ -2751,8 +2460,6 @@ }, "node_modules/express-rate-limit": { "version": "8.3.1", - "resolved": "https://registry.npmjs.org/express-rate-limit/-/express-rate-limit-8.3.1.tgz", - "integrity": "sha512-D1dKN+cmyPWuvB+G2SREQDzPY1agpBIcTa9sJxOPMCNeH3gwzhqJRDWCXW3gg0y//+LQ/8j52JbMROWyrKdMdw==", "license": "MIT", "dependencies": { "ip-address": "10.1.0" @@ -2769,15 +2476,11 @@ }, "node_modules/fast-deep-equal": { "version": "3.1.3", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", "dev": true, "license": "MIT" }, "node_modules/fast-json-stable-stringify": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", - "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", "dev": true, "license": "MIT" }, @@ -2793,8 +2496,6 @@ }, "node_modules/fb-watchman": { "version": "2.0.2", - "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.2.tgz", - "integrity": "sha512-p5161BqbuCaSnB8jIbzQHOlpgsPmK5rJVDfDKO91Axs5NC1uu3HRQm6wt9cd9/+GtQQIO53JdGXXoyDpTAsgYA==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -2944,8 +2645,6 @@ }, "node_modules/fs.realpath": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", "dev": true, "license": "ISC" }, @@ -2958,8 +2657,6 @@ }, "node_modules/gensync": { "version": "1.0.0-beta.2", - "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", - "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", "dev": true, "license": "MIT", "engines": { @@ -2968,8 +2665,6 @@ }, "node_modules/get-caller-file": { "version": "2.0.5", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", - "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", "dev": true, "license": "ISC", "engines": { @@ -3000,8 +2695,6 @@ }, "node_modules/get-package-type": { "version": "0.1.0", - "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz", - "integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==", "dev": true, "license": "MIT", "engines": { @@ -3021,8 +2714,6 @@ }, "node_modules/get-stream": { "version": "6.0.1", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", - "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", "dev": true, "license": "MIT", "engines": { @@ -3107,8 +2798,6 @@ }, "node_modules/graceful-fs": { "version": "4.2.11", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", - "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", "dev": true, "license": "ISC" }, @@ -3154,6 +2843,15 @@ "node": ">= 0.4" } }, + "node_modules/helmet": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/helmet/-/helmet-8.1.0.tgz", + "integrity": "sha512-jOiHyAZsmnr8LqoPGmCjYAaiuWwjAPLgY8ZX2XrmHawt99/u1y6RgrZMTeoPfpUbV96HOalYgz1qzkRbw54Pmg==", + "license": "MIT", + "engines": { + "node": ">=18.0.0" + } + }, "node_modules/html-escaper": { "version": "2.0.2", "dev": true, @@ -3179,8 +2877,6 @@ }, "node_modules/human-signals": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", - "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", "dev": true, "license": "Apache-2.0", "engines": { @@ -3203,8 +2899,6 @@ }, "node_modules/ignore": { "version": "5.3.2", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", - "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", "dev": true, "license": "MIT", "engines": { @@ -3213,8 +2907,6 @@ }, "node_modules/import-fresh": { "version": "3.3.1", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.1.tgz", - "integrity": "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==", "dev": true, "license": "MIT", "dependencies": { @@ -3230,8 +2922,6 @@ }, "node_modules/import-fresh/node_modules/resolve-from": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", - "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", "dev": true, "license": "MIT", "engines": { @@ -3240,8 +2930,6 @@ }, "node_modules/import-local": { "version": "3.2.0", - "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.2.0.tgz", - "integrity": "sha512-2SPlun1JUPWoM6t3F0dw0FkCF/jWY8kttcY4f599GLTSjh2OCuuhdTkJQsEcZzBqbXZGKMK2OqW1oZsjtf/gQA==", "dev": true, "license": "MIT", "dependencies": { @@ -3268,9 +2956,6 @@ }, "node_modules/inflight": { "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", - "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.", "dev": true, "license": "ISC", "dependencies": { @@ -3284,8 +2969,6 @@ }, "node_modules/ip-address": { "version": "10.1.0", - "resolved": "https://registry.npmjs.org/ip-address/-/ip-address-10.1.0.tgz", - "integrity": "sha512-XXADHxXmvT9+CRxhXg56LJovE+bmWnEWB78LB83VZTprKTmaC5QfruXocxzTZ2Kl0DNwKuBdlIhjL8LeY8Sf8Q==", "license": "MIT", "engines": { "node": ">= 12" @@ -3300,8 +2983,6 @@ }, "node_modules/is-arrayish": { "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", - "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", "dev": true, "license": "MIT" }, @@ -3323,8 +3004,6 @@ }, "node_modules/is-generator-fn": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-generator-fn/-/is-generator-fn-2.1.0.tgz", - "integrity": "sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==", "dev": true, "license": "MIT", "engines": { @@ -3348,8 +3027,6 @@ }, "node_modules/is-stream": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", - "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", "dev": true, "license": "MIT", "engines": { @@ -3374,8 +3051,6 @@ }, "node_modules/istanbul-lib-instrument": { "version": "6.0.3", - "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-6.0.3.tgz", - "integrity": "sha512-Vtgk7L/R2JHyyGW07spoFlB8/lpjiOLTjMdms6AFMraYt3BaJauod/NGrfnVG/y4Ix1JEuMRPDPEj2ua+zz1/Q==", "dev": true, "license": "BSD-3-Clause", "dependencies": { @@ -3443,8 +3118,6 @@ }, "node_modules/jest": { "version": "30.3.0", - "resolved": "https://registry.npmjs.org/jest/-/jest-30.3.0.tgz", - "integrity": "sha512-AkXIIFcaazymvey2i/+F94XRnM6TsVLZDhBMLsd1Sf/W0wzsvvpjeyUrCZD6HGG4SDYPgDJDBKeiJTBb10WzMg==", "dev": true, "license": "MIT", "dependencies": { @@ -3470,8 +3143,6 @@ }, "node_modules/jest-changed-files": { "version": "30.3.0", - "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-30.3.0.tgz", - "integrity": "sha512-B/7Cny6cV5At6M25EWDgf9S617lHivamL8vl6KEpJqkStauzcG4e+WPfDgMMF+H4FVH4A2PLRyvgDJan4441QA==", "dev": true, "license": "MIT", "dependencies": { @@ -3485,8 +3156,6 @@ }, "node_modules/jest-circus": { "version": "30.3.0", - "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-30.3.0.tgz", - "integrity": "sha512-PyXq5szeSfR/4f1lYqCmmQjh0vqDkURUYi9N6whnHjlRz4IUQfMcXkGLeEoiJtxtyPqgUaUUfyQlApXWBSN1RA==", "dev": true, "license": "MIT", "dependencies": { @@ -3517,8 +3186,6 @@ }, "node_modules/jest-cli": { "version": "30.3.0", - "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-30.3.0.tgz", - "integrity": "sha512-l6Tqx+j1fDXJEW5bqYykDQQ7mQg+9mhWXtnj+tQZrTWYHyHoi6Be8HPumDSA+UiX2/2buEgjA58iJzdj146uCw==", "dev": true, "license": "MIT", "dependencies": { @@ -3550,8 +3217,6 @@ }, "node_modules/jest-config": { "version": "30.3.0", - "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-30.3.0.tgz", - "integrity": "sha512-WPMAkMAtNDY9P/oKObtsRG/6KTrhtgPJoBTmk20uDn4Uy6/3EJnnaZJre/FMT1KVRx8cve1r7/FlMIOfRVWL4w==", "dev": true, "license": "MIT", "dependencies": { @@ -3601,8 +3266,6 @@ }, "node_modules/jest-diff": { "version": "30.3.0", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-30.3.0.tgz", - "integrity": "sha512-n3q4PDQjS4LrKxfWB3Z5KNk1XjXtZTBwQp71OP0Jo03Z6V60x++K5L8k6ZrW8MY8pOFylZvHM0zsjS1RqlHJZQ==", "dev": true, "license": "MIT", "dependencies": { @@ -3617,8 +3280,6 @@ }, "node_modules/jest-docblock": { "version": "30.2.0", - "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-30.2.0.tgz", - "integrity": "sha512-tR/FFgZKS1CXluOQzZvNH3+0z9jXr3ldGSD8bhyuxvlVUwbeLOGynkunvlTMxchC5urrKndYiwCFC0DLVjpOCA==", "dev": true, "license": "MIT", "dependencies": { @@ -3630,8 +3291,6 @@ }, "node_modules/jest-each": { "version": "30.3.0", - "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-30.3.0.tgz", - "integrity": "sha512-V8eMndg/aZ+3LnCJgSm13IxS5XSBM22QSZc9BtPK8Dek6pm+hfUNfwBdvsB3d342bo1q7wnSkC38zjX259qZNA==", "dev": true, "license": "MIT", "dependencies": { @@ -3647,8 +3306,6 @@ }, "node_modules/jest-environment-node": { "version": "30.3.0", - "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-30.3.0.tgz", - "integrity": "sha512-4i6HItw/JSiJVsC5q0hnKIe/hbYfZLVG9YJ/0pU9Hz2n/9qZe3Rhn5s5CUZA5ORZlcdT/vmAXRMyONXJwPrmYQ==", "dev": true, "license": "MIT", "dependencies": { @@ -3666,8 +3323,6 @@ }, "node_modules/jest-haste-map": { "version": "30.3.0", - "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-30.3.0.tgz", - "integrity": "sha512-mMi2oqG4KRU0R9QEtscl87JzMXfUhbKaFqOxmjb2CKcbHcUGFrJCBWHmnTiUqi6JcnzoBlO4rWfpdl2k/RfLCA==", "dev": true, "license": "MIT", "dependencies": { @@ -3691,8 +3346,6 @@ }, "node_modules/jest-leak-detector": { "version": "30.3.0", - "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-30.3.0.tgz", - "integrity": "sha512-cuKmUUGIjfXZAiGJ7TbEMx0bcqNdPPI6P1V+7aF+m/FUJqFDxkFR4JqkTu8ZOiU5AaX/x0hZ20KaaIPXQzbMGQ==", "dev": true, "license": "MIT", "dependencies": { @@ -3705,8 +3358,6 @@ }, "node_modules/jest-matcher-utils": { "version": "30.3.0", - "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-30.3.0.tgz", - "integrity": "sha512-HEtc9uFQgaUHkC7nLSlQL3Tph4Pjxt/yiPvkIrrDCt9jhoLIgxaubo1G+CFOnmHYMxHwwdaSN7mkIFs6ZK8OhA==", "dev": true, "license": "MIT", "dependencies": { @@ -3721,8 +3372,6 @@ }, "node_modules/jest-message-util": { "version": "30.3.0", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-30.3.0.tgz", - "integrity": "sha512-Z/j4Bo+4ySJ+JPJN3b2Qbl9hDq3VrXmnjjGEWD/x0BCXeOXPTV1iZYYzl2X8c1MaCOL+ewMyNBcm88sboE6YWw==", "dev": true, "license": "MIT", "dependencies": { @@ -3742,8 +3391,6 @@ }, "node_modules/jest-mock": { "version": "30.3.0", - "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-30.3.0.tgz", - "integrity": "sha512-OTzICK8CpE+t4ndhKrwlIdbM6Pn8j00lvmSmq5ejiO+KxukbLjgOflKWMn3KE34EZdQm5RqTuKj+5RIEniYhog==", "dev": true, "license": "MIT", "dependencies": { @@ -3757,8 +3404,6 @@ }, "node_modules/jest-pnp-resolver": { "version": "1.2.3", - "resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.3.tgz", - "integrity": "sha512-+3NpwQEnRoIBtx4fyhblQDPgJI0H1IEIkX7ShLUjPGA7TtUTvI1oiKi3SR4oBR0hQhQR80l4WAe5RrXBwWMA8w==", "dev": true, "license": "MIT", "engines": { @@ -3775,8 +3420,6 @@ }, "node_modules/jest-regex-util": { "version": "30.0.1", - "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-30.0.1.tgz", - "integrity": "sha512-jHEQgBXAgc+Gh4g0p3bCevgRCVRkB4VB70zhoAE48gxeSr1hfUOsM/C2WoJgVL7Eyg//hudYENbm3Ne+/dRVVA==", "dev": true, "license": "MIT", "engines": { @@ -3785,8 +3428,6 @@ }, "node_modules/jest-resolve": { "version": "30.3.0", - "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-30.3.0.tgz", - "integrity": "sha512-NRtTAHQlpd15F9rUR36jqwelbrDV/dY4vzNte3S2kxCKUJRYNd5/6nTSbYiak1VX5g8IoFF23Uj5TURkUW8O5g==", "dev": true, "license": "MIT", "dependencies": { @@ -3805,8 +3446,6 @@ }, "node_modules/jest-resolve-dependencies": { "version": "30.3.0", - "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-30.3.0.tgz", - "integrity": "sha512-9ev8s3YN6Hsyz9LV75XUwkCVFlwPbaFn6Wp75qnI0wzAINYWY8Fb3+6y59Rwd3QaS3kKXffHXsZMziMavfz/nw==", "dev": true, "license": "MIT", "dependencies": { @@ -3819,8 +3458,6 @@ }, "node_modules/jest-runner": { "version": "30.3.0", - "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-30.3.0.tgz", - "integrity": "sha512-gDv6C9LGKWDPLia9TSzZwf4h3kMQCqyTpq+95PODnTRDO0g9os48XIYYkS6D236vjpBir2fF63YmJFtqkS5Duw==", "dev": true, "license": "MIT", "dependencies": { @@ -3853,8 +3490,6 @@ }, "node_modules/jest-runtime": { "version": "30.3.0", - "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-30.3.0.tgz", - "integrity": "sha512-CgC+hIBJbuh78HEffkhNKcbXAytQViplcl8xupqeIWyKQF50kCQA8J7GeJCkjisC6hpnC9Muf8jV5RdtdFbGng==", "dev": true, "license": "MIT", "dependencies": { @@ -3887,8 +3522,6 @@ }, "node_modules/jest-snapshot": { "version": "30.3.0", - "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-30.3.0.tgz", - "integrity": "sha512-f14c7atpb4O2DeNhwcvS810Y63wEn8O1HqK/luJ4F6M4NjvxmAKQwBUWjbExUtMxWJQ0wVgmCKymeJK6NZMnfQ==", "dev": true, "license": "MIT", "dependencies": { @@ -3920,8 +3553,6 @@ }, "node_modules/jest-util": { "version": "30.3.0", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-30.3.0.tgz", - "integrity": "sha512-/jZDa00a3Sz7rdyu55NLrQCIrbyIkbBxareejQI315f/i8HjYN+ZWsDLLpoQSiUIEIyZF/R8fDg3BmB8AtHttg==", "dev": true, "license": "MIT", "dependencies": { @@ -3938,8 +3569,6 @@ }, "node_modules/jest-validate": { "version": "30.3.0", - "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-30.3.0.tgz", - "integrity": "sha512-I/xzC8h5G+SHCb2P2gWkJYrNiTbeL47KvKeW5EzplkyxzBRBw1ssSHlI/jXec0ukH2q7x2zAWQm7015iusg62Q==", "dev": true, "license": "MIT", "dependencies": { @@ -3956,8 +3585,6 @@ }, "node_modules/jest-validate/node_modules/camelcase": { "version": "6.3.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", - "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", "dev": true, "license": "MIT", "engines": { @@ -3969,8 +3596,6 @@ }, "node_modules/jest-watcher": { "version": "30.3.0", - "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-30.3.0.tgz", - "integrity": "sha512-PJ1d9ThtTR8aMiBWUdcownq9mDdLXsQzJayTk4kmaBRHKvwNQn+ANveuhEBUyNI2hR1TVhvQ8D5kHubbzBHR/w==", "dev": true, "license": "MIT", "dependencies": { @@ -3989,8 +3614,6 @@ }, "node_modules/jest-worker": { "version": "30.3.0", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-30.3.0.tgz", - "integrity": "sha512-DrCKkaQwHexjRUFTmPzs7sHQe0TSj9nvDALKGdwmK5mW9v7j90BudWirKAJHt3QQ9Dhrg1F7DogPzhChppkJpQ==", "dev": true, "license": "MIT", "dependencies": { @@ -4006,8 +3629,6 @@ }, "node_modules/jest-worker/node_modules/supports-color": { "version": "8.1.1", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", - "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", "dev": true, "license": "MIT", "dependencies": { @@ -4022,8 +3643,6 @@ }, "node_modules/js-yaml": { "version": "3.14.2", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.2.tgz", - "integrity": "sha512-PMSmkqxr106Xa156c2M265Z+FTrPl+oxd/rgOQy2tijQeK5TxQ43psO1ZCwhVOSdnn+RzkzlRz/eY4BgJBYVpg==", "dev": true, "license": "MIT", "dependencies": { @@ -4044,8 +3663,6 @@ }, "node_modules/jsesc": { "version": "3.1.0", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz", - "integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==", "dev": true, "license": "MIT", "bin": { @@ -4062,15 +3679,11 @@ }, "node_modules/json-parse-even-better-errors": { "version": "2.3.1", - "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", - "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", "dev": true, "license": "MIT" }, "node_modules/json-schema-traverse": { "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", "dev": true, "license": "MIT" }, @@ -4081,8 +3694,6 @@ }, "node_modules/json5": { "version": "2.2.3", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", - "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", "dev": true, "license": "MIT", "bin": { @@ -4094,8 +3705,7 @@ }, "node_modules/jsonwebtoken": { "version": "9.0.3", - "resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-9.0.3.tgz", - "integrity": "sha512-MT/xP0CrubFRNLNKvxJ2BYfy53Zkm++5bX9dtuPbqAeQpTVe0MQTFhao8+Cp//EmJp244xt6Drw/GVEGCUj40g==", + "license": "MIT", "dependencies": { "jws": "^4.0.1", "lodash.includes": "^4.3.0", @@ -4115,8 +3725,7 @@ }, "node_modules/jwa": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/jwa/-/jwa-2.0.1.tgz", - "integrity": "sha512-hRF04fqJIP8Abbkq5NKGN0Bbr3JxlQ+qhZufXVr0DvujKy93ZCbXZMHDL4EOtodSbCWxOqR8MS1tXA5hwqCXDg==", + "license": "MIT", "dependencies": { "buffer-equal-constant-time": "^1.0.1", "ecdsa-sig-formatter": "1.0.11", @@ -4125,8 +3734,7 @@ }, "node_modules/jws": { "version": "4.0.1", - "resolved": "https://registry.npmjs.org/jws/-/jws-4.0.1.tgz", - "integrity": "sha512-EKI/M/yqPncGUUh44xz0PxSidXFr/+r0pA70+gIYhjv+et7yxM+s29Y+VGDkovRofQem0fs7Uvf4+YmAdyRduA==", + "license": "MIT", "dependencies": { "jwa": "^2.0.1", "safe-buffer": "^5.0.1" @@ -4142,8 +3750,6 @@ }, "node_modules/leven": { "version": "3.1.0", - "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", - "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==", "dev": true, "license": "MIT", "engines": { @@ -4164,8 +3770,6 @@ }, "node_modules/lines-and-columns": { "version": "1.2.4", - "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", - "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", "dev": true, "license": "MIT" }, @@ -4185,45 +3789,36 @@ }, "node_modules/lodash.includes": { "version": "4.3.0", - "resolved": "https://registry.npmjs.org/lodash.includes/-/lodash.includes-4.3.0.tgz", - "integrity": "sha512-W3Bx6mdkRTGtlJISOvVD/lbqjTlPPUDTMnlXZFnVwi9NKJ6tiAk6LVdlhZMm17VZisqhKcgzpO5Wz91PCt5b0w==" + "license": "MIT" }, "node_modules/lodash.isboolean": { "version": "3.0.3", - "resolved": "https://registry.npmjs.org/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz", - "integrity": "sha512-Bz5mupy2SVbPHURB98VAcw+aHh4vRV5IPNhILUCsOzRmsTmSQ17jIuqopAentWoehktxGd9e/hbIXq980/1QJg==" + "license": "MIT" }, "node_modules/lodash.isinteger": { "version": "4.0.4", - "resolved": "https://registry.npmjs.org/lodash.isinteger/-/lodash.isinteger-4.0.4.tgz", - "integrity": "sha512-DBwtEWN2caHQ9/imiNeEA5ys1JoRtRfY3d7V9wkqtbycnAmTvRRmbHKDV4a0EYc678/dia0jrte4tjYwVBaZUA==" + "license": "MIT" }, "node_modules/lodash.isnumber": { "version": "3.0.3", - "resolved": "https://registry.npmjs.org/lodash.isnumber/-/lodash.isnumber-3.0.3.tgz", - "integrity": "sha512-QYqzpfwO3/CWf3XP+Z+tkQsfaLL/EnUlXWVkIk5FUPc4sBdTehEqZONuyRt2P67PXAk+NXmTBcc97zw9t1FQrw==" + "license": "MIT" }, "node_modules/lodash.isplainobject": { "version": "4.0.6", - "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz", - "integrity": "sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==" + "license": "MIT" }, "node_modules/lodash.isstring": { "version": "4.0.1", - "resolved": "https://registry.npmjs.org/lodash.isstring/-/lodash.isstring-4.0.1.tgz", - "integrity": "sha512-0wJxfxH1wgO3GrbuP+dTTk7op+6L41QCXbGINEmD+ny/G/eCqGzxyCsh7159S+mgDDcoarnBw6PC1PS5+wUGgw==" + "license": "MIT" }, "node_modules/lodash.merge": { "version": "4.6.2", - "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", - "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", "dev": true, "license": "MIT" }, "node_modules/lodash.once": { "version": "4.1.1", - "resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz", - "integrity": "sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg==" + "license": "MIT" }, "node_modules/lru-cache": { "version": "10.4.3", @@ -4246,8 +3841,6 @@ }, "node_modules/makeerror": { "version": "1.0.12", - "resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.12.tgz", - "integrity": "sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg==", "dev": true, "license": "BSD-3-Clause", "dependencies": { @@ -4280,8 +3873,6 @@ }, "node_modules/merge-stream": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", - "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", "dev": true, "license": "MIT" }, @@ -4327,8 +3918,6 @@ }, "node_modules/mimic-fn": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", - "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", "dev": true, "license": "MIT", "engines": { @@ -4337,8 +3926,6 @@ }, "node_modules/minimatch": { "version": "3.1.5", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz", - "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==", "dev": true, "license": "ISC", "dependencies": { @@ -4362,8 +3949,6 @@ }, "node_modules/napi-postinstall": { "version": "0.3.4", - "resolved": "https://registry.npmjs.org/napi-postinstall/-/napi-postinstall-0.3.4.tgz", - "integrity": "sha512-PHI5f1O0EP5xJ9gQmFGMS6IZcrVvTjpXjz7Na41gTE7eE2hK11lg04CECCYEEjdc17EV4DO+fkGEtt7TpTaTiQ==", "dev": true, "license": "MIT", "bin": { @@ -4390,22 +3975,16 @@ }, "node_modules/node-int64": { "version": "0.4.0", - "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", - "integrity": "sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==", "dev": true, "license": "MIT" }, "node_modules/node-releases": { "version": "2.0.36", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.36.tgz", - "integrity": "sha512-TdC8FSgHz8Mwtw9g5L4gR/Sh9XhSP/0DEkQxfEFXOpiul5IiHgHan2VhYYb6agDSfp4KuvltmGApc8HMgUrIkA==", "dev": true, "license": "MIT" }, "node_modules/normalize-path": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", "dev": true, "license": "MIT", "engines": { @@ -4414,8 +3993,6 @@ }, "node_modules/npm-run-path": { "version": "4.0.1", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", - "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", "dev": true, "license": "MIT", "dependencies": { @@ -4461,8 +4038,6 @@ }, "node_modules/onetime": { "version": "5.1.2", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", - "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", "dev": true, "license": "MIT", "dependencies": { @@ -4521,8 +4096,6 @@ }, "node_modules/p-try": { "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", "dev": true, "license": "MIT", "engines": { @@ -4536,8 +4109,6 @@ }, "node_modules/parent-module": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", - "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", "dev": true, "license": "MIT", "dependencies": { @@ -4557,8 +4128,6 @@ }, "node_modules/parse-json": { "version": "5.2.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", - "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", "dev": true, "license": "MIT", "dependencies": { @@ -4596,8 +4165,6 @@ }, "node_modules/path-is-absolute": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", "dev": true, "license": "MIT", "engines": { @@ -4653,8 +4220,6 @@ }, "node_modules/pirates": { "version": "4.0.7", - "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.7.tgz", - "integrity": "sha512-TfySrs/5nm8fQJDcBDuUng3VOUKsd7S+zqvbOTiGXHfxX4wK31ard+hoNuvkicM/2YFzlpDgABOevKSsB4G/FA==", "dev": true, "license": "MIT", "engines": { @@ -4663,8 +4228,6 @@ }, "node_modules/pkg-dir": { "version": "4.2.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", - "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", "dev": true, "license": "MIT", "dependencies": { @@ -4676,8 +4239,6 @@ }, "node_modules/pkg-dir/node_modules/find-up": { "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", "dev": true, "license": "MIT", "dependencies": { @@ -4690,8 +4251,6 @@ }, "node_modules/pkg-dir/node_modules/locate-path": { "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", "dev": true, "license": "MIT", "dependencies": { @@ -4703,8 +4262,6 @@ }, "node_modules/pkg-dir/node_modules/p-limit": { "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", "dev": true, "license": "MIT", "dependencies": { @@ -4719,8 +4276,6 @@ }, "node_modules/pkg-dir/node_modules/p-locate": { "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", "dev": true, "license": "MIT", "dependencies": { @@ -4740,8 +4295,6 @@ }, "node_modules/pretty-format": { "version": "30.3.0", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-30.3.0.tgz", - "integrity": "sha512-oG4T3wCbfeuvljnyAzhBvpN45E8iOTXCU/TD3zXW80HA3dQ4ahdqMkWGiPWZvjpQwlbyHrPTWUAqUzGzv4l1JQ==", "dev": true, "license": "MIT", "dependencies": { @@ -4755,8 +4308,6 @@ }, "node_modules/pretty-format/node_modules/ansi-styles": { "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", - "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", "dev": true, "license": "MIT", "engines": { @@ -4779,8 +4330,6 @@ }, "node_modules/punycode": { "version": "2.3.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", - "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", "dev": true, "license": "MIT", "engines": { @@ -4789,8 +4338,6 @@ }, "node_modules/pure-rand": { "version": "7.0.1", - "resolved": "https://registry.npmjs.org/pure-rand/-/pure-rand-7.0.1.tgz", - "integrity": "sha512-oTUZM/NAZS8p7ANR3SHh30kXB+zK2r2BPcEn/awJIbOvq82WoMN4p62AWWp3Hhw50G0xMsw1mhIBLqHw64EcNQ==", "dev": true, "funding": [ { @@ -4839,8 +4386,6 @@ }, "node_modules/react-is": { "version": "18.3.1", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", - "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==", "dev": true, "license": "MIT" }, @@ -4854,8 +4399,6 @@ }, "node_modules/require-directory": { "version": "2.1.1", - "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", "dev": true, "license": "MIT", "engines": { @@ -4864,8 +4407,6 @@ }, "node_modules/resolve-cwd": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz", - "integrity": "sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==", "dev": true, "license": "MIT", "dependencies": { @@ -4877,8 +4418,6 @@ }, "node_modules/resolve-from": { "version": "5.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", - "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", "dev": true, "license": "MIT", "engines": { @@ -4901,8 +4440,6 @@ }, "node_modules/safe-buffer": { "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", "funding": [ { "type": "github", @@ -4916,7 +4453,8 @@ "type": "consulting", "url": "https://feross.org/support" } - ] + ], + "license": "MIT" }, "node_modules/safe-regex": { "version": "2.1.1", @@ -5081,8 +4619,6 @@ }, "node_modules/slash": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", - "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", "dev": true, "license": "MIT", "engines": { @@ -5091,8 +4627,6 @@ }, "node_modules/source-map": { "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", "dev": true, "license": "BSD-3-Clause", "engines": { @@ -5101,8 +4635,6 @@ }, "node_modules/source-map-support": { "version": "0.5.13", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.13.tgz", - "integrity": "sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w==", "dev": true, "license": "MIT", "dependencies": { @@ -5131,15 +4663,11 @@ }, "node_modules/sprintf-js": { "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", "dev": true, "license": "BSD-3-Clause" }, "node_modules/stack-utils": { "version": "2.0.6", - "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.6.tgz", - "integrity": "sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ==", "dev": true, "license": "MIT", "dependencies": { @@ -5149,37 +4677,10 @@ "node": ">=10" } }, - "node_modules/stack-utils/node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, "node_modules/stack-utils/node_modules/escape-string-regexp": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", - "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", "dev": true, "license": "MIT", - "dependencies": { - "char-regex": "^1.0.2", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/stack-utils/node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "dependencies": { - "ansi-regex": "^5.0.1" - }, "engines": { "node": ">=8" } @@ -5193,8 +4694,6 @@ }, "node_modules/string-length": { "version": "4.0.2", - "resolved": "https://registry.npmjs.org/string-length/-/string-length-4.0.2.tgz", - "integrity": "sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ==", "dev": true, "license": "MIT", "dependencies": { @@ -5207,50 +4706,14 @@ }, "node_modules/string-length/node_modules/ansi-regex": { "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", "dev": true, "license": "MIT", - "dependencies": { - "eastasianwidth": "^0.2.0", - "emoji-regex": "^9.2.2", - "strip-ansi": "^7.0.1" - }, "engines": { "node": ">=8" } }, - "node_modules/string-length/node_modules/ansi-regex/node_modules/ansi-regex": { - "version": "6.2.2", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz", - "integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==", - "dev": true, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-regex?sponsor=1" - } - }, - "node_modules/string-length/node_modules/ansi-regex/node_modules/strip-ansi": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.2.0.tgz", - "integrity": "sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w==", - "dev": true, - "dependencies": { - "ansi-regex": "^6.2.2" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/strip-ansi?sponsor=1" - } - }, "node_modules/string-length/node_modules/strip-ansi": { "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", "dev": true, "license": "MIT", "dependencies": { @@ -5350,8 +4813,6 @@ }, "node_modules/strip-bom": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", - "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==", "dev": true, "license": "MIT", "engines": { @@ -5360,8 +4821,6 @@ }, "node_modules/strip-final-newline": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", - "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", "dev": true, "license": "MIT", "engines": { @@ -5370,15 +4829,8 @@ }, "node_modules/strip-json-comments": { "version": "3.1.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", - "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", "dev": true, "license": "MIT", - "dependencies": { - "cookie-signature": "^1.2.2", - "methods": "^1.1.2", - "superagent": "^10.3.0" - }, "engines": { "node": ">=8" }, @@ -5431,8 +4883,6 @@ }, "node_modules/synckit": { "version": "0.11.12", - "resolved": "https://registry.npmjs.org/synckit/-/synckit-0.11.12.tgz", - "integrity": "sha512-Bh7QjT8/SuKUIfObSXNHNSK6WHo6J1tHCqJsuaFDP7gP0fkzSfTxI8y85JrppZ0h8l0maIgc2tfuZQ6/t3GtnQ==", "dev": true, "license": "MIT", "dependencies": { @@ -5447,8 +4897,6 @@ }, "node_modules/tmpl": { "version": "1.0.5", - "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz", - "integrity": "sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==", "dev": true, "license": "BSD-3-Clause" }, @@ -5472,8 +4920,6 @@ }, "node_modules/type-detect": { "version": "4.0.8", - "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", - "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", "dev": true, "license": "MIT", "engines": { @@ -5482,8 +4928,6 @@ }, "node_modules/type-fest": { "version": "0.21.3", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", - "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", "dev": true, "license": "(MIT OR CC0-1.0)", "engines": { @@ -5507,8 +4951,6 @@ }, "node_modules/undici-types": { "version": "7.18.2", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.18.2.tgz", - "integrity": "sha512-AsuCzffGHJybSaRrmr5eHr81mwJU3kjw6M+uprWvCXiNeN9SOGwQ3Jn8jb8m3Z6izVgknn1R0FTCEAP2QrLY/w==", "dev": true, "license": "MIT" }, @@ -5521,8 +4963,6 @@ }, "node_modules/unrs-resolver": { "version": "1.11.1", - "resolved": "https://registry.npmjs.org/unrs-resolver/-/unrs-resolver-1.11.1.tgz", - "integrity": "sha512-bSjt9pjaEBnNiGgc9rUiHGKv5l4/TGzDmYw3RhnkJGtLhbnnA/5qJj7x3dNDCRx/PJxu774LlH8lCOlB4hEfKg==", "dev": true, "hasInstallScript": true, "license": "MIT", @@ -5556,8 +4996,6 @@ }, "node_modules/update-browserslist-db": { "version": "1.2.3", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.2.3.tgz", - "integrity": "sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w==", "dev": true, "funding": [ { @@ -5587,8 +5025,6 @@ }, "node_modules/uri-js": { "version": "4.4.1", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", - "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", "dev": true, "license": "BSD-2-Clause", "dependencies": { @@ -5597,8 +5033,6 @@ }, "node_modules/v8-to-istanbul": { "version": "9.3.0", - "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.3.0.tgz", - "integrity": "sha512-kiGUalWN+rgBJ/1OHZsBtU4rXZOfj/7rKQxULKlIzwzQSvMJUUNgPwJEEh7gU6xEVxC0ahoOBvN2YI8GH6FNgA==", "dev": true, "license": "ISC", "dependencies": { @@ -5619,8 +5053,6 @@ }, "node_modules/walker": { "version": "1.0.8", - "resolved": "https://registry.npmjs.org/walker/-/walker-1.0.8.tgz", - "integrity": "sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -5736,8 +5168,6 @@ }, "node_modules/write-file-atomic": { "version": "5.0.1", - "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-5.0.1.tgz", - "integrity": "sha512-+QU2zd6OTD8XWIJCbffaiQeH9U73qIqafo1x6V1snCWYGJf6cVE0cDR4D8xRzcEnfI21IFrUPzPGtcPf8AC+Rw==", "dev": true, "license": "ISC", "dependencies": { @@ -5750,8 +5180,6 @@ }, "node_modules/y18n": { "version": "5.0.8", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", - "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", "dev": true, "license": "ISC", "engines": { @@ -5760,15 +5188,11 @@ }, "node_modules/yallist": { "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", - "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", "dev": true, "license": "ISC" }, "node_modules/yargs": { "version": "17.7.2", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", - "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", "dev": true, "license": "MIT", "dependencies": { @@ -5786,8 +5210,6 @@ }, "node_modules/yargs-parser": { "version": "21.1.1", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", - "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", "dev": true, "license": "ISC", "engines": { @@ -5796,8 +5218,6 @@ }, "node_modules/yargs/node_modules/ansi-regex": { "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", "dev": true, "license": "MIT", "engines": { @@ -5806,15 +5226,11 @@ }, "node_modules/yargs/node_modules/emoji-regex": { "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", "dev": true, "license": "MIT" }, "node_modules/yargs/node_modules/string-width": { "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", "dev": true, "license": "MIT", "dependencies": { @@ -5828,8 +5244,6 @@ }, "node_modules/yargs/node_modules/strip-ansi": { "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", "dev": true, "license": "MIT", "dependencies": { @@ -5849,6 +5263,13 @@ "funding": { "url": "https://github.com/sponsors/sindresorhus" } + }, + "node_modules/zod": { + "version": "4.3.6", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/colinhacks" + } } } } diff --git a/node_modules/@babel/compat-data/node_modules/.bin/semver b/node_modules/@babel/compat-data/node_modules/.bin/semver deleted file mode 120000 index 5aaadf42..00000000 --- a/node_modules/@babel/compat-data/node_modules/.bin/semver +++ /dev/null @@ -1 +0,0 @@ -../semver/bin/semver.js \ No newline at end of file diff --git a/node_modules/@babel/compat-data/node_modules/.bin/semver~HEAD b/node_modules/@babel/compat-data/node_modules/.bin/semver~HEAD new file mode 100644 index 00000000..97c53279 --- /dev/null +++ b/node_modules/@babel/compat-data/node_modules/.bin/semver~HEAD @@ -0,0 +1,16 @@ +#!/bin/sh +basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')") + +case `uname` in + *CYGWIN*|*MINGW*|*MSYS*) + if command -v cygpath > /dev/null 2>&1; then + basedir=`cygpath -w "$basedir"` + fi + ;; +esac + +if [ -x "$basedir/node" ]; then + exec "$basedir/node" "$basedir/../semver/bin/semver.js" "$@" +else + exec node "$basedir/../semver/bin/semver.js" "$@" +fi diff --git a/node_modules/@babel/compat-data/node_modules/semver/LICENSE b/node_modules/@babel/compat-data/node_modules/semver/LICENSE deleted file mode 100644 index 19129e31..00000000 --- a/node_modules/@babel/compat-data/node_modules/semver/LICENSE +++ /dev/null @@ -1,15 +0,0 @@ -The ISC License - -Copyright (c) Isaac Z. Schlueter and Contributors - -Permission to use, copy, modify, and/or distribute this software for any -purpose with or without fee is hereby granted, provided that the above -copyright notice and this permission notice appear in all copies. - -THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR -IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. diff --git a/node_modules/@babel/compat-data/node_modules/semver/README.md b/node_modules/@babel/compat-data/node_modules/semver/README.md deleted file mode 100644 index 2293a14f..00000000 --- a/node_modules/@babel/compat-data/node_modules/semver/README.md +++ /dev/null @@ -1,443 +0,0 @@ -semver(1) -- The semantic versioner for npm -=========================================== - -## Install - -```bash -npm install semver -```` - -## Usage - -As a node module: - -```js -const semver = require('semver') - -semver.valid('1.2.3') // '1.2.3' -semver.valid('a.b.c') // null -semver.clean(' =v1.2.3 ') // '1.2.3' -semver.satisfies('1.2.3', '1.x || >=2.5.0 || 5.0.0 - 7.2.3') // true -semver.gt('1.2.3', '9.8.7') // false -semver.lt('1.2.3', '9.8.7') // true -semver.minVersion('>=1.0.0') // '1.0.0' -semver.valid(semver.coerce('v2')) // '2.0.0' -semver.valid(semver.coerce('42.6.7.9.3-alpha')) // '42.6.7' -``` - -As a command-line utility: - -``` -$ semver -h - -A JavaScript implementation of the https://semver.org/ specification -Copyright Isaac Z. Schlueter - -Usage: semver [options] [ [...]] -Prints valid versions sorted by SemVer precedence - -Options: --r --range - Print versions that match the specified range. - --i --increment [] - Increment a version by the specified level. Level can - be one of: major, minor, patch, premajor, preminor, - prepatch, or prerelease. Default level is 'patch'. - Only one version may be specified. - ---preid - Identifier to be used to prefix premajor, preminor, - prepatch or prerelease version increments. - --l --loose - Interpret versions and ranges loosely - --p --include-prerelease - Always include prerelease versions in range matching - --c --coerce - Coerce a string into SemVer if possible - (does not imply --loose) - ---rtl - Coerce version strings right to left - ---ltr - Coerce version strings left to right (default) - -Program exits successfully if any valid version satisfies -all supplied ranges, and prints all satisfying versions. - -If no satisfying versions are found, then exits failure. - -Versions are printed in ascending order, so supplying -multiple versions to the utility will just sort them. -``` - -## Versions - -A "version" is described by the `v2.0.0` specification found at -. - -A leading `"="` or `"v"` character is stripped off and ignored. - -## Ranges - -A `version range` is a set of `comparators` which specify versions -that satisfy the range. - -A `comparator` is composed of an `operator` and a `version`. The set -of primitive `operators` is: - -* `<` Less than -* `<=` Less than or equal to -* `>` Greater than -* `>=` Greater than or equal to -* `=` Equal. If no operator is specified, then equality is assumed, - so this operator is optional, but MAY be included. - -For example, the comparator `>=1.2.7` would match the versions -`1.2.7`, `1.2.8`, `2.5.3`, and `1.3.9`, but not the versions `1.2.6` -or `1.1.0`. - -Comparators can be joined by whitespace to form a `comparator set`, -which is satisfied by the **intersection** of all of the comparators -it includes. - -A range is composed of one or more comparator sets, joined by `||`. A -version matches a range if and only if every comparator in at least -one of the `||`-separated comparator sets is satisfied by the version. - -For example, the range `>=1.2.7 <1.3.0` would match the versions -`1.2.7`, `1.2.8`, and `1.2.99`, but not the versions `1.2.6`, `1.3.0`, -or `1.1.0`. - -The range `1.2.7 || >=1.2.9 <2.0.0` would match the versions `1.2.7`, -`1.2.9`, and `1.4.6`, but not the versions `1.2.8` or `2.0.0`. - -### Prerelease Tags - -If a version has a prerelease tag (for example, `1.2.3-alpha.3`) then -it will only be allowed to satisfy comparator sets if at least one -comparator with the same `[major, minor, patch]` tuple also has a -prerelease tag. - -For example, the range `>1.2.3-alpha.3` would be allowed to match the -version `1.2.3-alpha.7`, but it would *not* be satisfied by -`3.4.5-alpha.9`, even though `3.4.5-alpha.9` is technically "greater -than" `1.2.3-alpha.3` according to the SemVer sort rules. The version -range only accepts prerelease tags on the `1.2.3` version. The -version `3.4.5` *would* satisfy the range, because it does not have a -prerelease flag, and `3.4.5` is greater than `1.2.3-alpha.7`. - -The purpose for this behavior is twofold. First, prerelease versions -frequently are updated very quickly, and contain many breaking changes -that are (by the author's design) not yet fit for public consumption. -Therefore, by default, they are excluded from range matching -semantics. - -Second, a user who has opted into using a prerelease version has -clearly indicated the intent to use *that specific* set of -alpha/beta/rc versions. By including a prerelease tag in the range, -the user is indicating that they are aware of the risk. However, it -is still not appropriate to assume that they have opted into taking a -similar risk on the *next* set of prerelease versions. - -Note that this behavior can be suppressed (treating all prerelease -versions as if they were normal versions, for the purpose of range -matching) by setting the `includePrerelease` flag on the options -object to any -[functions](https://github.com/npm/node-semver#functions) that do -range matching. - -#### Prerelease Identifiers - -The method `.inc` takes an additional `identifier` string argument that -will append the value of the string as a prerelease identifier: - -```javascript -semver.inc('1.2.3', 'prerelease', 'beta') -// '1.2.4-beta.0' -``` - -command-line example: - -```bash -$ semver 1.2.3 -i prerelease --preid beta -1.2.4-beta.0 -``` - -Which then can be used to increment further: - -```bash -$ semver 1.2.4-beta.0 -i prerelease -1.2.4-beta.1 -``` - -### Advanced Range Syntax - -Advanced range syntax desugars to primitive comparators in -deterministic ways. - -Advanced ranges may be combined in the same way as primitive -comparators using white space or `||`. - -#### Hyphen Ranges `X.Y.Z - A.B.C` - -Specifies an inclusive set. - -* `1.2.3 - 2.3.4` := `>=1.2.3 <=2.3.4` - -If a partial version is provided as the first version in the inclusive -range, then the missing pieces are replaced with zeroes. - -* `1.2 - 2.3.4` := `>=1.2.0 <=2.3.4` - -If a partial version is provided as the second version in the -inclusive range, then all versions that start with the supplied parts -of the tuple are accepted, but nothing that would be greater than the -provided tuple parts. - -* `1.2.3 - 2.3` := `>=1.2.3 <2.4.0` -* `1.2.3 - 2` := `>=1.2.3 <3.0.0` - -#### X-Ranges `1.2.x` `1.X` `1.2.*` `*` - -Any of `X`, `x`, or `*` may be used to "stand in" for one of the -numeric values in the `[major, minor, patch]` tuple. - -* `*` := `>=0.0.0` (Any version satisfies) -* `1.x` := `>=1.0.0 <2.0.0` (Matching major version) -* `1.2.x` := `>=1.2.0 <1.3.0` (Matching major and minor versions) - -A partial version range is treated as an X-Range, so the special -character is in fact optional. - -* `""` (empty string) := `*` := `>=0.0.0` -* `1` := `1.x.x` := `>=1.0.0 <2.0.0` -* `1.2` := `1.2.x` := `>=1.2.0 <1.3.0` - -#### Tilde Ranges `~1.2.3` `~1.2` `~1` - -Allows patch-level changes if a minor version is specified on the -comparator. Allows minor-level changes if not. - -* `~1.2.3` := `>=1.2.3 <1.(2+1).0` := `>=1.2.3 <1.3.0` -* `~1.2` := `>=1.2.0 <1.(2+1).0` := `>=1.2.0 <1.3.0` (Same as `1.2.x`) -* `~1` := `>=1.0.0 <(1+1).0.0` := `>=1.0.0 <2.0.0` (Same as `1.x`) -* `~0.2.3` := `>=0.2.3 <0.(2+1).0` := `>=0.2.3 <0.3.0` -* `~0.2` := `>=0.2.0 <0.(2+1).0` := `>=0.2.0 <0.3.0` (Same as `0.2.x`) -* `~0` := `>=0.0.0 <(0+1).0.0` := `>=0.0.0 <1.0.0` (Same as `0.x`) -* `~1.2.3-beta.2` := `>=1.2.3-beta.2 <1.3.0` Note that prereleases in - the `1.2.3` version will be allowed, if they are greater than or - equal to `beta.2`. So, `1.2.3-beta.4` would be allowed, but - `1.2.4-beta.2` would not, because it is a prerelease of a - different `[major, minor, patch]` tuple. - -#### Caret Ranges `^1.2.3` `^0.2.5` `^0.0.4` - -Allows changes that do not modify the left-most non-zero element in the -`[major, minor, patch]` tuple. In other words, this allows patch and -minor updates for versions `1.0.0` and above, patch updates for -versions `0.X >=0.1.0`, and *no* updates for versions `0.0.X`. - -Many authors treat a `0.x` version as if the `x` were the major -"breaking-change" indicator. - -Caret ranges are ideal when an author may make breaking changes -between `0.2.4` and `0.3.0` releases, which is a common practice. -However, it presumes that there will *not* be breaking changes between -`0.2.4` and `0.2.5`. It allows for changes that are presumed to be -additive (but non-breaking), according to commonly observed practices. - -* `^1.2.3` := `>=1.2.3 <2.0.0` -* `^0.2.3` := `>=0.2.3 <0.3.0` -* `^0.0.3` := `>=0.0.3 <0.0.4` -* `^1.2.3-beta.2` := `>=1.2.3-beta.2 <2.0.0` Note that prereleases in - the `1.2.3` version will be allowed, if they are greater than or - equal to `beta.2`. So, `1.2.3-beta.4` would be allowed, but - `1.2.4-beta.2` would not, because it is a prerelease of a - different `[major, minor, patch]` tuple. -* `^0.0.3-beta` := `>=0.0.3-beta <0.0.4` Note that prereleases in the - `0.0.3` version *only* will be allowed, if they are greater than or - equal to `beta`. So, `0.0.3-pr.2` would be allowed. - -When parsing caret ranges, a missing `patch` value desugars to the -number `0`, but will allow flexibility within that value, even if the -major and minor versions are both `0`. - -* `^1.2.x` := `>=1.2.0 <2.0.0` -* `^0.0.x` := `>=0.0.0 <0.1.0` -* `^0.0` := `>=0.0.0 <0.1.0` - -A missing `minor` and `patch` values will desugar to zero, but also -allow flexibility within those values, even if the major version is -zero. - -* `^1.x` := `>=1.0.0 <2.0.0` -* `^0.x` := `>=0.0.0 <1.0.0` - -### Range Grammar - -Putting all this together, here is a Backus-Naur grammar for ranges, -for the benefit of parser authors: - -```bnf -range-set ::= range ( logical-or range ) * -logical-or ::= ( ' ' ) * '||' ( ' ' ) * -range ::= hyphen | simple ( ' ' simple ) * | '' -hyphen ::= partial ' - ' partial -simple ::= primitive | partial | tilde | caret -primitive ::= ( '<' | '>' | '>=' | '<=' | '=' ) partial -partial ::= xr ( '.' xr ( '.' xr qualifier ? )? )? -xr ::= 'x' | 'X' | '*' | nr -nr ::= '0' | ['1'-'9'] ( ['0'-'9'] ) * -tilde ::= '~' partial -caret ::= '^' partial -qualifier ::= ( '-' pre )? ( '+' build )? -pre ::= parts -build ::= parts -parts ::= part ( '.' part ) * -part ::= nr | [-0-9A-Za-z]+ -``` - -## Functions - -All methods and classes take a final `options` object argument. All -options in this object are `false` by default. The options supported -are: - -- `loose` Be more forgiving about not-quite-valid semver strings. - (Any resulting output will always be 100% strict compliant, of - course.) For backwards compatibility reasons, if the `options` - argument is a boolean value instead of an object, it is interpreted - to be the `loose` param. -- `includePrerelease` Set to suppress the [default - behavior](https://github.com/npm/node-semver#prerelease-tags) of - excluding prerelease tagged versions from ranges unless they are - explicitly opted into. - -Strict-mode Comparators and Ranges will be strict about the SemVer -strings that they parse. - -* `valid(v)`: Return the parsed version, or null if it's not valid. -* `inc(v, release)`: Return the version incremented by the release - type (`major`, `premajor`, `minor`, `preminor`, `patch`, - `prepatch`, or `prerelease`), or null if it's not valid - * `premajor` in one call will bump the version up to the next major - version and down to a prerelease of that major version. - `preminor`, and `prepatch` work the same way. - * If called from a non-prerelease version, the `prerelease` will work the - same as `prepatch`. It increments the patch version, then makes a - prerelease. If the input version is already a prerelease it simply - increments it. -* `prerelease(v)`: Returns an array of prerelease components, or null - if none exist. Example: `prerelease('1.2.3-alpha.1') -> ['alpha', 1]` -* `major(v)`: Return the major version number. -* `minor(v)`: Return the minor version number. -* `patch(v)`: Return the patch version number. -* `intersects(r1, r2, loose)`: Return true if the two supplied ranges - or comparators intersect. -* `parse(v)`: Attempt to parse a string as a semantic version, returning either - a `SemVer` object or `null`. - -### Comparison - -* `gt(v1, v2)`: `v1 > v2` -* `gte(v1, v2)`: `v1 >= v2` -* `lt(v1, v2)`: `v1 < v2` -* `lte(v1, v2)`: `v1 <= v2` -* `eq(v1, v2)`: `v1 == v2` This is true if they're logically equivalent, - even if they're not the exact same string. You already know how to - compare strings. -* `neq(v1, v2)`: `v1 != v2` The opposite of `eq`. -* `cmp(v1, comparator, v2)`: Pass in a comparison string, and it'll call - the corresponding function above. `"==="` and `"!=="` do simple - string comparison, but are included for completeness. Throws if an - invalid comparison string is provided. -* `compare(v1, v2)`: Return `0` if `v1 == v2`, or `1` if `v1` is greater, or `-1` if - `v2` is greater. Sorts in ascending order if passed to `Array.sort()`. -* `rcompare(v1, v2)`: The reverse of compare. Sorts an array of versions - in descending order when passed to `Array.sort()`. -* `compareBuild(v1, v2)`: The same as `compare` but considers `build` when two versions - are equal. Sorts in ascending order if passed to `Array.sort()`. - `v2` is greater. Sorts in ascending order if passed to `Array.sort()`. -* `diff(v1, v2)`: Returns difference between two versions by the release type - (`major`, `premajor`, `minor`, `preminor`, `patch`, `prepatch`, or `prerelease`), - or null if the versions are the same. - -### Comparators - -* `intersects(comparator)`: Return true if the comparators intersect - -### Ranges - -* `validRange(range)`: Return the valid range or null if it's not valid -* `satisfies(version, range)`: Return true if the version satisfies the - range. -* `maxSatisfying(versions, range)`: Return the highest version in the list - that satisfies the range, or `null` if none of them do. -* `minSatisfying(versions, range)`: Return the lowest version in the list - that satisfies the range, or `null` if none of them do. -* `minVersion(range)`: Return the lowest version that can possibly match - the given range. -* `gtr(version, range)`: Return `true` if version is greater than all the - versions possible in the range. -* `ltr(version, range)`: Return `true` if version is less than all the - versions possible in the range. -* `outside(version, range, hilo)`: Return true if the version is outside - the bounds of the range in either the high or low direction. The - `hilo` argument must be either the string `'>'` or `'<'`. (This is - the function called by `gtr` and `ltr`.) -* `intersects(range)`: Return true if any of the ranges comparators intersect - -Note that, since ranges may be non-contiguous, a version might not be -greater than a range, less than a range, *or* satisfy a range! For -example, the range `1.2 <1.2.9 || >2.0.0` would have a hole from `1.2.9` -until `2.0.0`, so the version `1.2.10` would not be greater than the -range (because `2.0.1` satisfies, which is higher), nor less than the -range (since `1.2.8` satisfies, which is lower), and it also does not -satisfy the range. - -If you want to know if a version satisfies or does not satisfy a -range, use the `satisfies(version, range)` function. - -### Coercion - -* `coerce(version, options)`: Coerces a string to semver if possible - -This aims to provide a very forgiving translation of a non-semver string to -semver. It looks for the first digit in a string, and consumes all -remaining characters which satisfy at least a partial semver (e.g., `1`, -`1.2`, `1.2.3`) up to the max permitted length (256 characters). Longer -versions are simply truncated (`4.6.3.9.2-alpha2` becomes `4.6.3`). All -surrounding text is simply ignored (`v3.4 replaces v3.3.1` becomes -`3.4.0`). Only text which lacks digits will fail coercion (`version one` -is not valid). The maximum length for any semver component considered for -coercion is 16 characters; longer components will be ignored -(`10000000000000000.4.7.4` becomes `4.7.4`). The maximum value for any -semver component is `Integer.MAX_SAFE_INTEGER || (2**53 - 1)`; higher value -components are invalid (`9999999999999999.4.7.4` is likely invalid). - -If the `options.rtl` flag is set, then `coerce` will return the right-most -coercible tuple that does not share an ending index with a longer coercible -tuple. For example, `1.2.3.4` will return `2.3.4` in rtl mode, not -`4.0.0`. `1.2.3/4` will return `4.0.0`, because the `4` is not a part of -any other overlapping SemVer tuple. - -### Clean - -* `clean(version)`: Clean a string to be a valid semver if possible - -This will return a cleaned and trimmed semver version. If the provided version is not valid a null will be returned. This does not work for ranges. - -ex. -* `s.clean(' = v 2.1.5foo')`: `null` -* `s.clean(' = v 2.1.5foo', { loose: true })`: `'2.1.5-foo'` -* `s.clean(' = v 2.1.5-foo')`: `null` -* `s.clean(' = v 2.1.5-foo', { loose: true })`: `'2.1.5-foo'` -* `s.clean('=v2.1.5')`: `'2.1.5'` -* `s.clean(' =v2.1.5')`: `2.1.5` -* `s.clean(' 2.1.5 ')`: `'2.1.5'` -* `s.clean('~1.0.0')`: `null` diff --git a/node_modules/@babel/compat-data/node_modules/semver/bin/semver.js b/node_modules/@babel/compat-data/node_modules/semver/bin/semver.js deleted file mode 100755 index 666034a7..00000000 --- a/node_modules/@babel/compat-data/node_modules/semver/bin/semver.js +++ /dev/null @@ -1,174 +0,0 @@ -#!/usr/bin/env node -// Standalone semver comparison program. -// Exits successfully and prints matching version(s) if -// any supplied version is valid and passes all tests. - -var argv = process.argv.slice(2) - -var versions = [] - -var range = [] - -var inc = null - -var version = require('../package.json').version - -var loose = false - -var includePrerelease = false - -var coerce = false - -var rtl = false - -var identifier - -var semver = require('../semver') - -var reverse = false - -var options = {} - -main() - -function main () { - if (!argv.length) return help() - while (argv.length) { - var a = argv.shift() - var indexOfEqualSign = a.indexOf('=') - if (indexOfEqualSign !== -1) { - a = a.slice(0, indexOfEqualSign) - argv.unshift(a.slice(indexOfEqualSign + 1)) - } - switch (a) { - case '-rv': case '-rev': case '--rev': case '--reverse': - reverse = true - break - case '-l': case '--loose': - loose = true - break - case '-p': case '--include-prerelease': - includePrerelease = true - break - case '-v': case '--version': - versions.push(argv.shift()) - break - case '-i': case '--inc': case '--increment': - switch (argv[0]) { - case 'major': case 'minor': case 'patch': case 'prerelease': - case 'premajor': case 'preminor': case 'prepatch': - inc = argv.shift() - break - default: - inc = 'patch' - break - } - break - case '--preid': - identifier = argv.shift() - break - case '-r': case '--range': - range.push(argv.shift()) - break - case '-c': case '--coerce': - coerce = true - break - case '--rtl': - rtl = true - break - case '--ltr': - rtl = false - break - case '-h': case '--help': case '-?': - return help() - default: - versions.push(a) - break - } - } - - var options = { loose: loose, includePrerelease: includePrerelease, rtl: rtl } - - versions = versions.map(function (v) { - return coerce ? (semver.coerce(v, options) || { version: v }).version : v - }).filter(function (v) { - return semver.valid(v) - }) - if (!versions.length) return fail() - if (inc && (versions.length !== 1 || range.length)) { return failInc() } - - for (var i = 0, l = range.length; i < l; i++) { - versions = versions.filter(function (v) { - return semver.satisfies(v, range[i], options) - }) - if (!versions.length) return fail() - } - return success(versions) -} - -function failInc () { - console.error('--inc can only be used on a single version with no range') - fail() -} - -function fail () { process.exit(1) } - -function success () { - var compare = reverse ? 'rcompare' : 'compare' - versions.sort(function (a, b) { - return semver[compare](a, b, options) - }).map(function (v) { - return semver.clean(v, options) - }).map(function (v) { - return inc ? semver.inc(v, inc, options, identifier) : v - }).forEach(function (v, i, _) { console.log(v) }) -} - -function help () { - console.log(['SemVer ' + version, - '', - 'A JavaScript implementation of the https://semver.org/ specification', - 'Copyright Isaac Z. Schlueter', - '', - 'Usage: semver [options] [ [...]]', - 'Prints valid versions sorted by SemVer precedence', - '', - 'Options:', - '-r --range ', - ' Print versions that match the specified range.', - '', - '-i --increment []', - ' Increment a version by the specified level. Level can', - ' be one of: major, minor, patch, premajor, preminor,', - " prepatch, or prerelease. Default level is 'patch'.", - ' Only one version may be specified.', - '', - '--preid ', - ' Identifier to be used to prefix premajor, preminor,', - ' prepatch or prerelease version increments.', - '', - '-l --loose', - ' Interpret versions and ranges loosely', - '', - '-p --include-prerelease', - ' Always include prerelease versions in range matching', - '', - '-c --coerce', - ' Coerce a string into SemVer if possible', - ' (does not imply --loose)', - '', - '--rtl', - ' Coerce version strings right to left', - '', - '--ltr', - ' Coerce version strings left to right (default)', - '', - 'Program exits successfully if any valid version satisfies', - 'all supplied ranges, and prints all satisfying versions.', - '', - 'If no satisfying versions are found, then exits failure.', - '', - 'Versions are printed in ascending order, so supplying', - 'multiple versions to the utility will just sort them.' - ].join('\n')) -} diff --git a/node_modules/@babel/compat-data/node_modules/semver/package.json b/node_modules/@babel/compat-data/node_modules/semver/package.json deleted file mode 100644 index 6b970a62..00000000 --- a/node_modules/@babel/compat-data/node_modules/semver/package.json +++ /dev/null @@ -1,38 +0,0 @@ -{ - "name": "semver", - "version": "6.3.1", - "description": "The semantic version parser used by npm.", - "main": "semver.js", - "scripts": { - "test": "tap test/ --100 --timeout=30", - "lint": "echo linting disabled", - "postlint": "template-oss-check", - "template-oss-apply": "template-oss-apply --force", - "lintfix": "npm run lint -- --fix", - "snap": "tap test/ --100 --timeout=30", - "posttest": "npm run lint" - }, - "devDependencies": { - "@npmcli/template-oss": "4.17.0", - "tap": "^12.7.0" - }, - "license": "ISC", - "repository": { - "type": "git", - "url": "https://github.com/npm/node-semver.git" - }, - "bin": { - "semver": "./bin/semver.js" - }, - "files": [ - "bin", - "range.bnf", - "semver.js" - ], - "author": "GitHub Inc.", - "templateOSS": { - "//@npmcli/template-oss": "This file is partially managed by @npmcli/template-oss. Edits may be overwritten.", - "content": "./scripts/template-oss", - "version": "4.17.0" - } -} diff --git a/node_modules/@babel/compat-data/node_modules/semver/range.bnf b/node_modules/@babel/compat-data/node_modules/semver/range.bnf deleted file mode 100644 index d4c6ae0d..00000000 --- a/node_modules/@babel/compat-data/node_modules/semver/range.bnf +++ /dev/null @@ -1,16 +0,0 @@ -range-set ::= range ( logical-or range ) * -logical-or ::= ( ' ' ) * '||' ( ' ' ) * -range ::= hyphen | simple ( ' ' simple ) * | '' -hyphen ::= partial ' - ' partial -simple ::= primitive | partial | tilde | caret -primitive ::= ( '<' | '>' | '>=' | '<=' | '=' ) partial -partial ::= xr ( '.' xr ( '.' xr qualifier ? )? )? -xr ::= 'x' | 'X' | '*' | nr -nr ::= '0' | [1-9] ( [0-9] ) * -tilde ::= '~' partial -caret ::= '^' partial -qualifier ::= ( '-' pre )? ( '+' build )? -pre ::= parts -build ::= parts -parts ::= part ( '.' part ) * -part ::= nr | [-0-9A-Za-z]+ diff --git a/node_modules/@babel/compat-data/node_modules/semver/semver.js b/node_modules/@babel/compat-data/node_modules/semver/semver.js deleted file mode 100644 index 39319c13..00000000 --- a/node_modules/@babel/compat-data/node_modules/semver/semver.js +++ /dev/null @@ -1,1643 +0,0 @@ -exports = module.exports = SemVer - -var debug -/* istanbul ignore next */ -if (typeof process === 'object' && - process.env && - process.env.NODE_DEBUG && - /\bsemver\b/i.test(process.env.NODE_DEBUG)) { - debug = function () { - var args = Array.prototype.slice.call(arguments, 0) - args.unshift('SEMVER') - console.log.apply(console, args) - } -} else { - debug = function () {} -} - -// Note: this is the semver.org version of the spec that it implements -// Not necessarily the package version of this code. -exports.SEMVER_SPEC_VERSION = '2.0.0' - -var MAX_LENGTH = 256 -var MAX_SAFE_INTEGER = Number.MAX_SAFE_INTEGER || - /* istanbul ignore next */ 9007199254740991 - -// Max safe segment length for coercion. -var MAX_SAFE_COMPONENT_LENGTH = 16 - -var MAX_SAFE_BUILD_LENGTH = MAX_LENGTH - 6 - -// The actual regexps go on exports.re -var re = exports.re = [] -var safeRe = exports.safeRe = [] -var src = exports.src = [] -var t = exports.tokens = {} -var R = 0 - -function tok (n) { - t[n] = R++ -} - -var LETTERDASHNUMBER = '[a-zA-Z0-9-]' - -// Replace some greedy regex tokens to prevent regex dos issues. These regex are -// used internally via the safeRe object since all inputs in this library get -// normalized first to trim and collapse all extra whitespace. The original -// regexes are exported for userland consumption and lower level usage. A -// future breaking change could export the safer regex only with a note that -// all input should have extra whitespace removed. -var safeRegexReplacements = [ - ['\\s', 1], - ['\\d', MAX_LENGTH], - [LETTERDASHNUMBER, MAX_SAFE_BUILD_LENGTH], -] - -function makeSafeRe (value) { - for (var i = 0; i < safeRegexReplacements.length; i++) { - var token = safeRegexReplacements[i][0] - var max = safeRegexReplacements[i][1] - value = value - .split(token + '*').join(token + '{0,' + max + '}') - .split(token + '+').join(token + '{1,' + max + '}') - } - return value -} - -// The following Regular Expressions can be used for tokenizing, -// validating, and parsing SemVer version strings. - -// ## Numeric Identifier -// A single `0`, or a non-zero digit followed by zero or more digits. - -tok('NUMERICIDENTIFIER') -src[t.NUMERICIDENTIFIER] = '0|[1-9]\\d*' -tok('NUMERICIDENTIFIERLOOSE') -src[t.NUMERICIDENTIFIERLOOSE] = '\\d+' - -// ## Non-numeric Identifier -// Zero or more digits, followed by a letter or hyphen, and then zero or -// more letters, digits, or hyphens. - -tok('NONNUMERICIDENTIFIER') -src[t.NONNUMERICIDENTIFIER] = '\\d*[a-zA-Z-]' + LETTERDASHNUMBER + '*' - -// ## Main Version -// Three dot-separated numeric identifiers. - -tok('MAINVERSION') -src[t.MAINVERSION] = '(' + src[t.NUMERICIDENTIFIER] + ')\\.' + - '(' + src[t.NUMERICIDENTIFIER] + ')\\.' + - '(' + src[t.NUMERICIDENTIFIER] + ')' - -tok('MAINVERSIONLOOSE') -src[t.MAINVERSIONLOOSE] = '(' + src[t.NUMERICIDENTIFIERLOOSE] + ')\\.' + - '(' + src[t.NUMERICIDENTIFIERLOOSE] + ')\\.' + - '(' + src[t.NUMERICIDENTIFIERLOOSE] + ')' - -// ## Pre-release Version Identifier -// A numeric identifier, or a non-numeric identifier. - -tok('PRERELEASEIDENTIFIER') -src[t.PRERELEASEIDENTIFIER] = '(?:' + src[t.NUMERICIDENTIFIER] + - '|' + src[t.NONNUMERICIDENTIFIER] + ')' - -tok('PRERELEASEIDENTIFIERLOOSE') -src[t.PRERELEASEIDENTIFIERLOOSE] = '(?:' + src[t.NUMERICIDENTIFIERLOOSE] + - '|' + src[t.NONNUMERICIDENTIFIER] + ')' - -// ## Pre-release Version -// Hyphen, followed by one or more dot-separated pre-release version -// identifiers. - -tok('PRERELEASE') -src[t.PRERELEASE] = '(?:-(' + src[t.PRERELEASEIDENTIFIER] + - '(?:\\.' + src[t.PRERELEASEIDENTIFIER] + ')*))' - -tok('PRERELEASELOOSE') -src[t.PRERELEASELOOSE] = '(?:-?(' + src[t.PRERELEASEIDENTIFIERLOOSE] + - '(?:\\.' + src[t.PRERELEASEIDENTIFIERLOOSE] + ')*))' - -// ## Build Metadata Identifier -// Any combination of digits, letters, or hyphens. - -tok('BUILDIDENTIFIER') -src[t.BUILDIDENTIFIER] = LETTERDASHNUMBER + '+' - -// ## Build Metadata -// Plus sign, followed by one or more period-separated build metadata -// identifiers. - -tok('BUILD') -src[t.BUILD] = '(?:\\+(' + src[t.BUILDIDENTIFIER] + - '(?:\\.' + src[t.BUILDIDENTIFIER] + ')*))' - -// ## Full Version String -// A main version, followed optionally by a pre-release version and -// build metadata. - -// Note that the only major, minor, patch, and pre-release sections of -// the version string are capturing groups. The build metadata is not a -// capturing group, because it should not ever be used in version -// comparison. - -tok('FULL') -tok('FULLPLAIN') -src[t.FULLPLAIN] = 'v?' + src[t.MAINVERSION] + - src[t.PRERELEASE] + '?' + - src[t.BUILD] + '?' - -src[t.FULL] = '^' + src[t.FULLPLAIN] + '$' - -// like full, but allows v1.2.3 and =1.2.3, which people do sometimes. -// also, 1.0.0alpha1 (prerelease without the hyphen) which is pretty -// common in the npm registry. -tok('LOOSEPLAIN') -src[t.LOOSEPLAIN] = '[v=\\s]*' + src[t.MAINVERSIONLOOSE] + - src[t.PRERELEASELOOSE] + '?' + - src[t.BUILD] + '?' - -tok('LOOSE') -src[t.LOOSE] = '^' + src[t.LOOSEPLAIN] + '$' - -tok('GTLT') -src[t.GTLT] = '((?:<|>)?=?)' - -// Something like "2.*" or "1.2.x". -// Note that "x.x" is a valid xRange identifer, meaning "any version" -// Only the first item is strictly required. -tok('XRANGEIDENTIFIERLOOSE') -src[t.XRANGEIDENTIFIERLOOSE] = src[t.NUMERICIDENTIFIERLOOSE] + '|x|X|\\*' -tok('XRANGEIDENTIFIER') -src[t.XRANGEIDENTIFIER] = src[t.NUMERICIDENTIFIER] + '|x|X|\\*' - -tok('XRANGEPLAIN') -src[t.XRANGEPLAIN] = '[v=\\s]*(' + src[t.XRANGEIDENTIFIER] + ')' + - '(?:\\.(' + src[t.XRANGEIDENTIFIER] + ')' + - '(?:\\.(' + src[t.XRANGEIDENTIFIER] + ')' + - '(?:' + src[t.PRERELEASE] + ')?' + - src[t.BUILD] + '?' + - ')?)?' - -tok('XRANGEPLAINLOOSE') -src[t.XRANGEPLAINLOOSE] = '[v=\\s]*(' + src[t.XRANGEIDENTIFIERLOOSE] + ')' + - '(?:\\.(' + src[t.XRANGEIDENTIFIERLOOSE] + ')' + - '(?:\\.(' + src[t.XRANGEIDENTIFIERLOOSE] + ')' + - '(?:' + src[t.PRERELEASELOOSE] + ')?' + - src[t.BUILD] + '?' + - ')?)?' - -tok('XRANGE') -src[t.XRANGE] = '^' + src[t.GTLT] + '\\s*' + src[t.XRANGEPLAIN] + '$' -tok('XRANGELOOSE') -src[t.XRANGELOOSE] = '^' + src[t.GTLT] + '\\s*' + src[t.XRANGEPLAINLOOSE] + '$' - -// Coercion. -// Extract anything that could conceivably be a part of a valid semver -tok('COERCE') -src[t.COERCE] = '(^|[^\\d])' + - '(\\d{1,' + MAX_SAFE_COMPONENT_LENGTH + '})' + - '(?:\\.(\\d{1,' + MAX_SAFE_COMPONENT_LENGTH + '}))?' + - '(?:\\.(\\d{1,' + MAX_SAFE_COMPONENT_LENGTH + '}))?' + - '(?:$|[^\\d])' -tok('COERCERTL') -re[t.COERCERTL] = new RegExp(src[t.COERCE], 'g') -safeRe[t.COERCERTL] = new RegExp(makeSafeRe(src[t.COERCE]), 'g') - -// Tilde ranges. -// Meaning is "reasonably at or greater than" -tok('LONETILDE') -src[t.LONETILDE] = '(?:~>?)' - -tok('TILDETRIM') -src[t.TILDETRIM] = '(\\s*)' + src[t.LONETILDE] + '\\s+' -re[t.TILDETRIM] = new RegExp(src[t.TILDETRIM], 'g') -safeRe[t.TILDETRIM] = new RegExp(makeSafeRe(src[t.TILDETRIM]), 'g') -var tildeTrimReplace = '$1~' - -tok('TILDE') -src[t.TILDE] = '^' + src[t.LONETILDE] + src[t.XRANGEPLAIN] + '$' -tok('TILDELOOSE') -src[t.TILDELOOSE] = '^' + src[t.LONETILDE] + src[t.XRANGEPLAINLOOSE] + '$' - -// Caret ranges. -// Meaning is "at least and backwards compatible with" -tok('LONECARET') -src[t.LONECARET] = '(?:\\^)' - -tok('CARETTRIM') -src[t.CARETTRIM] = '(\\s*)' + src[t.LONECARET] + '\\s+' -re[t.CARETTRIM] = new RegExp(src[t.CARETTRIM], 'g') -safeRe[t.CARETTRIM] = new RegExp(makeSafeRe(src[t.CARETTRIM]), 'g') -var caretTrimReplace = '$1^' - -tok('CARET') -src[t.CARET] = '^' + src[t.LONECARET] + src[t.XRANGEPLAIN] + '$' -tok('CARETLOOSE') -src[t.CARETLOOSE] = '^' + src[t.LONECARET] + src[t.XRANGEPLAINLOOSE] + '$' - -// A simple gt/lt/eq thing, or just "" to indicate "any version" -tok('COMPARATORLOOSE') -src[t.COMPARATORLOOSE] = '^' + src[t.GTLT] + '\\s*(' + src[t.LOOSEPLAIN] + ')$|^$' -tok('COMPARATOR') -src[t.COMPARATOR] = '^' + src[t.GTLT] + '\\s*(' + src[t.FULLPLAIN] + ')$|^$' - -// An expression to strip any whitespace between the gtlt and the thing -// it modifies, so that `> 1.2.3` ==> `>1.2.3` -tok('COMPARATORTRIM') -src[t.COMPARATORTRIM] = '(\\s*)' + src[t.GTLT] + - '\\s*(' + src[t.LOOSEPLAIN] + '|' + src[t.XRANGEPLAIN] + ')' - -// this one has to use the /g flag -re[t.COMPARATORTRIM] = new RegExp(src[t.COMPARATORTRIM], 'g') -safeRe[t.COMPARATORTRIM] = new RegExp(makeSafeRe(src[t.COMPARATORTRIM]), 'g') -var comparatorTrimReplace = '$1$2$3' - -// Something like `1.2.3 - 1.2.4` -// Note that these all use the loose form, because they'll be -// checked against either the strict or loose comparator form -// later. -tok('HYPHENRANGE') -src[t.HYPHENRANGE] = '^\\s*(' + src[t.XRANGEPLAIN] + ')' + - '\\s+-\\s+' + - '(' + src[t.XRANGEPLAIN] + ')' + - '\\s*$' - -tok('HYPHENRANGELOOSE') -src[t.HYPHENRANGELOOSE] = '^\\s*(' + src[t.XRANGEPLAINLOOSE] + ')' + - '\\s+-\\s+' + - '(' + src[t.XRANGEPLAINLOOSE] + ')' + - '\\s*$' - -// Star ranges basically just allow anything at all. -tok('STAR') -src[t.STAR] = '(<|>)?=?\\s*\\*' - -// Compile to actual regexp objects. -// All are flag-free, unless they were created above with a flag. -for (var i = 0; i < R; i++) { - debug(i, src[i]) - if (!re[i]) { - re[i] = new RegExp(src[i]) - - // Replace all greedy whitespace to prevent regex dos issues. These regex are - // used internally via the safeRe object since all inputs in this library get - // normalized first to trim and collapse all extra whitespace. The original - // regexes are exported for userland consumption and lower level usage. A - // future breaking change could export the safer regex only with a note that - // all input should have extra whitespace removed. - safeRe[i] = new RegExp(makeSafeRe(src[i])) - } -} - -exports.parse = parse -function parse (version, options) { - if (!options || typeof options !== 'object') { - options = { - loose: !!options, - includePrerelease: false - } - } - - if (version instanceof SemVer) { - return version - } - - if (typeof version !== 'string') { - return null - } - - if (version.length > MAX_LENGTH) { - return null - } - - var r = options.loose ? safeRe[t.LOOSE] : safeRe[t.FULL] - if (!r.test(version)) { - return null - } - - try { - return new SemVer(version, options) - } catch (er) { - return null - } -} - -exports.valid = valid -function valid (version, options) { - var v = parse(version, options) - return v ? v.version : null -} - -exports.clean = clean -function clean (version, options) { - var s = parse(version.trim().replace(/^[=v]+/, ''), options) - return s ? s.version : null -} - -exports.SemVer = SemVer - -function SemVer (version, options) { - if (!options || typeof options !== 'object') { - options = { - loose: !!options, - includePrerelease: false - } - } - if (version instanceof SemVer) { - if (version.loose === options.loose) { - return version - } else { - version = version.version - } - } else if (typeof version !== 'string') { - throw new TypeError('Invalid Version: ' + version) - } - - if (version.length > MAX_LENGTH) { - throw new TypeError('version is longer than ' + MAX_LENGTH + ' characters') - } - - if (!(this instanceof SemVer)) { - return new SemVer(version, options) - } - - debug('SemVer', version, options) - this.options = options - this.loose = !!options.loose - - var m = version.trim().match(options.loose ? safeRe[t.LOOSE] : safeRe[t.FULL]) - - if (!m) { - throw new TypeError('Invalid Version: ' + version) - } - - this.raw = version - - // these are actually numbers - this.major = +m[1] - this.minor = +m[2] - this.patch = +m[3] - - if (this.major > MAX_SAFE_INTEGER || this.major < 0) { - throw new TypeError('Invalid major version') - } - - if (this.minor > MAX_SAFE_INTEGER || this.minor < 0) { - throw new TypeError('Invalid minor version') - } - - if (this.patch > MAX_SAFE_INTEGER || this.patch < 0) { - throw new TypeError('Invalid patch version') - } - - // numberify any prerelease numeric ids - if (!m[4]) { - this.prerelease = [] - } else { - this.prerelease = m[4].split('.').map(function (id) { - if (/^[0-9]+$/.test(id)) { - var num = +id - if (num >= 0 && num < MAX_SAFE_INTEGER) { - return num - } - } - return id - }) - } - - this.build = m[5] ? m[5].split('.') : [] - this.format() -} - -SemVer.prototype.format = function () { - this.version = this.major + '.' + this.minor + '.' + this.patch - if (this.prerelease.length) { - this.version += '-' + this.prerelease.join('.') - } - return this.version -} - -SemVer.prototype.toString = function () { - return this.version -} - -SemVer.prototype.compare = function (other) { - debug('SemVer.compare', this.version, this.options, other) - if (!(other instanceof SemVer)) { - other = new SemVer(other, this.options) - } - - return this.compareMain(other) || this.comparePre(other) -} - -SemVer.prototype.compareMain = function (other) { - if (!(other instanceof SemVer)) { - other = new SemVer(other, this.options) - } - - return compareIdentifiers(this.major, other.major) || - compareIdentifiers(this.minor, other.minor) || - compareIdentifiers(this.patch, other.patch) -} - -SemVer.prototype.comparePre = function (other) { - if (!(other instanceof SemVer)) { - other = new SemVer(other, this.options) - } - - // NOT having a prerelease is > having one - if (this.prerelease.length && !other.prerelease.length) { - return -1 - } else if (!this.prerelease.length && other.prerelease.length) { - return 1 - } else if (!this.prerelease.length && !other.prerelease.length) { - return 0 - } - - var i = 0 - do { - var a = this.prerelease[i] - var b = other.prerelease[i] - debug('prerelease compare', i, a, b) - if (a === undefined && b === undefined) { - return 0 - } else if (b === undefined) { - return 1 - } else if (a === undefined) { - return -1 - } else if (a === b) { - continue - } else { - return compareIdentifiers(a, b) - } - } while (++i) -} - -SemVer.prototype.compareBuild = function (other) { - if (!(other instanceof SemVer)) { - other = new SemVer(other, this.options) - } - - var i = 0 - do { - var a = this.build[i] - var b = other.build[i] - debug('prerelease compare', i, a, b) - if (a === undefined && b === undefined) { - return 0 - } else if (b === undefined) { - return 1 - } else if (a === undefined) { - return -1 - } else if (a === b) { - continue - } else { - return compareIdentifiers(a, b) - } - } while (++i) -} - -// preminor will bump the version up to the next minor release, and immediately -// down to pre-release. premajor and prepatch work the same way. -SemVer.prototype.inc = function (release, identifier) { - switch (release) { - case 'premajor': - this.prerelease.length = 0 - this.patch = 0 - this.minor = 0 - this.major++ - this.inc('pre', identifier) - break - case 'preminor': - this.prerelease.length = 0 - this.patch = 0 - this.minor++ - this.inc('pre', identifier) - break - case 'prepatch': - // If this is already a prerelease, it will bump to the next version - // drop any prereleases that might already exist, since they are not - // relevant at this point. - this.prerelease.length = 0 - this.inc('patch', identifier) - this.inc('pre', identifier) - break - // If the input is a non-prerelease version, this acts the same as - // prepatch. - case 'prerelease': - if (this.prerelease.length === 0) { - this.inc('patch', identifier) - } - this.inc('pre', identifier) - break - - case 'major': - // If this is a pre-major version, bump up to the same major version. - // Otherwise increment major. - // 1.0.0-5 bumps to 1.0.0 - // 1.1.0 bumps to 2.0.0 - if (this.minor !== 0 || - this.patch !== 0 || - this.prerelease.length === 0) { - this.major++ - } - this.minor = 0 - this.patch = 0 - this.prerelease = [] - break - case 'minor': - // If this is a pre-minor version, bump up to the same minor version. - // Otherwise increment minor. - // 1.2.0-5 bumps to 1.2.0 - // 1.2.1 bumps to 1.3.0 - if (this.patch !== 0 || this.prerelease.length === 0) { - this.minor++ - } - this.patch = 0 - this.prerelease = [] - break - case 'patch': - // If this is not a pre-release version, it will increment the patch. - // If it is a pre-release it will bump up to the same patch version. - // 1.2.0-5 patches to 1.2.0 - // 1.2.0 patches to 1.2.1 - if (this.prerelease.length === 0) { - this.patch++ - } - this.prerelease = [] - break - // This probably shouldn't be used publicly. - // 1.0.0 "pre" would become 1.0.0-0 which is the wrong direction. - case 'pre': - if (this.prerelease.length === 0) { - this.prerelease = [0] - } else { - var i = this.prerelease.length - while (--i >= 0) { - if (typeof this.prerelease[i] === 'number') { - this.prerelease[i]++ - i = -2 - } - } - if (i === -1) { - // didn't increment anything - this.prerelease.push(0) - } - } - if (identifier) { - // 1.2.0-beta.1 bumps to 1.2.0-beta.2, - // 1.2.0-beta.fooblz or 1.2.0-beta bumps to 1.2.0-beta.0 - if (this.prerelease[0] === identifier) { - if (isNaN(this.prerelease[1])) { - this.prerelease = [identifier, 0] - } - } else { - this.prerelease = [identifier, 0] - } - } - break - - default: - throw new Error('invalid increment argument: ' + release) - } - this.format() - this.raw = this.version - return this -} - -exports.inc = inc -function inc (version, release, loose, identifier) { - if (typeof (loose) === 'string') { - identifier = loose - loose = undefined - } - - try { - return new SemVer(version, loose).inc(release, identifier).version - } catch (er) { - return null - } -} - -exports.diff = diff -function diff (version1, version2) { - if (eq(version1, version2)) { - return null - } else { - var v1 = parse(version1) - var v2 = parse(version2) - var prefix = '' - if (v1.prerelease.length || v2.prerelease.length) { - prefix = 'pre' - var defaultResult = 'prerelease' - } - for (var key in v1) { - if (key === 'major' || key === 'minor' || key === 'patch') { - if (v1[key] !== v2[key]) { - return prefix + key - } - } - } - return defaultResult // may be undefined - } -} - -exports.compareIdentifiers = compareIdentifiers - -var numeric = /^[0-9]+$/ -function compareIdentifiers (a, b) { - var anum = numeric.test(a) - var bnum = numeric.test(b) - - if (anum && bnum) { - a = +a - b = +b - } - - return a === b ? 0 - : (anum && !bnum) ? -1 - : (bnum && !anum) ? 1 - : a < b ? -1 - : 1 -} - -exports.rcompareIdentifiers = rcompareIdentifiers -function rcompareIdentifiers (a, b) { - return compareIdentifiers(b, a) -} - -exports.major = major -function major (a, loose) { - return new SemVer(a, loose).major -} - -exports.minor = minor -function minor (a, loose) { - return new SemVer(a, loose).minor -} - -exports.patch = patch -function patch (a, loose) { - return new SemVer(a, loose).patch -} - -exports.compare = compare -function compare (a, b, loose) { - return new SemVer(a, loose).compare(new SemVer(b, loose)) -} - -exports.compareLoose = compareLoose -function compareLoose (a, b) { - return compare(a, b, true) -} - -exports.compareBuild = compareBuild -function compareBuild (a, b, loose) { - var versionA = new SemVer(a, loose) - var versionB = new SemVer(b, loose) - return versionA.compare(versionB) || versionA.compareBuild(versionB) -} - -exports.rcompare = rcompare -function rcompare (a, b, loose) { - return compare(b, a, loose) -} - -exports.sort = sort -function sort (list, loose) { - return list.sort(function (a, b) { - return exports.compareBuild(a, b, loose) - }) -} - -exports.rsort = rsort -function rsort (list, loose) { - return list.sort(function (a, b) { - return exports.compareBuild(b, a, loose) - }) -} - -exports.gt = gt -function gt (a, b, loose) { - return compare(a, b, loose) > 0 -} - -exports.lt = lt -function lt (a, b, loose) { - return compare(a, b, loose) < 0 -} - -exports.eq = eq -function eq (a, b, loose) { - return compare(a, b, loose) === 0 -} - -exports.neq = neq -function neq (a, b, loose) { - return compare(a, b, loose) !== 0 -} - -exports.gte = gte -function gte (a, b, loose) { - return compare(a, b, loose) >= 0 -} - -exports.lte = lte -function lte (a, b, loose) { - return compare(a, b, loose) <= 0 -} - -exports.cmp = cmp -function cmp (a, op, b, loose) { - switch (op) { - case '===': - if (typeof a === 'object') - a = a.version - if (typeof b === 'object') - b = b.version - return a === b - - case '!==': - if (typeof a === 'object') - a = a.version - if (typeof b === 'object') - b = b.version - return a !== b - - case '': - case '=': - case '==': - return eq(a, b, loose) - - case '!=': - return neq(a, b, loose) - - case '>': - return gt(a, b, loose) - - case '>=': - return gte(a, b, loose) - - case '<': - return lt(a, b, loose) - - case '<=': - return lte(a, b, loose) - - default: - throw new TypeError('Invalid operator: ' + op) - } -} - -exports.Comparator = Comparator -function Comparator (comp, options) { - if (!options || typeof options !== 'object') { - options = { - loose: !!options, - includePrerelease: false - } - } - - if (comp instanceof Comparator) { - if (comp.loose === !!options.loose) { - return comp - } else { - comp = comp.value - } - } - - if (!(this instanceof Comparator)) { - return new Comparator(comp, options) - } - - comp = comp.trim().split(/\s+/).join(' ') - debug('comparator', comp, options) - this.options = options - this.loose = !!options.loose - this.parse(comp) - - if (this.semver === ANY) { - this.value = '' - } else { - this.value = this.operator + this.semver.version - } - - debug('comp', this) -} - -var ANY = {} -Comparator.prototype.parse = function (comp) { - var r = this.options.loose ? safeRe[t.COMPARATORLOOSE] : safeRe[t.COMPARATOR] - var m = comp.match(r) - - if (!m) { - throw new TypeError('Invalid comparator: ' + comp) - } - - this.operator = m[1] !== undefined ? m[1] : '' - if (this.operator === '=') { - this.operator = '' - } - - // if it literally is just '>' or '' then allow anything. - if (!m[2]) { - this.semver = ANY - } else { - this.semver = new SemVer(m[2], this.options.loose) - } -} - -Comparator.prototype.toString = function () { - return this.value -} - -Comparator.prototype.test = function (version) { - debug('Comparator.test', version, this.options.loose) - - if (this.semver === ANY || version === ANY) { - return true - } - - if (typeof version === 'string') { - try { - version = new SemVer(version, this.options) - } catch (er) { - return false - } - } - - return cmp(version, this.operator, this.semver, this.options) -} - -Comparator.prototype.intersects = function (comp, options) { - if (!(comp instanceof Comparator)) { - throw new TypeError('a Comparator is required') - } - - if (!options || typeof options !== 'object') { - options = { - loose: !!options, - includePrerelease: false - } - } - - var rangeTmp - - if (this.operator === '') { - if (this.value === '') { - return true - } - rangeTmp = new Range(comp.value, options) - return satisfies(this.value, rangeTmp, options) - } else if (comp.operator === '') { - if (comp.value === '') { - return true - } - rangeTmp = new Range(this.value, options) - return satisfies(comp.semver, rangeTmp, options) - } - - var sameDirectionIncreasing = - (this.operator === '>=' || this.operator === '>') && - (comp.operator === '>=' || comp.operator === '>') - var sameDirectionDecreasing = - (this.operator === '<=' || this.operator === '<') && - (comp.operator === '<=' || comp.operator === '<') - var sameSemVer = this.semver.version === comp.semver.version - var differentDirectionsInclusive = - (this.operator === '>=' || this.operator === '<=') && - (comp.operator === '>=' || comp.operator === '<=') - var oppositeDirectionsLessThan = - cmp(this.semver, '<', comp.semver, options) && - ((this.operator === '>=' || this.operator === '>') && - (comp.operator === '<=' || comp.operator === '<')) - var oppositeDirectionsGreaterThan = - cmp(this.semver, '>', comp.semver, options) && - ((this.operator === '<=' || this.operator === '<') && - (comp.operator === '>=' || comp.operator === '>')) - - return sameDirectionIncreasing || sameDirectionDecreasing || - (sameSemVer && differentDirectionsInclusive) || - oppositeDirectionsLessThan || oppositeDirectionsGreaterThan -} - -exports.Range = Range -function Range (range, options) { - if (!options || typeof options !== 'object') { - options = { - loose: !!options, - includePrerelease: false - } - } - - if (range instanceof Range) { - if (range.loose === !!options.loose && - range.includePrerelease === !!options.includePrerelease) { - return range - } else { - return new Range(range.raw, options) - } - } - - if (range instanceof Comparator) { - return new Range(range.value, options) - } - - if (!(this instanceof Range)) { - return new Range(range, options) - } - - this.options = options - this.loose = !!options.loose - this.includePrerelease = !!options.includePrerelease - - // First reduce all whitespace as much as possible so we do not have to rely - // on potentially slow regexes like \s*. This is then stored and used for - // future error messages as well. - this.raw = range - .trim() - .split(/\s+/) - .join(' ') - - // First, split based on boolean or || - this.set = this.raw.split('||').map(function (range) { - return this.parseRange(range.trim()) - }, this).filter(function (c) { - // throw out any that are not relevant for whatever reason - return c.length - }) - - if (!this.set.length) { - throw new TypeError('Invalid SemVer Range: ' + this.raw) - } - - this.format() -} - -Range.prototype.format = function () { - this.range = this.set.map(function (comps) { - return comps.join(' ').trim() - }).join('||').trim() - return this.range -} - -Range.prototype.toString = function () { - return this.range -} - -Range.prototype.parseRange = function (range) { - var loose = this.options.loose - // `1.2.3 - 1.2.4` => `>=1.2.3 <=1.2.4` - var hr = loose ? safeRe[t.HYPHENRANGELOOSE] : safeRe[t.HYPHENRANGE] - range = range.replace(hr, hyphenReplace) - debug('hyphen replace', range) - // `> 1.2.3 < 1.2.5` => `>1.2.3 <1.2.5` - range = range.replace(safeRe[t.COMPARATORTRIM], comparatorTrimReplace) - debug('comparator trim', range, safeRe[t.COMPARATORTRIM]) - - // `~ 1.2.3` => `~1.2.3` - range = range.replace(safeRe[t.TILDETRIM], tildeTrimReplace) - - // `^ 1.2.3` => `^1.2.3` - range = range.replace(safeRe[t.CARETTRIM], caretTrimReplace) - - // normalize spaces - range = range.split(/\s+/).join(' ') - - // At this point, the range is completely trimmed and - // ready to be split into comparators. - - var compRe = loose ? safeRe[t.COMPARATORLOOSE] : safeRe[t.COMPARATOR] - var set = range.split(' ').map(function (comp) { - return parseComparator(comp, this.options) - }, this).join(' ').split(/\s+/) - if (this.options.loose) { - // in loose mode, throw out any that are not valid comparators - set = set.filter(function (comp) { - return !!comp.match(compRe) - }) - } - set = set.map(function (comp) { - return new Comparator(comp, this.options) - }, this) - - return set -} - -Range.prototype.intersects = function (range, options) { - if (!(range instanceof Range)) { - throw new TypeError('a Range is required') - } - - return this.set.some(function (thisComparators) { - return ( - isSatisfiable(thisComparators, options) && - range.set.some(function (rangeComparators) { - return ( - isSatisfiable(rangeComparators, options) && - thisComparators.every(function (thisComparator) { - return rangeComparators.every(function (rangeComparator) { - return thisComparator.intersects(rangeComparator, options) - }) - }) - ) - }) - ) - }) -} - -// take a set of comparators and determine whether there -// exists a version which can satisfy it -function isSatisfiable (comparators, options) { - var result = true - var remainingComparators = comparators.slice() - var testComparator = remainingComparators.pop() - - while (result && remainingComparators.length) { - result = remainingComparators.every(function (otherComparator) { - return testComparator.intersects(otherComparator, options) - }) - - testComparator = remainingComparators.pop() - } - - return result -} - -// Mostly just for testing and legacy API reasons -exports.toComparators = toComparators -function toComparators (range, options) { - return new Range(range, options).set.map(function (comp) { - return comp.map(function (c) { - return c.value - }).join(' ').trim().split(' ') - }) -} - -// comprised of xranges, tildes, stars, and gtlt's at this point. -// already replaced the hyphen ranges -// turn into a set of JUST comparators. -function parseComparator (comp, options) { - debug('comp', comp, options) - comp = replaceCarets(comp, options) - debug('caret', comp) - comp = replaceTildes(comp, options) - debug('tildes', comp) - comp = replaceXRanges(comp, options) - debug('xrange', comp) - comp = replaceStars(comp, options) - debug('stars', comp) - return comp -} - -function isX (id) { - return !id || id.toLowerCase() === 'x' || id === '*' -} - -// ~, ~> --> * (any, kinda silly) -// ~2, ~2.x, ~2.x.x, ~>2, ~>2.x ~>2.x.x --> >=2.0.0 <3.0.0 -// ~2.0, ~2.0.x, ~>2.0, ~>2.0.x --> >=2.0.0 <2.1.0 -// ~1.2, ~1.2.x, ~>1.2, ~>1.2.x --> >=1.2.0 <1.3.0 -// ~1.2.3, ~>1.2.3 --> >=1.2.3 <1.3.0 -// ~1.2.0, ~>1.2.0 --> >=1.2.0 <1.3.0 -function replaceTildes (comp, options) { - return comp.trim().split(/\s+/).map(function (comp) { - return replaceTilde(comp, options) - }).join(' ') -} - -function replaceTilde (comp, options) { - var r = options.loose ? safeRe[t.TILDELOOSE] : safeRe[t.TILDE] - return comp.replace(r, function (_, M, m, p, pr) { - debug('tilde', comp, _, M, m, p, pr) - var ret - - if (isX(M)) { - ret = '' - } else if (isX(m)) { - ret = '>=' + M + '.0.0 <' + (+M + 1) + '.0.0' - } else if (isX(p)) { - // ~1.2 == >=1.2.0 <1.3.0 - ret = '>=' + M + '.' + m + '.0 <' + M + '.' + (+m + 1) + '.0' - } else if (pr) { - debug('replaceTilde pr', pr) - ret = '>=' + M + '.' + m + '.' + p + '-' + pr + - ' <' + M + '.' + (+m + 1) + '.0' - } else { - // ~1.2.3 == >=1.2.3 <1.3.0 - ret = '>=' + M + '.' + m + '.' + p + - ' <' + M + '.' + (+m + 1) + '.0' - } - - debug('tilde return', ret) - return ret - }) -} - -// ^ --> * (any, kinda silly) -// ^2, ^2.x, ^2.x.x --> >=2.0.0 <3.0.0 -// ^2.0, ^2.0.x --> >=2.0.0 <3.0.0 -// ^1.2, ^1.2.x --> >=1.2.0 <2.0.0 -// ^1.2.3 --> >=1.2.3 <2.0.0 -// ^1.2.0 --> >=1.2.0 <2.0.0 -function replaceCarets (comp, options) { - return comp.trim().split(/\s+/).map(function (comp) { - return replaceCaret(comp, options) - }).join(' ') -} - -function replaceCaret (comp, options) { - debug('caret', comp, options) - var r = options.loose ? safeRe[t.CARETLOOSE] : safeRe[t.CARET] - return comp.replace(r, function (_, M, m, p, pr) { - debug('caret', comp, _, M, m, p, pr) - var ret - - if (isX(M)) { - ret = '' - } else if (isX(m)) { - ret = '>=' + M + '.0.0 <' + (+M + 1) + '.0.0' - } else if (isX(p)) { - if (M === '0') { - ret = '>=' + M + '.' + m + '.0 <' + M + '.' + (+m + 1) + '.0' - } else { - ret = '>=' + M + '.' + m + '.0 <' + (+M + 1) + '.0.0' - } - } else if (pr) { - debug('replaceCaret pr', pr) - if (M === '0') { - if (m === '0') { - ret = '>=' + M + '.' + m + '.' + p + '-' + pr + - ' <' + M + '.' + m + '.' + (+p + 1) - } else { - ret = '>=' + M + '.' + m + '.' + p + '-' + pr + - ' <' + M + '.' + (+m + 1) + '.0' - } - } else { - ret = '>=' + M + '.' + m + '.' + p + '-' + pr + - ' <' + (+M + 1) + '.0.0' - } - } else { - debug('no pr') - if (M === '0') { - if (m === '0') { - ret = '>=' + M + '.' + m + '.' + p + - ' <' + M + '.' + m + '.' + (+p + 1) - } else { - ret = '>=' + M + '.' + m + '.' + p + - ' <' + M + '.' + (+m + 1) + '.0' - } - } else { - ret = '>=' + M + '.' + m + '.' + p + - ' <' + (+M + 1) + '.0.0' - } - } - - debug('caret return', ret) - return ret - }) -} - -function replaceXRanges (comp, options) { - debug('replaceXRanges', comp, options) - return comp.split(/\s+/).map(function (comp) { - return replaceXRange(comp, options) - }).join(' ') -} - -function replaceXRange (comp, options) { - comp = comp.trim() - var r = options.loose ? safeRe[t.XRANGELOOSE] : safeRe[t.XRANGE] - return comp.replace(r, function (ret, gtlt, M, m, p, pr) { - debug('xRange', comp, ret, gtlt, M, m, p, pr) - var xM = isX(M) - var xm = xM || isX(m) - var xp = xm || isX(p) - var anyX = xp - - if (gtlt === '=' && anyX) { - gtlt = '' - } - - // if we're including prereleases in the match, then we need - // to fix this to -0, the lowest possible prerelease value - pr = options.includePrerelease ? '-0' : '' - - if (xM) { - if (gtlt === '>' || gtlt === '<') { - // nothing is allowed - ret = '<0.0.0-0' - } else { - // nothing is forbidden - ret = '*' - } - } else if (gtlt && anyX) { - // we know patch is an x, because we have any x at all. - // replace X with 0 - if (xm) { - m = 0 - } - p = 0 - - if (gtlt === '>') { - // >1 => >=2.0.0 - // >1.2 => >=1.3.0 - // >1.2.3 => >= 1.2.4 - gtlt = '>=' - if (xm) { - M = +M + 1 - m = 0 - p = 0 - } else { - m = +m + 1 - p = 0 - } - } else if (gtlt === '<=') { - // <=0.7.x is actually <0.8.0, since any 0.7.x should - // pass. Similarly, <=7.x is actually <8.0.0, etc. - gtlt = '<' - if (xm) { - M = +M + 1 - } else { - m = +m + 1 - } - } - - ret = gtlt + M + '.' + m + '.' + p + pr - } else if (xm) { - ret = '>=' + M + '.0.0' + pr + ' <' + (+M + 1) + '.0.0' + pr - } else if (xp) { - ret = '>=' + M + '.' + m + '.0' + pr + - ' <' + M + '.' + (+m + 1) + '.0' + pr - } - - debug('xRange return', ret) - - return ret - }) -} - -// Because * is AND-ed with everything else in the comparator, -// and '' means "any version", just remove the *s entirely. -function replaceStars (comp, options) { - debug('replaceStars', comp, options) - // Looseness is ignored here. star is always as loose as it gets! - return comp.trim().replace(safeRe[t.STAR], '') -} - -// This function is passed to string.replace(re[t.HYPHENRANGE]) -// M, m, patch, prerelease, build -// 1.2 - 3.4.5 => >=1.2.0 <=3.4.5 -// 1.2.3 - 3.4 => >=1.2.0 <3.5.0 Any 3.4.x will do -// 1.2 - 3.4 => >=1.2.0 <3.5.0 -function hyphenReplace ($0, - from, fM, fm, fp, fpr, fb, - to, tM, tm, tp, tpr, tb) { - if (isX(fM)) { - from = '' - } else if (isX(fm)) { - from = '>=' + fM + '.0.0' - } else if (isX(fp)) { - from = '>=' + fM + '.' + fm + '.0' - } else { - from = '>=' + from - } - - if (isX(tM)) { - to = '' - } else if (isX(tm)) { - to = '<' + (+tM + 1) + '.0.0' - } else if (isX(tp)) { - to = '<' + tM + '.' + (+tm + 1) + '.0' - } else if (tpr) { - to = '<=' + tM + '.' + tm + '.' + tp + '-' + tpr - } else { - to = '<=' + to - } - - return (from + ' ' + to).trim() -} - -// if ANY of the sets match ALL of its comparators, then pass -Range.prototype.test = function (version) { - if (!version) { - return false - } - - if (typeof version === 'string') { - try { - version = new SemVer(version, this.options) - } catch (er) { - return false - } - } - - for (var i = 0; i < this.set.length; i++) { - if (testSet(this.set[i], version, this.options)) { - return true - } - } - return false -} - -function testSet (set, version, options) { - for (var i = 0; i < set.length; i++) { - if (!set[i].test(version)) { - return false - } - } - - if (version.prerelease.length && !options.includePrerelease) { - // Find the set of versions that are allowed to have prereleases - // For example, ^1.2.3-pr.1 desugars to >=1.2.3-pr.1 <2.0.0 - // That should allow `1.2.3-pr.2` to pass. - // However, `1.2.4-alpha.notready` should NOT be allowed, - // even though it's within the range set by the comparators. - for (i = 0; i < set.length; i++) { - debug(set[i].semver) - if (set[i].semver === ANY) { - continue - } - - if (set[i].semver.prerelease.length > 0) { - var allowed = set[i].semver - if (allowed.major === version.major && - allowed.minor === version.minor && - allowed.patch === version.patch) { - return true - } - } - } - - // Version has a -pre, but it's not one of the ones we like. - return false - } - - return true -} - -exports.satisfies = satisfies -function satisfies (version, range, options) { - try { - range = new Range(range, options) - } catch (er) { - return false - } - return range.test(version) -} - -exports.maxSatisfying = maxSatisfying -function maxSatisfying (versions, range, options) { - var max = null - var maxSV = null - try { - var rangeObj = new Range(range, options) - } catch (er) { - return null - } - versions.forEach(function (v) { - if (rangeObj.test(v)) { - // satisfies(v, range, options) - if (!max || maxSV.compare(v) === -1) { - // compare(max, v, true) - max = v - maxSV = new SemVer(max, options) - } - } - }) - return max -} - -exports.minSatisfying = minSatisfying -function minSatisfying (versions, range, options) { - var min = null - var minSV = null - try { - var rangeObj = new Range(range, options) - } catch (er) { - return null - } - versions.forEach(function (v) { - if (rangeObj.test(v)) { - // satisfies(v, range, options) - if (!min || minSV.compare(v) === 1) { - // compare(min, v, true) - min = v - minSV = new SemVer(min, options) - } - } - }) - return min -} - -exports.minVersion = minVersion -function minVersion (range, loose) { - range = new Range(range, loose) - - var minver = new SemVer('0.0.0') - if (range.test(minver)) { - return minver - } - - minver = new SemVer('0.0.0-0') - if (range.test(minver)) { - return minver - } - - minver = null - for (var i = 0; i < range.set.length; ++i) { - var comparators = range.set[i] - - comparators.forEach(function (comparator) { - // Clone to avoid manipulating the comparator's semver object. - var compver = new SemVer(comparator.semver.version) - switch (comparator.operator) { - case '>': - if (compver.prerelease.length === 0) { - compver.patch++ - } else { - compver.prerelease.push(0) - } - compver.raw = compver.format() - /* fallthrough */ - case '': - case '>=': - if (!minver || gt(minver, compver)) { - minver = compver - } - break - case '<': - case '<=': - /* Ignore maximum versions */ - break - /* istanbul ignore next */ - default: - throw new Error('Unexpected operation: ' + comparator.operator) - } - }) - } - - if (minver && range.test(minver)) { - return minver - } - - return null -} - -exports.validRange = validRange -function validRange (range, options) { - try { - // Return '*' instead of '' so that truthiness works. - // This will throw if it's invalid anyway - return new Range(range, options).range || '*' - } catch (er) { - return null - } -} - -// Determine if version is less than all the versions possible in the range -exports.ltr = ltr -function ltr (version, range, options) { - return outside(version, range, '<', options) -} - -// Determine if version is greater than all the versions possible in the range. -exports.gtr = gtr -function gtr (version, range, options) { - return outside(version, range, '>', options) -} - -exports.outside = outside -function outside (version, range, hilo, options) { - version = new SemVer(version, options) - range = new Range(range, options) - - var gtfn, ltefn, ltfn, comp, ecomp - switch (hilo) { - case '>': - gtfn = gt - ltefn = lte - ltfn = lt - comp = '>' - ecomp = '>=' - break - case '<': - gtfn = lt - ltefn = gte - ltfn = gt - comp = '<' - ecomp = '<=' - break - default: - throw new TypeError('Must provide a hilo val of "<" or ">"') - } - - // If it satisifes the range it is not outside - if (satisfies(version, range, options)) { - return false - } - - // From now on, variable terms are as if we're in "gtr" mode. - // but note that everything is flipped for the "ltr" function. - - for (var i = 0; i < range.set.length; ++i) { - var comparators = range.set[i] - - var high = null - var low = null - - comparators.forEach(function (comparator) { - if (comparator.semver === ANY) { - comparator = new Comparator('>=0.0.0') - } - high = high || comparator - low = low || comparator - if (gtfn(comparator.semver, high.semver, options)) { - high = comparator - } else if (ltfn(comparator.semver, low.semver, options)) { - low = comparator - } - }) - - // If the edge version comparator has a operator then our version - // isn't outside it - if (high.operator === comp || high.operator === ecomp) { - return false - } - - // If the lowest version comparator has an operator and our version - // is less than it then it isn't higher than the range - if ((!low.operator || low.operator === comp) && - ltefn(version, low.semver)) { - return false - } else if (low.operator === ecomp && ltfn(version, low.semver)) { - return false - } - } - return true -} - -exports.prerelease = prerelease -function prerelease (version, options) { - var parsed = parse(version, options) - return (parsed && parsed.prerelease.length) ? parsed.prerelease : null -} - -exports.intersects = intersects -function intersects (r1, r2, options) { - r1 = new Range(r1, options) - r2 = new Range(r2, options) - return r1.intersects(r2) -} - -exports.coerce = coerce -function coerce (version, options) { - if (version instanceof SemVer) { - return version - } - - if (typeof version === 'number') { - version = String(version) - } - - if (typeof version !== 'string') { - return null - } - - options = options || {} - - var match = null - if (!options.rtl) { - match = version.match(safeRe[t.COERCE]) - } else { - // Find the right-most coercible string that does not share - // a terminus with a more left-ward coercible string. - // Eg, '1.2.3.4' wants to coerce '2.3.4', not '3.4' or '4' - // - // Walk through the string checking with a /g regexp - // Manually set the index so as to pick up overlapping matches. - // Stop when we get a match that ends at the string end, since no - // coercible string can be more right-ward without the same terminus. - var next - while ((next = safeRe[t.COERCERTL].exec(version)) && - (!match || match.index + match[0].length !== version.length) - ) { - if (!match || - next.index + next[0].length !== match.index + match[0].length) { - match = next - } - safeRe[t.COERCERTL].lastIndex = next.index + next[1].length + next[2].length - } - // leave it in a clean state - safeRe[t.COERCERTL].lastIndex = -1 - } - - if (match === null) { - return null - } - - return parse(match[2] + - '.' + (match[3] || '0') + - '.' + (match[4] || '0'), options) -} diff --git a/node_modules/@babel/core/node_modules/.bin/semver.cmd b/node_modules/@babel/core/node_modules/.bin/semver.cmd new file mode 100644 index 00000000..7d4c104a --- /dev/null +++ b/node_modules/@babel/core/node_modules/.bin/semver.cmd @@ -0,0 +1,17 @@ +@ECHO off +GOTO start +:find_dp0 +SET dp0=%~dp0 +EXIT /b +:start +SETLOCAL +CALL :find_dp0 + +IF EXIST "%dp0%\node.exe" ( + SET "_prog=%dp0%\node.exe" +) ELSE ( + SET "_prog=node" + SET PATHEXT=%PATHEXT:;.JS;=;% +) + +endLocal & goto #_undefined_# 2>NUL || title %COMSPEC% & "%_prog%" "%dp0%\..\semver\bin\semver.js" %* diff --git a/node_modules/@babel/core/node_modules/.bin/semver.ps1 b/node_modules/@babel/core/node_modules/.bin/semver.ps1 new file mode 100644 index 00000000..314717ad --- /dev/null +++ b/node_modules/@babel/core/node_modules/.bin/semver.ps1 @@ -0,0 +1,28 @@ +#!/usr/bin/env pwsh +$basedir=Split-Path $MyInvocation.MyCommand.Definition -Parent + +$exe="" +if ($PSVersionTable.PSVersion -lt "6.0" -or $IsWindows) { + # Fix case when both the Windows and Linux builds of Node + # are installed in the same directory + $exe=".exe" +} +$ret=0 +if (Test-Path "$basedir/node$exe") { + # Support pipeline input + if ($MyInvocation.ExpectingInput) { + $input | & "$basedir/node$exe" "$basedir/../semver/bin/semver.js" $args + } else { + & "$basedir/node$exe" "$basedir/../semver/bin/semver.js" $args + } + $ret=$LASTEXITCODE +} else { + # Support pipeline input + if ($MyInvocation.ExpectingInput) { + $input | & "node$exe" "$basedir/../semver/bin/semver.js" $args + } else { + & "node$exe" "$basedir/../semver/bin/semver.js" $args + } + $ret=$LASTEXITCODE +} +exit $ret diff --git a/node_modules/@babel/core/node_modules/.bin/semver~HEAD b/node_modules/@babel/core/node_modules/.bin/semver~HEAD new file mode 100644 index 00000000..97c53279 --- /dev/null +++ b/node_modules/@babel/core/node_modules/.bin/semver~HEAD @@ -0,0 +1,16 @@ +#!/bin/sh +basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')") + +case `uname` in + *CYGWIN*|*MINGW*|*MSYS*) + if command -v cygpath > /dev/null 2>&1; then + basedir=`cygpath -w "$basedir"` + fi + ;; +esac + +if [ -x "$basedir/node" ]; then + exec "$basedir/node" "$basedir/../semver/bin/semver.js" "$@" +else + exec node "$basedir/../semver/bin/semver.js" "$@" +fi diff --git a/node_modules/@babel/core/node_modules/semver/bin/semver.js b/node_modules/@babel/core/node_modules/semver/bin/semver.js old mode 100755 new mode 100644 diff --git a/node_modules/@babel/helper-compilation-targets/node_modules/.bin/semver.cmd b/node_modules/@babel/helper-compilation-targets/node_modules/.bin/semver.cmd new file mode 100644 index 00000000..7d4c104a --- /dev/null +++ b/node_modules/@babel/helper-compilation-targets/node_modules/.bin/semver.cmd @@ -0,0 +1,17 @@ +@ECHO off +GOTO start +:find_dp0 +SET dp0=%~dp0 +EXIT /b +:start +SETLOCAL +CALL :find_dp0 + +IF EXIST "%dp0%\node.exe" ( + SET "_prog=%dp0%\node.exe" +) ELSE ( + SET "_prog=node" + SET PATHEXT=%PATHEXT:;.JS;=;% +) + +endLocal & goto #_undefined_# 2>NUL || title %COMSPEC% & "%_prog%" "%dp0%\..\semver\bin\semver.js" %* diff --git a/node_modules/@babel/helper-compilation-targets/node_modules/.bin/semver.ps1 b/node_modules/@babel/helper-compilation-targets/node_modules/.bin/semver.ps1 new file mode 100644 index 00000000..314717ad --- /dev/null +++ b/node_modules/@babel/helper-compilation-targets/node_modules/.bin/semver.ps1 @@ -0,0 +1,28 @@ +#!/usr/bin/env pwsh +$basedir=Split-Path $MyInvocation.MyCommand.Definition -Parent + +$exe="" +if ($PSVersionTable.PSVersion -lt "6.0" -or $IsWindows) { + # Fix case when both the Windows and Linux builds of Node + # are installed in the same directory + $exe=".exe" +} +$ret=0 +if (Test-Path "$basedir/node$exe") { + # Support pipeline input + if ($MyInvocation.ExpectingInput) { + $input | & "$basedir/node$exe" "$basedir/../semver/bin/semver.js" $args + } else { + & "$basedir/node$exe" "$basedir/../semver/bin/semver.js" $args + } + $ret=$LASTEXITCODE +} else { + # Support pipeline input + if ($MyInvocation.ExpectingInput) { + $input | & "node$exe" "$basedir/../semver/bin/semver.js" $args + } else { + & "node$exe" "$basedir/../semver/bin/semver.js" $args + } + $ret=$LASTEXITCODE +} +exit $ret diff --git a/node_modules/@babel/helper-compilation-targets/node_modules/.bin/semver~HEAD b/node_modules/@babel/helper-compilation-targets/node_modules/.bin/semver~HEAD new file mode 100644 index 00000000..97c53279 --- /dev/null +++ b/node_modules/@babel/helper-compilation-targets/node_modules/.bin/semver~HEAD @@ -0,0 +1,16 @@ +#!/bin/sh +basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')") + +case `uname` in + *CYGWIN*|*MINGW*|*MSYS*) + if command -v cygpath > /dev/null 2>&1; then + basedir=`cygpath -w "$basedir"` + fi + ;; +esac + +if [ -x "$basedir/node" ]; then + exec "$basedir/node" "$basedir/../semver/bin/semver.js" "$@" +else + exec node "$basedir/../semver/bin/semver.js" "$@" +fi diff --git a/node_modules/@babel/helper-compilation-targets/node_modules/semver/bin/semver.js b/node_modules/@babel/helper-compilation-targets/node_modules/semver/bin/semver.js old mode 100755 new mode 100644 diff --git a/node_modules/@babel/parser/bin/babel-parser.js b/node_modules/@babel/parser/bin/babel-parser.js old mode 100755 new mode 100644 diff --git a/node_modules/@eslint/eslintrc/node_modules/.bin/js-yaml.cmd b/node_modules/@eslint/eslintrc/node_modules/.bin/js-yaml.cmd new file mode 100644 index 00000000..7154987a --- /dev/null +++ b/node_modules/@eslint/eslintrc/node_modules/.bin/js-yaml.cmd @@ -0,0 +1,17 @@ +@ECHO off +GOTO start +:find_dp0 +SET dp0=%~dp0 +EXIT /b +:start +SETLOCAL +CALL :find_dp0 + +IF EXIST "%dp0%\node.exe" ( + SET "_prog=%dp0%\node.exe" +) ELSE ( + SET "_prog=node" + SET PATHEXT=%PATHEXT:;.JS;=;% +) + +endLocal & goto #_undefined_# 2>NUL || title %COMSPEC% & "%_prog%" "%dp0%\..\js-yaml\bin\js-yaml.js" %* diff --git a/node_modules/@eslint/eslintrc/node_modules/.bin/js-yaml.ps1 b/node_modules/@eslint/eslintrc/node_modules/.bin/js-yaml.ps1 new file mode 100644 index 00000000..2acfc61c --- /dev/null +++ b/node_modules/@eslint/eslintrc/node_modules/.bin/js-yaml.ps1 @@ -0,0 +1,28 @@ +#!/usr/bin/env pwsh +$basedir=Split-Path $MyInvocation.MyCommand.Definition -Parent + +$exe="" +if ($PSVersionTable.PSVersion -lt "6.0" -or $IsWindows) { + # Fix case when both the Windows and Linux builds of Node + # are installed in the same directory + $exe=".exe" +} +$ret=0 +if (Test-Path "$basedir/node$exe") { + # Support pipeline input + if ($MyInvocation.ExpectingInput) { + $input | & "$basedir/node$exe" "$basedir/../js-yaml/bin/js-yaml.js" $args + } else { + & "$basedir/node$exe" "$basedir/../js-yaml/bin/js-yaml.js" $args + } + $ret=$LASTEXITCODE +} else { + # Support pipeline input + if ($MyInvocation.ExpectingInput) { + $input | & "node$exe" "$basedir/../js-yaml/bin/js-yaml.js" $args + } else { + & "node$exe" "$basedir/../js-yaml/bin/js-yaml.js" $args + } + $ret=$LASTEXITCODE +} +exit $ret diff --git a/node_modules/@eslint/eslintrc/node_modules/.bin/js-yaml~HEAD b/node_modules/@eslint/eslintrc/node_modules/.bin/js-yaml~HEAD new file mode 100644 index 00000000..82416ef1 --- /dev/null +++ b/node_modules/@eslint/eslintrc/node_modules/.bin/js-yaml~HEAD @@ -0,0 +1,16 @@ +#!/bin/sh +basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')") + +case `uname` in + *CYGWIN*|*MINGW*|*MSYS*) + if command -v cygpath > /dev/null 2>&1; then + basedir=`cygpath -w "$basedir"` + fi + ;; +esac + +if [ -x "$basedir/node" ]; then + exec "$basedir/node" "$basedir/../js-yaml/bin/js-yaml.js" "$@" +else + exec node "$basedir/../js-yaml/bin/js-yaml.js" "$@" +fi diff --git a/node_modules/@eslint/eslintrc/node_modules/js-yaml/bin/js-yaml.js b/node_modules/@eslint/eslintrc/node_modules/js-yaml/bin/js-yaml.js old mode 100755 new mode 100644 diff --git a/node_modules/@unrs/resolver-binding-win32-x64-msvc/README.md b/node_modules/@unrs/resolver-binding-win32-x64-msvc/README.md new file mode 100644 index 00000000..83db4d3a --- /dev/null +++ b/node_modules/@unrs/resolver-binding-win32-x64-msvc/README.md @@ -0,0 +1,3 @@ +# `@unrs/resolver-binding-win32-x64-msvc` + +This is the **x86_64-pc-windows-msvc** binary for `@unrs/resolver-binding` diff --git a/node_modules/@unrs/resolver-binding-win32-x64-msvc/package.json b/node_modules/@unrs/resolver-binding-win32-x64-msvc/package.json new file mode 100644 index 00000000..d7720dbd --- /dev/null +++ b/node_modules/@unrs/resolver-binding-win32-x64-msvc/package.json @@ -0,0 +1,23 @@ +{ + "name": "@unrs/resolver-binding-win32-x64-msvc", + "version": "1.11.1", + "cpu": [ + "x64" + ], + "main": "resolver.win32-x64-msvc.node", + "files": [ + "resolver.win32-x64-msvc.node" + ], + "description": "UnRS Resolver Node API with PNP support", + "author": "JounQin (https://www.1stG.me)", + "homepage": "https://github.com/unrs/unrs-resolver#readme", + "license": "MIT", + "publishConfig": { + "registry": "https://registry.npmjs.org", + "access": "public" + }, + "repository": "git+https://github.com/unrs/unrs-resolver.git", + "os": [ + "win32" + ] +} \ No newline at end of file diff --git a/node_modules/@unrs/resolver-binding-win32-x64-msvc/resolver.win32-x64-msvc.node b/node_modules/@unrs/resolver-binding-win32-x64-msvc/resolver.win32-x64-msvc.node new file mode 100644 index 00000000..32b484ea Binary files /dev/null and b/node_modules/@unrs/resolver-binding-win32-x64-msvc/resolver.win32-x64-msvc.node differ diff --git a/node_modules/acorn/bin/acorn b/node_modules/acorn/bin/acorn old mode 100755 new mode 100644 diff --git a/node_modules/ajv/scripts/info b/node_modules/ajv/scripts/info old mode 100755 new mode 100644 diff --git a/node_modules/ajv/scripts/prepare-tests b/node_modules/ajv/scripts/prepare-tests old mode 100755 new mode 100644 diff --git a/node_modules/ajv/scripts/publish-built-version b/node_modules/ajv/scripts/publish-built-version old mode 100755 new mode 100644 diff --git a/node_modules/ajv/scripts/travis-gh-pages b/node_modules/ajv/scripts/travis-gh-pages old mode 100755 new mode 100644 diff --git a/node_modules/baseline-browser-mapping/dist/cli.cjs b/node_modules/baseline-browser-mapping/dist/cli.cjs old mode 100755 new mode 100644 diff --git a/node_modules/browserslist/cli.js b/node_modules/browserslist/cli.js old mode 100755 new mode 100644 diff --git a/node_modules/cjs-module-lexer/LICENSE b/node_modules/cjs-module-lexer/LICENSE old mode 100755 new mode 100644 diff --git a/node_modules/cjs-module-lexer/README.md b/node_modules/cjs-module-lexer/README.md old mode 100755 new mode 100644 diff --git a/node_modules/cjs-module-lexer/lexer.d.ts b/node_modules/cjs-module-lexer/lexer.d.ts old mode 100755 new mode 100644 diff --git a/node_modules/cjs-module-lexer/lexer.js b/node_modules/cjs-module-lexer/lexer.js old mode 100755 new mode 100644 diff --git a/node_modules/cjs-module-lexer/package.json b/node_modules/cjs-module-lexer/package.json old mode 100755 new mode 100644 diff --git a/node_modules/cliui/node_modules/wrap-ansi/index.js b/node_modules/cliui/node_modules/wrap-ansi/index.js old mode 100755 new mode 100644 diff --git a/node_modules/eslint-plugin-jsdoc/dist/rules/requireReturnsCheck.cjs b/node_modules/eslint-plugin-jsdoc/dist/rules/requireReturnsCheck.cjs old mode 100755 new mode 100644 diff --git a/node_modules/eslint-plugin-jsdoc/src/rules/requireReturnsCheck.js b/node_modules/eslint-plugin-jsdoc/src/rules/requireReturnsCheck.js old mode 100755 new mode 100644 diff --git a/node_modules/eslint/bin/eslint.js b/node_modules/eslint/bin/eslint.js old mode 100755 new mode 100644 diff --git a/node_modules/esprima/bin/esparse.js b/node_modules/esprima/bin/esparse.js old mode 100755 new mode 100644 diff --git a/node_modules/esprima/bin/esvalidate.js b/node_modules/esprima/bin/esvalidate.js old mode 100755 new mode 100644 diff --git a/node_modules/esrecurse/package.json b/node_modules/esrecurse/package.json old mode 100755 new mode 100644 diff --git a/node_modules/exit-x/test/fixtures/create-files.sh b/node_modules/exit-x/test/fixtures/create-files.sh old mode 100755 new mode 100644 diff --git a/node_modules/glob/dist/esm/bin.mjs b/node_modules/glob/dist/esm/bin.mjs old mode 100755 new mode 100644 diff --git a/node_modules/helmet/CHANGELOG.md b/node_modules/helmet/CHANGELOG.md new file mode 100644 index 00000000..24288456 --- /dev/null +++ b/node_modules/helmet/CHANGELOG.md @@ -0,0 +1,974 @@ +# Changelog + +## 8.1.0 - 2025-03-17 + +### Changed + +- `Content-Security-Policy` gives a better error when a directive value, like `self`, should be quoted. See [#482](https://github.com/helmetjs/helmet/issues/482) + +## 8.0.0 - 2024-09-28 + +### Changed + +- **Breaking:** `Strict-Transport-Security` now has a max-age of 365 days, up from 180 +- **Breaking:** `Content-Security-Policy` middleware now throws an error if a directive should have quotes but does not, such as `self` instead of `'self'`. See [#454](https://github.com/helmetjs/helmet/issues/454) +- **Breaking:** `Content-Security-Policy`'s `getDefaultDirectives` now returns a deep copy. This only affects users who were mutating the result +- **Breaking:** `Strict-Transport-Security` now throws an error when "includeSubDomains" option is misspelled. This was previously a warning + +### Removed + +- **Breaking:** Drop support for Node 16 and 17. Node 18+ is now required + +## 7.2.0 - 2024-09-28 + +### Changed + +- `Content-Security-Policy` middleware now warns if a directive should have quotes but does not, such as `self` instead of `'self'`. This will be an error in future versions. See [#454](https://github.com/helmetjs/helmet/issues/454) + +## 7.1.0 - 2023-11-07 + +### Added + +- `helmet.crossOriginEmbedderPolicy` now supports the `unsafe-none` directive. See [#477](https://github.com/helmetjs/helmet/pull/447) + +## 7.0.0 - 2023-05-06 + +### Changed + +- **Breaking:** `Cross-Origin-Embedder-Policy` middleware is now disabled by default. See [#411](https://github.com/helmetjs/helmet/issues/411) + +### Removed + +- **Breaking:** Drop support for Node 14 and 15. Node 16+ is now required +- **Breaking:** `Expect-CT` is no longer part of Helmet. If you still need it, you can use the [`expect-ct` package](https://www.npmjs.com/package/expect-ct). See [#378](https://github.com/helmetjs/helmet/issues/378) + +## 6.2.0 - 2023-05-06 + +- Expose header names (e.g., `strictTransportSecurity` for the `Strict-Transport-Security` header, instead of `hsts`) +- Rework documentation + +## 6.1.5 - 2023-04-11 + +### Fixed + +- Fixed yet another issue with TypeScript exports. See [#420](https://github.com/helmetjs/helmet/pull/418) + +## 6.1.4 - 2023-04-10 + +### Fixed + +- Fix another issue with TypeScript default exports. See [#418](https://github.com/helmetjs/helmet/pull/418) + +## 6.1.3 - 2023-04-10 + +### Fixed + +- Fix issue with TypeScript default exports. See [#417](https://github.com/helmetjs/helmet/pull/417) + +## 6.1.2 - 2023-04-09 + +### Fixed + +- Retored `main` to package to help with some build tools + +## 6.1.1 - 2023-04-08 + +### Fixed + +- Fixed missing package metadata + +## 6.1.0 - 2023-04-08 + +### Changed + +- Improve support for various TypeScript setups, including "nodenext". See [#405](https://github.com/helmetjs/helmet/pull/405) + +## 6.0.1 - 2022-11-29 + +### Fixed + +- `crossOriginEmbedderPolicy` did not accept options at the top level. See [#390](https://github.com/helmetjs/helmet/issues/390) + +## 6.0.0 - 2022-08-26 + +### Changed + +- **Breaking:** `helmet.contentSecurityPolicy` no longer sets `block-all-mixed-content` directive by default +- **Breaking:** `helmet.expectCt` is no longer set by default. It can, however, be explicitly enabled. It will be removed in Helmet 7. See [#310](https://github.com/helmetjs/helmet/issues/310) +- **Breaking:** Increase TypeScript strictness around some arguments. Only affects TypeScript users, and may not require any code changes. See [#369](https://github.com/helmetjs/helmet/issues/369) +- `helmet.frameguard` no longer offers a specific error when trying to use `ALLOW-FROM`; it just says that it is unsupported. Only the error message has changed + +### Removed + +- **Breaking:** Dropped support for Node 12 and 13. Node 14+ is now required + +## 5.1.1 - 2022-07-23 + +### Changed + +- Fix TypeScript bug with some TypeScript configurations. See [#375](https://github.com/helmetjs/helmet/pull/375) and [#359](https://github.com/helmetjs/helmet/issues/359) + +## 5.1.0 - 2022-05-17 + +### Added + +- `Cross-Origin-Embedder-Policy`: support `credentialless` policy. See [#365](https://github.com/helmetjs/helmet/pull/365) +- Documented how to set both `Content-Security-Policy` and `Content-Security-Policy-Report-Only` + +### Changed + +- Cleaned up some documentation around `Origin-Agent-Cluster` + +## 5.0.2 - 2022-01-22 + +### Changed + +- Improve imports for CommonJS and ECMAScript modules. See [#345](https://github.com/helmetjs/helmet/pull/345) +- Fixed some documentation + +## 5.0.1 - 2022-01-03 + +### Changed + +- Fixed some documentation + +### Removed + +- Removed some unused internal code + +## 5.0.0 - 2022-01-02 + +### Added + +- ECMAScript module imports (i.e., `import helmet from "helmet"` and `import { frameguard } from "helmet"`). See [#320](https://github.com/helmetjs/helmet/issues/320) + +### Changed + +- **Breaking:** `helmet.contentSecurityPolicy`: `useDefaults` option now defaults to `true` +- **Breaking:** `helmet.contentSecurityPolicy`: `form-action` directive is now set to `'self'` by default +- **Breaking:** `helmet.crossOriginEmbedderPolicy` is enabled by default +- **Breaking:** `helmet.crossOriginOpenerPolicy` is enabled by default +- **Breaking:** `helmet.crossOriginResourcePolicy` is enabled by default +- **Breaking:** `helmet.originAgentCluster` is enabled by default +- `helmet.frameguard`: add TypeScript editor autocomplete. See [#322](https://github.com/helmetjs/helmet/pull/322) +- Top-level `helmet()` function is slightly faster + +### Removed + +- **Breaking:** Drop support for Node 10 and 11. Node 12+ is now required + +## 4.6.0 - 2021-05-01 + +### Added + +- `helmet.contentSecurityPolicy`: the `useDefaults` option, defaulting to `false`, lets you selectively override defaults more easily +- Explicitly define TypeScript types in `package.json`. See [#303](https://github.com/helmetjs/helmet/pull/303) + +## 4.5.0 - 2021-04-17 + +### Added + +- `helmet.crossOriginEmbedderPolicy`: a new middleware for the `Cross-Origin-Embedder-Policy` header, disabled by default +- `helmet.crossOriginOpenerPolicy`: a new middleware for the `Cross-Origin-Opener-Policy` header, disabled by default +- `helmet.crossOriginResourcePolicy`: a new middleware for the `Cross-Origin-Resource-Policy` header, disabled by default + +### Changed + +- `true` enables a middleware with default options. Previously, this would fail with an error if the middleware was already enabled by default. +- Log a warning when passing options to `originAgentCluster` at the top level + +### Fixed + +- Incorrect documentation + +## 4.4.1 - 2021-01-18 + +### Changed + +- Shrink the published package by about 2.5 kB + +## 4.4.0 - 2021-01-17 + +### Added + +- `helmet.originAgentCluster`: a new middleware for the `Origin-Agent-Cluster` header, disabled by default + +## 4.3.1 - 2020-12-27 + +### Fixed + +- `helmet.contentSecurityPolicy`: broken TypeScript types. See [#283](https://github.com/helmetjs/helmet/issues/283) + +## 4.3.0 - 2020-12-27 + +### Added + +- `helmet.contentSecurityPolicy`: setting the `default-src` to `helmet.contentSecurityPolicy.dangerouslyDisableDefaultSrc` disables it + +### Changed + +- `helmet.frameguard`: slightly improved error messages for non-strings + +## 4.2.0 - 2020-11-01 + +### Added + +- `helmet.contentSecurityPolicy`: get the default directives with `contentSecurityPolicy.getDefaultDirectives()` + +### Changed + +- `helmet()` now supports objects that don't have `Object.prototype` in their chain, such as `Object.create(null)`, as options +- `helmet.expectCt`: `max-age` is now first. See [#264](https://github.com/helmetjs/helmet/pull/264) + +## 4.1.1 - 2020-09-10 + +### Changed + +- Fixed a few errors in the README + +## 4.1.0 - 2020-08-15 + +### Added + +- `helmet.contentSecurityPolicy`: + - Directive values can now include functions, as they could in Helmet 3. See [#243](https://github.com/helmetjs/helmet/issues/243) + +### Changed + +- Helmet should now play more nicely with TypeScript + +### Removed + +- The `HelmetOptions` interface is no longer exported. This only affects TypeScript users. If you need the functionality back, see [this comment](https://github.com/helmetjs/helmet/issues/235#issuecomment-674016883) + +## 4.0.0 - 2020-08-02 + +See the [Helmet 4 upgrade guide](https://github.com/helmetjs/helmet/wiki/Helmet-4-upgrade-guide) for help upgrading from Helmet 3. + +### Added + +- `helmet.contentSecurityPolicy`: + - If no `default-src` directive is supplied, an error is thrown + - Directive lists can be any iterable, not just arrays + +### Changed + +- This package no longer has dependencies. This should have no effect on end users, other than speeding up installation time. +- `helmet.contentSecurityPolicy`: + - There is now a default set of directives if none are supplied + - Duplicate keys now throw an error. See [helmetjs/csp#73](https://github.com/helmetjs/csp/issues/73) + - This middleware is more lenient, allowing more directive names or values +- `helmet.xssFilter` now disables the buggy XSS filter by default. See [#230](https://github.com/helmetjs/helmet/issues/230) + +### Removed + +- Dropped support for old Node versions. Node 10+ is now required +- `helmet.featurePolicy`. If you still need it, use the `feature-policy` package on npm. +- `helmet.hpkp`. If you still need it, use the `hpkp` package on npm. +- `helmet.noCache`. If you still need it, use the `nocache` package on npm. +- `helmet.contentSecurityPolicy`: + - Removed browser sniffing (including the `browserSniff` and `disableAndroid` parameters). See [helmetjs/csp#97](https://github.com/helmetjs/csp/issues/97) + - Removed conditional support. This includes directive functions and support for a function as the `reportOnly`. [Read this if you need help.](https://github.com/helmetjs/helmet/wiki/Conditionally-using-middleware) + - Removed a lot of checks—you should be checking your CSP with a different tool + - Removed support for legacy headers (and therefore the `setAllHeaders` parameter). [Read this if you need help.](https://github.com/helmetjs/helmet/wiki/Setting-legacy-Content-Security-Policy-headers-in-Helmet-4) + - Removed the `loose` option + - Removed support for functions as directive values. You must supply an iterable of strings +- `helmet.frameguard`: + - Dropped support for the `ALLOW-FROM` action. [Read more here.](https://github.com/helmetjs/helmet/wiki/How-to-use-X%E2%80%93Frame%E2%80%93Options's-%60ALLOW%E2%80%93FROM%60-directive) +- `helmet.hidePoweredBy` no longer accepts arguments. See [this article](https://github.com/helmetjs/helmet/wiki/How-to-set-a-custom-X%E2%80%93Powered%E2%80%93By-header) to see how to replicate the removed behavior. See [#224](https://github.com/helmetjs/helmet/issues/224). +- `helmet.hsts`: + - Dropped support for `includeSubdomains` with a lowercase D. See [#231](https://github.com/helmetjs/helmet/issues/231) + - Dropped support for `setIf`. [Read this if you need help.](https://github.com/helmetjs/helmet/wiki/Conditionally-using-middleware) See [#232](https://github.com/helmetjs/helmet/issues/232) +- `helmet.xssFilter` no longer accepts options. Read ["How to disable blocking with X-XSS-Protection"](https://github.com/helmetjs/helmet/wiki/How-to-disable-blocking-with-X%E2%80%93XSS%E2%80%93Protection) and ["How to enable the `report` directive with X-XSS-Protection"](https://github.com/helmetjs/helmet/wiki/How-to-enable-the-%60report%60-directive-with-X%E2%80%93XSS%E2%80%93Protection) if you need the legacy behavior. + +## 3.23.3 - 2020-06-26 + +### Changed + +- `helmet.expectCt` is no longer a separate package. This should have no effect on end users. +- `helmet.frameguard` is no longer a separate package. This should have no effect on end users. + +## 3.23.2 - 2020-06-23 + +### Changed + +- `helmet.dnsPrefetchControl` is no longer a separate package. This should have no effect on end users. + +## 3.23.1 - 2020-06-16 + +### Changed + +- `helmet.ieNoOpen` is no longer a separate package. This should have no effect on end users. + +## 3.23.0 - 2020-06-12 + +### Deprecated + +- `helmet.featurePolicy` is deprecated. Use the `feature-policy` module instead. + +## 3.22.1 - 2020-06-10 + +### Changed + +- Rewrote internals in TypeScript. This should have no effect on end users. + +## 3.22.0 - 2020-03-24 + +### Changed + +- Updated `helmet-csp` to v2.10.0 + - Add support for the `allow-downloads` sandbox directive. See [helmet-csp#103](https://github.com/helmetjs/csp/pull/103) + +### Deprecated + +- `helmet.noCache` is deprecated. Use the `nocache` module instead. See [#215](https://github.com/helmetjs/helmet/issues/215) + +## 3.21.3 - 2020-02-24 + +### Changed + +- Updated `helmet-csp` to v2.9.5 + - Updated `bowser` subdependency from 2.7.0 to 2.9.0 + - Fixed an issue some people were having when importing the `bowser` subdependency. See [helmet-csp#96](https://github.com/helmetjs/csp/issues/96) and [#101](https://github.com/helmetjs/csp/pull/101) + +## 3.21.2 - 2019-10-21 + +### Changed + +- Updated `helmet-csp` to v2.9.4 + - Updated `bowser` subdependency from 2.6.1 to 2.7.0. See [helmet-csp#94](https://github.com/helmetjs/csp/pull/94) + +## 3.21.1 - 2019-09-20 + +### Fixed + +- Updated `helmet-csp` to v2.9.2 + - Fixed a bug where a request from Firefox 4 could delete `default-src` from future responses + - Fixed tablet PC detection by updating `bowser` subdependency to latest version + +## 3.21.0 - 2019-09-04 + +### Added + +- Updated `x-xss-protection` to v1.3.0 + - Added `mode: null` to disable `mode=block` + +### Changed + +- Updated `helmet-csp` to v2.9.1 + - Updated `bowser` subdependency from 2.5.3 to 2.5.4. See [helmet-csp#88](https://github.com/helmetjs/csp/pull/88) + +## 3.20.1 - 2019-08-28 + +### Changed + +- Updated `helmet-csp` to v2.9.0 + +## 3.20.0 - 2019-07-24 + +### Changed + +- Updated `helmet-csp` to v2.8.0 + +## 3.19.0 - 2019-07-17 + +### Changed + +- Updated `dns-prefetch-control` to v0.2.0 +- Updated `dont-sniff-mimetype` to v1.1.0 +- Updated `helmet-crossdomain` to v0.4.0 +- Updated `hide-powered-by` to v1.1.0 +- Updated `x-xss-protection` to v1.2.0 + +## 3.18.0 - 2019-05-05 + +### Added + +- `featurePolicy` has 19 new features: `ambientLightSensor`, `documentDomain`, `documentWrite`, `encryptedMedia`, `fontDisplayLateSwap`, `layoutAnimations`, `legacyImageFormats`, `loadingFrameDefaultEager`, `oversizedImages`, `pictureInPicture`, `serial`, `syncScript`, `unoptimizedImages`, `unoptimizedLosslessImages`, `unoptimizedLossyImages`, `unsizedMedia`, `verticalScroll`, `wakeLock`, and `xr` + +### Changed + +- Updated `expect-ct` to v0.2.0 +- Updated `feature-policy` to v0.3.0 +- Updated `frameguard` to v3.1.0 +- Updated `nocache` to v2.1.0 + +## 3.17.0 - 2019-05-03 + +### Added + +- `referrerPolicy` now supports multiple values + +### Changed + +- Updated `referrerPolicy` to v1.2.0 + +## 3.16.0 - 2019-03-10 + +### Added + +- Add email to `bugs` field in `package.json` + +### Changed + +- Updated `hsts` to v2.2.0 +- Updated `ienoopen` to v1.1.0 +- Changelog is now in the [Keep A Changelog](https://keepachangelog.com/) format +- Dropped support for Node <4. See [the commit](https://github.com/helmetjs/helmet/commit/a49cec3ca58cce484d2d05e1f908549caa92ed03) for more information +- Updated Adam Baldwin's contact information + +### Deprecated + +- `helmet.hsts`'s `setIf` option has been deprecated and will be removed in `hsts@3`. See [helmetjs/hsts#22](https://github.com/helmetjs/hsts/issues/22) for more + +* The `includeSubdomains` option (with a lowercase `d`) has been deprecated and will be removed in `hsts@3`. Use the uppercase-D `includeSubDomains` option instead. See [helmetjs/hsts#21](https://github.com/helmetjs/hsts/issues/21) for more + +## 3.15.1 - 2019-02-10 + +### Deprecated + +- The `hpkp` middleware has been deprecated. If you still need to use this module, install the standalone `hpkp` module from npm. See [#180](https://github.com/helmetjs/helmet/issues/180) for more. + +## 3.15.0 - 2018-11-07 + +### Added + +- `helmet.featurePolicy` now supports four new features + +## 3.14.0 - 2018-10-09 + +### Added + +- `helmet.featurePolicy` middleware + +## 3.13.0 - 2018-07-22 + +### Added + +- `helmet.permittedCrossDomainPolicies` middleware + +## 3.12.2 - 2018-07-20 + +### Fixed + +- Removed `lodash.reduce` dependency from `csp` + +## 3.12.1 - 2018-05-16 + +### Fixed + +- `expectCt` should use comma instead of semicolon as delimiter + +## 3.12.0 - 2018-03-02 + +### Added + +- `xssFilter` now supports `reportUri` option + +## 3.11.0 - 2018-02-09 + +### Added + +- Main Helmet middleware is now named to help with debugging + +## 3.10.0 - 2018-01-23 + +### Added + +- `csp` now supports `prefix-src` directive + +### Fixed + +- `csp` no longer loads JSON files internally, helping some module bundlers +- `false` should be able to disable a CSP directive + +## 3.9.0 - 2017-10-13 + +### Added + +- `csp` now supports `strict-dynamic` value +- `csp` now supports `require-sri-for` directive + +### Changed + +- Removed `connect` dependency + +## 3.8.2 - 2017-09-27 + +### Changed + +- Updated `connect` dependency to latest + +## 3.8.1 - 2017-07-28 + +### Fixed + +- `csp` does not automatically set `report-to` when setting `report-uri` + +## 3.8.0 - 2017-07-21 + +### Changed + +- `hsts` no longer cares whether it's HTTPS and always sets the header + +## 3.7.0 - 2017-07-21 + +### Added + +- `csp` now supports `report-to` directive + +### Changed + +- Throw an error when used incorrectly +- Add a few documentation files to `npmignore` + +## 3.6.1 - 2017-05-21 + +### Changed + +- Bump `connect` version + +## 3.6.0 - 2017-05-04 + +### Added + +- `expectCt` middleware for setting the `Expect-CT` header + +## 3.5.0 - 2017-03-06 + +### Added + +- `csp` now supports the `worker-src` directive + +## 3.4.1 - 2017-02-24 + +### Changed + +- Bump `connect` version + +## 3.4.0 - 2017-01-13 + +### Added + +- `csp` now supports more `sandbox` directives + +## 3.3.0 - 2016-12-31 + +### Added + +- `referrerPolicy` allows `strict-origin` and `strict-origin-when-cross-origin` directives + +### Changed + +- Bump `connect` version + +## 3.2.0 - 2016-12-22 + +### Added + +- `csp` now allows `manifest-src` directive + +## 3.1.0 - 2016-11-03 + +### Added + +- `csp` now allows `frame-src` directive + +## 3.0.0 - 2016-10-28 + +### Changed + +- `csp` will check your directives for common mistakes and throw errors if it finds them. This can be disabled with `loose: true`. +- Empty arrays are no longer allowed in `csp`. For source lists (like `script-src` or `object-src`), use the standard `scriptSrc: ["'none'"]`. The `sandbox` directive can be `sandbox: true` to block everything. +- `false` can disable a CSP directive. For example, `scriptSrc: false` is the same as not specifying it. +- In CSP, `reportOnly: true` no longer requires a `report-uri` to be set. +- `hsts`'s `maxAge` now defaults to 180 days (instead of 1 day) +- `hsts`'s `maxAge` parameter is seconds, not milliseconds +- `hsts` includes subdomains by default +- `domain` parameter in `frameguard` cannot be empty + +### Removed + +- `noEtag` option no longer present in `noCache` +- iOS Chrome `connect-src` workaround in CSP module + +## 2.3.0 - 2016-09-30 + +### Added + +- `hpkp` middleware now supports the `includeSubDomains` property with a capital D + +### Fixed + +- `hpkp` was setting `includeSubdomains` instead of `includeSubDomains` + +## 2.2.0 - 2016-09-16 + +### Added + +- `referrerPolicy` middleware + +## 2.1.3 - 2016-09-07 + +### Changed + +- Top-level aliases (like `helmet.xssFilter`) are no longer dynamically required + +## 2.1.2 - 2016-07-27 + +### Deprecated + +- `nocache`'s `noEtag` option is now deprecated + +### Fixed + +- `csp` now better handles Firefox on mobile + +## 2.1.1 - 2016-06-10 + +### Changed + +- Remove several dependencies from `helmet-csp` + +### Fixed + +- `frameguard` had a documentation error about its default value +- `frameguard` docs in main Helmet readme said `frameguard`, not `helmet.frameguard` + +## 2.1.0 - 2016-05-18 + +### Added + +- `csp` lets you dynamically set `reportOnly` + +## 2.0.0 - 2016-04-29 + +### Added + +- Pass configuration to enable/disable default middlewares + +### Changed + +- `dnsPrefetchControl` middleware is now enabled by default + +### Removed + +- No more module aliases. There is now just one way to include each middleware +- `frameguard` can no longer be initialized with strings; you must use an object + +### Fixed + +- Make `hpkp` lowercase in documentation +- Update `hpkp` spec URL in readmes +- Update `frameguard` header name in readme + +## 1.3.0 - 2016-03-01 + +### Added + +- `hpkp` has a `setIf` option to conditionally set the header + +## 1.2.0 - 2016-02-29 + +### Added + +- `csp` now has a `browserSniff` option to disable all user-agent sniffing + +### Changed + +- `frameguard` can now be initialized with options +- Add `npmignore` file to speed up installs slightly + +## 1.1.0 - 2016-01-12 + +### Added + +- Code of conduct +- `dnsPrefetchControl` middleware + +### Fixed + +- `csp` readme had syntax errors + +## 1.0.2 - 2016-01-08 + +### Fixed + +- `csp` wouldn't recognize `IE Mobile` browsers +- `csp` had some errors in its readme +- Main readme had a syntax error + +## 1.0.1 - 2015-12-19 + +### Fixed + +- `csp` with no User Agent would cause errors + +## 1.0.0 - 2015-12-18 + +### Added + +- `csp` module supports dynamically-generated values + +### Changed + +- `csp` directives are now under the `directives` key +- `hpkp`'s `Report-Only` header is now opt-in, not opt-out +- Tweak readmes of every sub-repo + +### Removed + +- `crossdomain` middleware +- `csp` no longer throws errors when some directives aren't quoted (`'self'`, for example) +- `maxage` option in the `hpkp` middleware +- `safari5` option from `csp` module + +### Fixed + +- Old Firefox Content-Security-Policy behavior for `unsafe-inline` and `unsafe-eval` +- Dynamic `csp` policies is no longer recursive + +## 0.15.0 - 2015-11-26 + +### Changed + +- `hpkp` allows a `report-uri` without the `Report-Only` header + +## 0.14.0 - 2015-11-01 + +### Added + +- `nocache` now sends the `Surrogate-Control` header + +### Changed + +- `nocache` no longer contains the `private` directive in the `Cache-Control` header + +## 0.13.0 - 2015-10-23 + +### Added + +- `xssFilter` now has a function name +- Added new CSP docs to readme + +### Changed + +- HSTS option renamed from `includeSubdomains` to `includeSubDomains` + +## 0.11.0 - 2015-09-18 + +### Added + +- `csp` now supports Microsoft Edge +- CSP Level 2 support + +### Changed + +- Updated `connect` to 3.4.0 +- Updated `depd` to 1.1.0 + +### Fixed + +- Added `license` key to `csp`'s `package.json` +- Empty `csp` directives now support every directive, not just `sandbox` + +## 0.10.0 - 2015-07-08 + +### Added + +- Add "Handling CSP violations" to `csp` readme +- Add license to `package.json` + +### Changed + +- `hpkp` had a link to the wrong place in its readme +- `hpkp` requires 2 or more pins + +### Fixed + +- `hpkp` might have miscalculated `maxAge` slightly wrong + +## 0.9.0 - 2015-04-24 + +### Changed + +- `nocache` adds `private` to its `Cache-Control` directive +- Added a description to `package.json` + +## 0.8.0 - 2015-04-21 + +### Changed + +- Removed hefty Lodash dependency from HSTS and CSP +- Updated string detection module in Frameguard +- Changed readme slightly to better reflect project's focus + +### Deprecated + +- Deprecated `crossdomain` middleware + +### Removed + +- `crossdomain` is no longer a default middleware + +## 0.7.1 - 2015-03-23 + +### Changed + +- Updated all outdated dependencies (insofar as possible) +- HSTS now uses Lodash like all the rest of the libraries + +## 0.7.0 - 2015-03-05 + +### Added + +- `hpkp` middleware + +### Changed + +- Travis CI should test 0.10 and 0.12 +- Minor code cleanup + +## 0.6.2 - 2015-03-01 + +### Changed + +- Improved `xssFilter` performance +- Updated Lodash versions + +## 0.6.1 - 2015-02-13 + +### Added + +- "Other recommended modules" in README + +### Changed + +- Updated Lodash version + +### Fixed + +- `frameguard` middleware exported a function called `xframe` + +## 0.6.0 - 2015-01-21 + +### Added + +- You can disable `csp` for Android + +### Fixed + +- `csp` on Chrome Mobile on Android and iOS + +## 0.5.4 - 2014-12-21 + +### Changed + +- `nocache` should force revalidation + +## 0.5.3 - 2014-12-08 + +### Changed + +- `platform` version in CSP and X-XSS-Protection + +### Fixed + +- Updated bad wording in frameguard docs + +## 0.5.2 - 2014-11-16 + +### Changed + +- Updated Connect version + +### Fixed + +- Fixed minor `csp` bugfixes + +## 0.5.1 - 2014-11-09 + +### Changed + +- Updated URLs in `package.json` for new URL + +### Fixed + +- CSP would set all headers forever after receiving an unknown user agent + +## 0.5.0 - 2014-10-28 + +### Added + +- Most middlewares have some aliases now + +### Changed + +- `xframe` now called `frameguard` (though `xframe` still works) +- `frameguard` chooses sameorigin by default +- `frameguard` understands "SAME-ORIGIN" in addition to "SAMEORIGIN" +- `nocache` removed from default middleware stack +- Middleware split out into their own modules +- Documentation +- Updated supported Node version to at least 0.10.0 +- Bumped Connect version + +### Removed + +- Deprecation warnings + +### Fixed + +- Readme link was broken + +## 0.4.2 - 2014-10-16 + +### Added + +- Support preload in HSTS header + +## 0.4.1 - 2014-08-24 + +### Added + +- Use [helmet-crossdomain](https://github.com/helmetjs/crossdomain) to test the waters +- 2 spaces instead of 4 throughout the code + +## 0.4.0 - 2014-07-17 + +### Added + +- `nocache` now sets the Expires and Pragma headers +- `nocache` now allows you to crush ETags + +### Changed + +- Improved the docs for nosniff +- Reverted HSTS behavior of requiring a specified max-age + +### Fixed + +- Allow HSTS to have a max-age of 0 + +## 0.3.2 - 2014-06-30 + +### Added + +- All middleware functions are named +- Throw error with non-positive HSTS max-age + +### Changed + +- Added semicolons in README +- Make some Errors more specific + +### Removed + +- Removed all comment headers; refer to the readme + +### Fixed + +- `helmet()` was having issues +- Fixed Syntax errors in README + +This changelog was created after the release of 0.3.1. diff --git a/node_modules/helmet/LICENSE b/node_modules/helmet/LICENSE new file mode 100644 index 00000000..2df8eee3 --- /dev/null +++ b/node_modules/helmet/LICENSE @@ -0,0 +1,22 @@ +The MIT License + +Copyright (c) 2012-2025 Evan Hahn, Adam Baldwin + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +'Software'), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/node_modules/helmet/README.md b/node_modules/helmet/README.md new file mode 100644 index 00000000..db428767 --- /dev/null +++ b/node_modules/helmet/README.md @@ -0,0 +1,702 @@ +# Helmet + +Help secure Express apps by setting HTTP response headers. + +```javascript +import helmet from "helmet"; + +const app = express(); + +app.use(helmet()); +``` + +Helmet sets the following headers by default: + +- [`Content-Security-Policy`](#content-security-policy): A powerful allow-list of what can happen on your page which mitigates many attacks +- [`Cross-Origin-Opener-Policy`](#cross-origin-opener-policy): Helps process-isolate your page +- [`Cross-Origin-Resource-Policy`](#cross-origin-resource-policy): Blocks others from loading your resources cross-origin +- [`Origin-Agent-Cluster`](#origin-agent-cluster): Changes process isolation to be origin-based +- [`Referrer-Policy`](#referrer-policy): Controls the [`Referer`][Referer] header +- [`Strict-Transport-Security`](#strict-transport-security): Tells browsers to prefer HTTPS +- [`X-Content-Type-Options`](#x-content-type-options): Avoids [MIME sniffing] +- [`X-DNS-Prefetch-Control`](#x-dns-prefetch-control): Controls DNS prefetching +- [`X-Download-Options`](#x-download-options): Forces downloads to be saved (Internet Explorer only) +- [`X-Frame-Options`](#x-frame-options): Legacy header that mitigates [clickjacking] attacks +- [`X-Permitted-Cross-Domain-Policies`](#x-permitted-cross-domain-policies): Controls cross-domain behavior for Adobe products, like Acrobat +- [`X-Powered-By`](#x-powered-by): Info about the web server. Removed because it could be used in simple attacks +- [`X-XSS-Protection`](#x-xss-protection): Legacy header that tries to mitigate [XSS attacks][XSS], but makes things worse, so Helmet disables it + +Each header can be configured. For example, here's how you configure the `Content-Security-Policy` header: + +```js +// Configure the Content-Security-Policy header. +app.use( + helmet({ + contentSecurityPolicy: { + directives: { + "script-src": ["'self'", "example.com"], + }, + }, + }), +); +``` + +Headers can also be disabled. For example, here's how you disable the `Content-Security-Policy` and `X-Download-Options` headers: + +```js +// Disable the Content-Security-Policy and X-Download-Options headers +app.use( + helmet({ + contentSecurityPolicy: false, + xDownloadOptions: false, + }), +); +``` + +## Reference + +
+Content-Security-Policy + +Default: + +```http +Content-Security-Policy: default-src 'self';base-uri 'self';font-src 'self' https: data:;form-action 'self';frame-ancestors 'self';img-src 'self' data:;object-src 'none';script-src 'self';script-src-attr 'none';style-src 'self' https: 'unsafe-inline';upgrade-insecure-requests +``` + +The `Content-Security-Policy` header mitigates a large number of attacks, such as [cross-site scripting][XSS]. See [MDN's introductory article on Content Security Policy](https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP). + +This header is powerful but likely requires some configuration for your specific app. + +To configure this header, pass an object with a nested `directives` object. Each key is a directive name in camel case (such as `defaultSrc`) or kebab case (such as `default-src`). Each value is an array (or other iterable) of strings or functions for that directive. If a function appears in the array, it will be called with the request and response objects. + +```javascript +// Sets all of the defaults, but overrides `script-src` +// and disables the default `style-src`. +app.use( + helmet({ + contentSecurityPolicy: { + directives: { + "script-src": ["'self'", "example.com"], + "style-src": null, + }, + }, + }), +); +``` + +```js +// Sets the `script-src` directive to +// "'self' 'nonce-e33cc...'" +// (or similar) +app.use((req, res, next) => { + res.locals.cspNonce = crypto.randomBytes(32).toString("hex"); + next(); +}); +app.use( + helmet({ + contentSecurityPolicy: { + directives: { + scriptSrc: ["'self'", (req, res) => `'nonce-${res.locals.cspNonce}'`], + }, + }, + }), +); +``` + +These directives are merged into a default policy, which you can disable by setting `useDefaults` to `false`. + +```javascript +// Sets "Content-Security-Policy: default-src 'self'; +// script-src 'self' example.com;object-src 'none'; +// upgrade-insecure-requests" +app.use( + helmet({ + contentSecurityPolicy: { + useDefaults: false, + directives: { + defaultSrc: ["'self'"], + scriptSrc: ["'self'", "example.com"], + objectSrc: ["'none'"], + upgradeInsecureRequests: [], + }, + }, + }), +); +``` + +You can get the default directives object with `helmet.contentSecurityPolicy.getDefaultDirectives()`. Here is the default policy (formatted for readability): + +``` +default-src 'self'; +base-uri 'self'; +font-src 'self' https: data:; +form-action 'self'; +frame-ancestors 'self'; +img-src 'self' data:; +object-src 'none'; +script-src 'self'; +script-src-attr 'none'; +style-src 'self' https: 'unsafe-inline'; +upgrade-insecure-requests +``` + +The `default-src` directive can be explicitly disabled by setting its value to `helmet.contentSecurityPolicy.dangerouslyDisableDefaultSrc`, but this is not recommended. + +You can set the [`Content-Security-Policy-Report-Only`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy-Report-Only) instead: + +```javascript +// Sets the Content-Security-Policy-Report-Only header +app.use( + helmet({ + contentSecurityPolicy: { + directives: { + /* ... */ + }, + reportOnly: true, + }, + }), +); +``` + +Helmet performs very little validation on your CSP. You should rely on CSP checkers like [CSP Evaluator](https://csp-evaluator.withgoogle.com/) instead. + +To disable the `Content-Security-Policy` header: + +```js +app.use( + helmet({ + contentSecurityPolicy: false, + }), +); +``` + +You can use this as standalone middleware with `app.use(helmet.contentSecurityPolicy())`. + +
+ +
+Cross-Origin-Embedder-Policy + +This header is not set by default. + +The `Cross-Origin-Embedder-Policy` header helps control what resources can be loaded cross-origin. See [MDN's article on this header](https://developer.cdn.mozilla.net/en-US/docs/Web/HTTP/Headers/Cross-Origin-Embedder-Policy) for more. + +```js +// Helmet does not set Cross-Origin-Embedder-Policy +// by default. +app.use(helmet()); + +// Sets "Cross-Origin-Embedder-Policy: require-corp" +app.use(helmet({ crossOriginEmbedderPolicy: true })); + +// Sets "Cross-Origin-Embedder-Policy: credentialless" +app.use(helmet({ crossOriginEmbedderPolicy: { policy: "credentialless" } })); +``` + +You can use this as standalone middleware with `app.use(helmet.crossOriginEmbedderPolicy())`. + +
+ +
+Cross-Origin-Opener-Policy + +Default: + +```http +Cross-Origin-Opener-Policy: same-origin +``` + +The `Cross-Origin-Opener-Policy` header helps process-isolate your page. For more, see [MDN's article on this header](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cross-Origin-Opener-Policy). + +```js +// Sets "Cross-Origin-Opener-Policy: same-origin" +app.use(helmet()); + +// Sets "Cross-Origin-Opener-Policy: same-origin-allow-popups" +app.use( + helmet({ + crossOriginOpenerPolicy: { policy: "same-origin-allow-popups" }, + }), +); +``` + +To disable the `Cross-Origin-Opener-Policy` header: + +```js +app.use( + helmet({ + crossOriginOpenerPolicy: false, + }), +); +``` + +You can use this as standalone middleware with `app.use(helmet.crossOriginOpenerPolicy())`. + +
+ +
+Cross-Origin-Resource-Policy + +Default: + +```http +Cross-Origin-Resource-Policy: same-origin +``` + +The `Cross-Origin-Resource-Policy` header blocks others from loading your resources cross-origin in some cases. For more, see ["Consider deploying Cross-Origin Resource Policy"](https://resourcepolicy.fyi/) and [MDN's article on this header](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cross-Origin-Resource-Policy). + +```js +// Sets "Cross-Origin-Resource-Policy: same-origin" +app.use(helmet()); + +// Sets "Cross-Origin-Resource-Policy: same-site" +app.use(helmet({ crossOriginResourcePolicy: { policy: "same-site" } })); +``` + +To disable the `Cross-Origin-Resource-Policy` header: + +```js +app.use( + helmet({ + crossOriginResourcePolicy: false, + }), +); +``` + +You can use this as standalone middleware with `app.use(helmet.crossOriginResourcePolicy())`. + +
+ +
+Origin-Agent-Cluster + +Default: + +```http +Origin-Agent-Cluster: ?1 +``` + +The `Origin-Agent-Cluster` header provides a mechanism to allow web applications to isolate their origins from other processes. Read more about it [in the spec](https://whatpr.org/html/6214/origin.html#origin-keyed-agent-clusters). + +This header takes no options and is set by default. + +```js +// Sets "Origin-Agent-Cluster: ?1" +app.use(helmet()); +``` + +To disable the `Origin-Agent-Cluster` header: + +```js +app.use( + helmet({ + originAgentCluster: false, + }), +); +``` + +You can use this as standalone middleware with `app.use(helmet.originAgentCluster())`. + +
+ +
+Referrer-Policy + +Default: + +```http +Referrer-Policy: no-referrer +``` + +The `Referrer-Policy` header which controls what information is set in [the `Referer` request header][Referer]. See ["Referer header: privacy and security concerns"](https://developer.mozilla.org/en-US/docs/Web/Security/Referer_header:_privacy_and_security_concerns) and [the header's documentation](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Referrer-Policy) on MDN for more. + +```js +// Sets "Referrer-Policy: no-referrer" +app.use(helmet()); +``` + +`policy` is a string or array of strings representing the policy. If passed as an array, it will be joined with commas, which is useful when setting [a fallback policy](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Referrer-Policy#Specifying_a_fallback_policy). It defaults to `no-referrer`. + +```js +// Sets "Referrer-Policy: no-referrer" +app.use( + helmet({ + referrerPolicy: { + policy: "no-referrer", + }, + }), +); + +// Sets "Referrer-Policy: origin,unsafe-url" +app.use( + helmet({ + referrerPolicy: { + policy: ["origin", "unsafe-url"], + }, + }), +); +``` + +To disable the `Referrer-Policy` header: + +```js +app.use( + helmet({ + referrerPolicy: false, + }), +); +``` + +You can use this as standalone middleware with `app.use(helmet.referrerPolicy())`. + +
+ +
+Strict-Transport-Security + +Default: + +```http +Strict-Transport-Security: max-age=31536000; includeSubDomains +``` + +The `Strict-Transport-Security` header tells browsers to prefer HTTPS instead of insecure HTTP. See [the documentation on MDN](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Strict-Transport-Security) for more. + +```js +// Sets "Strict-Transport-Security: max-age=31536000; includeSubDomains" +app.use(helmet()); +``` + +`maxAge` is the number of seconds browsers should remember to prefer HTTPS. If passed a non-integer, the value is rounded down. It defaults to 365 days. + +`includeSubDomains` is a boolean which dictates whether to include the `includeSubDomains` directive, which makes this policy extend to subdomains. It defaults to `true`. + +`preload` is a boolean. If true, it adds the `preload` directive, expressing intent to add your HSTS policy to browsers. See [the "Preloading Strict Transport Security" section on MDN](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Strict-Transport-Security#Preloading_Strict_Transport_Security) for more. It defaults to `false`. + +```js +// Sets "Strict-Transport-Security: max-age=123456; includeSubDomains" +app.use( + helmet({ + strictTransportSecurity: { + maxAge: 123456, + }, + }), +); + +// Sets "Strict-Transport-Security: max-age=123456" +app.use( + helmet({ + strictTransportSecurity: { + maxAge: 123456, + includeSubDomains: false, + }, + }), +); + +// Sets "Strict-Transport-Security: max-age=123456; includeSubDomains; preload" +app.use( + helmet({ + strictTransportSecurity: { + maxAge: 63072000, + preload: true, + }, + }), +); +``` + +To disable the `Strict-Transport-Security` header: + +```js +app.use( + helmet({ + strictTransportSecurity: false, + }), +); +``` + +You may wish to disable this header for local development, as it can make your browser force redirects from `http://localhost` to `https://localhost`, which may not be desirable if you develop multiple apps using `localhost`. See [this issue](https://github.com/helmetjs/helmet/issues/451) for more discussion. + +You can use this as standalone middleware with `app.use(helmet.strictTransportSecurity())`. + +
+ +
+X-Content-Type-Options + +Default: + +```http +X-Content-Type-Options: nosniff +``` + +The `X-Content-Type-Options` mitigates [MIME type sniffing](https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/MIME_types#MIME_sniffing) which can cause security issues. See [documentation for this header on MDN](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Content-Type-Options) for more. + +This header takes no options and is set by default. + +```js +// Sets "X-Content-Type-Options: nosniff" +app.use(helmet()); +``` + +To disable the `X-Content-Type-Options` header: + +```js +app.use( + helmet({ + xContentTypeOptions: false, + }), +); +``` + +You can use this as standalone middleware with `app.use(helmet.xContentTypeOptions())`. + +
+ +
+X-DNS-Prefetch-Control + +Default: + +```http +X-DNS-Prefetch-Control: off +``` + +The `X-DNS-Prefetch-Control` header helps control DNS prefetching, which can improve user privacy at the expense of performance. See [documentation on MDN](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-DNS-Prefetch-Control) for more. + +```js +// Sets "X-DNS-Prefetch-Control: off" +app.use(helmet()); +``` + +`allow` is a boolean dictating whether to enable DNS prefetching. It defaults to `false`. + +Examples: + +```js +// Sets "X-DNS-Prefetch-Control: off" +app.use( + helmet({ + xDnsPrefetchControl: { allow: false }, + }), +); + +// Sets "X-DNS-Prefetch-Control: on" +app.use( + helmet({ + xDnsPrefetchControl: { allow: true }, + }), +); +``` + +To disable the `X-DNS-Prefetch-Control` header and use the browser's default value: + +```js +app.use( + helmet({ + xDnsPrefetchControl: false, + }), +); +``` + +You can use this as standalone middleware with `app.use(helmet.xDnsPrefetchControl())`. + +
+ +
+X-Download-Options + +Default: + +```http +X-Download-Options: noopen +``` + +The `X-Download-Options` header is specific to Internet Explorer 8. It forces potentially-unsafe downloads to be saved, mitigating execution of HTML in your site's context. For more, see [this old post on MSDN](https://docs.microsoft.com/en-us/archive/blogs/ie/ie8-security-part-v-comprehensive-protection). + +This header takes no options and is set by default. + +```js +// Sets "X-Download-Options: noopen" +app.use(helmet()); +``` + +To disable the `X-Download-Options` header: + +```js +app.use( + helmet({ + xDownloadOptions: false, + }), +); +``` + +You can use this as standalone middleware with `app.use(helmet.xDownloadOptions())`. + +
+ +
+X-Frame-Options + +Default: + +```http +X-Frame-Options: SAMEORIGIN +``` + +The legacy `X-Frame-Options` header to help you mitigate [clickjacking attacks](https://en.wikipedia.org/wiki/Clickjacking). This header is superseded by [the `frame-ancestors` Content Security Policy directive](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/frame-ancestors) but is still useful on old browsers or if no CSP is used. For more, see [the documentation on MDN](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Frame-Options). + +```js +// Sets "X-Frame-Options: SAMEORIGIN" +app.use(helmet()); +``` + +`action` is a string that specifies which directive to use—either `DENY` or `SAMEORIGIN`. (A legacy directive, `ALLOW-FROM`, is not supported by Helmet. [Read more here.](https://github.com/helmetjs/helmet/wiki/How-to-use-X%E2%80%93Frame%E2%80%93Options's-%60ALLOW%E2%80%93FROM%60-directive)) It defaults to `SAMEORIGIN`. + +Examples: + +```js +// Sets "X-Frame-Options: DENY" +app.use( + helmet({ + xFrameOptions: { action: "deny" }, + }), +); + +// Sets "X-Frame-Options: SAMEORIGIN" +app.use( + helmet({ + xFrameOptions: { action: "sameorigin" }, + }), +); +``` + +To disable the `X-Frame-Options` header: + +```js +app.use( + helmet({ + xFrameOptions: false, + }), +); +``` + +You can use this as standalone middleware with `app.use(helmet.xFrameOptions())`. + +
+ +
+X-Permitted-Cross-Domain-Policies + +Default: + +```http +X-Permitted-Cross-Domain-Policies: none +``` + +The `X-Permitted-Cross-Domain-Policies` header tells some clients (mostly Adobe products) your domain's policy for loading cross-domain content. See [the description on OWASP](https://owasp.org/www-project-secure-headers/) for more. + +```js +// Sets "X-Permitted-Cross-Domain-Policies: none" +app.use(helmet()); +``` + +`permittedPolicies` is a string that must be `"none"`, `"master-only"`, `"by-content-type"`, or `"all"`. It defaults to `"none"`. + +Examples: + +```js +// Sets "X-Permitted-Cross-Domain-Policies: none" +app.use( + helmet({ + xPermittedCrossDomainPolicies: { + permittedPolicies: "none", + }, + }), +); + +// Sets "X-Permitted-Cross-Domain-Policies: by-content-type" +app.use( + helmet({ + xPermittedCrossDomainPolicies: { + permittedPolicies: "by-content-type", + }, + }), +); +``` + +To disable the `X-Permitted-Cross-Domain-Policies` header: + +```js +app.use( + helmet({ + xPermittedCrossDomainPolicies: false, + }), +); +``` + +You can use this as standalone middleware with `app.use(helmet.xPermittedCrossDomainPolicies())`. + +
+ +
+X-Powered-By + +Default: the `X-Powered-By` header, if present, is removed. + +Helmet removes the `X-Powered-By` header, which is set by default in Express and some other frameworks. Removing the header offers very limited security benefits (see [this discussion](https://github.com/expressjs/express/pull/2813#issuecomment-159270428)) and is mostly removed to save bandwidth, but may thwart simplistic attackers. + +Note: [Express has a built-in way to disable the `X-Powered-By` header](https://stackoverflow.com/a/12484642/804100), which you may wish to use instead. + +The removal of this header takes no options. The header is removed by default. + +To disable this behavior: + +```js +// Not required, but recommended for Express users: +app.disable("x-powered-by"); + +// Ask Helmet to ignore the X-Powered-By header. +app.use( + helmet({ + xPoweredBy: false, + }), +); +``` + +You can use this as standalone middleware with `app.use(helmet.xPoweredBy())`. + +
+ +
+X-XSS-Protection + +Default: + +```http +X-XSS-Protection: 0 +``` + +Helmet disables browsers' buggy cross-site scripting filter by setting the legacy `X-XSS-Protection` header to `0`. See [discussion about disabling the header here](https://github.com/helmetjs/helmet/issues/230) and [documentation on MDN](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-XSS-Protection). + +This header takes no options and is set by default. + +To disable the `X-XSS-Protection` header: + +```js +// This is not recommended. +app.use( + helmet({ + xXssProtection: false, + }), +); +``` + +You can use this as standalone middleware with `app.use(helmet.xXssProtection())`. + +
+ +[Referer]: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Referer +[MIME sniffing]: https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/MIME_types#mime_sniffing +[Clickjacking]: https://en.wikipedia.org/wiki/Clickjacking +[XSS]: https://developer.mozilla.org/en-US/docs/Glossary/Cross-site_scripting diff --git a/node_modules/helmet/SECURITY.md b/node_modules/helmet/SECURITY.md new file mode 100644 index 00000000..406d4992 --- /dev/null +++ b/node_modules/helmet/SECURITY.md @@ -0,0 +1,7 @@ +# Security issue reporting & disclosure process + +If you feel you have found a security issue or concern with Helmet, please reach out to the maintainers. + +Contact Evan Hahn at or Adam Baldwin at . Evan Hahn [can also be reached in other ways](https://evanhahn.com/contact). + +We will try to communicate in a timely manner and address your concerns. diff --git a/node_modules/helmet/index.cjs b/node_modules/helmet/index.cjs new file mode 100644 index 00000000..7bff9fa4 --- /dev/null +++ b/node_modules/helmet/index.cjs @@ -0,0 +1,588 @@ +"use strict" + +Object.defineProperties(exports, {__esModule: {value: true}, [Symbol.toStringTag]: {value: "Module"}}) + +const dangerouslyDisableDefaultSrc = Symbol("dangerouslyDisableDefaultSrc") +const SHOULD_BE_QUOTED = new Set(["none", "self", "strict-dynamic", "report-sample", "inline-speculation-rules", "unsafe-inline", "unsafe-eval", "unsafe-hashes", "wasm-unsafe-eval"]) +const getDefaultDirectives = () => ({ + "default-src": ["'self'"], + "base-uri": ["'self'"], + "font-src": ["'self'", "https:", "data:"], + "form-action": ["'self'"], + "frame-ancestors": ["'self'"], + "img-src": ["'self'", "data:"], + "object-src": ["'none'"], + "script-src": ["'self'"], + "script-src-attr": ["'none'"], + "style-src": ["'self'", "https:", "'unsafe-inline'"], + "upgrade-insecure-requests": [] +}) +const dashify = str => str.replace(/[A-Z]/g, capitalLetter => "-" + capitalLetter.toLowerCase()) +const assertDirectiveValueIsValid = (directiveName, directiveValue) => { + if (/;|,/.test(directiveValue)) { + throw new Error(`Content-Security-Policy received an invalid directive value for ${JSON.stringify(directiveName)}`) + } +} +const assertDirectiveValueEntryIsValid = (directiveName, directiveValueEntry) => { + if (SHOULD_BE_QUOTED.has(directiveValueEntry) || directiveValueEntry.startsWith("nonce-") || directiveValueEntry.startsWith("sha256-") || directiveValueEntry.startsWith("sha384-") || directiveValueEntry.startsWith("sha512-")) { + throw new Error(`Content-Security-Policy received an invalid directive value for ${JSON.stringify(directiveName)}. ${JSON.stringify(directiveValueEntry)} should be quoted`) + } +} +function normalizeDirectives(options) { + const defaultDirectives = getDefaultDirectives() + const {useDefaults = true, directives: rawDirectives = defaultDirectives} = options + const result = new Map() + const directiveNamesSeen = new Set() + const directivesExplicitlyDisabled = new Set() + for (const rawDirectiveName in rawDirectives) { + if (!Object.hasOwn(rawDirectives, rawDirectiveName)) { + continue + } + if (rawDirectiveName.length === 0 || /[^a-zA-Z0-9-]/.test(rawDirectiveName)) { + throw new Error(`Content-Security-Policy received an invalid directive name ${JSON.stringify(rawDirectiveName)}`) + } + const directiveName = dashify(rawDirectiveName) + if (directiveNamesSeen.has(directiveName)) { + throw new Error(`Content-Security-Policy received a duplicate directive ${JSON.stringify(directiveName)}`) + } + directiveNamesSeen.add(directiveName) + const rawDirectiveValue = rawDirectives[rawDirectiveName] + let directiveValue + if (rawDirectiveValue === null) { + if (directiveName === "default-src") { + throw new Error("Content-Security-Policy needs a default-src but it was set to `null`. If you really want to disable it, set it to `contentSecurityPolicy.dangerouslyDisableDefaultSrc`.") + } + directivesExplicitlyDisabled.add(directiveName) + continue + } else if (typeof rawDirectiveValue === "string") { + directiveValue = [rawDirectiveValue] + } else if (!rawDirectiveValue) { + throw new Error(`Content-Security-Policy received an invalid directive value for ${JSON.stringify(directiveName)}`) + } else if (rawDirectiveValue === dangerouslyDisableDefaultSrc) { + if (directiveName === "default-src") { + directivesExplicitlyDisabled.add("default-src") + continue + } else { + throw new Error(`Content-Security-Policy: tried to disable ${JSON.stringify(directiveName)} as if it were default-src; simply omit the key`) + } + } else { + directiveValue = rawDirectiveValue + } + for (const element of directiveValue) { + if (typeof element !== "string") continue + assertDirectiveValueIsValid(directiveName, element) + assertDirectiveValueEntryIsValid(directiveName, element) + } + result.set(directiveName, directiveValue) + } + if (useDefaults) { + Object.entries(defaultDirectives).forEach(([defaultDirectiveName, defaultDirectiveValue]) => { + if (!result.has(defaultDirectiveName) && !directivesExplicitlyDisabled.has(defaultDirectiveName)) { + result.set(defaultDirectiveName, defaultDirectiveValue) + } + }) + } + if (!result.size) { + throw new Error("Content-Security-Policy has no directives. Either set some or disable the header") + } + if (!result.has("default-src") && !directivesExplicitlyDisabled.has("default-src")) { + throw new Error("Content-Security-Policy needs a default-src but none was provided. If you really want to disable it, set it to `contentSecurityPolicy.dangerouslyDisableDefaultSrc`.") + } + return result +} +function getHeaderValue(req, res, normalizedDirectives) { + const result = [] + for (const [directiveName, rawDirectiveValue] of normalizedDirectives) { + let directiveValue = "" + for (const element of rawDirectiveValue) { + if (typeof element === "function") { + const newElement = element(req, res) + assertDirectiveValueEntryIsValid(directiveName, newElement) + directiveValue += " " + newElement + } else { + directiveValue += " " + element + } + } + if (directiveValue) { + assertDirectiveValueIsValid(directiveName, directiveValue) + result.push(`${directiveName}${directiveValue}`) + } else { + result.push(directiveName) + } + } + return result.join(";") +} +const contentSecurityPolicy = function contentSecurityPolicy(options = {}) { + const headerName = options.reportOnly ? "Content-Security-Policy-Report-Only" : "Content-Security-Policy" + const normalizedDirectives = normalizeDirectives(options) + return function contentSecurityPolicyMiddleware(req, res, next) { + const result = getHeaderValue(req, res, normalizedDirectives) + if (result instanceof Error) { + next(result) + } else { + res.setHeader(headerName, result) + next() + } + } +} +contentSecurityPolicy.getDefaultDirectives = getDefaultDirectives +contentSecurityPolicy.dangerouslyDisableDefaultSrc = dangerouslyDisableDefaultSrc + +const ALLOWED_POLICIES$2 = new Set(["require-corp", "credentialless", "unsafe-none"]) +function getHeaderValueFromOptions$6({policy = "require-corp"}) { + if (ALLOWED_POLICIES$2.has(policy)) { + return policy + } else { + throw new Error(`Cross-Origin-Embedder-Policy does not support the ${JSON.stringify(policy)} policy`) + } +} +function crossOriginEmbedderPolicy(options = {}) { + const headerValue = getHeaderValueFromOptions$6(options) + return function crossOriginEmbedderPolicyMiddleware(_req, res, next) { + res.setHeader("Cross-Origin-Embedder-Policy", headerValue) + next() + } +} + +const ALLOWED_POLICIES$1 = new Set(["same-origin", "same-origin-allow-popups", "unsafe-none"]) +function getHeaderValueFromOptions$5({policy = "same-origin"}) { + if (ALLOWED_POLICIES$1.has(policy)) { + return policy + } else { + throw new Error(`Cross-Origin-Opener-Policy does not support the ${JSON.stringify(policy)} policy`) + } +} +function crossOriginOpenerPolicy(options = {}) { + const headerValue = getHeaderValueFromOptions$5(options) + return function crossOriginOpenerPolicyMiddleware(_req, res, next) { + res.setHeader("Cross-Origin-Opener-Policy", headerValue) + next() + } +} + +const ALLOWED_POLICIES = new Set(["same-origin", "same-site", "cross-origin"]) +function getHeaderValueFromOptions$4({policy = "same-origin"}) { + if (ALLOWED_POLICIES.has(policy)) { + return policy + } else { + throw new Error(`Cross-Origin-Resource-Policy does not support the ${JSON.stringify(policy)} policy`) + } +} +function crossOriginResourcePolicy(options = {}) { + const headerValue = getHeaderValueFromOptions$4(options) + return function crossOriginResourcePolicyMiddleware(_req, res, next) { + res.setHeader("Cross-Origin-Resource-Policy", headerValue) + next() + } +} + +function originAgentCluster() { + return function originAgentClusterMiddleware(_req, res, next) { + res.setHeader("Origin-Agent-Cluster", "?1") + next() + } +} + +const ALLOWED_TOKENS = new Set(["no-referrer", "no-referrer-when-downgrade", "same-origin", "origin", "strict-origin", "origin-when-cross-origin", "strict-origin-when-cross-origin", "unsafe-url", ""]) +function getHeaderValueFromOptions$3({policy = ["no-referrer"]}) { + const tokens = typeof policy === "string" ? [policy] : policy + if (tokens.length === 0) { + throw new Error("Referrer-Policy received no policy tokens") + } + const tokensSeen = new Set() + tokens.forEach(token => { + if (!ALLOWED_TOKENS.has(token)) { + throw new Error(`Referrer-Policy received an unexpected policy token ${JSON.stringify(token)}`) + } else if (tokensSeen.has(token)) { + throw new Error(`Referrer-Policy received a duplicate policy token ${JSON.stringify(token)}`) + } + tokensSeen.add(token) + }) + return tokens.join(",") +} +function referrerPolicy(options = {}) { + const headerValue = getHeaderValueFromOptions$3(options) + return function referrerPolicyMiddleware(_req, res, next) { + res.setHeader("Referrer-Policy", headerValue) + next() + } +} + +const DEFAULT_MAX_AGE = 365 * 24 * 60 * 60 +function parseMaxAge(value = DEFAULT_MAX_AGE) { + if (value >= 0 && Number.isFinite(value)) { + return Math.floor(value) + } else { + throw new Error(`Strict-Transport-Security: ${JSON.stringify(value)} is not a valid value for maxAge. Please choose a positive integer.`) + } +} +function getHeaderValueFromOptions$2(options) { + if ("maxage" in options) { + throw new Error("Strict-Transport-Security received an unsupported property, `maxage`. Did you mean to pass `maxAge`?") + } + if ("includeSubdomains" in options) { + throw new Error('Strict-Transport-Security middleware should use `includeSubDomains` instead of `includeSubdomains`. (The correct one has an uppercase "D".)') + } + const directives = [`max-age=${parseMaxAge(options.maxAge)}`] + if (options.includeSubDomains === undefined || options.includeSubDomains) { + directives.push("includeSubDomains") + } + if (options.preload) { + directives.push("preload") + } + return directives.join("; ") +} +function strictTransportSecurity(options = {}) { + const headerValue = getHeaderValueFromOptions$2(options) + return function strictTransportSecurityMiddleware(_req, res, next) { + res.setHeader("Strict-Transport-Security", headerValue) + next() + } +} + +function xContentTypeOptions() { + return function xContentTypeOptionsMiddleware(_req, res, next) { + res.setHeader("X-Content-Type-Options", "nosniff") + next() + } +} + +function xDnsPrefetchControl(options = {}) { + const headerValue = options.allow ? "on" : "off" + return function xDnsPrefetchControlMiddleware(_req, res, next) { + res.setHeader("X-DNS-Prefetch-Control", headerValue) + next() + } +} + +function xDownloadOptions() { + return function xDownloadOptionsMiddleware(_req, res, next) { + res.setHeader("X-Download-Options", "noopen") + next() + } +} + +function getHeaderValueFromOptions$1({action = "sameorigin"}) { + const normalizedAction = typeof action === "string" ? action.toUpperCase() : action + switch (normalizedAction) { + case "SAME-ORIGIN": + return "SAMEORIGIN" + case "DENY": + case "SAMEORIGIN": + return normalizedAction + default: + throw new Error(`X-Frame-Options received an invalid action ${JSON.stringify(action)}`) + } +} +function xFrameOptions(options = {}) { + const headerValue = getHeaderValueFromOptions$1(options) + return function xFrameOptionsMiddleware(_req, res, next) { + res.setHeader("X-Frame-Options", headerValue) + next() + } +} + +const ALLOWED_PERMITTED_POLICIES = new Set(["none", "master-only", "by-content-type", "all"]) +function getHeaderValueFromOptions({permittedPolicies = "none"}) { + if (ALLOWED_PERMITTED_POLICIES.has(permittedPolicies)) { + return permittedPolicies + } else { + throw new Error(`X-Permitted-Cross-Domain-Policies does not support ${JSON.stringify(permittedPolicies)}`) + } +} +function xPermittedCrossDomainPolicies(options = {}) { + const headerValue = getHeaderValueFromOptions(options) + return function xPermittedCrossDomainPoliciesMiddleware(_req, res, next) { + res.setHeader("X-Permitted-Cross-Domain-Policies", headerValue) + next() + } +} + +function xPoweredBy() { + return function xPoweredByMiddleware(_req, res, next) { + res.removeHeader("X-Powered-By") + next() + } +} + +function xXssProtection() { + return function xXssProtectionMiddleware(_req, res, next) { + res.setHeader("X-XSS-Protection", "0") + next() + } +} + +function getMiddlewareFunctionsFromOptions(options) { + const result = [] + switch (options.contentSecurityPolicy) { + case undefined: + case true: + result.push(contentSecurityPolicy()) + break + case false: + break + default: + result.push(contentSecurityPolicy(options.contentSecurityPolicy)) + break + } + switch (options.crossOriginEmbedderPolicy) { + case undefined: + case false: + break + case true: + result.push(crossOriginEmbedderPolicy()) + break + default: + result.push(crossOriginEmbedderPolicy(options.crossOriginEmbedderPolicy)) + break + } + switch (options.crossOriginOpenerPolicy) { + case undefined: + case true: + result.push(crossOriginOpenerPolicy()) + break + case false: + break + default: + result.push(crossOriginOpenerPolicy(options.crossOriginOpenerPolicy)) + break + } + switch (options.crossOriginResourcePolicy) { + case undefined: + case true: + result.push(crossOriginResourcePolicy()) + break + case false: + break + default: + result.push(crossOriginResourcePolicy(options.crossOriginResourcePolicy)) + break + } + switch (options.originAgentCluster) { + case undefined: + case true: + result.push(originAgentCluster()) + break + case false: + break + default: + console.warn("Origin-Agent-Cluster does not take options. Remove the property to silence this warning.") + result.push(originAgentCluster()) + break + } + switch (options.referrerPolicy) { + case undefined: + case true: + result.push(referrerPolicy()) + break + case false: + break + default: + result.push(referrerPolicy(options.referrerPolicy)) + break + } + if ("strictTransportSecurity" in options && "hsts" in options) { + throw new Error("Strict-Transport-Security option was specified twice. Remove `hsts` to silence this warning.") + } + const strictTransportSecurityOption = options.strictTransportSecurity ?? options.hsts + switch (strictTransportSecurityOption) { + case undefined: + case true: + result.push(strictTransportSecurity()) + break + case false: + break + default: + result.push(strictTransportSecurity(strictTransportSecurityOption)) + break + } + if ("xContentTypeOptions" in options && "noSniff" in options) { + throw new Error("X-Content-Type-Options option was specified twice. Remove `noSniff` to silence this warning.") + } + const xContentTypeOptionsOption = options.xContentTypeOptions ?? options.noSniff + switch (xContentTypeOptionsOption) { + case undefined: + case true: + result.push(xContentTypeOptions()) + break + case false: + break + default: + console.warn("X-Content-Type-Options does not take options. Remove the property to silence this warning.") + result.push(xContentTypeOptions()) + break + } + if ("xDnsPrefetchControl" in options && "dnsPrefetchControl" in options) { + throw new Error("X-DNS-Prefetch-Control option was specified twice. Remove `dnsPrefetchControl` to silence this warning.") + } + const xDnsPrefetchControlOption = options.xDnsPrefetchControl ?? options.dnsPrefetchControl + switch (xDnsPrefetchControlOption) { + case undefined: + case true: + result.push(xDnsPrefetchControl()) + break + case false: + break + default: + result.push(xDnsPrefetchControl(xDnsPrefetchControlOption)) + break + } + if ("xDownloadOptions" in options && "ieNoOpen" in options) { + throw new Error("X-Download-Options option was specified twice. Remove `ieNoOpen` to silence this warning.") + } + const xDownloadOptionsOption = options.xDownloadOptions ?? options.ieNoOpen + switch (xDownloadOptionsOption) { + case undefined: + case true: + result.push(xDownloadOptions()) + break + case false: + break + default: + console.warn("X-Download-Options does not take options. Remove the property to silence this warning.") + result.push(xDownloadOptions()) + break + } + if ("xFrameOptions" in options && "frameguard" in options) { + throw new Error("X-Frame-Options option was specified twice. Remove `frameguard` to silence this warning.") + } + const xFrameOptionsOption = options.xFrameOptions ?? options.frameguard + switch (xFrameOptionsOption) { + case undefined: + case true: + result.push(xFrameOptions()) + break + case false: + break + default: + result.push(xFrameOptions(xFrameOptionsOption)) + break + } + if ("xPermittedCrossDomainPolicies" in options && "permittedCrossDomainPolicies" in options) { + throw new Error("X-Permitted-Cross-Domain-Policies option was specified twice. Remove `permittedCrossDomainPolicies` to silence this warning.") + } + const xPermittedCrossDomainPoliciesOption = options.xPermittedCrossDomainPolicies ?? options.permittedCrossDomainPolicies + switch (xPermittedCrossDomainPoliciesOption) { + case undefined: + case true: + result.push(xPermittedCrossDomainPolicies()) + break + case false: + break + default: + result.push(xPermittedCrossDomainPolicies(xPermittedCrossDomainPoliciesOption)) + break + } + if ("xPoweredBy" in options && "hidePoweredBy" in options) { + throw new Error("X-Powered-By option was specified twice. Remove `hidePoweredBy` to silence this warning.") + } + const xPoweredByOption = options.xPoweredBy ?? options.hidePoweredBy + switch (xPoweredByOption) { + case undefined: + case true: + result.push(xPoweredBy()) + break + case false: + break + default: + console.warn("X-Powered-By does not take options. Remove the property to silence this warning.") + result.push(xPoweredBy()) + break + } + if ("xXssProtection" in options && "xssFilter" in options) { + throw new Error("X-XSS-Protection option was specified twice. Remove `xssFilter` to silence this warning.") + } + const xXssProtectionOption = options.xXssProtection ?? options.xssFilter + switch (xXssProtectionOption) { + case undefined: + case true: + result.push(xXssProtection()) + break + case false: + break + default: + console.warn("X-XSS-Protection does not take options. Remove the property to silence this warning.") + result.push(xXssProtection()) + break + } + return result +} +const helmet = Object.assign( + function helmet(options = {}) { + // People should be able to pass an options object with no prototype, + // so we want this optional chaining. + // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition + if (options.constructor?.name === "IncomingMessage") { + throw new Error("It appears you have done something like `app.use(helmet)`, but it should be `app.use(helmet())`.") + } + const middlewareFunctions = getMiddlewareFunctionsFromOptions(options) + return function helmetMiddleware(req, res, next) { + let middlewareIndex = 0 + ;(function internalNext(err) { + if (err) { + next(err) + return + } + const middlewareFunction = middlewareFunctions[middlewareIndex] + if (middlewareFunction) { + middlewareIndex++ + middlewareFunction(req, res, internalNext) + } else { + next() + } + })() + } + }, + { + contentSecurityPolicy, + crossOriginEmbedderPolicy, + crossOriginOpenerPolicy, + crossOriginResourcePolicy, + originAgentCluster, + referrerPolicy, + strictTransportSecurity, + xContentTypeOptions, + xDnsPrefetchControl, + xDownloadOptions, + xFrameOptions, + xPermittedCrossDomainPolicies, + xPoweredBy, + xXssProtection, + // Legacy aliases + dnsPrefetchControl: xDnsPrefetchControl, + xssFilter: xXssProtection, + permittedCrossDomainPolicies: xPermittedCrossDomainPolicies, + ieNoOpen: xDownloadOptions, + noSniff: xContentTypeOptions, + frameguard: xFrameOptions, + hidePoweredBy: xPoweredBy, + hsts: strictTransportSecurity + } +) + +exports.contentSecurityPolicy = contentSecurityPolicy +exports.crossOriginEmbedderPolicy = crossOriginEmbedderPolicy +exports.crossOriginOpenerPolicy = crossOriginOpenerPolicy +exports.crossOriginResourcePolicy = crossOriginResourcePolicy +exports.default = helmet +exports.dnsPrefetchControl = xDnsPrefetchControl +exports.frameguard = xFrameOptions +exports.hidePoweredBy = xPoweredBy +exports.hsts = strictTransportSecurity +exports.ieNoOpen = xDownloadOptions +exports.noSniff = xContentTypeOptions +exports.originAgentCluster = originAgentCluster +exports.permittedCrossDomainPolicies = xPermittedCrossDomainPolicies +exports.referrerPolicy = referrerPolicy +exports.strictTransportSecurity = strictTransportSecurity +exports.xContentTypeOptions = xContentTypeOptions +exports.xDnsPrefetchControl = xDnsPrefetchControl +exports.xDownloadOptions = xDownloadOptions +exports.xFrameOptions = xFrameOptions +exports.xPermittedCrossDomainPolicies = xPermittedCrossDomainPolicies +exports.xPoweredBy = xPoweredBy +exports.xXssProtection = xXssProtection +exports.xssFilter = xXssProtection + +module.exports = exports.default +module.exports.default = module.exports diff --git a/node_modules/helmet/index.d.cts b/node_modules/helmet/index.d.cts new file mode 100644 index 00000000..2ad47b43 --- /dev/null +++ b/node_modules/helmet/index.d.cts @@ -0,0 +1,186 @@ +import {IncomingMessage, ServerResponse} from "node:http" + +type ContentSecurityPolicyDirectiveValueFunction = (req: IncomingMessage, res: ServerResponse) => string +type ContentSecurityPolicyDirectiveValue = string | ContentSecurityPolicyDirectiveValueFunction +interface ContentSecurityPolicyOptions { + useDefaults?: boolean + directives?: Record | typeof dangerouslyDisableDefaultSrc> + reportOnly?: boolean +} +interface ContentSecurityPolicy { + (options?: Readonly): (req: IncomingMessage, res: ServerResponse, next: (err?: Error) => void) => void + getDefaultDirectives: typeof getDefaultDirectives + dangerouslyDisableDefaultSrc: typeof dangerouslyDisableDefaultSrc +} +declare const dangerouslyDisableDefaultSrc: unique symbol +declare const getDefaultDirectives: () => Record> +declare const contentSecurityPolicy: ContentSecurityPolicy + +interface CrossOriginEmbedderPolicyOptions { + policy?: "require-corp" | "credentialless" | "unsafe-none" +} +declare function crossOriginEmbedderPolicy(options?: Readonly): (_req: IncomingMessage, res: ServerResponse, next: () => void) => void + +interface CrossOriginOpenerPolicyOptions { + policy?: "same-origin" | "same-origin-allow-popups" | "unsafe-none" +} +declare function crossOriginOpenerPolicy(options?: Readonly): (_req: IncomingMessage, res: ServerResponse, next: () => void) => void + +interface CrossOriginResourcePolicyOptions { + policy?: "same-origin" | "same-site" | "cross-origin" +} +declare function crossOriginResourcePolicy(options?: Readonly): (_req: IncomingMessage, res: ServerResponse, next: () => void) => void + +declare function originAgentCluster(): (_req: IncomingMessage, res: ServerResponse, next: () => void) => void + +type ReferrerPolicyToken = "no-referrer" | "no-referrer-when-downgrade" | "same-origin" | "origin" | "strict-origin" | "origin-when-cross-origin" | "strict-origin-when-cross-origin" | "unsafe-url" | "" +interface ReferrerPolicyOptions { + policy?: ReferrerPolicyToken | ReferrerPolicyToken[] +} +declare function referrerPolicy(options?: Readonly): (_req: IncomingMessage, res: ServerResponse, next: () => void) => void + +interface StrictTransportSecurityOptions { + maxAge?: number + includeSubDomains?: boolean + preload?: boolean +} +declare function strictTransportSecurity(options?: Readonly): (_req: IncomingMessage, res: ServerResponse, next: () => void) => void + +declare function xContentTypeOptions(): (_req: IncomingMessage, res: ServerResponse, next: () => void) => void + +interface XDnsPrefetchControlOptions { + allow?: boolean +} +declare function xDnsPrefetchControl(options?: Readonly): (_req: IncomingMessage, res: ServerResponse, next: () => void) => void + +declare function xDownloadOptions(): (_req: IncomingMessage, res: ServerResponse, next: () => void) => void + +interface XFrameOptionsOptions { + action?: "deny" | "sameorigin" +} +declare function xFrameOptions(options?: Readonly): (_req: IncomingMessage, res: ServerResponse, next: () => void) => void + +interface XPermittedCrossDomainPoliciesOptions { + permittedPolicies?: "none" | "master-only" | "by-content-type" | "all" +} +declare function xPermittedCrossDomainPolicies(options?: Readonly): (_req: IncomingMessage, res: ServerResponse, next: () => void) => void + +declare function xPoweredBy(): (_req: IncomingMessage, res: ServerResponse, next: () => void) => void + +declare function xXssProtection(): (_req: IncomingMessage, res: ServerResponse, next: () => void) => void + +type HelmetOptions = { + contentSecurityPolicy?: ContentSecurityPolicyOptions | boolean + crossOriginEmbedderPolicy?: CrossOriginEmbedderPolicyOptions | boolean + crossOriginOpenerPolicy?: CrossOriginOpenerPolicyOptions | boolean + crossOriginResourcePolicy?: CrossOriginResourcePolicyOptions | boolean + originAgentCluster?: boolean + referrerPolicy?: ReferrerPolicyOptions | boolean +} & ( + | { + strictTransportSecurity?: StrictTransportSecurityOptions | boolean + hsts?: never + } + | { + hsts?: StrictTransportSecurityOptions | boolean + strictTransportSecurity?: never + } +) & + ( + | { + xContentTypeOptions?: boolean + noSniff?: never + } + | { + noSniff?: boolean + xContentTypeOptions?: never + } + ) & + ( + | { + xDnsPrefetchControl?: XDnsPrefetchControlOptions | boolean + dnsPrefetchControl?: never + } + | { + dnsPrefetchControl?: XDnsPrefetchControlOptions | boolean + xDnsPrefetchControl?: never + } + ) & + ( + | { + xDownloadOptions?: boolean + ieNoOpen?: never + } + | { + ieNoOpen?: boolean + xDownloadOptions?: never + } + ) & + ( + | { + xFrameOptions?: XFrameOptionsOptions | boolean + frameguard?: never + } + | { + frameguard?: XFrameOptionsOptions | boolean + xFrameOptions?: never + } + ) & + ( + | { + xPermittedCrossDomainPolicies?: XPermittedCrossDomainPoliciesOptions | boolean + permittedCrossDomainPolicies?: never + } + | { + permittedCrossDomainPolicies?: XPermittedCrossDomainPoliciesOptions | boolean + xPermittedCrossDomainPolicies?: never + } + ) & + ( + | { + xPoweredBy?: boolean + hidePoweredBy?: never + } + | { + hidePoweredBy?: boolean + xPoweredBy?: never + } + ) & + ( + | { + xXssProtection?: boolean + xssFilter?: never + } + | { + xssFilter?: boolean + xXssProtection?: never + } + ) +interface Helmet { + (options?: Readonly): (req: IncomingMessage, res: ServerResponse, next: (err?: unknown) => void) => void + contentSecurityPolicy: typeof contentSecurityPolicy + crossOriginEmbedderPolicy: typeof crossOriginEmbedderPolicy + crossOriginOpenerPolicy: typeof crossOriginOpenerPolicy + crossOriginResourcePolicy: typeof crossOriginResourcePolicy + originAgentCluster: typeof originAgentCluster + referrerPolicy: typeof referrerPolicy + strictTransportSecurity: typeof strictTransportSecurity + xContentTypeOptions: typeof xContentTypeOptions + xDnsPrefetchControl: typeof xDnsPrefetchControl + xDownloadOptions: typeof xDownloadOptions + xFrameOptions: typeof xFrameOptions + xPermittedCrossDomainPolicies: typeof xPermittedCrossDomainPolicies + xPoweredBy: typeof xPoweredBy + xXssProtection: typeof xXssProtection + dnsPrefetchControl: typeof xDnsPrefetchControl + frameguard: typeof xFrameOptions + hidePoweredBy: typeof xPoweredBy + hsts: typeof strictTransportSecurity + ieNoOpen: typeof xDownloadOptions + noSniff: typeof xContentTypeOptions + permittedCrossDomainPolicies: typeof xPermittedCrossDomainPolicies + xssFilter: typeof xXssProtection +} +declare const helmet: Helmet + +export {type HelmetOptions, contentSecurityPolicy, crossOriginEmbedderPolicy, crossOriginOpenerPolicy, crossOriginResourcePolicy, helmet as default, xDnsPrefetchControl as dnsPrefetchControl, xFrameOptions as frameguard, xPoweredBy as hidePoweredBy, strictTransportSecurity as hsts, xDownloadOptions as ieNoOpen, xContentTypeOptions as noSniff, originAgentCluster, xPermittedCrossDomainPolicies as permittedCrossDomainPolicies, referrerPolicy, strictTransportSecurity, xContentTypeOptions, xDnsPrefetchControl, xDownloadOptions, xFrameOptions, xPermittedCrossDomainPolicies, xPoweredBy, xXssProtection, xXssProtection as xssFilter} diff --git a/node_modules/helmet/index.d.mts b/node_modules/helmet/index.d.mts new file mode 100644 index 00000000..2ad47b43 --- /dev/null +++ b/node_modules/helmet/index.d.mts @@ -0,0 +1,186 @@ +import {IncomingMessage, ServerResponse} from "node:http" + +type ContentSecurityPolicyDirectiveValueFunction = (req: IncomingMessage, res: ServerResponse) => string +type ContentSecurityPolicyDirectiveValue = string | ContentSecurityPolicyDirectiveValueFunction +interface ContentSecurityPolicyOptions { + useDefaults?: boolean + directives?: Record | typeof dangerouslyDisableDefaultSrc> + reportOnly?: boolean +} +interface ContentSecurityPolicy { + (options?: Readonly): (req: IncomingMessage, res: ServerResponse, next: (err?: Error) => void) => void + getDefaultDirectives: typeof getDefaultDirectives + dangerouslyDisableDefaultSrc: typeof dangerouslyDisableDefaultSrc +} +declare const dangerouslyDisableDefaultSrc: unique symbol +declare const getDefaultDirectives: () => Record> +declare const contentSecurityPolicy: ContentSecurityPolicy + +interface CrossOriginEmbedderPolicyOptions { + policy?: "require-corp" | "credentialless" | "unsafe-none" +} +declare function crossOriginEmbedderPolicy(options?: Readonly): (_req: IncomingMessage, res: ServerResponse, next: () => void) => void + +interface CrossOriginOpenerPolicyOptions { + policy?: "same-origin" | "same-origin-allow-popups" | "unsafe-none" +} +declare function crossOriginOpenerPolicy(options?: Readonly): (_req: IncomingMessage, res: ServerResponse, next: () => void) => void + +interface CrossOriginResourcePolicyOptions { + policy?: "same-origin" | "same-site" | "cross-origin" +} +declare function crossOriginResourcePolicy(options?: Readonly): (_req: IncomingMessage, res: ServerResponse, next: () => void) => void + +declare function originAgentCluster(): (_req: IncomingMessage, res: ServerResponse, next: () => void) => void + +type ReferrerPolicyToken = "no-referrer" | "no-referrer-when-downgrade" | "same-origin" | "origin" | "strict-origin" | "origin-when-cross-origin" | "strict-origin-when-cross-origin" | "unsafe-url" | "" +interface ReferrerPolicyOptions { + policy?: ReferrerPolicyToken | ReferrerPolicyToken[] +} +declare function referrerPolicy(options?: Readonly): (_req: IncomingMessage, res: ServerResponse, next: () => void) => void + +interface StrictTransportSecurityOptions { + maxAge?: number + includeSubDomains?: boolean + preload?: boolean +} +declare function strictTransportSecurity(options?: Readonly): (_req: IncomingMessage, res: ServerResponse, next: () => void) => void + +declare function xContentTypeOptions(): (_req: IncomingMessage, res: ServerResponse, next: () => void) => void + +interface XDnsPrefetchControlOptions { + allow?: boolean +} +declare function xDnsPrefetchControl(options?: Readonly): (_req: IncomingMessage, res: ServerResponse, next: () => void) => void + +declare function xDownloadOptions(): (_req: IncomingMessage, res: ServerResponse, next: () => void) => void + +interface XFrameOptionsOptions { + action?: "deny" | "sameorigin" +} +declare function xFrameOptions(options?: Readonly): (_req: IncomingMessage, res: ServerResponse, next: () => void) => void + +interface XPermittedCrossDomainPoliciesOptions { + permittedPolicies?: "none" | "master-only" | "by-content-type" | "all" +} +declare function xPermittedCrossDomainPolicies(options?: Readonly): (_req: IncomingMessage, res: ServerResponse, next: () => void) => void + +declare function xPoweredBy(): (_req: IncomingMessage, res: ServerResponse, next: () => void) => void + +declare function xXssProtection(): (_req: IncomingMessage, res: ServerResponse, next: () => void) => void + +type HelmetOptions = { + contentSecurityPolicy?: ContentSecurityPolicyOptions | boolean + crossOriginEmbedderPolicy?: CrossOriginEmbedderPolicyOptions | boolean + crossOriginOpenerPolicy?: CrossOriginOpenerPolicyOptions | boolean + crossOriginResourcePolicy?: CrossOriginResourcePolicyOptions | boolean + originAgentCluster?: boolean + referrerPolicy?: ReferrerPolicyOptions | boolean +} & ( + | { + strictTransportSecurity?: StrictTransportSecurityOptions | boolean + hsts?: never + } + | { + hsts?: StrictTransportSecurityOptions | boolean + strictTransportSecurity?: never + } +) & + ( + | { + xContentTypeOptions?: boolean + noSniff?: never + } + | { + noSniff?: boolean + xContentTypeOptions?: never + } + ) & + ( + | { + xDnsPrefetchControl?: XDnsPrefetchControlOptions | boolean + dnsPrefetchControl?: never + } + | { + dnsPrefetchControl?: XDnsPrefetchControlOptions | boolean + xDnsPrefetchControl?: never + } + ) & + ( + | { + xDownloadOptions?: boolean + ieNoOpen?: never + } + | { + ieNoOpen?: boolean + xDownloadOptions?: never + } + ) & + ( + | { + xFrameOptions?: XFrameOptionsOptions | boolean + frameguard?: never + } + | { + frameguard?: XFrameOptionsOptions | boolean + xFrameOptions?: never + } + ) & + ( + | { + xPermittedCrossDomainPolicies?: XPermittedCrossDomainPoliciesOptions | boolean + permittedCrossDomainPolicies?: never + } + | { + permittedCrossDomainPolicies?: XPermittedCrossDomainPoliciesOptions | boolean + xPermittedCrossDomainPolicies?: never + } + ) & + ( + | { + xPoweredBy?: boolean + hidePoweredBy?: never + } + | { + hidePoweredBy?: boolean + xPoweredBy?: never + } + ) & + ( + | { + xXssProtection?: boolean + xssFilter?: never + } + | { + xssFilter?: boolean + xXssProtection?: never + } + ) +interface Helmet { + (options?: Readonly): (req: IncomingMessage, res: ServerResponse, next: (err?: unknown) => void) => void + contentSecurityPolicy: typeof contentSecurityPolicy + crossOriginEmbedderPolicy: typeof crossOriginEmbedderPolicy + crossOriginOpenerPolicy: typeof crossOriginOpenerPolicy + crossOriginResourcePolicy: typeof crossOriginResourcePolicy + originAgentCluster: typeof originAgentCluster + referrerPolicy: typeof referrerPolicy + strictTransportSecurity: typeof strictTransportSecurity + xContentTypeOptions: typeof xContentTypeOptions + xDnsPrefetchControl: typeof xDnsPrefetchControl + xDownloadOptions: typeof xDownloadOptions + xFrameOptions: typeof xFrameOptions + xPermittedCrossDomainPolicies: typeof xPermittedCrossDomainPolicies + xPoweredBy: typeof xPoweredBy + xXssProtection: typeof xXssProtection + dnsPrefetchControl: typeof xDnsPrefetchControl + frameguard: typeof xFrameOptions + hidePoweredBy: typeof xPoweredBy + hsts: typeof strictTransportSecurity + ieNoOpen: typeof xDownloadOptions + noSniff: typeof xContentTypeOptions + permittedCrossDomainPolicies: typeof xPermittedCrossDomainPolicies + xssFilter: typeof xXssProtection +} +declare const helmet: Helmet + +export {type HelmetOptions, contentSecurityPolicy, crossOriginEmbedderPolicy, crossOriginOpenerPolicy, crossOriginResourcePolicy, helmet as default, xDnsPrefetchControl as dnsPrefetchControl, xFrameOptions as frameguard, xPoweredBy as hidePoweredBy, strictTransportSecurity as hsts, xDownloadOptions as ieNoOpen, xContentTypeOptions as noSniff, originAgentCluster, xPermittedCrossDomainPolicies as permittedCrossDomainPolicies, referrerPolicy, strictTransportSecurity, xContentTypeOptions, xDnsPrefetchControl, xDownloadOptions, xFrameOptions, xPermittedCrossDomainPolicies, xPoweredBy, xXssProtection, xXssProtection as xssFilter} diff --git a/node_modules/helmet/index.mjs b/node_modules/helmet/index.mjs new file mode 100644 index 00000000..0ff61008 --- /dev/null +++ b/node_modules/helmet/index.mjs @@ -0,0 +1,559 @@ +const dangerouslyDisableDefaultSrc = Symbol("dangerouslyDisableDefaultSrc") +const SHOULD_BE_QUOTED = new Set(["none", "self", "strict-dynamic", "report-sample", "inline-speculation-rules", "unsafe-inline", "unsafe-eval", "unsafe-hashes", "wasm-unsafe-eval"]) +const getDefaultDirectives = () => ({ + "default-src": ["'self'"], + "base-uri": ["'self'"], + "font-src": ["'self'", "https:", "data:"], + "form-action": ["'self'"], + "frame-ancestors": ["'self'"], + "img-src": ["'self'", "data:"], + "object-src": ["'none'"], + "script-src": ["'self'"], + "script-src-attr": ["'none'"], + "style-src": ["'self'", "https:", "'unsafe-inline'"], + "upgrade-insecure-requests": [] +}) +const dashify = str => str.replace(/[A-Z]/g, capitalLetter => "-" + capitalLetter.toLowerCase()) +const assertDirectiveValueIsValid = (directiveName, directiveValue) => { + if (/;|,/.test(directiveValue)) { + throw new Error(`Content-Security-Policy received an invalid directive value for ${JSON.stringify(directiveName)}`) + } +} +const assertDirectiveValueEntryIsValid = (directiveName, directiveValueEntry) => { + if (SHOULD_BE_QUOTED.has(directiveValueEntry) || directiveValueEntry.startsWith("nonce-") || directiveValueEntry.startsWith("sha256-") || directiveValueEntry.startsWith("sha384-") || directiveValueEntry.startsWith("sha512-")) { + throw new Error(`Content-Security-Policy received an invalid directive value for ${JSON.stringify(directiveName)}. ${JSON.stringify(directiveValueEntry)} should be quoted`) + } +} +function normalizeDirectives(options) { + const defaultDirectives = getDefaultDirectives() + const {useDefaults = true, directives: rawDirectives = defaultDirectives} = options + const result = new Map() + const directiveNamesSeen = new Set() + const directivesExplicitlyDisabled = new Set() + for (const rawDirectiveName in rawDirectives) { + if (!Object.hasOwn(rawDirectives, rawDirectiveName)) { + continue + } + if (rawDirectiveName.length === 0 || /[^a-zA-Z0-9-]/.test(rawDirectiveName)) { + throw new Error(`Content-Security-Policy received an invalid directive name ${JSON.stringify(rawDirectiveName)}`) + } + const directiveName = dashify(rawDirectiveName) + if (directiveNamesSeen.has(directiveName)) { + throw new Error(`Content-Security-Policy received a duplicate directive ${JSON.stringify(directiveName)}`) + } + directiveNamesSeen.add(directiveName) + const rawDirectiveValue = rawDirectives[rawDirectiveName] + let directiveValue + if (rawDirectiveValue === null) { + if (directiveName === "default-src") { + throw new Error("Content-Security-Policy needs a default-src but it was set to `null`. If you really want to disable it, set it to `contentSecurityPolicy.dangerouslyDisableDefaultSrc`.") + } + directivesExplicitlyDisabled.add(directiveName) + continue + } else if (typeof rawDirectiveValue === "string") { + directiveValue = [rawDirectiveValue] + } else if (!rawDirectiveValue) { + throw new Error(`Content-Security-Policy received an invalid directive value for ${JSON.stringify(directiveName)}`) + } else if (rawDirectiveValue === dangerouslyDisableDefaultSrc) { + if (directiveName === "default-src") { + directivesExplicitlyDisabled.add("default-src") + continue + } else { + throw new Error(`Content-Security-Policy: tried to disable ${JSON.stringify(directiveName)} as if it were default-src; simply omit the key`) + } + } else { + directiveValue = rawDirectiveValue + } + for (const element of directiveValue) { + if (typeof element !== "string") continue + assertDirectiveValueIsValid(directiveName, element) + assertDirectiveValueEntryIsValid(directiveName, element) + } + result.set(directiveName, directiveValue) + } + if (useDefaults) { + Object.entries(defaultDirectives).forEach(([defaultDirectiveName, defaultDirectiveValue]) => { + if (!result.has(defaultDirectiveName) && !directivesExplicitlyDisabled.has(defaultDirectiveName)) { + result.set(defaultDirectiveName, defaultDirectiveValue) + } + }) + } + if (!result.size) { + throw new Error("Content-Security-Policy has no directives. Either set some or disable the header") + } + if (!result.has("default-src") && !directivesExplicitlyDisabled.has("default-src")) { + throw new Error("Content-Security-Policy needs a default-src but none was provided. If you really want to disable it, set it to `contentSecurityPolicy.dangerouslyDisableDefaultSrc`.") + } + return result +} +function getHeaderValue(req, res, normalizedDirectives) { + const result = [] + for (const [directiveName, rawDirectiveValue] of normalizedDirectives) { + let directiveValue = "" + for (const element of rawDirectiveValue) { + if (typeof element === "function") { + const newElement = element(req, res) + assertDirectiveValueEntryIsValid(directiveName, newElement) + directiveValue += " " + newElement + } else { + directiveValue += " " + element + } + } + if (directiveValue) { + assertDirectiveValueIsValid(directiveName, directiveValue) + result.push(`${directiveName}${directiveValue}`) + } else { + result.push(directiveName) + } + } + return result.join(";") +} +const contentSecurityPolicy = function contentSecurityPolicy(options = {}) { + const headerName = options.reportOnly ? "Content-Security-Policy-Report-Only" : "Content-Security-Policy" + const normalizedDirectives = normalizeDirectives(options) + return function contentSecurityPolicyMiddleware(req, res, next) { + const result = getHeaderValue(req, res, normalizedDirectives) + if (result instanceof Error) { + next(result) + } else { + res.setHeader(headerName, result) + next() + } + } +} +contentSecurityPolicy.getDefaultDirectives = getDefaultDirectives +contentSecurityPolicy.dangerouslyDisableDefaultSrc = dangerouslyDisableDefaultSrc + +const ALLOWED_POLICIES$2 = new Set(["require-corp", "credentialless", "unsafe-none"]) +function getHeaderValueFromOptions$6({policy = "require-corp"}) { + if (ALLOWED_POLICIES$2.has(policy)) { + return policy + } else { + throw new Error(`Cross-Origin-Embedder-Policy does not support the ${JSON.stringify(policy)} policy`) + } +} +function crossOriginEmbedderPolicy(options = {}) { + const headerValue = getHeaderValueFromOptions$6(options) + return function crossOriginEmbedderPolicyMiddleware(_req, res, next) { + res.setHeader("Cross-Origin-Embedder-Policy", headerValue) + next() + } +} + +const ALLOWED_POLICIES$1 = new Set(["same-origin", "same-origin-allow-popups", "unsafe-none"]) +function getHeaderValueFromOptions$5({policy = "same-origin"}) { + if (ALLOWED_POLICIES$1.has(policy)) { + return policy + } else { + throw new Error(`Cross-Origin-Opener-Policy does not support the ${JSON.stringify(policy)} policy`) + } +} +function crossOriginOpenerPolicy(options = {}) { + const headerValue = getHeaderValueFromOptions$5(options) + return function crossOriginOpenerPolicyMiddleware(_req, res, next) { + res.setHeader("Cross-Origin-Opener-Policy", headerValue) + next() + } +} + +const ALLOWED_POLICIES = new Set(["same-origin", "same-site", "cross-origin"]) +function getHeaderValueFromOptions$4({policy = "same-origin"}) { + if (ALLOWED_POLICIES.has(policy)) { + return policy + } else { + throw new Error(`Cross-Origin-Resource-Policy does not support the ${JSON.stringify(policy)} policy`) + } +} +function crossOriginResourcePolicy(options = {}) { + const headerValue = getHeaderValueFromOptions$4(options) + return function crossOriginResourcePolicyMiddleware(_req, res, next) { + res.setHeader("Cross-Origin-Resource-Policy", headerValue) + next() + } +} + +function originAgentCluster() { + return function originAgentClusterMiddleware(_req, res, next) { + res.setHeader("Origin-Agent-Cluster", "?1") + next() + } +} + +const ALLOWED_TOKENS = new Set(["no-referrer", "no-referrer-when-downgrade", "same-origin", "origin", "strict-origin", "origin-when-cross-origin", "strict-origin-when-cross-origin", "unsafe-url", ""]) +function getHeaderValueFromOptions$3({policy = ["no-referrer"]}) { + const tokens = typeof policy === "string" ? [policy] : policy + if (tokens.length === 0) { + throw new Error("Referrer-Policy received no policy tokens") + } + const tokensSeen = new Set() + tokens.forEach(token => { + if (!ALLOWED_TOKENS.has(token)) { + throw new Error(`Referrer-Policy received an unexpected policy token ${JSON.stringify(token)}`) + } else if (tokensSeen.has(token)) { + throw new Error(`Referrer-Policy received a duplicate policy token ${JSON.stringify(token)}`) + } + tokensSeen.add(token) + }) + return tokens.join(",") +} +function referrerPolicy(options = {}) { + const headerValue = getHeaderValueFromOptions$3(options) + return function referrerPolicyMiddleware(_req, res, next) { + res.setHeader("Referrer-Policy", headerValue) + next() + } +} + +const DEFAULT_MAX_AGE = 365 * 24 * 60 * 60 +function parseMaxAge(value = DEFAULT_MAX_AGE) { + if (value >= 0 && Number.isFinite(value)) { + return Math.floor(value) + } else { + throw new Error(`Strict-Transport-Security: ${JSON.stringify(value)} is not a valid value for maxAge. Please choose a positive integer.`) + } +} +function getHeaderValueFromOptions$2(options) { + if ("maxage" in options) { + throw new Error("Strict-Transport-Security received an unsupported property, `maxage`. Did you mean to pass `maxAge`?") + } + if ("includeSubdomains" in options) { + throw new Error('Strict-Transport-Security middleware should use `includeSubDomains` instead of `includeSubdomains`. (The correct one has an uppercase "D".)') + } + const directives = [`max-age=${parseMaxAge(options.maxAge)}`] + if (options.includeSubDomains === undefined || options.includeSubDomains) { + directives.push("includeSubDomains") + } + if (options.preload) { + directives.push("preload") + } + return directives.join("; ") +} +function strictTransportSecurity(options = {}) { + const headerValue = getHeaderValueFromOptions$2(options) + return function strictTransportSecurityMiddleware(_req, res, next) { + res.setHeader("Strict-Transport-Security", headerValue) + next() + } +} + +function xContentTypeOptions() { + return function xContentTypeOptionsMiddleware(_req, res, next) { + res.setHeader("X-Content-Type-Options", "nosniff") + next() + } +} + +function xDnsPrefetchControl(options = {}) { + const headerValue = options.allow ? "on" : "off" + return function xDnsPrefetchControlMiddleware(_req, res, next) { + res.setHeader("X-DNS-Prefetch-Control", headerValue) + next() + } +} + +function xDownloadOptions() { + return function xDownloadOptionsMiddleware(_req, res, next) { + res.setHeader("X-Download-Options", "noopen") + next() + } +} + +function getHeaderValueFromOptions$1({action = "sameorigin"}) { + const normalizedAction = typeof action === "string" ? action.toUpperCase() : action + switch (normalizedAction) { + case "SAME-ORIGIN": + return "SAMEORIGIN" + case "DENY": + case "SAMEORIGIN": + return normalizedAction + default: + throw new Error(`X-Frame-Options received an invalid action ${JSON.stringify(action)}`) + } +} +function xFrameOptions(options = {}) { + const headerValue = getHeaderValueFromOptions$1(options) + return function xFrameOptionsMiddleware(_req, res, next) { + res.setHeader("X-Frame-Options", headerValue) + next() + } +} + +const ALLOWED_PERMITTED_POLICIES = new Set(["none", "master-only", "by-content-type", "all"]) +function getHeaderValueFromOptions({permittedPolicies = "none"}) { + if (ALLOWED_PERMITTED_POLICIES.has(permittedPolicies)) { + return permittedPolicies + } else { + throw new Error(`X-Permitted-Cross-Domain-Policies does not support ${JSON.stringify(permittedPolicies)}`) + } +} +function xPermittedCrossDomainPolicies(options = {}) { + const headerValue = getHeaderValueFromOptions(options) + return function xPermittedCrossDomainPoliciesMiddleware(_req, res, next) { + res.setHeader("X-Permitted-Cross-Domain-Policies", headerValue) + next() + } +} + +function xPoweredBy() { + return function xPoweredByMiddleware(_req, res, next) { + res.removeHeader("X-Powered-By") + next() + } +} + +function xXssProtection() { + return function xXssProtectionMiddleware(_req, res, next) { + res.setHeader("X-XSS-Protection", "0") + next() + } +} + +function getMiddlewareFunctionsFromOptions(options) { + const result = [] + switch (options.contentSecurityPolicy) { + case undefined: + case true: + result.push(contentSecurityPolicy()) + break + case false: + break + default: + result.push(contentSecurityPolicy(options.contentSecurityPolicy)) + break + } + switch (options.crossOriginEmbedderPolicy) { + case undefined: + case false: + break + case true: + result.push(crossOriginEmbedderPolicy()) + break + default: + result.push(crossOriginEmbedderPolicy(options.crossOriginEmbedderPolicy)) + break + } + switch (options.crossOriginOpenerPolicy) { + case undefined: + case true: + result.push(crossOriginOpenerPolicy()) + break + case false: + break + default: + result.push(crossOriginOpenerPolicy(options.crossOriginOpenerPolicy)) + break + } + switch (options.crossOriginResourcePolicy) { + case undefined: + case true: + result.push(crossOriginResourcePolicy()) + break + case false: + break + default: + result.push(crossOriginResourcePolicy(options.crossOriginResourcePolicy)) + break + } + switch (options.originAgentCluster) { + case undefined: + case true: + result.push(originAgentCluster()) + break + case false: + break + default: + console.warn("Origin-Agent-Cluster does not take options. Remove the property to silence this warning.") + result.push(originAgentCluster()) + break + } + switch (options.referrerPolicy) { + case undefined: + case true: + result.push(referrerPolicy()) + break + case false: + break + default: + result.push(referrerPolicy(options.referrerPolicy)) + break + } + if ("strictTransportSecurity" in options && "hsts" in options) { + throw new Error("Strict-Transport-Security option was specified twice. Remove `hsts` to silence this warning.") + } + const strictTransportSecurityOption = options.strictTransportSecurity ?? options.hsts + switch (strictTransportSecurityOption) { + case undefined: + case true: + result.push(strictTransportSecurity()) + break + case false: + break + default: + result.push(strictTransportSecurity(strictTransportSecurityOption)) + break + } + if ("xContentTypeOptions" in options && "noSniff" in options) { + throw new Error("X-Content-Type-Options option was specified twice. Remove `noSniff` to silence this warning.") + } + const xContentTypeOptionsOption = options.xContentTypeOptions ?? options.noSniff + switch (xContentTypeOptionsOption) { + case undefined: + case true: + result.push(xContentTypeOptions()) + break + case false: + break + default: + console.warn("X-Content-Type-Options does not take options. Remove the property to silence this warning.") + result.push(xContentTypeOptions()) + break + } + if ("xDnsPrefetchControl" in options && "dnsPrefetchControl" in options) { + throw new Error("X-DNS-Prefetch-Control option was specified twice. Remove `dnsPrefetchControl` to silence this warning.") + } + const xDnsPrefetchControlOption = options.xDnsPrefetchControl ?? options.dnsPrefetchControl + switch (xDnsPrefetchControlOption) { + case undefined: + case true: + result.push(xDnsPrefetchControl()) + break + case false: + break + default: + result.push(xDnsPrefetchControl(xDnsPrefetchControlOption)) + break + } + if ("xDownloadOptions" in options && "ieNoOpen" in options) { + throw new Error("X-Download-Options option was specified twice. Remove `ieNoOpen` to silence this warning.") + } + const xDownloadOptionsOption = options.xDownloadOptions ?? options.ieNoOpen + switch (xDownloadOptionsOption) { + case undefined: + case true: + result.push(xDownloadOptions()) + break + case false: + break + default: + console.warn("X-Download-Options does not take options. Remove the property to silence this warning.") + result.push(xDownloadOptions()) + break + } + if ("xFrameOptions" in options && "frameguard" in options) { + throw new Error("X-Frame-Options option was specified twice. Remove `frameguard` to silence this warning.") + } + const xFrameOptionsOption = options.xFrameOptions ?? options.frameguard + switch (xFrameOptionsOption) { + case undefined: + case true: + result.push(xFrameOptions()) + break + case false: + break + default: + result.push(xFrameOptions(xFrameOptionsOption)) + break + } + if ("xPermittedCrossDomainPolicies" in options && "permittedCrossDomainPolicies" in options) { + throw new Error("X-Permitted-Cross-Domain-Policies option was specified twice. Remove `permittedCrossDomainPolicies` to silence this warning.") + } + const xPermittedCrossDomainPoliciesOption = options.xPermittedCrossDomainPolicies ?? options.permittedCrossDomainPolicies + switch (xPermittedCrossDomainPoliciesOption) { + case undefined: + case true: + result.push(xPermittedCrossDomainPolicies()) + break + case false: + break + default: + result.push(xPermittedCrossDomainPolicies(xPermittedCrossDomainPoliciesOption)) + break + } + if ("xPoweredBy" in options && "hidePoweredBy" in options) { + throw new Error("X-Powered-By option was specified twice. Remove `hidePoweredBy` to silence this warning.") + } + const xPoweredByOption = options.xPoweredBy ?? options.hidePoweredBy + switch (xPoweredByOption) { + case undefined: + case true: + result.push(xPoweredBy()) + break + case false: + break + default: + console.warn("X-Powered-By does not take options. Remove the property to silence this warning.") + result.push(xPoweredBy()) + break + } + if ("xXssProtection" in options && "xssFilter" in options) { + throw new Error("X-XSS-Protection option was specified twice. Remove `xssFilter` to silence this warning.") + } + const xXssProtectionOption = options.xXssProtection ?? options.xssFilter + switch (xXssProtectionOption) { + case undefined: + case true: + result.push(xXssProtection()) + break + case false: + break + default: + console.warn("X-XSS-Protection does not take options. Remove the property to silence this warning.") + result.push(xXssProtection()) + break + } + return result +} +const helmet = Object.assign( + function helmet(options = {}) { + // People should be able to pass an options object with no prototype, + // so we want this optional chaining. + // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition + if (options.constructor?.name === "IncomingMessage") { + throw new Error("It appears you have done something like `app.use(helmet)`, but it should be `app.use(helmet())`.") + } + const middlewareFunctions = getMiddlewareFunctionsFromOptions(options) + return function helmetMiddleware(req, res, next) { + let middlewareIndex = 0 + ;(function internalNext(err) { + if (err) { + next(err) + return + } + const middlewareFunction = middlewareFunctions[middlewareIndex] + if (middlewareFunction) { + middlewareIndex++ + middlewareFunction(req, res, internalNext) + } else { + next() + } + })() + } + }, + { + contentSecurityPolicy, + crossOriginEmbedderPolicy, + crossOriginOpenerPolicy, + crossOriginResourcePolicy, + originAgentCluster, + referrerPolicy, + strictTransportSecurity, + xContentTypeOptions, + xDnsPrefetchControl, + xDownloadOptions, + xFrameOptions, + xPermittedCrossDomainPolicies, + xPoweredBy, + xXssProtection, + // Legacy aliases + dnsPrefetchControl: xDnsPrefetchControl, + xssFilter: xXssProtection, + permittedCrossDomainPolicies: xPermittedCrossDomainPolicies, + ieNoOpen: xDownloadOptions, + noSniff: xContentTypeOptions, + frameguard: xFrameOptions, + hidePoweredBy: xPoweredBy, + hsts: strictTransportSecurity + } +) + +export {contentSecurityPolicy, crossOriginEmbedderPolicy, crossOriginOpenerPolicy, crossOriginResourcePolicy, helmet as default, xDnsPrefetchControl as dnsPrefetchControl, xFrameOptions as frameguard, xPoweredBy as hidePoweredBy, strictTransportSecurity as hsts, xDownloadOptions as ieNoOpen, xContentTypeOptions as noSniff, originAgentCluster, xPermittedCrossDomainPolicies as permittedCrossDomainPolicies, referrerPolicy, strictTransportSecurity, xContentTypeOptions, xDnsPrefetchControl, xDownloadOptions, xFrameOptions, xPermittedCrossDomainPolicies, xPoweredBy, xXssProtection, xXssProtection as xssFilter} diff --git a/node_modules/helmet/package.json b/node_modules/helmet/package.json new file mode 100644 index 00000000..88688157 --- /dev/null +++ b/node_modules/helmet/package.json @@ -0,0 +1,48 @@ +{ + "name": "helmet", + "description": "help secure Express/Connect apps with various HTTP headers", + "version": "8.1.0", + "author": "Adam Baldwin (https://evilpacket.net)", + "contributors": [ + "Evan Hahn (https://evanhahn.com)" + ], + "homepage": "https://helmetjs.github.io/", + "bugs": { + "url": "https://github.com/helmetjs/helmet/issues", + "email": "me@evanhahn.com" + }, + "repository": { + "type": "git", + "url": "git://github.com/helmetjs/helmet.git" + }, + "license": "MIT", + "keywords": [ + "express", + "security", + "headers", + "backend", + "content-security-policy", + "cross-origin-embedder-policy", + "cross-origin-opener-policy", + "cross-origin-resource-policy", + "origin-agent-cluster", + "referrer-policy", + "strict-transport-security", + "x-content-type-options", + "x-dns-prefetch-control", + "x-download-options", + "x-frame-options", + "x-permitted-cross-domain-policies", + "x-powered-by", + "x-xss-protection" + ], + "engines": { + "node": ">=18.0.0" + }, + "exports": { + "import": "./index.mjs", + "require": "./index.cjs" + }, + "main": "./index.cjs", + "types": "./index.d.cts" +} diff --git a/node_modules/import-local/fixtures/cli.js b/node_modules/import-local/fixtures/cli.js old mode 100755 new mode 100644 diff --git a/node_modules/jest-cli/bin/jest.js b/node_modules/jest-cli/bin/jest.js old mode 100755 new mode 100644 diff --git a/node_modules/jest/bin/jest.js b/node_modules/jest/bin/jest.js old mode 100755 new mode 100644 diff --git a/node_modules/js-yaml/bin/js-yaml.js b/node_modules/js-yaml/bin/js-yaml.js old mode 100755 new mode 100644 diff --git a/node_modules/jsesc/bin/jsesc b/node_modules/jsesc/bin/jsesc old mode 100755 new mode 100644 diff --git a/node_modules/json5/lib/cli.js b/node_modules/json5/lib/cli.js old mode 100755 new mode 100644 diff --git a/node_modules/mime/cli.js b/node_modules/mime/cli.js old mode 100755 new mode 100644 diff --git a/node_modules/napi-postinstall/lib/cli.js b/node_modules/napi-postinstall/lib/cli.js old mode 100755 new mode 100644 diff --git a/node_modules/pretty-format/README.md b/node_modules/pretty-format/README.md old mode 100755 new mode 100644 diff --git a/node_modules/regexp-tree/bin/regexp-tree b/node_modules/regexp-tree/bin/regexp-tree old mode 100755 new mode 100644 diff --git a/node_modules/safe-regex/bin/cli.js b/node_modules/safe-regex/bin/cli.js old mode 100755 new mode 100644 diff --git a/node_modules/semver/bin/semver.js b/node_modules/semver/bin/semver.js old mode 100755 new mode 100644 diff --git a/node_modules/stack-utils/node_modules/ansi-regex/index.d.ts b/node_modules/stack-utils/node_modules/ansi-regex/index.d.ts deleted file mode 100644 index 2dbf6af2..00000000 --- a/node_modules/stack-utils/node_modules/ansi-regex/index.d.ts +++ /dev/null @@ -1,37 +0,0 @@ -declare namespace ansiRegex { - interface Options { - /** - Match only the first ANSI escape. - - @default false - */ - onlyFirst: boolean; - } -} - -/** -Regular expression for matching ANSI escape codes. - -@example -``` -import ansiRegex = require('ansi-regex'); - -ansiRegex().test('\u001B[4mcake\u001B[0m'); -//=> true - -ansiRegex().test('cake'); -//=> false - -'\u001B[4mcake\u001B[0m'.match(ansiRegex()); -//=> ['\u001B[4m', '\u001B[0m'] - -'\u001B[4mcake\u001B[0m'.match(ansiRegex({onlyFirst: true})); -//=> ['\u001B[4m'] - -'\u001B]8;;https://github.com\u0007click\u001B]8;;\u0007'.match(ansiRegex()); -//=> ['\u001B]8;;https://github.com\u0007', '\u001B]8;;\u0007'] -``` -*/ -declare function ansiRegex(options?: ansiRegex.Options): RegExp; - -export = ansiRegex; diff --git a/node_modules/stack-utils/node_modules/ansi-regex/index.js b/node_modules/stack-utils/node_modules/ansi-regex/index.js deleted file mode 100644 index 616ff837..00000000 --- a/node_modules/stack-utils/node_modules/ansi-regex/index.js +++ /dev/null @@ -1,10 +0,0 @@ -'use strict'; - -module.exports = ({onlyFirst = false} = {}) => { - const pattern = [ - '[\\u001B\\u009B][[\\]()#;?]*(?:(?:(?:(?:;[-a-zA-Z\\d\\/#&.:=?%@~_]+)*|[a-zA-Z\\d]+(?:;[-a-zA-Z\\d\\/#&.:=?%@~_]*)*)?\\u0007)', - '(?:(?:\\d{1,4}(?:;\\d{0,4})*)?[\\dA-PR-TZcf-ntqry=><~]))' - ].join('|'); - - return new RegExp(pattern, onlyFirst ? undefined : 'g'); -}; diff --git a/node_modules/stack-utils/node_modules/ansi-regex/license b/node_modules/stack-utils/node_modules/ansi-regex/license deleted file mode 100644 index e7af2f77..00000000 --- a/node_modules/stack-utils/node_modules/ansi-regex/license +++ /dev/null @@ -1,9 +0,0 @@ -MIT License - -Copyright (c) Sindre Sorhus (sindresorhus.com) - -Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/node_modules/stack-utils/node_modules/ansi-regex/package.json b/node_modules/stack-utils/node_modules/ansi-regex/package.json deleted file mode 100644 index 017f5311..00000000 --- a/node_modules/stack-utils/node_modules/ansi-regex/package.json +++ /dev/null @@ -1,55 +0,0 @@ -{ - "name": "ansi-regex", - "version": "5.0.1", - "description": "Regular expression for matching ANSI escape codes", - "license": "MIT", - "repository": "chalk/ansi-regex", - "author": { - "name": "Sindre Sorhus", - "email": "sindresorhus@gmail.com", - "url": "sindresorhus.com" - }, - "engines": { - "node": ">=8" - }, - "scripts": { - "test": "xo && ava && tsd", - "view-supported": "node fixtures/view-codes.js" - }, - "files": [ - "index.js", - "index.d.ts" - ], - "keywords": [ - "ansi", - "styles", - "color", - "colour", - "colors", - "terminal", - "console", - "cli", - "string", - "tty", - "escape", - "formatting", - "rgb", - "256", - "shell", - "xterm", - "command-line", - "text", - "regex", - "regexp", - "re", - "match", - "test", - "find", - "pattern" - ], - "devDependencies": { - "ava": "^2.4.0", - "tsd": "^0.9.0", - "xo": "^0.25.3" - } -} diff --git a/node_modules/stack-utils/node_modules/ansi-regex/readme.md b/node_modules/stack-utils/node_modules/ansi-regex/readme.md deleted file mode 100644 index 4d848bc3..00000000 --- a/node_modules/stack-utils/node_modules/ansi-regex/readme.md +++ /dev/null @@ -1,78 +0,0 @@ -# ansi-regex - -> Regular expression for matching [ANSI escape codes](https://en.wikipedia.org/wiki/ANSI_escape_code) - - -## Install - -``` -$ npm install ansi-regex -``` - - -## Usage - -```js -const ansiRegex = require('ansi-regex'); - -ansiRegex().test('\u001B[4mcake\u001B[0m'); -//=> true - -ansiRegex().test('cake'); -//=> false - -'\u001B[4mcake\u001B[0m'.match(ansiRegex()); -//=> ['\u001B[4m', '\u001B[0m'] - -'\u001B[4mcake\u001B[0m'.match(ansiRegex({onlyFirst: true})); -//=> ['\u001B[4m'] - -'\u001B]8;;https://github.com\u0007click\u001B]8;;\u0007'.match(ansiRegex()); -//=> ['\u001B]8;;https://github.com\u0007', '\u001B]8;;\u0007'] -``` - - -## API - -### ansiRegex(options?) - -Returns a regex for matching ANSI escape codes. - -#### options - -Type: `object` - -##### onlyFirst - -Type: `boolean`
-Default: `false` *(Matches any ANSI escape codes in a string)* - -Match only the first ANSI escape. - - -## FAQ - -### Why do you test for codes not in the ECMA 48 standard? - -Some of the codes we run as a test are codes that we acquired finding various lists of non-standard or manufacturer specific codes. We test for both standard and non-standard codes, as most of them follow the same or similar format and can be safely matched in strings without the risk of removing actual string content. There are a few non-standard control codes that do not follow the traditional format (i.e. they end in numbers) thus forcing us to exclude them from the test because we cannot reliably match them. - -On the historical side, those ECMA standards were established in the early 90's whereas the VT100, for example, was designed in the mid/late 70's. At that point in time, control codes were still pretty ungoverned and engineers used them for a multitude of things, namely to activate hardware ports that may have been proprietary. Somewhere else you see a similar 'anarchy' of codes is in the x86 architecture for processors; there are a ton of "interrupts" that can mean different things on certain brands of processors, most of which have been phased out. - - -## Maintainers - -- [Sindre Sorhus](https://github.com/sindresorhus) -- [Josh Junon](https://github.com/qix-) - - ---- - -
- - Get professional support for this package with a Tidelift subscription - -
- - Tidelift helps make open source sustainable for maintainers while giving companies
assurances about security, maintenance, and licensing for their dependencies. -
-
diff --git a/node_modules/stack-utils/node_modules/strip-ansi/index.d.ts b/node_modules/stack-utils/node_modules/strip-ansi/index.d.ts deleted file mode 100644 index 907fccc2..00000000 --- a/node_modules/stack-utils/node_modules/strip-ansi/index.d.ts +++ /dev/null @@ -1,17 +0,0 @@ -/** -Strip [ANSI escape codes](https://en.wikipedia.org/wiki/ANSI_escape_code) from a string. - -@example -``` -import stripAnsi = require('strip-ansi'); - -stripAnsi('\u001B[4mUnicorn\u001B[0m'); -//=> 'Unicorn' - -stripAnsi('\u001B]8;;https://github.com\u0007Click\u001B]8;;\u0007'); -//=> 'Click' -``` -*/ -declare function stripAnsi(string: string): string; - -export = stripAnsi; diff --git a/node_modules/stack-utils/node_modules/strip-ansi/index.js b/node_modules/stack-utils/node_modules/strip-ansi/index.js deleted file mode 100644 index 9a593dfc..00000000 --- a/node_modules/stack-utils/node_modules/strip-ansi/index.js +++ /dev/null @@ -1,4 +0,0 @@ -'use strict'; -const ansiRegex = require('ansi-regex'); - -module.exports = string => typeof string === 'string' ? string.replace(ansiRegex(), '') : string; diff --git a/node_modules/stack-utils/node_modules/strip-ansi/license b/node_modules/stack-utils/node_modules/strip-ansi/license deleted file mode 100644 index e7af2f77..00000000 --- a/node_modules/stack-utils/node_modules/strip-ansi/license +++ /dev/null @@ -1,9 +0,0 @@ -MIT License - -Copyright (c) Sindre Sorhus (sindresorhus.com) - -Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/node_modules/stack-utils/node_modules/strip-ansi/package.json b/node_modules/stack-utils/node_modules/strip-ansi/package.json deleted file mode 100644 index 1a41108d..00000000 --- a/node_modules/stack-utils/node_modules/strip-ansi/package.json +++ /dev/null @@ -1,54 +0,0 @@ -{ - "name": "strip-ansi", - "version": "6.0.1", - "description": "Strip ANSI escape codes from a string", - "license": "MIT", - "repository": "chalk/strip-ansi", - "author": { - "name": "Sindre Sorhus", - "email": "sindresorhus@gmail.com", - "url": "sindresorhus.com" - }, - "engines": { - "node": ">=8" - }, - "scripts": { - "test": "xo && ava && tsd" - }, - "files": [ - "index.js", - "index.d.ts" - ], - "keywords": [ - "strip", - "trim", - "remove", - "ansi", - "styles", - "color", - "colour", - "colors", - "terminal", - "console", - "string", - "tty", - "escape", - "formatting", - "rgb", - "256", - "shell", - "xterm", - "log", - "logging", - "command-line", - "text" - ], - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "devDependencies": { - "ava": "^2.4.0", - "tsd": "^0.10.0", - "xo": "^0.25.3" - } -} diff --git a/node_modules/stack-utils/node_modules/strip-ansi/readme.md b/node_modules/stack-utils/node_modules/strip-ansi/readme.md deleted file mode 100644 index 7c4b56d4..00000000 --- a/node_modules/stack-utils/node_modules/strip-ansi/readme.md +++ /dev/null @@ -1,46 +0,0 @@ -# strip-ansi [![Build Status](https://travis-ci.org/chalk/strip-ansi.svg?branch=master)](https://travis-ci.org/chalk/strip-ansi) - -> Strip [ANSI escape codes](https://en.wikipedia.org/wiki/ANSI_escape_code) from a string - - -## Install - -``` -$ npm install strip-ansi -``` - - -## Usage - -```js -const stripAnsi = require('strip-ansi'); - -stripAnsi('\u001B[4mUnicorn\u001B[0m'); -//=> 'Unicorn' - -stripAnsi('\u001B]8;;https://github.com\u0007Click\u001B]8;;\u0007'); -//=> 'Click' -``` - - -## strip-ansi for enterprise - -Available as part of the Tidelift Subscription. - -The maintainers of strip-ansi and thousands of other packages are working with Tidelift to deliver commercial support and maintenance for the open source dependencies you use to build your applications. Save time, reduce risk, and improve code health, while paying the maintainers of the exact dependencies you use. [Learn more.](https://tidelift.com/subscription/pkg/npm-strip-ansi?utm_source=npm-strip-ansi&utm_medium=referral&utm_campaign=enterprise&utm_term=repo) - - -## Related - -- [strip-ansi-cli](https://github.com/chalk/strip-ansi-cli) - CLI for this module -- [strip-ansi-stream](https://github.com/chalk/strip-ansi-stream) - Streaming version of this module -- [has-ansi](https://github.com/chalk/has-ansi) - Check if a string has ANSI escape codes -- [ansi-regex](https://github.com/chalk/ansi-regex) - Regular expression for matching ANSI escape codes -- [chalk](https://github.com/chalk/chalk) - Terminal string styling done right - - -## Maintainers - -- [Sindre Sorhus](https://github.com/sindresorhus) -- [Josh Junon](https://github.com/qix-) - diff --git a/node_modules/string-length/node_modules/ansi-regex/node_modules/ansi-regex/index.d.ts b/node_modules/string-length/node_modules/ansi-regex/node_modules/ansi-regex/index.d.ts deleted file mode 100644 index 7d562e9c..00000000 --- a/node_modules/string-length/node_modules/ansi-regex/node_modules/ansi-regex/index.d.ts +++ /dev/null @@ -1,33 +0,0 @@ -export type Options = { - /** - Match only the first ANSI escape. - - @default false - */ - readonly onlyFirst: boolean; -}; - -/** -Regular expression for matching ANSI escape codes. - -@example -``` -import ansiRegex from 'ansi-regex'; - -ansiRegex().test('\u001B[4mcake\u001B[0m'); -//=> true - -ansiRegex().test('cake'); -//=> false - -'\u001B[4mcake\u001B[0m'.match(ansiRegex()); -//=> ['\u001B[4m', '\u001B[0m'] - -'\u001B[4mcake\u001B[0m'.match(ansiRegex({onlyFirst: true})); -//=> ['\u001B[4m'] - -'\u001B]8;;https://github.com\u0007click\u001B]8;;\u0007'.match(ansiRegex()); -//=> ['\u001B]8;;https://github.com\u0007', '\u001B]8;;\u0007'] -``` -*/ -export default function ansiRegex(options?: Options): RegExp; diff --git a/node_modules/string-length/node_modules/ansi-regex/node_modules/ansi-regex/index.js b/node_modules/string-length/node_modules/ansi-regex/node_modules/ansi-regex/index.js deleted file mode 100644 index 2cc5ca24..00000000 --- a/node_modules/string-length/node_modules/ansi-regex/node_modules/ansi-regex/index.js +++ /dev/null @@ -1,14 +0,0 @@ -export default function ansiRegex({onlyFirst = false} = {}) { - // Valid string terminator sequences are BEL, ESC\, and 0x9c - const ST = '(?:\\u0007|\\u001B\\u005C|\\u009C)'; - - // OSC sequences only: ESC ] ... ST (non-greedy until the first ST) - const osc = `(?:\\u001B\\][\\s\\S]*?${ST})`; - - // CSI and related: ESC/C1, optional intermediates, optional params (supports ; and :) then final byte - const csi = '[\\u001B\\u009B][[\\]()#;?]*(?:\\d{1,4}(?:[;:]\\d{0,4})*)?[\\dA-PR-TZcf-nq-uy=><~]'; - - const pattern = `${osc}|${csi}`; - - return new RegExp(pattern, onlyFirst ? undefined : 'g'); -} diff --git a/node_modules/string-length/node_modules/ansi-regex/node_modules/ansi-regex/license b/node_modules/string-length/node_modules/ansi-regex/node_modules/ansi-regex/license deleted file mode 100644 index fa7ceba3..00000000 --- a/node_modules/string-length/node_modules/ansi-regex/node_modules/ansi-regex/license +++ /dev/null @@ -1,9 +0,0 @@ -MIT License - -Copyright (c) Sindre Sorhus (https://sindresorhus.com) - -Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/node_modules/string-length/node_modules/ansi-regex/node_modules/ansi-regex/package.json b/node_modules/string-length/node_modules/ansi-regex/node_modules/ansi-regex/package.json deleted file mode 100644 index 2efe9ebb..00000000 --- a/node_modules/string-length/node_modules/ansi-regex/node_modules/ansi-regex/package.json +++ /dev/null @@ -1,61 +0,0 @@ -{ - "name": "ansi-regex", - "version": "6.2.2", - "description": "Regular expression for matching ANSI escape codes", - "license": "MIT", - "repository": "chalk/ansi-regex", - "funding": "https://github.com/chalk/ansi-regex?sponsor=1", - "author": { - "name": "Sindre Sorhus", - "email": "sindresorhus@gmail.com", - "url": "https://sindresorhus.com" - }, - "type": "module", - "exports": "./index.js", - "types": "./index.d.ts", - "sideEffects": false, - "engines": { - "node": ">=12" - }, - "scripts": { - "test": "xo && ava && tsd", - "view-supported": "node fixtures/view-codes.js" - }, - "files": [ - "index.js", - "index.d.ts" - ], - "keywords": [ - "ansi", - "styles", - "color", - "colour", - "colors", - "terminal", - "console", - "cli", - "string", - "tty", - "escape", - "formatting", - "rgb", - "256", - "shell", - "xterm", - "command-line", - "text", - "regex", - "regexp", - "re", - "match", - "test", - "find", - "pattern" - ], - "devDependencies": { - "ansi-escapes": "^5.0.0", - "ava": "^3.15.0", - "tsd": "^0.21.0", - "xo": "^0.54.2" - } -} diff --git a/node_modules/string-length/node_modules/ansi-regex/node_modules/ansi-regex/readme.md b/node_modules/string-length/node_modules/ansi-regex/node_modules/ansi-regex/readme.md deleted file mode 100644 index 4d3c415a..00000000 --- a/node_modules/string-length/node_modules/ansi-regex/node_modules/ansi-regex/readme.md +++ /dev/null @@ -1,66 +0,0 @@ -# ansi-regex - -> Regular expression for matching [ANSI escape codes](https://en.wikipedia.org/wiki/ANSI_escape_code) - -## Install - -```sh -npm install ansi-regex -``` - -## Usage - -```js -import ansiRegex from 'ansi-regex'; - -ansiRegex().test('\u001B[4mcake\u001B[0m'); -//=> true - -ansiRegex().test('cake'); -//=> false - -'\u001B[4mcake\u001B[0m'.match(ansiRegex()); -//=> ['\u001B[4m', '\u001B[0m'] - -'\u001B[4mcake\u001B[0m'.match(ansiRegex({onlyFirst: true})); -//=> ['\u001B[4m'] - -'\u001B]8;;https://github.com\u0007click\u001B]8;;\u0007'.match(ansiRegex()); -//=> ['\u001B]8;;https://github.com\u0007', '\u001B]8;;\u0007'] -``` - -## API - -### ansiRegex(options?) - -Returns a regex for matching ANSI escape codes. - -#### options - -Type: `object` - -##### onlyFirst - -Type: `boolean`\ -Default: `false` *(Matches any ANSI escape codes in a string)* - -Match only the first ANSI escape. - -## Important - -If you run the regex against untrusted user input in a server context, you should [give it a timeout](https://github.com/sindresorhus/super-regex). - -**I do not consider [ReDoS](https://blog.yossarian.net/2022/12/28/ReDoS-vulnerabilities-and-misaligned-incentives) a valid vulnerability for this package.** - -## FAQ - -### Why do you test for codes not in the ECMA 48 standard? - -Some of the codes we run as a test are codes that we acquired finding various lists of non-standard or manufacturer specific codes. We test for both standard and non-standard codes, as most of them follow the same or similar format and can be safely matched in strings without the risk of removing actual string content. There are a few non-standard control codes that do not follow the traditional format (i.e. they end in numbers) thus forcing us to exclude them from the test because we cannot reliably match them. - -On the historical side, those ECMA standards were established in the early 90's whereas the VT100, for example, was designed in the mid/late 70's. At that point in time, control codes were still pretty ungoverned and engineers used them for a multitude of things, namely to activate hardware ports that may have been proprietary. Somewhere else you see a similar 'anarchy' of codes is in the x86 architecture for processors; there are a ton of "interrupts" that can mean different things on certain brands of processors, most of which have been phased out. - -## Maintainers - -- [Sindre Sorhus](https://github.com/sindresorhus) -- [Josh Junon](https://github.com/qix-) diff --git a/node_modules/string-length/node_modules/ansi-regex/node_modules/strip-ansi/index.d.ts b/node_modules/string-length/node_modules/ansi-regex/node_modules/strip-ansi/index.d.ts deleted file mode 100644 index 44e954d0..00000000 --- a/node_modules/string-length/node_modules/ansi-regex/node_modules/strip-ansi/index.d.ts +++ /dev/null @@ -1,15 +0,0 @@ -/** -Strip [ANSI escape codes](https://en.wikipedia.org/wiki/ANSI_escape_code) from a string. - -@example -``` -import stripAnsi from 'strip-ansi'; - -stripAnsi('\u001B[4mUnicorn\u001B[0m'); -//=> 'Unicorn' - -stripAnsi('\u001B]8;;https://github.com\u0007Click\u001B]8;;\u0007'); -//=> 'Click' -``` -*/ -export default function stripAnsi(string: string): string; diff --git a/node_modules/string-length/node_modules/ansi-regex/node_modules/strip-ansi/index.js b/node_modules/string-length/node_modules/ansi-regex/node_modules/strip-ansi/index.js deleted file mode 100644 index 03096354..00000000 --- a/node_modules/string-length/node_modules/ansi-regex/node_modules/strip-ansi/index.js +++ /dev/null @@ -1,19 +0,0 @@ -import ansiRegex from 'ansi-regex'; - -const regex = ansiRegex(); - -export default function stripAnsi(string) { - if (typeof string !== 'string') { - throw new TypeError(`Expected a \`string\`, got \`${typeof string}\``); - } - - // Fast path: ANSI codes require ESC (7-bit) or CSI (8-bit) introducer - if (!string.includes('\u001B') && !string.includes('\u009B')) { - return string; - } - - // Even though the regex is global, we don't need to reset the `.lastIndex` - // because unlike `.exec()` and `.test()`, `.replace()` does it automatically - // and doing it manually has a performance penalty. - return string.replace(regex, ''); -} diff --git a/node_modules/string-length/node_modules/ansi-regex/node_modules/strip-ansi/license b/node_modules/string-length/node_modules/ansi-regex/node_modules/strip-ansi/license deleted file mode 100644 index fa7ceba3..00000000 --- a/node_modules/string-length/node_modules/ansi-regex/node_modules/strip-ansi/license +++ /dev/null @@ -1,9 +0,0 @@ -MIT License - -Copyright (c) Sindre Sorhus (https://sindresorhus.com) - -Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/node_modules/string-length/node_modules/ansi-regex/node_modules/strip-ansi/package.json b/node_modules/string-length/node_modules/ansi-regex/node_modules/strip-ansi/package.json deleted file mode 100644 index a1786b3c..00000000 --- a/node_modules/string-length/node_modules/ansi-regex/node_modules/strip-ansi/package.json +++ /dev/null @@ -1,59 +0,0 @@ -{ - "name": "strip-ansi", - "version": "7.2.0", - "description": "Strip ANSI escape codes from a string", - "license": "MIT", - "repository": "chalk/strip-ansi", - "funding": "https://github.com/chalk/strip-ansi?sponsor=1", - "author": { - "name": "Sindre Sorhus", - "email": "sindresorhus@gmail.com", - "url": "https://sindresorhus.com" - }, - "type": "module", - "exports": "./index.js", - "types": "./index.d.ts", - "sideEffects": false, - "engines": { - "node": ">=12" - }, - "scripts": { - "test": "xo && ava && tsd" - }, - "files": [ - "index.js", - "index.d.ts" - ], - "keywords": [ - "strip", - "trim", - "remove", - "ansi", - "styles", - "color", - "colour", - "colors", - "terminal", - "console", - "string", - "tty", - "escape", - "formatting", - "rgb", - "256", - "shell", - "xterm", - "log", - "logging", - "command-line", - "text" - ], - "dependencies": { - "ansi-regex": "^6.2.2" - }, - "devDependencies": { - "ava": "^6.4.1", - "tsd": "^0.33.0", - "xo": "^1.2.3" - } -} diff --git a/node_modules/string-length/node_modules/ansi-regex/node_modules/strip-ansi/readme.md b/node_modules/string-length/node_modules/ansi-regex/node_modules/strip-ansi/readme.md deleted file mode 100644 index 109b692b..00000000 --- a/node_modules/string-length/node_modules/ansi-regex/node_modules/strip-ansi/readme.md +++ /dev/null @@ -1,37 +0,0 @@ -# strip-ansi - -> Strip [ANSI escape codes](https://en.wikipedia.org/wiki/ANSI_escape_code) from a string - -> [!NOTE] -> Node.js has this built-in now with [`stripVTControlCharacters`](https://nodejs.org/api/util.html#utilstripvtcontrolcharactersstr). The benefit of this package is consistent behavior across Node.js versions and faster improvements. The Node.js version is actually based on this package. - -## Install - -```sh -npm install strip-ansi -``` - -## Usage - -```js -import stripAnsi from 'strip-ansi'; - -stripAnsi('\u001B[4mUnicorn\u001B[0m'); -//=> 'Unicorn' - -stripAnsi('\u001B]8;;https://github.com\u0007Click\u001B]8;;\u0007'); -//=> 'Click' -``` - -## Related - -- [strip-ansi-cli](https://github.com/chalk/strip-ansi-cli) - CLI for this module -- [strip-ansi-stream](https://github.com/chalk/strip-ansi-stream) - Streaming version of this module -- [has-ansi](https://github.com/chalk/has-ansi) - Check if a string has ANSI escape codes -- [ansi-regex](https://github.com/chalk/ansi-regex) - Regular expression for matching ANSI escape codes -- [chalk](https://github.com/chalk/chalk) - Terminal string styling done right - -## Maintainers - -- [Sindre Sorhus](https://github.com/sindresorhus) -- [Josh Junon](https://github.com/qix-) diff --git a/node_modules/update-browserslist-db/cli.js b/node_modules/update-browserslist-db/cli.js old mode 100755 new mode 100644 diff --git a/node_modules/uri-js/LICENSE b/node_modules/uri-js/LICENSE old mode 100755 new mode 100644 diff --git a/node_modules/uri-js/README.md b/node_modules/uri-js/README.md old mode 100755 new mode 100644 diff --git a/node_modules/uri-js/dist/es5/uri.all.d.ts b/node_modules/uri-js/dist/es5/uri.all.d.ts old mode 100755 new mode 100644 diff --git a/node_modules/uri-js/dist/es5/uri.all.js b/node_modules/uri-js/dist/es5/uri.all.js old mode 100755 new mode 100644 diff --git a/node_modules/uri-js/dist/es5/uri.all.js.map b/node_modules/uri-js/dist/es5/uri.all.js.map old mode 100755 new mode 100644 diff --git a/node_modules/uri-js/dist/es5/uri.all.min.d.ts b/node_modules/uri-js/dist/es5/uri.all.min.d.ts old mode 100755 new mode 100644 diff --git a/node_modules/uri-js/dist/es5/uri.all.min.js b/node_modules/uri-js/dist/es5/uri.all.min.js old mode 100755 new mode 100644 diff --git a/node_modules/uri-js/dist/es5/uri.all.min.js.map b/node_modules/uri-js/dist/es5/uri.all.min.js.map old mode 100755 new mode 100644 diff --git a/node_modules/uri-js/dist/esnext/index.d.ts b/node_modules/uri-js/dist/esnext/index.d.ts old mode 100755 new mode 100644 diff --git a/node_modules/uri-js/dist/esnext/index.js b/node_modules/uri-js/dist/esnext/index.js old mode 100755 new mode 100644 diff --git a/node_modules/uri-js/dist/esnext/index.js.map b/node_modules/uri-js/dist/esnext/index.js.map old mode 100755 new mode 100644 diff --git a/node_modules/uri-js/dist/esnext/regexps-iri.d.ts b/node_modules/uri-js/dist/esnext/regexps-iri.d.ts old mode 100755 new mode 100644 diff --git a/node_modules/uri-js/dist/esnext/regexps-iri.js b/node_modules/uri-js/dist/esnext/regexps-iri.js old mode 100755 new mode 100644 diff --git a/node_modules/uri-js/dist/esnext/regexps-iri.js.map b/node_modules/uri-js/dist/esnext/regexps-iri.js.map old mode 100755 new mode 100644 diff --git a/node_modules/uri-js/dist/esnext/regexps-uri.d.ts b/node_modules/uri-js/dist/esnext/regexps-uri.d.ts old mode 100755 new mode 100644 diff --git a/node_modules/uri-js/dist/esnext/regexps-uri.js b/node_modules/uri-js/dist/esnext/regexps-uri.js old mode 100755 new mode 100644 diff --git a/node_modules/uri-js/dist/esnext/regexps-uri.js.map b/node_modules/uri-js/dist/esnext/regexps-uri.js.map old mode 100755 new mode 100644 diff --git a/node_modules/uri-js/dist/esnext/schemes/http.d.ts b/node_modules/uri-js/dist/esnext/schemes/http.d.ts old mode 100755 new mode 100644 diff --git a/node_modules/uri-js/dist/esnext/schemes/http.js b/node_modules/uri-js/dist/esnext/schemes/http.js old mode 100755 new mode 100644 diff --git a/node_modules/uri-js/dist/esnext/schemes/http.js.map b/node_modules/uri-js/dist/esnext/schemes/http.js.map old mode 100755 new mode 100644 diff --git a/node_modules/uri-js/dist/esnext/schemes/https.d.ts b/node_modules/uri-js/dist/esnext/schemes/https.d.ts old mode 100755 new mode 100644 diff --git a/node_modules/uri-js/dist/esnext/schemes/https.js b/node_modules/uri-js/dist/esnext/schemes/https.js old mode 100755 new mode 100644 diff --git a/node_modules/uri-js/dist/esnext/schemes/https.js.map b/node_modules/uri-js/dist/esnext/schemes/https.js.map old mode 100755 new mode 100644 diff --git a/node_modules/uri-js/dist/esnext/schemes/mailto.d.ts b/node_modules/uri-js/dist/esnext/schemes/mailto.d.ts old mode 100755 new mode 100644 diff --git a/node_modules/uri-js/dist/esnext/schemes/mailto.js b/node_modules/uri-js/dist/esnext/schemes/mailto.js old mode 100755 new mode 100644 diff --git a/node_modules/uri-js/dist/esnext/schemes/mailto.js.map b/node_modules/uri-js/dist/esnext/schemes/mailto.js.map old mode 100755 new mode 100644 diff --git a/node_modules/uri-js/dist/esnext/schemes/urn-uuid.d.ts b/node_modules/uri-js/dist/esnext/schemes/urn-uuid.d.ts old mode 100755 new mode 100644 diff --git a/node_modules/uri-js/dist/esnext/schemes/urn-uuid.js b/node_modules/uri-js/dist/esnext/schemes/urn-uuid.js old mode 100755 new mode 100644 diff --git a/node_modules/uri-js/dist/esnext/schemes/urn-uuid.js.map b/node_modules/uri-js/dist/esnext/schemes/urn-uuid.js.map old mode 100755 new mode 100644 diff --git a/node_modules/uri-js/dist/esnext/schemes/urn.d.ts b/node_modules/uri-js/dist/esnext/schemes/urn.d.ts old mode 100755 new mode 100644 diff --git a/node_modules/uri-js/dist/esnext/schemes/urn.js b/node_modules/uri-js/dist/esnext/schemes/urn.js old mode 100755 new mode 100644 diff --git a/node_modules/uri-js/dist/esnext/schemes/urn.js.map b/node_modules/uri-js/dist/esnext/schemes/urn.js.map old mode 100755 new mode 100644 diff --git a/node_modules/uri-js/dist/esnext/schemes/ws.d.ts b/node_modules/uri-js/dist/esnext/schemes/ws.d.ts old mode 100755 new mode 100644 diff --git a/node_modules/uri-js/dist/esnext/schemes/ws.js b/node_modules/uri-js/dist/esnext/schemes/ws.js old mode 100755 new mode 100644 diff --git a/node_modules/uri-js/dist/esnext/schemes/ws.js.map b/node_modules/uri-js/dist/esnext/schemes/ws.js.map old mode 100755 new mode 100644 diff --git a/node_modules/uri-js/dist/esnext/schemes/wss.d.ts b/node_modules/uri-js/dist/esnext/schemes/wss.d.ts old mode 100755 new mode 100644 diff --git a/node_modules/uri-js/dist/esnext/schemes/wss.js b/node_modules/uri-js/dist/esnext/schemes/wss.js old mode 100755 new mode 100644 diff --git a/node_modules/uri-js/dist/esnext/schemes/wss.js.map b/node_modules/uri-js/dist/esnext/schemes/wss.js.map old mode 100755 new mode 100644 diff --git a/node_modules/uri-js/dist/esnext/uri.d.ts b/node_modules/uri-js/dist/esnext/uri.d.ts old mode 100755 new mode 100644 diff --git a/node_modules/uri-js/dist/esnext/uri.js b/node_modules/uri-js/dist/esnext/uri.js old mode 100755 new mode 100644 diff --git a/node_modules/uri-js/dist/esnext/uri.js.map b/node_modules/uri-js/dist/esnext/uri.js.map old mode 100755 new mode 100644 diff --git a/node_modules/uri-js/dist/esnext/util.d.ts b/node_modules/uri-js/dist/esnext/util.d.ts old mode 100755 new mode 100644 diff --git a/node_modules/uri-js/dist/esnext/util.js b/node_modules/uri-js/dist/esnext/util.js old mode 100755 new mode 100644 diff --git a/node_modules/uri-js/dist/esnext/util.js.map b/node_modules/uri-js/dist/esnext/util.js.map old mode 100755 new mode 100644 diff --git a/node_modules/uri-js/package.json b/node_modules/uri-js/package.json old mode 100755 new mode 100644 diff --git a/node_modules/uri-js/yarn.lock b/node_modules/uri-js/yarn.lock old mode 100755 new mode 100644 diff --git a/node_modules/which/bin/node-which b/node_modules/which/bin/node-which old mode 100755 new mode 100644 diff --git a/node_modules/wrap-ansi-cjs/index.js b/node_modules/wrap-ansi-cjs/index.js old mode 100755 new mode 100644 diff --git a/node_modules/wrap-ansi/index.js b/node_modules/wrap-ansi/index.js old mode 100755 new mode 100644 diff --git a/node_modules/zod/LICENSE b/node_modules/zod/LICENSE new file mode 100644 index 00000000..c0657962 --- /dev/null +++ b/node_modules/zod/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2025 Colin McDonnell + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/node_modules/zod/README.md b/node_modules/zod/README.md new file mode 100644 index 00000000..305059e6 --- /dev/null +++ b/node_modules/zod/README.md @@ -0,0 +1,208 @@ +

+ Zod logo +

Zod

+

+ TypeScript-first schema validation with static type inference +
+ by @colinhacks +

+

+
+ +

+Zod CI status +License +npm +discord server +stars +

+ +
+ Docs +   •   + Discord +   •   + 𝕏 +   •   + Bluesky +
+
+ +
+
+ +

Featured sponsor: Jazz

+ +
+ + + + jazz logo + + +
+

Learn more about featured sponsorships

+
+ +
+
+
+ +### [Read the docs →](https://zod.dev/api) + +
+
+ +## What is Zod? + +Zod is a TypeScript-first validation library. Define a schema and parse some data with it. You'll get back a strongly typed, validated result. + +```ts +import * as z from "zod"; + +const User = z.object({ + name: z.string(), +}); + +// some untrusted data... +const input = { + /* stuff */ +}; + +// the parsed result is validated and type safe! +const data = User.parse(input); + +// so you can use it with confidence :) +console.log(data.name); +``` + +
+ +## Features + +- Zero external dependencies +- Works in Node.js and all modern browsers +- Tiny: `2kb` core bundle (gzipped) +- Immutable API: methods return a new instance +- Concise interface +- Works with TypeScript and plain JS +- Built-in JSON Schema conversion +- Extensive ecosystem + +
+ +## Installation + +```sh +npm install zod +``` + +
+ +## Basic usage + +Before you can do anything else, you need to define a schema. For the purposes of this guide, we'll use a simple object schema. + +```ts +import * as z from "zod"; + +const Player = z.object({ + username: z.string(), + xp: z.number(), +}); +``` + +### Parsing data + +Given any Zod schema, use `.parse` to validate an input. If it's valid, Zod returns a strongly-typed _deep clone_ of the input. + +```ts +Player.parse({ username: "billie", xp: 100 }); +// => returns { username: "billie", xp: 100 } +``` + +**Note** — If your schema uses certain asynchronous APIs like `async` [refinements](https://zod.dev/api#refinements) or [transforms](https://zod.dev/api#transforms), you'll need to use the `.parseAsync()` method instead. + +```ts +const schema = z.string().refine(async (val) => val.length <= 8); + +await schema.parseAsync("hello"); +// => "hello" +``` + +### Handling errors + +When validation fails, the `.parse()` method will throw a `ZodError` instance with granular information about the validation issues. + +```ts +try { + Player.parse({ username: 42, xp: "100" }); +} catch (err) { + if (err instanceof z.ZodError) { + err.issues; + /* [ + { + expected: 'string', + code: 'invalid_type', + path: [ 'username' ], + message: 'Invalid input: expected string' + }, + { + expected: 'number', + code: 'invalid_type', + path: [ 'xp' ], + message: 'Invalid input: expected number' + } + ] */ + } +} +``` + +To avoid a `try/catch` block, you can use the `.safeParse()` method to get back a plain result object containing either the successfully parsed data or a `ZodError`. The result type is a [discriminated union](https://www.typescriptlang.org/docs/handbook/2/narrowing.html#discriminated-unions), so you can handle both cases conveniently. + +```ts +const result = Player.safeParse({ username: 42, xp: "100" }); +if (!result.success) { + result.error; // ZodError instance +} else { + result.data; // { username: string; xp: number } +} +``` + +**Note** — If your schema uses certain asynchronous APIs like `async` [refinements](#refine) or [transforms](#transform), you'll need to use the `.safeParseAsync()` method instead. + +```ts +const schema = z.string().refine(async (val) => val.length <= 8); + +await schema.safeParseAsync("hello"); +// => { success: true; data: "hello" } +``` + +### Inferring types + +Zod infers a static type from your schema definitions. You can extract this type with the `z.infer<>` utility and use it however you like. + +```ts +const Player = z.object({ + username: z.string(), + xp: z.number(), +}); + +// extract the inferred type +type Player = z.infer; + +// use it in your code +const player: Player = { username: "billie", xp: 100 }; +``` + +In some cases, the input & output types of a schema can diverge. For instance, the `.transform()` API can convert the input from one type to another. In these cases, you can extract the input and output types independently: + +```ts +const mySchema = z.string().transform((val) => val.length); + +type MySchemaIn = z.input; +// => string + +type MySchemaOut = z.output; // equivalent to z.infer +// number +``` diff --git a/node_modules/zod/index.cjs b/node_modules/zod/index.cjs new file mode 100644 index 00000000..3e30380f --- /dev/null +++ b/node_modules/zod/index.cjs @@ -0,0 +1,33 @@ +"use strict"; +var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + var desc = Object.getOwnPropertyDescriptor(m, k); + if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { + desc = { enumerable: true, get: function() { return m[k]; } }; + } + Object.defineProperty(o, k2, desc); +}) : (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + o[k2] = m[k]; +})); +var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { + Object.defineProperty(o, "default", { enumerable: true, value: v }); +}) : function(o, v) { + o["default"] = v; +}); +var __importStar = (this && this.__importStar) || function (mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); + __setModuleDefault(result, mod); + return result; +}; +var __exportStar = (this && this.__exportStar) || function(m, exports) { + for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p); +}; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.z = void 0; +const z = __importStar(require("./v4/classic/external.cjs")); +exports.z = z; +__exportStar(require("./v4/classic/external.cjs"), exports); +exports.default = z; diff --git a/node_modules/zod/index.d.cts b/node_modules/zod/index.d.cts new file mode 100644 index 00000000..ed2f3c30 --- /dev/null +++ b/node_modules/zod/index.d.cts @@ -0,0 +1,4 @@ +import * as z from "./v4/classic/external.cjs"; +export * from "./v4/classic/external.cjs"; +export { z }; +export default z; diff --git a/node_modules/zod/index.d.ts b/node_modules/zod/index.d.ts new file mode 100644 index 00000000..b0bbaefb --- /dev/null +++ b/node_modules/zod/index.d.ts @@ -0,0 +1,4 @@ +import * as z from "./v4/classic/external.js"; +export * from "./v4/classic/external.js"; +export { z }; +export default z; diff --git a/node_modules/zod/index.js b/node_modules/zod/index.js new file mode 100644 index 00000000..b0bbaefb --- /dev/null +++ b/node_modules/zod/index.js @@ -0,0 +1,4 @@ +import * as z from "./v4/classic/external.js"; +export * from "./v4/classic/external.js"; +export { z }; +export default z; diff --git a/node_modules/zod/locales/index.cjs b/node_modules/zod/locales/index.cjs new file mode 100644 index 00000000..65f2079f --- /dev/null +++ b/node_modules/zod/locales/index.cjs @@ -0,0 +1,17 @@ +"use strict"; +var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + var desc = Object.getOwnPropertyDescriptor(m, k); + if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { + desc = { enumerable: true, get: function() { return m[k]; } }; + } + Object.defineProperty(o, k2, desc); +}) : (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + o[k2] = m[k]; +})); +var __exportStar = (this && this.__exportStar) || function(m, exports) { + for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p); +}; +Object.defineProperty(exports, "__esModule", { value: true }); +__exportStar(require("../v4/locales/index.cjs"), exports); diff --git a/node_modules/zod/locales/index.d.cts b/node_modules/zod/locales/index.d.cts new file mode 100644 index 00000000..cd70ce63 --- /dev/null +++ b/node_modules/zod/locales/index.d.cts @@ -0,0 +1 @@ +export * from "../v4/locales/index.cjs"; diff --git a/node_modules/zod/locales/index.d.ts b/node_modules/zod/locales/index.d.ts new file mode 100644 index 00000000..e6e7dd67 --- /dev/null +++ b/node_modules/zod/locales/index.d.ts @@ -0,0 +1 @@ +export * from "../v4/locales/index.js"; diff --git a/node_modules/zod/locales/index.js b/node_modules/zod/locales/index.js new file mode 100644 index 00000000..e6e7dd67 --- /dev/null +++ b/node_modules/zod/locales/index.js @@ -0,0 +1 @@ +export * from "../v4/locales/index.js"; diff --git a/node_modules/zod/locales/package.json b/node_modules/zod/locales/package.json new file mode 100644 index 00000000..6cc7aaea --- /dev/null +++ b/node_modules/zod/locales/package.json @@ -0,0 +1,6 @@ +{ + "type": "module", + "main": "./index.cjs", + "module": "./index.js", + "types": "./index.d.cts" +} diff --git a/node_modules/zod/mini/index.cjs b/node_modules/zod/mini/index.cjs new file mode 100644 index 00000000..90a31e2c --- /dev/null +++ b/node_modules/zod/mini/index.cjs @@ -0,0 +1,32 @@ +"use strict"; +var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + var desc = Object.getOwnPropertyDescriptor(m, k); + if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { + desc = { enumerable: true, get: function() { return m[k]; } }; + } + Object.defineProperty(o, k2, desc); +}) : (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + o[k2] = m[k]; +})); +var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { + Object.defineProperty(o, "default", { enumerable: true, value: v }); +}) : function(o, v) { + o["default"] = v; +}); +var __importStar = (this && this.__importStar) || function (mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); + __setModuleDefault(result, mod); + return result; +}; +var __exportStar = (this && this.__exportStar) || function(m, exports) { + for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p); +}; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.z = void 0; +const z = __importStar(require("../v4/mini/external.cjs")); +exports.z = z; +__exportStar(require("../v4/mini/external.cjs"), exports); diff --git a/node_modules/zod/mini/index.d.cts b/node_modules/zod/mini/index.d.cts new file mode 100644 index 00000000..bca69bd6 --- /dev/null +++ b/node_modules/zod/mini/index.d.cts @@ -0,0 +1,3 @@ +import * as z from "../v4/mini/external.cjs"; +export * from "../v4/mini/external.cjs"; +export { z }; diff --git a/node_modules/zod/mini/index.d.ts b/node_modules/zod/mini/index.d.ts new file mode 100644 index 00000000..bb95da0a --- /dev/null +++ b/node_modules/zod/mini/index.d.ts @@ -0,0 +1,3 @@ +import * as z from "../v4/mini/external.js"; +export * from "../v4/mini/external.js"; +export { z }; diff --git a/node_modules/zod/mini/index.js b/node_modules/zod/mini/index.js new file mode 100644 index 00000000..bb95da0a --- /dev/null +++ b/node_modules/zod/mini/index.js @@ -0,0 +1,3 @@ +import * as z from "../v4/mini/external.js"; +export * from "../v4/mini/external.js"; +export { z }; diff --git a/node_modules/zod/mini/package.json b/node_modules/zod/mini/package.json new file mode 100644 index 00000000..6cc7aaea --- /dev/null +++ b/node_modules/zod/mini/package.json @@ -0,0 +1,6 @@ +{ + "type": "module", + "main": "./index.cjs", + "module": "./index.js", + "types": "./index.d.cts" +} diff --git a/node_modules/zod/package.json b/node_modules/zod/package.json new file mode 100644 index 00000000..d6bf8353 --- /dev/null +++ b/node_modules/zod/package.json @@ -0,0 +1,135 @@ +{ + "name": "zod", + "version": "4.3.6", + "type": "module", + "license": "MIT", + "author": "Colin McDonnell ", + "description": "TypeScript-first schema declaration and validation library with static type inference", + "homepage": "https://zod.dev", + "llms": "https://zod.dev/llms.txt", + "llmsFull": "https://zod.dev/llms-full.txt", + "mcpServer": "https://mcp.inkeep.com/zod/mcp", + "funding": "https://github.com/sponsors/colinhacks", + "sideEffects": false, + "files": [ + "src", + "**/*.js", + "**/*.mjs", + "**/*.cjs", + "**/*.d.ts", + "**/*.d.mts", + "**/*.d.cts", + "**/package.json" + ], + "keywords": [ + "typescript", + "schema", + "validation", + "type", + "inference" + ], + "main": "./index.cjs", + "types": "./index.d.cts", + "module": "./index.js", + "zshy": { + "exports": { + "./package.json": "./package.json", + ".": "./src/index.ts", + "./mini": "./src/mini/index.ts", + "./locales": "./src/locales/index.ts", + "./v3": "./src/v3/index.ts", + "./v4": "./src/v4/index.ts", + "./v4-mini": "./src/v4-mini/index.ts", + "./v4/mini": "./src/v4/mini/index.ts", + "./v4/core": "./src/v4/core/index.ts", + "./v4/locales": "./src/v4/locales/index.ts", + "./v4/locales/*": "./src/v4/locales/*" + }, + "conditions": { + "@zod/source": "src" + } + }, + "exports": { + "./package.json": "./package.json", + ".": { + "@zod/source": "./src/index.ts", + "types": "./index.d.cts", + "import": "./index.js", + "require": "./index.cjs" + }, + "./mini": { + "@zod/source": "./src/mini/index.ts", + "types": "./mini/index.d.cts", + "import": "./mini/index.js", + "require": "./mini/index.cjs" + }, + "./locales": { + "@zod/source": "./src/locales/index.ts", + "types": "./locales/index.d.cts", + "import": "./locales/index.js", + "require": "./locales/index.cjs" + }, + "./v3": { + "@zod/source": "./src/v3/index.ts", + "types": "./v3/index.d.cts", + "import": "./v3/index.js", + "require": "./v3/index.cjs" + }, + "./v4": { + "@zod/source": "./src/v4/index.ts", + "types": "./v4/index.d.cts", + "import": "./v4/index.js", + "require": "./v4/index.cjs" + }, + "./v4-mini": { + "@zod/source": "./src/v4-mini/index.ts", + "types": "./v4-mini/index.d.cts", + "import": "./v4-mini/index.js", + "require": "./v4-mini/index.cjs" + }, + "./v4/mini": { + "@zod/source": "./src/v4/mini/index.ts", + "types": "./v4/mini/index.d.cts", + "import": "./v4/mini/index.js", + "require": "./v4/mini/index.cjs" + }, + "./v4/core": { + "@zod/source": "./src/v4/core/index.ts", + "types": "./v4/core/index.d.cts", + "import": "./v4/core/index.js", + "require": "./v4/core/index.cjs" + }, + "./v4/locales": { + "@zod/source": "./src/v4/locales/index.ts", + "types": "./v4/locales/index.d.cts", + "import": "./v4/locales/index.js", + "require": "./v4/locales/index.cjs" + }, + "./v4/locales/*": { + "@zod/source": "./src/v4/locales/*", + "types": "./v4/locales/*", + "import": "./v4/locales/*", + "require": "./v4/locales/*" + } + }, + "repository": { + "type": "git", + "url": "git+https://github.com/colinhacks/zod.git" + }, + "bugs": { + "url": "https://github.com/colinhacks/zod/issues" + }, + "support": { + "backing": { + "npm-funding": true + } + }, + "scripts": { + "clean": "git clean -xdf . -e node_modules", + "build": "zshy --project tsconfig.build.json", + "postbuild": "tsx ../../scripts/write-stub-package-jsons.ts && pnpm biome check --write .", + "test:watch": "pnpm vitest", + "test": "pnpm vitest run", + "prepublishOnly": "tsx ../../scripts/check-versions.ts" + } +} diff --git a/node_modules/zod/src/index.ts b/node_modules/zod/src/index.ts new file mode 100644 index 00000000..b0bbaefb --- /dev/null +++ b/node_modules/zod/src/index.ts @@ -0,0 +1,4 @@ +import * as z from "./v4/classic/external.js"; +export * from "./v4/classic/external.js"; +export { z }; +export default z; diff --git a/node_modules/zod/src/locales/index.ts b/node_modules/zod/src/locales/index.ts new file mode 100644 index 00000000..e6e7dd67 --- /dev/null +++ b/node_modules/zod/src/locales/index.ts @@ -0,0 +1 @@ +export * from "../v4/locales/index.js"; diff --git a/node_modules/zod/src/mini/index.ts b/node_modules/zod/src/mini/index.ts new file mode 100644 index 00000000..bb95da0a --- /dev/null +++ b/node_modules/zod/src/mini/index.ts @@ -0,0 +1,3 @@ +import * as z from "../v4/mini/external.js"; +export * from "../v4/mini/external.js"; +export { z }; diff --git a/node_modules/zod/src/v3/ZodError.ts b/node_modules/zod/src/v3/ZodError.ts new file mode 100644 index 00000000..b4c6865c --- /dev/null +++ b/node_modules/zod/src/v3/ZodError.ts @@ -0,0 +1,330 @@ +import type { Primitive } from "./helpers/typeAliases.js"; +import { util, type ZodParsedType } from "./helpers/util.js"; +import type { TypeOf, ZodType } from "./index.js"; + +type allKeys = T extends any ? keyof T : never; + +export type inferFlattenedErrors, U = string> = typeToFlattenedError, U>; +export type typeToFlattenedError = { + formErrors: U[]; + fieldErrors: { + [P in allKeys]?: U[]; + }; +}; + +export const ZodIssueCode = util.arrayToEnum([ + "invalid_type", + "invalid_literal", + "custom", + "invalid_union", + "invalid_union_discriminator", + "invalid_enum_value", + "unrecognized_keys", + "invalid_arguments", + "invalid_return_type", + "invalid_date", + "invalid_string", + "too_small", + "too_big", + "invalid_intersection_types", + "not_multiple_of", + "not_finite", +]); + +export type ZodIssueCode = keyof typeof ZodIssueCode; + +export type ZodIssueBase = { + path: (string | number)[]; + message?: string | undefined; +}; + +export interface ZodInvalidTypeIssue extends ZodIssueBase { + code: typeof ZodIssueCode.invalid_type; + expected: ZodParsedType; + received: ZodParsedType; +} + +export interface ZodInvalidLiteralIssue extends ZodIssueBase { + code: typeof ZodIssueCode.invalid_literal; + expected: unknown; + received: unknown; +} + +export interface ZodUnrecognizedKeysIssue extends ZodIssueBase { + code: typeof ZodIssueCode.unrecognized_keys; + keys: string[]; +} + +export interface ZodInvalidUnionIssue extends ZodIssueBase { + code: typeof ZodIssueCode.invalid_union; + unionErrors: ZodError[]; +} + +export interface ZodInvalidUnionDiscriminatorIssue extends ZodIssueBase { + code: typeof ZodIssueCode.invalid_union_discriminator; + options: Primitive[]; +} + +export interface ZodInvalidEnumValueIssue extends ZodIssueBase { + received: string | number; + code: typeof ZodIssueCode.invalid_enum_value; + options: (string | number)[]; +} + +export interface ZodInvalidArgumentsIssue extends ZodIssueBase { + code: typeof ZodIssueCode.invalid_arguments; + argumentsError: ZodError; +} + +export interface ZodInvalidReturnTypeIssue extends ZodIssueBase { + code: typeof ZodIssueCode.invalid_return_type; + returnTypeError: ZodError; +} + +export interface ZodInvalidDateIssue extends ZodIssueBase { + code: typeof ZodIssueCode.invalid_date; +} + +export type StringValidation = + | "email" + | "url" + | "emoji" + | "uuid" + | "nanoid" + | "regex" + | "cuid" + | "cuid2" + | "ulid" + | "datetime" + | "date" + | "time" + | "duration" + | "ip" + | "cidr" + | "base64" + | "jwt" + | "base64url" + | { includes: string; position?: number | undefined } + | { startsWith: string } + | { endsWith: string }; + +export interface ZodInvalidStringIssue extends ZodIssueBase { + code: typeof ZodIssueCode.invalid_string; + validation: StringValidation; +} + +export interface ZodTooSmallIssue extends ZodIssueBase { + code: typeof ZodIssueCode.too_small; + minimum: number | bigint; + inclusive: boolean; + exact?: boolean; + type: "array" | "string" | "number" | "set" | "date" | "bigint"; +} + +export interface ZodTooBigIssue extends ZodIssueBase { + code: typeof ZodIssueCode.too_big; + maximum: number | bigint; + inclusive: boolean; + exact?: boolean; + type: "array" | "string" | "number" | "set" | "date" | "bigint"; +} + +export interface ZodInvalidIntersectionTypesIssue extends ZodIssueBase { + code: typeof ZodIssueCode.invalid_intersection_types; +} + +export interface ZodNotMultipleOfIssue extends ZodIssueBase { + code: typeof ZodIssueCode.not_multiple_of; + multipleOf: number | bigint; +} + +export interface ZodNotFiniteIssue extends ZodIssueBase { + code: typeof ZodIssueCode.not_finite; +} + +export interface ZodCustomIssue extends ZodIssueBase { + code: typeof ZodIssueCode.custom; + params?: { [k: string]: any }; +} + +export type DenormalizedError = { [k: string]: DenormalizedError | string[] }; + +export type ZodIssueOptionalMessage = + | ZodInvalidTypeIssue + | ZodInvalidLiteralIssue + | ZodUnrecognizedKeysIssue + | ZodInvalidUnionIssue + | ZodInvalidUnionDiscriminatorIssue + | ZodInvalidEnumValueIssue + | ZodInvalidArgumentsIssue + | ZodInvalidReturnTypeIssue + | ZodInvalidDateIssue + | ZodInvalidStringIssue + | ZodTooSmallIssue + | ZodTooBigIssue + | ZodInvalidIntersectionTypesIssue + | ZodNotMultipleOfIssue + | ZodNotFiniteIssue + | ZodCustomIssue; + +export type ZodIssue = ZodIssueOptionalMessage & { + fatal?: boolean | undefined; + message: string; +}; + +export const quotelessJson = (obj: any) => { + const json = JSON.stringify(obj, null, 2); + return json.replace(/"([^"]+)":/g, "$1:"); +}; + +type recursiveZodFormattedError = T extends [any, ...any[]] + ? { [K in keyof T]?: ZodFormattedError } + : T extends any[] + ? { [k: number]: ZodFormattedError } + : T extends object + ? { [K in keyof T]?: ZodFormattedError } + : unknown; + +export type ZodFormattedError = { + _errors: U[]; +} & recursiveZodFormattedError>; + +export type inferFormattedError, U = string> = ZodFormattedError, U>; + +export class ZodError extends Error { + issues: ZodIssue[] = []; + + get errors() { + return this.issues; + } + + constructor(issues: ZodIssue[]) { + super(); + + const actualProto = new.target.prototype; + if (Object.setPrototypeOf) { + // eslint-disable-next-line ban/ban + Object.setPrototypeOf(this, actualProto); + } else { + (this as any).__proto__ = actualProto; + } + this.name = "ZodError"; + this.issues = issues; + } + + format(): ZodFormattedError; + format(mapper: (issue: ZodIssue) => U): ZodFormattedError; + format(_mapper?: any) { + const mapper: (issue: ZodIssue) => any = + _mapper || + function (issue: ZodIssue) { + return issue.message; + }; + const fieldErrors: ZodFormattedError = { _errors: [] } as any; + const processError = (error: ZodError) => { + for (const issue of error.issues) { + if (issue.code === "invalid_union") { + issue.unionErrors.map(processError); + } else if (issue.code === "invalid_return_type") { + processError(issue.returnTypeError); + } else if (issue.code === "invalid_arguments") { + processError(issue.argumentsError); + } else if (issue.path.length === 0) { + (fieldErrors as any)._errors.push(mapper(issue)); + } else { + let curr: any = fieldErrors; + let i = 0; + while (i < issue.path.length) { + const el = issue.path[i]!; + const terminal = i === issue.path.length - 1; + + if (!terminal) { + curr[el] = curr[el] || { _errors: [] }; + // if (typeof el === "string") { + // curr[el] = curr[el] || { _errors: [] }; + // } else if (typeof el === "number") { + // const errorArray: any = []; + // errorArray._errors = []; + // curr[el] = curr[el] || errorArray; + // } + } else { + curr[el] = curr[el] || { _errors: [] }; + curr[el]._errors.push(mapper(issue)); + } + + curr = curr[el]; + i++; + } + } + } + }; + + processError(this); + return fieldErrors; + } + + static create = (issues: ZodIssue[]) => { + const error = new ZodError(issues); + return error; + }; + + static assert(value: unknown): asserts value is ZodError { + if (!(value instanceof ZodError)) { + throw new Error(`Not a ZodError: ${value}`); + } + } + + override toString() { + return this.message; + } + override get message() { + return JSON.stringify(this.issues, util.jsonStringifyReplacer, 2); + } + + get isEmpty(): boolean { + return this.issues.length === 0; + } + + addIssue = (sub: ZodIssue) => { + this.issues = [...this.issues, sub]; + }; + + addIssues = (subs: ZodIssue[] = []) => { + this.issues = [...this.issues, ...subs]; + }; + + flatten(): typeToFlattenedError; + flatten(mapper?: (issue: ZodIssue) => U): typeToFlattenedError; + flatten(mapper: (issue: ZodIssue) => U = (issue: ZodIssue) => issue.message as any): any { + const fieldErrors: any = Object.create(null); + const formErrors: U[] = []; + for (const sub of this.issues) { + if (sub.path.length > 0) { + const firstEl = sub.path[0]!; + fieldErrors[firstEl] = fieldErrors[firstEl] || []; + fieldErrors[firstEl].push(mapper(sub)); + } else { + formErrors.push(mapper(sub)); + } + } + return { formErrors, fieldErrors }; + } + + get formErrors() { + return this.flatten(); + } +} + +type stripPath = T extends any ? util.OmitKeys : never; + +export type IssueData = stripPath & { + path?: (string | number)[]; + fatal?: boolean | undefined; +}; + +export type ErrorMapCtx = { + defaultError: string; + data: any; +}; + +export type ZodErrorMap = (issue: ZodIssueOptionalMessage, _ctx: ErrorMapCtx) => { message: string }; diff --git a/node_modules/zod/src/v3/benchmarks/datetime.ts b/node_modules/zod/src/v3/benchmarks/datetime.ts new file mode 100644 index 00000000..85552c25 --- /dev/null +++ b/node_modules/zod/src/v3/benchmarks/datetime.ts @@ -0,0 +1,58 @@ +import Benchmark from "benchmark"; + +const datetimeValidationSuite = new Benchmark.Suite("datetime"); + +const DATA = "2021-01-01"; +const MONTHS_31 = new Set([1, 3, 5, 7, 8, 10, 12]); +const MONTHS_30 = new Set([4, 6, 9, 11]); + +const simpleDatetimeRegex = /^(\d{4})-(\d{2})-(\d{2})$/; +const datetimeRegexNoLeapYearValidation = + /^\d{4}-((0[13578]|10|12)-31|(0[13-9]|1[0-2])-30|(0[1-9]|1[0-2])-(0[1-9]|1\d|2\d))$/; +const datetimeRegexWithLeapYearValidation = + /^((\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-((0[13578]|1[02])-(0[1-9]|[12]\d|3[01])|(0[469]|11)-(0[1-9]|[12]\d|30)|(02)-(0[1-9]|1\d|2[0-8])))$/; + +datetimeValidationSuite + .add("new Date()", () => { + return !Number.isNaN(new Date(DATA).getTime()); + }) + .add("regex (no validation)", () => { + return simpleDatetimeRegex.test(DATA); + }) + .add("regex (no leap year)", () => { + return datetimeRegexNoLeapYearValidation.test(DATA); + }) + .add("regex (w/ leap year)", () => { + return datetimeRegexWithLeapYearValidation.test(DATA); + }) + .add("capture groups + code", () => { + const match = DATA.match(simpleDatetimeRegex); + if (!match) return false; + + // Extract year, month, and day from the capture groups + const year = Number.parseInt(match[1], 10); + const month = Number.parseInt(match[2], 10); // month is 0-indexed in JavaScript Date, so subtract 1 + const day = Number.parseInt(match[3], 10); + + if (month === 2) { + if ((year % 4 === 0 && year % 100 !== 0) || year % 400 === 0) { + return day <= 29; + } + return day <= 28; + } + if (MONTHS_30.has(month)) { + return day <= 30; + } + if (MONTHS_31.has(month)) { + return day <= 31; + } + return false; + }) + + .on("cycle", (e: Benchmark.Event) => { + console.log(`${datetimeValidationSuite.name!}: ${e.target}`); + }); + +export default { + suites: [datetimeValidationSuite], +}; diff --git a/node_modules/zod/src/v3/benchmarks/discriminatedUnion.ts b/node_modules/zod/src/v3/benchmarks/discriminatedUnion.ts new file mode 100644 index 00000000..47737e6c --- /dev/null +++ b/node_modules/zod/src/v3/benchmarks/discriminatedUnion.ts @@ -0,0 +1,80 @@ +import Benchmark from "benchmark"; + +import { z } from "zod/v3"; + +const doubleSuite = new Benchmark.Suite("z.discriminatedUnion: double"); +const manySuite = new Benchmark.Suite("z.discriminatedUnion: many"); + +const aSchema = z.object({ + type: z.literal("a"), +}); +const objA = { + type: "a", +}; + +const bSchema = z.object({ + type: z.literal("b"), +}); +const objB = { + type: "b", +}; + +const cSchema = z.object({ + type: z.literal("c"), +}); +const objC = { + type: "c", +}; + +const dSchema = z.object({ + type: z.literal("d"), +}); + +const double = z.discriminatedUnion("type", [aSchema, bSchema]); +const many = z.discriminatedUnion("type", [aSchema, bSchema, cSchema, dSchema]); + +doubleSuite + .add("valid: a", () => { + double.parse(objA); + }) + .add("valid: b", () => { + double.parse(objB); + }) + .add("invalid: null", () => { + try { + double.parse(null); + } catch (_err) {} + }) + .add("invalid: wrong shape", () => { + try { + double.parse(objC); + } catch (_err) {} + }) + .on("cycle", (e: Benchmark.Event) => { + console.log(`${(doubleSuite as any).name}: ${e.target}`); + }); + +manySuite + .add("valid: a", () => { + many.parse(objA); + }) + .add("valid: c", () => { + many.parse(objC); + }) + .add("invalid: null", () => { + try { + many.parse(null); + } catch (_err) {} + }) + .add("invalid: wrong shape", () => { + try { + many.parse({ type: "unknown" }); + } catch (_err) {} + }) + .on("cycle", (e: Benchmark.Event) => { + console.log(`${(manySuite as any).name}: ${e.target}`); + }); + +export default { + suites: [doubleSuite, manySuite], +}; diff --git a/node_modules/zod/src/v3/benchmarks/index.ts b/node_modules/zod/src/v3/benchmarks/index.ts new file mode 100644 index 00000000..ca81c5bb --- /dev/null +++ b/node_modules/zod/src/v3/benchmarks/index.ts @@ -0,0 +1,59 @@ +import type Benchmark from "benchmark"; + +import datetimeBenchmarks from "./datetime.js"; +import discriminatedUnionBenchmarks from "./discriminatedUnion.js"; +import ipv4Benchmarks from "./ipv4.js"; +import objectBenchmarks from "./object.js"; +import primitiveBenchmarks from "./primitives.js"; +import realworld from "./realworld.js"; +import stringBenchmarks from "./string.js"; +import unionBenchmarks from "./union.js"; + +const argv = process.argv.slice(2); +let suites: Benchmark.Suite[] = []; + +if (!argv.length) { + suites = [ + ...realworld.suites, + ...primitiveBenchmarks.suites, + ...stringBenchmarks.suites, + ...objectBenchmarks.suites, + ...unionBenchmarks.suites, + ...discriminatedUnionBenchmarks.suites, + ]; +} else { + if (argv.includes("--realworld")) { + suites.push(...realworld.suites); + } + if (argv.includes("--primitives")) { + suites.push(...primitiveBenchmarks.suites); + } + if (argv.includes("--string")) { + suites.push(...stringBenchmarks.suites); + } + if (argv.includes("--object")) { + suites.push(...objectBenchmarks.suites); + } + if (argv.includes("--union")) { + suites.push(...unionBenchmarks.suites); + } + if (argv.includes("--discriminatedUnion")) { + suites.push(...datetimeBenchmarks.suites); + } + if (argv.includes("--datetime")) { + suites.push(...datetimeBenchmarks.suites); + } + if (argv.includes("--ipv4")) { + suites.push(...ipv4Benchmarks.suites); + } +} + +for (const suite of suites) { + suite.run({}); +} + +// exit on Ctrl-C +process.on("SIGINT", function () { + console.log("Exiting..."); + process.exit(); +}); diff --git a/node_modules/zod/src/v3/benchmarks/ipv4.ts b/node_modules/zod/src/v3/benchmarks/ipv4.ts new file mode 100644 index 00000000..913ffd41 --- /dev/null +++ b/node_modules/zod/src/v3/benchmarks/ipv4.ts @@ -0,0 +1,57 @@ +import Benchmark from "benchmark"; + +const suite = new Benchmark.Suite("ipv4"); + +const DATA = "127.0.0.1"; +const ipv4RegexA = + /^(((25[0-5])|(2[0-4][0-9])|(1[0-9]{2})|([0-9]{1,2}))\.){3}((25[0-5])|(2[0-4][0-9])|(1[0-9]{2})|([0-9]{1,2}))$/; +const ipv4RegexB = + /^(?:(?:(?=(25[0-5]))\1|(?=(2[0-4][0-9]))\2|(?=(1[0-9]{2}))\3|(?=([0-9]{1,2}))\4)\.){3}(?:(?=(25[0-5]))\5|(?=(2[0-4][0-9]))\6|(?=(1[0-9]{2}))\7|(?=([0-9]{1,2}))\8)$/; +const ipv4RegexC = /^(?:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)\.){3}(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)$/; +const ipv4RegexD = /^(\b25[0-5]|\b2[0-4][0-9]|\b[01]?[0-9][0-9]?)(\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$/; +const ipv4RegexE = /^((25[0-5]|(2[0-4]|1\d|[1-9]|)\d)\.){3}(25[0-5]|(2[0-4]|1\d|[1-9]|)\d)$/; +const ipv4RegexF = /^((25[0-5]|(2[0-4]|1\d|[1-9]|)\d)\.?\b){4}$/; +const ipv4RegexG = /^((25[0-5]|(2[0-4]|1\d|[1-9]|)\d)(\.(?!$)|$)){4}$/; +const ipv4RegexH = /^((25[0-5]|(2[0-4]|1[0-9]|[1-9]|)[0-9])(\.(?!$)|$)){4}$/; +const ipv4RegexI = + /^(?:(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\.){3}(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])$/; + +suite + .add("A", () => { + return ipv4RegexA.test(DATA); + }) + .add("B", () => { + return ipv4RegexB.test(DATA); + }) + .add("C", () => { + return ipv4RegexC.test(DATA); + }) + .add("D", () => { + return ipv4RegexD.test(DATA); + }) + .add("E", () => { + return ipv4RegexE.test(DATA); + }) + .add("F", () => { + return ipv4RegexF.test(DATA); + }) + .add("G", () => { + return ipv4RegexG.test(DATA); + }) + .add("H", () => { + return ipv4RegexH.test(DATA); + }) + .add("I", () => { + return ipv4RegexI.test(DATA); + }) + .on("cycle", (e: Benchmark.Event) => { + console.log(`${suite.name!}: ${e.target}`); + }); + +export default { + suites: [suite], +}; + +if (require.main === module) { + suite.run(); +} diff --git a/node_modules/zod/src/v3/benchmarks/object.ts b/node_modules/zod/src/v3/benchmarks/object.ts new file mode 100644 index 00000000..3c1da102 --- /dev/null +++ b/node_modules/zod/src/v3/benchmarks/object.ts @@ -0,0 +1,69 @@ +import Benchmark from "benchmark"; + +import { z } from "zod/v3"; + +const emptySuite = new Benchmark.Suite("z.object: empty"); +const shortSuite = new Benchmark.Suite("z.object: short"); +const longSuite = new Benchmark.Suite("z.object: long"); + +const empty = z.object({}); +const short = z.object({ + string: z.string(), +}); +const long = z.object({ + string: z.string(), + number: z.number(), + boolean: z.boolean(), +}); + +emptySuite + .add("valid", () => { + empty.parse({}); + }) + .add("valid: extra keys", () => { + empty.parse({ string: "string" }); + }) + .add("invalid: null", () => { + try { + empty.parse(null); + } catch (_err) {} + }) + .on("cycle", (e: Benchmark.Event) => { + console.log(`${(emptySuite as any).name}: ${e.target}`); + }); + +shortSuite + .add("valid", () => { + short.parse({ string: "string" }); + }) + .add("valid: extra keys", () => { + short.parse({ string: "string", number: 42 }); + }) + .add("invalid: null", () => { + try { + short.parse(null); + } catch (_err) {} + }) + .on("cycle", (e: Benchmark.Event) => { + console.log(`${(shortSuite as any).name}: ${e.target}`); + }); + +longSuite + .add("valid", () => { + long.parse({ string: "string", number: 42, boolean: true }); + }) + .add("valid: extra keys", () => { + long.parse({ string: "string", number: 42, boolean: true, list: [] }); + }) + .add("invalid: null", () => { + try { + long.parse(null); + } catch (_err) {} + }) + .on("cycle", (e: Benchmark.Event) => { + console.log(`${(longSuite as any).name}: ${e.target}`); + }); + +export default { + suites: [emptySuite, shortSuite, longSuite], +}; diff --git a/node_modules/zod/src/v3/benchmarks/primitives.ts b/node_modules/zod/src/v3/benchmarks/primitives.ts new file mode 100644 index 00000000..fd61b38f --- /dev/null +++ b/node_modules/zod/src/v3/benchmarks/primitives.ts @@ -0,0 +1,162 @@ +import Benchmark from "benchmark"; + +import { z } from "zod/v3"; +import { Mocker } from "../tests/Mocker.js"; + +const val = new Mocker(); + +const enumSuite = new Benchmark.Suite("z.enum"); +const enumSchema = z.enum(["a", "b", "c"]); + +enumSuite + .add("valid", () => { + enumSchema.parse("a"); + }) + .add("invalid", () => { + try { + enumSchema.parse("x"); + } catch (_e: any) {} + }) + .on("cycle", (e: Benchmark.Event) => { + console.log(`z.enum: ${e.target}`); + }); + +const longEnumSuite = new Benchmark.Suite("long z.enum"); +const longEnumSchema = z.enum([ + "one", + "two", + "three", + "four", + "five", + "six", + "seven", + "eight", + "nine", + "ten", + "eleven", + "twelve", + "thirteen", + "fourteen", + "fifteen", + "sixteen", + "seventeen", +]); + +longEnumSuite + .add("valid", () => { + longEnumSchema.parse("five"); + }) + .add("invalid", () => { + try { + longEnumSchema.parse("invalid"); + } catch (_e: any) {} + }) + .on("cycle", (e: Benchmark.Event) => { + console.log(`long z.enum: ${e.target}`); + }); + +const undefinedSuite = new Benchmark.Suite("z.undefined"); +const undefinedSchema = z.undefined(); + +undefinedSuite + .add("valid", () => { + undefinedSchema.parse(undefined); + }) + .add("invalid", () => { + try { + undefinedSchema.parse(1); + } catch (_e: any) {} + }) + .on("cycle", (e: Benchmark.Event) => { + console.log(`z.undefined: ${e.target}`); + }); + +const literalSuite = new Benchmark.Suite("z.literal"); +const short = "short"; +const bad = "bad"; +const literalSchema = z.literal("short"); + +literalSuite + .add("valid", () => { + literalSchema.parse(short); + }) + .add("invalid", () => { + try { + literalSchema.parse(bad); + } catch (_e: any) {} + }) + .on("cycle", (e: Benchmark.Event) => { + console.log(`z.literal: ${e.target}`); + }); + +const numberSuite = new Benchmark.Suite("z.number"); +const numberSchema = z.number().int(); + +numberSuite + .add("valid", () => { + numberSchema.parse(1); + }) + .add("invalid type", () => { + try { + numberSchema.parse("bad"); + } catch (_e: any) {} + }) + .add("invalid number", () => { + try { + numberSchema.parse(0.5); + } catch (_e: any) {} + }) + .on("cycle", (e: Benchmark.Event) => { + console.log(`z.number: ${e.target}`); + }); + +const dateSuite = new Benchmark.Suite("z.date"); + +const plainDate = z.date(); +const minMaxDate = z.date().min(new Date("2021-01-01")).max(new Date("2030-01-01")); + +dateSuite + .add("valid", () => { + plainDate.parse(new Date()); + }) + .add("invalid", () => { + try { + plainDate.parse(1); + } catch (_e: any) {} + }) + .add("valid min and max", () => { + minMaxDate.parse(new Date("2023-01-01")); + }) + .add("invalid min", () => { + try { + minMaxDate.parse(new Date("2019-01-01")); + } catch (_e: any) {} + }) + .add("invalid max", () => { + try { + minMaxDate.parse(new Date("2031-01-01")); + } catch (_e: any) {} + }) + .on("cycle", (e: Benchmark.Event) => { + console.log(`z.date: ${e.target}`); + }); + +const symbolSuite = new Benchmark.Suite("z.symbol"); +const symbolSchema = z.symbol(); + +symbolSuite + .add("valid", () => { + symbolSchema.parse(val.symbol); + }) + .add("invalid", () => { + try { + symbolSchema.parse(1); + } catch (_e: any) {} + }) + .on("cycle", (e: Benchmark.Event) => { + console.log(`z.symbol: ${e.target}`); + }); + +export default { + suites: [enumSuite, longEnumSuite, undefinedSuite, literalSuite, numberSuite, dateSuite, symbolSuite], +}; diff --git a/node_modules/zod/src/v3/benchmarks/realworld.ts b/node_modules/zod/src/v3/benchmarks/realworld.ts new file mode 100644 index 00000000..d64c4f0d --- /dev/null +++ b/node_modules/zod/src/v3/benchmarks/realworld.ts @@ -0,0 +1,63 @@ +import Benchmark from "benchmark"; + +import { z } from "zod/v3"; + +const shortSuite = new Benchmark.Suite("realworld"); + +const People = z.array( + z.object({ + type: z.literal("person"), + hair: z.enum(["blue", "brown"]), + active: z.boolean(), + name: z.string(), + age: z.number().int(), + hobbies: z.array(z.string()), + address: z.object({ + street: z.string(), + zip: z.string(), + country: z.string(), + }), + }) +); + +let i = 0; + +function num() { + return ++i; +} + +function str() { + return (++i % 100).toString(16); +} + +function array(fn: () => T): T[] { + return Array.from({ length: ++i % 10 }, () => fn()); +} + +const people = Array.from({ length: 100 }, () => { + return { + type: "person", + hair: i % 2 ? "blue" : "brown", + active: !!(i % 2), + name: str(), + age: num(), + hobbies: array(str), + address: { + street: str(), + zip: str(), + country: str(), + }, + }; +}); + +shortSuite + .add("valid", () => { + People.parse(people); + }) + .on("cycle", (e: Benchmark.Event) => { + console.log(`${(shortSuite as any).name}: ${e.target}`); + }); + +export default { + suites: [shortSuite], +}; diff --git a/node_modules/zod/src/v3/benchmarks/string.ts b/node_modules/zod/src/v3/benchmarks/string.ts new file mode 100644 index 00000000..6b3d29f9 --- /dev/null +++ b/node_modules/zod/src/v3/benchmarks/string.ts @@ -0,0 +1,55 @@ +import Benchmark from "benchmark"; + +import { z } from "zod/v3"; + +const SUITE_NAME = "z.string"; +const suite = new Benchmark.Suite(SUITE_NAME); + +const empty = ""; +const short = "short"; +const long = "long".repeat(256); +const manual = (str: unknown) => { + if (typeof str !== "string") { + throw new Error("Not a string"); + } + + return str; +}; +const stringSchema = z.string(); +const optionalStringSchema = z.string().optional(); +const optionalNullableStringSchema = z.string().optional().nullable(); + +suite + .add("empty string", () => { + stringSchema.parse(empty); + }) + .add("short string", () => { + stringSchema.parse(short); + }) + .add("long string", () => { + stringSchema.parse(long); + }) + .add("optional string", () => { + optionalStringSchema.parse(long); + }) + .add("nullable string", () => { + optionalNullableStringSchema.parse(long); + }) + .add("nullable (null) string", () => { + optionalNullableStringSchema.parse(null); + }) + .add("invalid: null", () => { + try { + stringSchema.parse(null); + } catch (_err) {} + }) + .add("manual parser: long", () => { + manual(long); + }) + .on("cycle", (e: Benchmark.Event) => { + console.log(`${SUITE_NAME}: ${e.target}`); + }); + +export default { + suites: [suite], +}; diff --git a/node_modules/zod/src/v3/benchmarks/union.ts b/node_modules/zod/src/v3/benchmarks/union.ts new file mode 100644 index 00000000..d716dcef --- /dev/null +++ b/node_modules/zod/src/v3/benchmarks/union.ts @@ -0,0 +1,80 @@ +import Benchmark from "benchmark"; + +import { z } from "zod/v3"; + +const doubleSuite = new Benchmark.Suite("z.union: double"); +const manySuite = new Benchmark.Suite("z.union: many"); + +const aSchema = z.object({ + type: z.literal("a"), +}); +const objA = { + type: "a", +}; + +const bSchema = z.object({ + type: z.literal("b"), +}); +const objB = { + type: "b", +}; + +const cSchema = z.object({ + type: z.literal("c"), +}); +const objC = { + type: "c", +}; + +const dSchema = z.object({ + type: z.literal("d"), +}); + +const double = z.union([aSchema, bSchema]); +const many = z.union([aSchema, bSchema, cSchema, dSchema]); + +doubleSuite + .add("valid: a", () => { + double.parse(objA); + }) + .add("valid: b", () => { + double.parse(objB); + }) + .add("invalid: null", () => { + try { + double.parse(null); + } catch (_err) {} + }) + .add("invalid: wrong shape", () => { + try { + double.parse(objC); + } catch (_err) {} + }) + .on("cycle", (e: Benchmark.Event) => { + console.log(`${(doubleSuite as any).name}: ${e.target}`); + }); + +manySuite + .add("valid: a", () => { + many.parse(objA); + }) + .add("valid: c", () => { + many.parse(objC); + }) + .add("invalid: null", () => { + try { + many.parse(null); + } catch (_err) {} + }) + .add("invalid: wrong shape", () => { + try { + many.parse({ type: "unknown" }); + } catch (_err) {} + }) + .on("cycle", (e: Benchmark.Event) => { + console.log(`${(manySuite as any).name}: ${e.target}`); + }); + +export default { + suites: [doubleSuite, manySuite], +}; diff --git a/node_modules/zod/src/v3/errors.ts b/node_modules/zod/src/v3/errors.ts new file mode 100644 index 00000000..3c0dae65 --- /dev/null +++ b/node_modules/zod/src/v3/errors.ts @@ -0,0 +1,13 @@ +import type { ZodErrorMap } from "./ZodError.js"; +import defaultErrorMap from "./locales/en.js"; + +let overrideErrorMap = defaultErrorMap; +export { defaultErrorMap }; + +export function setErrorMap(map: ZodErrorMap) { + overrideErrorMap = map; +} + +export function getErrorMap() { + return overrideErrorMap; +} diff --git a/node_modules/zod/src/v3/external.ts b/node_modules/zod/src/v3/external.ts new file mode 100644 index 00000000..f0a4be4c --- /dev/null +++ b/node_modules/zod/src/v3/external.ts @@ -0,0 +1,6 @@ +export * from "./errors.js"; +export * from "./helpers/parseUtil.js"; +export * from "./helpers/typeAliases.js"; +export * from "./helpers/util.js"; +export * from "./types.js"; +export * from "./ZodError.js"; diff --git a/node_modules/zod/src/v3/helpers/enumUtil.ts b/node_modules/zod/src/v3/helpers/enumUtil.ts new file mode 100644 index 00000000..526b2273 --- /dev/null +++ b/node_modules/zod/src/v3/helpers/enumUtil.ts @@ -0,0 +1,17 @@ +export namespace enumUtil { + type UnionToIntersectionFn = (T extends unknown ? (k: () => T) => void : never) extends ( + k: infer Intersection + ) => void + ? Intersection + : never; + + type GetUnionLast = UnionToIntersectionFn extends () => infer Last ? Last : never; + + type UnionToTuple = [T] extends [never] + ? Tuple + : UnionToTuple>, [GetUnionLast, ...Tuple]>; + + type CastToStringTuple = T extends [string, ...string[]] ? T : never; + + export type UnionToTupleString = CastToStringTuple>; +} diff --git a/node_modules/zod/src/v3/helpers/errorUtil.ts b/node_modules/zod/src/v3/helpers/errorUtil.ts new file mode 100644 index 00000000..319ef6b7 --- /dev/null +++ b/node_modules/zod/src/v3/helpers/errorUtil.ts @@ -0,0 +1,8 @@ +export namespace errorUtil { + export type ErrMessage = string | { message?: string | undefined }; + export const errToObj = (message?: ErrMessage): { message?: string | undefined } => + typeof message === "string" ? { message } : message || {}; + // biome-ignore lint: + export const toString = (message?: ErrMessage): string | undefined => + typeof message === "string" ? message : message?.message; +} diff --git a/node_modules/zod/src/v3/helpers/parseUtil.ts b/node_modules/zod/src/v3/helpers/parseUtil.ts new file mode 100644 index 00000000..1076ad9d --- /dev/null +++ b/node_modules/zod/src/v3/helpers/parseUtil.ts @@ -0,0 +1,176 @@ +import type { IssueData, ZodErrorMap, ZodIssue } from "../ZodError.js"; +import { getErrorMap } from "../errors.js"; +import defaultErrorMap from "../locales/en.js"; +import type { ZodParsedType } from "./util.js"; + +export const makeIssue = (params: { + data: any; + path: (string | number)[]; + errorMaps: ZodErrorMap[]; + issueData: IssueData; +}): ZodIssue => { + const { data, path, errorMaps, issueData } = params; + const fullPath = [...path, ...(issueData.path || [])]; + const fullIssue = { + ...issueData, + path: fullPath, + }; + + if (issueData.message !== undefined) { + return { + ...issueData, + path: fullPath, + message: issueData.message, + }; + } + + let errorMessage = ""; + const maps = errorMaps + .filter((m) => !!m) + .slice() + .reverse(); + for (const map of maps) { + errorMessage = map(fullIssue, { data, defaultError: errorMessage }).message; + } + + return { + ...issueData, + path: fullPath, + message: errorMessage, + }; +}; + +export type ParseParams = { + path: (string | number)[]; + errorMap: ZodErrorMap; + async: boolean; +}; + +export type ParsePathComponent = string | number; +export type ParsePath = ParsePathComponent[]; +export const EMPTY_PATH: ParsePath = []; + +export interface ParseContext { + readonly common: { + readonly issues: ZodIssue[]; + readonly contextualErrorMap?: ZodErrorMap | undefined; + readonly async: boolean; + }; + readonly path: ParsePath; + readonly schemaErrorMap?: ZodErrorMap | undefined; + readonly parent: ParseContext | null; + readonly data: any; + readonly parsedType: ZodParsedType; +} + +export type ParseInput = { + data: any; + path: (string | number)[]; + parent: ParseContext; +}; + +export function addIssueToContext(ctx: ParseContext, issueData: IssueData): void { + const overrideMap = getErrorMap(); + const issue = makeIssue({ + issueData: issueData, + data: ctx.data, + path: ctx.path, + errorMaps: [ + ctx.common.contextualErrorMap, // contextual error map is first priority + ctx.schemaErrorMap, // then schema-bound map if available + overrideMap, // then global override map + overrideMap === defaultErrorMap ? undefined : defaultErrorMap, // then global default map + ].filter((x) => !!x), + }); + ctx.common.issues.push(issue); +} + +export type ObjectPair = { + key: SyncParseReturnType; + value: SyncParseReturnType; +}; +export class ParseStatus { + value: "aborted" | "dirty" | "valid" = "valid"; + dirty(): void { + if (this.value === "valid") this.value = "dirty"; + } + abort(): void { + if (this.value !== "aborted") this.value = "aborted"; + } + + static mergeArray(status: ParseStatus, results: SyncParseReturnType[]): SyncParseReturnType { + const arrayValue: any[] = []; + for (const s of results) { + if (s.status === "aborted") return INVALID; + if (s.status === "dirty") status.dirty(); + arrayValue.push(s.value); + } + + return { status: status.value, value: arrayValue }; + } + + static async mergeObjectAsync( + status: ParseStatus, + pairs: { key: ParseReturnType; value: ParseReturnType }[] + ): Promise> { + const syncPairs: ObjectPair[] = []; + for (const pair of pairs) { + const key = await pair.key; + const value = await pair.value; + syncPairs.push({ + key, + value, + }); + } + return ParseStatus.mergeObjectSync(status, syncPairs); + } + + static mergeObjectSync( + status: ParseStatus, + pairs: { + key: SyncParseReturnType; + value: SyncParseReturnType; + alwaysSet?: boolean; + }[] + ): SyncParseReturnType { + const finalObject: any = {}; + for (const pair of pairs) { + const { key, value } = pair; + if (key.status === "aborted") return INVALID; + if (value.status === "aborted") return INVALID; + if (key.status === "dirty") status.dirty(); + if (value.status === "dirty") status.dirty(); + + if (key.value !== "__proto__" && (typeof value.value !== "undefined" || pair.alwaysSet)) { + finalObject[key.value] = value.value; + } + } + + return { status: status.value, value: finalObject }; + } +} +export interface ParseResult { + status: "aborted" | "dirty" | "valid"; + data: any; +} + +export type INVALID = { status: "aborted" }; +export const INVALID: INVALID = Object.freeze({ + status: "aborted", +}); + +export type DIRTY = { status: "dirty"; value: T }; +export const DIRTY = (value: T): DIRTY => ({ status: "dirty", value }); + +export type OK = { status: "valid"; value: T }; +export const OK = (value: T): OK => ({ status: "valid", value }); + +export type SyncParseReturnType = OK | DIRTY | INVALID; +export type AsyncParseReturnType = Promise>; +export type ParseReturnType = SyncParseReturnType | AsyncParseReturnType; + +export const isAborted = (x: ParseReturnType): x is INVALID => (x as any).status === "aborted"; +export const isDirty = (x: ParseReturnType): x is OK | DIRTY => (x as any).status === "dirty"; +export const isValid = (x: ParseReturnType): x is OK => (x as any).status === "valid"; +export const isAsync = (x: ParseReturnType): x is AsyncParseReturnType => + typeof Promise !== "undefined" && x instanceof Promise; diff --git a/node_modules/zod/src/v3/helpers/partialUtil.ts b/node_modules/zod/src/v3/helpers/partialUtil.ts new file mode 100644 index 00000000..0eff8ff3 --- /dev/null +++ b/node_modules/zod/src/v3/helpers/partialUtil.ts @@ -0,0 +1,34 @@ +import type { + ZodArray, + ZodNullable, + ZodObject, + ZodOptional, + ZodRawShape, + ZodTuple, + ZodTupleItems, + ZodTypeAny, +} from "../types.js"; + +export namespace partialUtil { + export type DeepPartial = T extends ZodObject + ? ZodObject< + { [k in keyof T["shape"]]: ZodOptional> }, + T["_def"]["unknownKeys"], + T["_def"]["catchall"] + > + : T extends ZodArray + ? ZodArray, Card> + : T extends ZodOptional + ? ZodOptional> + : T extends ZodNullable + ? ZodNullable> + : T extends ZodTuple + ? { + [k in keyof Items]: Items[k] extends ZodTypeAny ? DeepPartial : never; + } extends infer PI + ? PI extends ZodTupleItems + ? ZodTuple + : never + : never + : T; +} diff --git a/node_modules/zod/src/v3/helpers/typeAliases.ts b/node_modules/zod/src/v3/helpers/typeAliases.ts new file mode 100644 index 00000000..32df022c --- /dev/null +++ b/node_modules/zod/src/v3/helpers/typeAliases.ts @@ -0,0 +1,2 @@ +export type Primitive = string | number | symbol | bigint | boolean | null | undefined; +export type Scalars = Primitive | Primitive[]; diff --git a/node_modules/zod/src/v3/helpers/util.ts b/node_modules/zod/src/v3/helpers/util.ts new file mode 100644 index 00000000..030ea821 --- /dev/null +++ b/node_modules/zod/src/v3/helpers/util.ts @@ -0,0 +1,224 @@ +export namespace util { + type AssertEqual = (() => V extends T ? 1 : 2) extends () => V extends U ? 1 : 2 ? true : false; + + export type isAny = 0 extends 1 & T ? true : false; + export const assertEqual = (_: AssertEqual): void => {}; + export function assertIs(_arg: T): void {} + export function assertNever(_x: never): never { + throw new Error(); + } + + export type Omit = Pick>; + export type OmitKeys = Pick>; + export type MakePartial = Omit & Partial>; + export type Exactly = T & Record, never>; + export type InexactPartial = { [k in keyof T]?: T[k] | undefined }; + export const arrayToEnum = (items: U): { [k in U[number]]: k } => { + const obj: any = {}; + for (const item of items) { + obj[item] = item; + } + return obj; + }; + + export const getValidEnumValues = (obj: any): any[] => { + const validKeys = objectKeys(obj).filter((k: any) => typeof obj[obj[k]] !== "number"); + const filtered: any = {}; + for (const k of validKeys) { + filtered[k] = obj[k]; + } + return objectValues(filtered); + }; + + export const objectValues = (obj: any): any[] => { + return objectKeys(obj).map(function (e) { + return obj[e]; + }); + }; + + export const objectKeys: ObjectConstructor["keys"] = + typeof Object.keys === "function" // eslint-disable-line ban/ban + ? (obj: any) => Object.keys(obj) // eslint-disable-line ban/ban + : (object: any) => { + const keys = []; + for (const key in object) { + if (Object.prototype.hasOwnProperty.call(object, key)) { + keys.push(key); + } + } + return keys; + }; + + export const find = (arr: T[], checker: (arg: T) => any): T | undefined => { + for (const item of arr) { + if (checker(item)) return item; + } + return undefined; + }; + + export type identity = objectUtil.identity; + export type flatten = objectUtil.flatten; + + export type noUndefined = T extends undefined ? never : T; + + export const isInteger: NumberConstructor["isInteger"] = + typeof Number.isInteger === "function" + ? (val) => Number.isInteger(val) // eslint-disable-line ban/ban + : (val) => typeof val === "number" && Number.isFinite(val) && Math.floor(val) === val; + + export function joinValues(array: T, separator = " | "): string { + return array.map((val) => (typeof val === "string" ? `'${val}'` : val)).join(separator); + } + + export const jsonStringifyReplacer = (_: string, value: any): any => { + if (typeof value === "bigint") { + return value.toString(); + } + return value; + }; +} + +export namespace objectUtil { + export type MergeShapes = + // fast path when there is no keys overlap + keyof U & keyof V extends never + ? U & V + : { + [k in Exclude]: U[k]; + } & V; + + type optionalKeys = { + [k in keyof T]: undefined extends T[k] ? k : never; + }[keyof T]; + type requiredKeys = { + [k in keyof T]: undefined extends T[k] ? never : k; + }[keyof T]; + export type addQuestionMarks = { + [K in requiredKeys]: T[K]; + } & { + [K in optionalKeys]?: T[K]; + } & { [k in keyof T]?: unknown }; + + export type identity = T; + export type flatten = identity<{ [k in keyof T]: T[k] }>; + + export type noNeverKeys = { + [k in keyof T]: [T[k]] extends [never] ? never : k; + }[keyof T]; + + export type noNever = identity<{ + [k in noNeverKeys]: k extends keyof T ? T[k] : never; + }>; + + export const mergeShapes = (first: U, second: T): T & U => { + return { + ...first, + ...second, // second overwrites first + }; + }; + + export type extendShape = keyof A & keyof B extends never // fast path when there is no keys overlap + ? A & B + : { + [K in keyof A as K extends keyof B ? never : K]: A[K]; + } & { + [K in keyof B]: B[K]; + }; +} + +export const ZodParsedType: { + string: "string"; + nan: "nan"; + number: "number"; + integer: "integer"; + float: "float"; + boolean: "boolean"; + date: "date"; + bigint: "bigint"; + symbol: "symbol"; + function: "function"; + undefined: "undefined"; + null: "null"; + array: "array"; + object: "object"; + unknown: "unknown"; + promise: "promise"; + void: "void"; + never: "never"; + map: "map"; + set: "set"; +} = util.arrayToEnum([ + "string", + "nan", + "number", + "integer", + "float", + "boolean", + "date", + "bigint", + "symbol", + "function", + "undefined", + "null", + "array", + "object", + "unknown", + "promise", + "void", + "never", + "map", + "set", +]); + +export type ZodParsedType = keyof typeof ZodParsedType; + +export const getParsedType = (data: any): ZodParsedType => { + const t = typeof data; + + switch (t) { + case "undefined": + return ZodParsedType.undefined; + + case "string": + return ZodParsedType.string; + + case "number": + return Number.isNaN(data) ? ZodParsedType.nan : ZodParsedType.number; + + case "boolean": + return ZodParsedType.boolean; + + case "function": + return ZodParsedType.function; + + case "bigint": + return ZodParsedType.bigint; + + case "symbol": + return ZodParsedType.symbol; + + case "object": + if (Array.isArray(data)) { + return ZodParsedType.array; + } + if (data === null) { + return ZodParsedType.null; + } + if (data.then && typeof data.then === "function" && data.catch && typeof data.catch === "function") { + return ZodParsedType.promise; + } + if (typeof Map !== "undefined" && data instanceof Map) { + return ZodParsedType.map; + } + if (typeof Set !== "undefined" && data instanceof Set) { + return ZodParsedType.set; + } + if (typeof Date !== "undefined" && data instanceof Date) { + return ZodParsedType.date; + } + return ZodParsedType.object; + + default: + return ZodParsedType.unknown; + } +}; diff --git a/node_modules/zod/src/v3/index.ts b/node_modules/zod/src/v3/index.ts new file mode 100644 index 00000000..a9dab573 --- /dev/null +++ b/node_modules/zod/src/v3/index.ts @@ -0,0 +1,4 @@ +import * as z from "./external.js"; +export * from "./external.js"; +export { z }; +export default z; diff --git a/node_modules/zod/src/v3/locales/en.ts b/node_modules/zod/src/v3/locales/en.ts new file mode 100644 index 00000000..0264f82e --- /dev/null +++ b/node_modules/zod/src/v3/locales/en.ts @@ -0,0 +1,124 @@ +import { type ZodErrorMap, ZodIssueCode } from "../ZodError.js"; +import { util, ZodParsedType } from "../helpers/util.js"; + +const errorMap: ZodErrorMap = (issue, _ctx) => { + let message: string; + switch (issue.code) { + case ZodIssueCode.invalid_type: + if (issue.received === ZodParsedType.undefined) { + message = "Required"; + } else { + message = `Expected ${issue.expected}, received ${issue.received}`; + } + break; + case ZodIssueCode.invalid_literal: + message = `Invalid literal value, expected ${JSON.stringify(issue.expected, util.jsonStringifyReplacer)}`; + break; + case ZodIssueCode.unrecognized_keys: + message = `Unrecognized key(s) in object: ${util.joinValues(issue.keys, ", ")}`; + break; + case ZodIssueCode.invalid_union: + message = `Invalid input`; + break; + case ZodIssueCode.invalid_union_discriminator: + message = `Invalid discriminator value. Expected ${util.joinValues(issue.options)}`; + break; + case ZodIssueCode.invalid_enum_value: + message = `Invalid enum value. Expected ${util.joinValues(issue.options)}, received '${issue.received}'`; + break; + case ZodIssueCode.invalid_arguments: + message = `Invalid function arguments`; + break; + case ZodIssueCode.invalid_return_type: + message = `Invalid function return type`; + break; + case ZodIssueCode.invalid_date: + message = `Invalid date`; + break; + case ZodIssueCode.invalid_string: + if (typeof issue.validation === "object") { + if ("includes" in issue.validation) { + message = `Invalid input: must include "${issue.validation.includes}"`; + + if (typeof issue.validation.position === "number") { + message = `${message} at one or more positions greater than or equal to ${issue.validation.position}`; + } + } else if ("startsWith" in issue.validation) { + message = `Invalid input: must start with "${issue.validation.startsWith}"`; + } else if ("endsWith" in issue.validation) { + message = `Invalid input: must end with "${issue.validation.endsWith}"`; + } else { + util.assertNever(issue.validation); + } + } else if (issue.validation !== "regex") { + message = `Invalid ${issue.validation}`; + } else { + message = "Invalid"; + } + break; + case ZodIssueCode.too_small: + if (issue.type === "array") + message = `Array must contain ${ + issue.exact ? "exactly" : issue.inclusive ? `at least` : `more than` + } ${issue.minimum} element(s)`; + else if (issue.type === "string") + message = `String must contain ${ + issue.exact ? "exactly" : issue.inclusive ? `at least` : `over` + } ${issue.minimum} character(s)`; + else if (issue.type === "number") + message = `Number must be ${ + issue.exact ? `exactly equal to ` : issue.inclusive ? `greater than or equal to ` : `greater than ` + }${issue.minimum}`; + else if (issue.type === "bigint") + message = `Number must be ${ + issue.exact ? `exactly equal to ` : issue.inclusive ? `greater than or equal to ` : `greater than ` + }${issue.minimum}`; + else if (issue.type === "date") + message = `Date must be ${ + issue.exact ? `exactly equal to ` : issue.inclusive ? `greater than or equal to ` : `greater than ` + }${new Date(Number(issue.minimum))}`; + else message = "Invalid input"; + break; + case ZodIssueCode.too_big: + if (issue.type === "array") + message = `Array must contain ${ + issue.exact ? `exactly` : issue.inclusive ? `at most` : `less than` + } ${issue.maximum} element(s)`; + else if (issue.type === "string") + message = `String must contain ${ + issue.exact ? `exactly` : issue.inclusive ? `at most` : `under` + } ${issue.maximum} character(s)`; + else if (issue.type === "number") + message = `Number must be ${ + issue.exact ? `exactly` : issue.inclusive ? `less than or equal to` : `less than` + } ${issue.maximum}`; + else if (issue.type === "bigint") + message = `BigInt must be ${ + issue.exact ? `exactly` : issue.inclusive ? `less than or equal to` : `less than` + } ${issue.maximum}`; + else if (issue.type === "date") + message = `Date must be ${ + issue.exact ? `exactly` : issue.inclusive ? `smaller than or equal to` : `smaller than` + } ${new Date(Number(issue.maximum))}`; + else message = "Invalid input"; + break; + case ZodIssueCode.custom: + message = `Invalid input`; + break; + case ZodIssueCode.invalid_intersection_types: + message = `Intersection results could not be merged`; + break; + case ZodIssueCode.not_multiple_of: + message = `Number must be a multiple of ${issue.multipleOf}`; + break; + case ZodIssueCode.not_finite: + message = "Number must be finite"; + break; + default: + message = _ctx.defaultError; + util.assertNever(issue); + } + return { message }; +}; + +export default errorMap; diff --git a/node_modules/zod/src/v3/standard-schema.ts b/node_modules/zod/src/v3/standard-schema.ts new file mode 100644 index 00000000..07193fd1 --- /dev/null +++ b/node_modules/zod/src/v3/standard-schema.ts @@ -0,0 +1,113 @@ +/** + * The Standard Schema interface. + */ +export type StandardSchemaV1 = { + /** + * The Standard Schema properties. + */ + readonly "~standard": StandardSchemaV1.Props; +}; + +export declare namespace StandardSchemaV1 { + /** + * The Standard Schema properties interface. + */ + export interface Props { + /** + * The version number of the standard. + */ + readonly version: 1; + /** + * The vendor name of the schema library. + */ + readonly vendor: string; + /** + * Validates unknown input values. + */ + readonly validate: (value: unknown) => Result | Promise>; + /** + * Inferred types associated with the schema. + */ + readonly types?: Types | undefined; + } + + /** + * The result interface of the validate function. + */ + export type Result = SuccessResult | FailureResult; + + /** + * The result interface if validation succeeds. + */ + export interface SuccessResult { + /** + * The typed output value. + */ + readonly value: Output; + /** + * The non-existent issues. + */ + readonly issues?: undefined; + } + + /** + * The result interface if validation fails. + */ + export interface FailureResult { + /** + * The issues of failed validation. + */ + readonly issues: ReadonlyArray; + } + + /** + * The issue interface of the failure output. + */ + export interface Issue { + /** + * The error message of the issue. + */ + readonly message: string; + /** + * The path of the issue, if any. + */ + readonly path?: ReadonlyArray | undefined; + } + + /** + * The path segment interface of the issue. + */ + export interface PathSegment { + /** + * The key representing a path segment. + */ + readonly key: PropertyKey; + } + + /** + * The Standard Schema types interface. + */ + export interface Types { + /** + * The input type of the schema. + */ + readonly input: Input; + /** + * The output type of the schema. + */ + readonly output: Output; + } + + /** + * Infers the input type of a Standard Schema. + */ + export type InferInput = NonNullable["input"]; + + /** + * Infers the output type of a Standard Schema. + */ + export type InferOutput = NonNullable["output"]; + + // biome-ignore lint/complexity/noUselessEmptyExport: needed for granular visibility control of TS namespace + export {}; +} diff --git a/node_modules/zod/src/v3/tests/Mocker.ts b/node_modules/zod/src/v3/tests/Mocker.ts new file mode 100644 index 00000000..c9fbdd51 --- /dev/null +++ b/node_modules/zod/src/v3/tests/Mocker.ts @@ -0,0 +1,54 @@ +function getRandomInt(max: number) { + return Math.floor(Math.random() * Math.floor(max)); +} + +const testSymbol = Symbol("test"); + +export class Mocker { + pick = (...args: any[]): any => { + return args[getRandomInt(args.length)]; + }; + + get string(): string { + return Math.random().toString(36).substring(7); + } + get number(): number { + return Math.random() * 100; + } + get bigint(): bigint { + return BigInt(Math.floor(Math.random() * 10000)); + } + get boolean(): boolean { + return Math.random() < 0.5; + } + get date(): Date { + return new Date(Math.floor(Date.now() * Math.random())); + } + get symbol(): symbol { + return testSymbol; + } + get null(): null { + return null; + } + get undefined(): undefined { + return undefined; + } + get stringOptional(): string | undefined { + return this.pick(this.string, this.undefined); + } + get stringNullable(): string | null { + return this.pick(this.string, this.null); + } + get numberOptional(): number | undefined { + return this.pick(this.number, this.undefined); + } + get numberNullable(): number | null { + return this.pick(this.number, this.null); + } + get booleanOptional(): boolean | undefined { + return this.pick(this.boolean, this.undefined); + } + get booleanNullable(): boolean | null { + return this.pick(this.boolean, this.null); + } +} diff --git a/node_modules/zod/src/v3/tests/all-errors.test.ts b/node_modules/zod/src/v3/tests/all-errors.test.ts new file mode 100644 index 00000000..8fdf8f42 --- /dev/null +++ b/node_modules/zod/src/v3/tests/all-errors.test.ts @@ -0,0 +1,157 @@ +// @ts-ignore TS6133 +import { expect, test } from "vitest"; + +import * as z from "zod/v3"; +import { util } from "../helpers/util.js"; + +const Test = z.object({ + f1: z.number(), + f2: z.string().optional(), + f3: z.string().nullable(), + f4: z.array(z.object({ t: z.union([z.string(), z.boolean()]) })), +}); +type TestFlattenedErrors = z.inferFlattenedErrors; +type TestFormErrors = z.inferFlattenedErrors; + +test("default flattened errors type inference", () => { + type TestTypeErrors = { + formErrors: string[]; + fieldErrors: { [P in keyof z.TypeOf]?: string[] | undefined }; + }; + + util.assertEqual, TestTypeErrors>(true); + util.assertEqual, TestTypeErrors>(false); +}); + +test("custom flattened errors type inference", () => { + type ErrorType = { message: string; code: number }; + type TestTypeErrors = { + formErrors: ErrorType[]; + fieldErrors: { + [P in keyof z.TypeOf]?: ErrorType[] | undefined; + }; + }; + + util.assertEqual, TestTypeErrors>(false); + util.assertEqual, TestTypeErrors>(true); + util.assertEqual, TestTypeErrors>(false); +}); + +test("form errors type inference", () => { + type TestTypeErrors = { + formErrors: string[]; + fieldErrors: { [P in keyof z.TypeOf]?: string[] | undefined }; + }; + + util.assertEqual, TestTypeErrors>(true); +}); + +test(".flatten() type assertion", () => { + const parsed = Test.safeParse({}) as z.SafeParseError; + const validFlattenedErrors: TestFlattenedErrors = parsed.error.flatten(() => ({ message: "", code: 0 })); + // @ts-expect-error should fail assertion between `TestFlattenedErrors` and unmapped `flatten()`. + const invalidFlattenedErrors: TestFlattenedErrors = parsed.error.flatten(); + const validFormErrors: TestFormErrors = parsed.error.flatten(); + // @ts-expect-error should fail assertion between `TestFormErrors` and mapped `flatten()`. + const invalidFormErrors: TestFormErrors = parsed.error.flatten(() => ({ + message: "string", + code: 0, + })); + + [validFlattenedErrors, invalidFlattenedErrors, validFormErrors, invalidFormErrors]; +}); + +test(".formErrors type assertion", () => { + const parsed = Test.safeParse({}) as z.SafeParseError; + const validFormErrors: TestFormErrors = parsed.error.formErrors; + // @ts-expect-error should fail assertion between `TestFlattenedErrors` and `.formErrors`. + const invalidFlattenedErrors: TestFlattenedErrors = parsed.error.formErrors; + + [validFormErrors, invalidFlattenedErrors]; +}); + +test("all errors", () => { + const propertySchema = z.string(); + const schema = z + .object({ + a: propertySchema, + b: propertySchema, + }) + .refine( + (val) => { + return val.a === val.b; + }, + { message: "Must be equal" } + ); + + try { + schema.parse({ + a: "asdf", + b: "qwer", + }); + } catch (error) { + if (error instanceof z.ZodError) { + expect(error.flatten()).toEqual({ + formErrors: ["Must be equal"], + fieldErrors: {}, + }); + } + } + + try { + schema.parse({ + a: null, + b: null, + }); + } catch (_error) { + const error = _error as z.ZodError; + expect(error.flatten()).toEqual({ + formErrors: [], + fieldErrors: { + a: ["Expected string, received null"], + b: ["Expected string, received null"], + }, + }); + + expect(error.flatten((iss) => iss.message.toUpperCase())).toEqual({ + formErrors: [], + fieldErrors: { + a: ["EXPECTED STRING, RECEIVED NULL"], + b: ["EXPECTED STRING, RECEIVED NULL"], + }, + }); + // Test identity + + expect(error.flatten((i: z.ZodIssue) => i)).toEqual({ + formErrors: [], + fieldErrors: { + a: [ + { + code: "invalid_type", + expected: "string", + message: "Expected string, received null", + path: ["a"], + received: "null", + }, + ], + b: [ + { + code: "invalid_type", + expected: "string", + message: "Expected string, received null", + path: ["b"], + received: "null", + }, + ], + }, + }); + // Test mapping + expect(error.flatten((i: z.ZodIssue) => i.message.length)).toEqual({ + formErrors: [], + fieldErrors: { + a: ["Expected string, received null".length], + b: ["Expected string, received null".length], + }, + }); + } +}); diff --git a/node_modules/zod/src/v3/tests/anyunknown.test.ts b/node_modules/zod/src/v3/tests/anyunknown.test.ts new file mode 100644 index 00000000..49d07db2 --- /dev/null +++ b/node_modules/zod/src/v3/tests/anyunknown.test.ts @@ -0,0 +1,28 @@ +// @ts-ignore TS6133 +import { expect, test } from "vitest"; + +import * as z from "zod/v3"; +import { util } from "../helpers/util.js"; + +test("check any inference", () => { + const t1 = z.any(); + t1.optional(); + t1.nullable(); + type t1 = z.infer; + util.assertEqual(true); +}); + +test("check unknown inference", () => { + const t1 = z.unknown(); + t1.optional(); + t1.nullable(); + type t1 = z.infer; + util.assertEqual(true); +}); + +test("check never inference", () => { + const t1 = z.never(); + expect(() => t1.parse(undefined)).toThrow(); + expect(() => t1.parse("asdf")).toThrow(); + expect(() => t1.parse(null)).toThrow(); +}); diff --git a/node_modules/zod/src/v3/tests/array.test.ts b/node_modules/zod/src/v3/tests/array.test.ts new file mode 100644 index 00000000..df5b9d37 --- /dev/null +++ b/node_modules/zod/src/v3/tests/array.test.ts @@ -0,0 +1,71 @@ +// @ts-ignore TS6133 +import { expect, test } from "vitest"; + +import * as z from "zod/v3"; +import { util } from "../helpers/util.js"; + +const minTwo = z.string().array().min(2); +const maxTwo = z.string().array().max(2); +const justTwo = z.string().array().length(2); +const intNum = z.string().array().nonempty(); +const nonEmptyMax = z.string().array().nonempty().max(2); + +type t1 = z.infer; +util.assertEqual<[string, ...string[]], t1>(true); + +type t2 = z.infer; +util.assertEqual(true); + +test("passing validations", () => { + minTwo.parse(["a", "a"]); + minTwo.parse(["a", "a", "a"]); + maxTwo.parse(["a", "a"]); + maxTwo.parse(["a"]); + justTwo.parse(["a", "a"]); + intNum.parse(["a"]); + nonEmptyMax.parse(["a"]); +}); + +test("failing validations", () => { + expect(() => minTwo.parse(["a"])).toThrow(); + expect(() => maxTwo.parse(["a", "a", "a"])).toThrow(); + expect(() => justTwo.parse(["a"])).toThrow(); + expect(() => justTwo.parse(["a", "a", "a"])).toThrow(); + expect(() => intNum.parse([])).toThrow(); + expect(() => nonEmptyMax.parse([])).toThrow(); + expect(() => nonEmptyMax.parse(["a", "a", "a"])).toThrow(); +}); + +test("parse empty array in nonempty", () => { + expect(() => + z + .array(z.string()) + .nonempty() + .parse([] as any) + ).toThrow(); +}); + +test("get element", () => { + justTwo.element.parse("asdf"); + expect(() => justTwo.element.parse(12)).toThrow(); +}); + +test("continue parsing despite array size error", () => { + const schema = z.object({ + people: z.string().array().min(2), + }); + + const result = schema.safeParse({ + people: [123], + }); + expect(result.success).toEqual(false); + if (!result.success) { + expect(result.error.issues.length).toEqual(2); + } +}); + +test("parse should fail given sparse array", () => { + const schema = z.array(z.string()).nonempty().min(1).max(3); + + expect(() => schema.parse(new Array(3))).toThrow(); +}); diff --git a/node_modules/zod/src/v3/tests/async-parsing.test.ts b/node_modules/zod/src/v3/tests/async-parsing.test.ts new file mode 100644 index 00000000..01dbc4f1 --- /dev/null +++ b/node_modules/zod/src/v3/tests/async-parsing.test.ts @@ -0,0 +1,388 @@ +// @ts-ignore TS6133 +import { expect, test } from "vitest"; + +import * as z from "zod/v3"; + +/// string +const stringSchema = z.string(); + +test("string async parse", async () => { + const goodData = "XXX"; + const badData = 12; + + const goodResult = await stringSchema.safeParseAsync(goodData); + expect(goodResult.success).toBe(true); + if (goodResult.success) expect(goodResult.data).toEqual(goodData); + + const badResult = await stringSchema.safeParseAsync(badData); + expect(badResult.success).toBe(false); + if (!badResult.success) expect(badResult.error).toBeInstanceOf(z.ZodError); +}); + +/// number +const numberSchema = z.number(); +test("number async parse", async () => { + const goodData = 1234.2353; + const badData = "1234"; + + const goodResult = await numberSchema.safeParseAsync(goodData); + expect(goodResult.success).toBe(true); + if (goodResult.success) expect(goodResult.data).toEqual(goodData); + + const badResult = await numberSchema.safeParseAsync(badData); + expect(badResult.success).toBe(false); + if (!badResult.success) expect(badResult.error).toBeInstanceOf(z.ZodError); +}); + +/// bigInt +const bigIntSchema = z.bigint(); +test("bigInt async parse", async () => { + const goodData = BigInt(145); + const badData = 134; + + const goodResult = await bigIntSchema.safeParseAsync(goodData); + expect(goodResult.success).toBe(true); + if (goodResult.success) expect(goodResult.data).toEqual(goodData); + + const badResult = await bigIntSchema.safeParseAsync(badData); + expect(badResult.success).toBe(false); + if (!badResult.success) expect(badResult.error).toBeInstanceOf(z.ZodError); +}); + +/// boolean +const booleanSchema = z.boolean(); +test("boolean async parse", async () => { + const goodData = true; + const badData = 1; + + const goodResult = await booleanSchema.safeParseAsync(goodData); + expect(goodResult.success).toBe(true); + if (goodResult.success) expect(goodResult.data).toEqual(goodData); + + const badResult = await booleanSchema.safeParseAsync(badData); + expect(badResult.success).toBe(false); + if (!badResult.success) expect(badResult.error).toBeInstanceOf(z.ZodError); +}); + +/// date +const dateSchema = z.date(); +test("date async parse", async () => { + const goodData = new Date(); + const badData = new Date().toISOString(); + + const goodResult = await dateSchema.safeParseAsync(goodData); + expect(goodResult.success).toBe(true); + if (goodResult.success) expect(goodResult.data).toEqual(goodData); + + const badResult = await dateSchema.safeParseAsync(badData); + expect(badResult.success).toBe(false); + if (!badResult.success) expect(badResult.error).toBeInstanceOf(z.ZodError); +}); + +/// undefined +const undefinedSchema = z.undefined(); +test("undefined async parse", async () => { + const goodData = undefined; + const badData = "XXX"; + + const goodResult = await undefinedSchema.safeParseAsync(goodData); + expect(goodResult.success).toBe(true); + if (goodResult.success) expect(goodResult.data).toEqual(undefined); + + const badResult = await undefinedSchema.safeParseAsync(badData); + expect(badResult.success).toBe(false); + if (!badResult.success) expect(badResult.error).toBeInstanceOf(z.ZodError); +}); + +/// null +const nullSchema = z.null(); +test("null async parse", async () => { + const goodData = null; + const badData = undefined; + + const goodResult = await nullSchema.safeParseAsync(goodData); + expect(goodResult.success).toBe(true); + if (goodResult.success) expect(goodResult.data).toEqual(goodData); + + const badResult = await nullSchema.safeParseAsync(badData); + expect(badResult.success).toBe(false); + if (!badResult.success) expect(badResult.error).toBeInstanceOf(z.ZodError); +}); + +/// any +const anySchema = z.any(); +test("any async parse", async () => { + const goodData = [{}]; + // const badData = 'XXX'; + + const goodResult = await anySchema.safeParseAsync(goodData); + expect(goodResult.success).toBe(true); + if (goodResult.success) expect(goodResult.data).toEqual(goodData); + + // const badResult = await anySchema.safeParseAsync(badData); + // expect(badResult.success).toBe(false); + // if (!badResult.success) expect(badResult.error).toBeInstanceOf(z.ZodError); +}); + +/// unknown +const unknownSchema = z.unknown(); +test("unknown async parse", async () => { + const goodData = ["asdf", 124, () => {}]; + // const badData = 'XXX'; + + const goodResult = await unknownSchema.safeParseAsync(goodData); + expect(goodResult.success).toBe(true); + if (goodResult.success) expect(goodResult.data).toEqual(goodData); + + // const badResult = await unknownSchema.safeParseAsync(badData); + // expect(badResult.success).toBe(false); + // if (!badResult.success) expect(badResult.error).toBeInstanceOf(z.ZodError); +}); + +/// void +const voidSchema = z.void(); +test("void async parse", async () => { + const goodData = undefined; + const badData = 0; + + const goodResult = await voidSchema.safeParseAsync(goodData); + expect(goodResult.success).toBe(true); + if (goodResult.success) expect(goodResult.data).toEqual(goodData); + + const badResult = await voidSchema.safeParseAsync(badData); + expect(badResult.success).toBe(false); + if (!badResult.success) expect(badResult.error).toBeInstanceOf(z.ZodError); +}); + +/// array +const arraySchema = z.array(z.string()); +test("array async parse", async () => { + const goodData = ["XXX"]; + const badData = "XXX"; + + const goodResult = await arraySchema.safeParseAsync(goodData); + expect(goodResult.success).toBe(true); + if (goodResult.success) expect(goodResult.data).toEqual(goodData); + + const badResult = await arraySchema.safeParseAsync(badData); + expect(badResult.success).toBe(false); + if (!badResult.success) expect(badResult.error).toBeInstanceOf(z.ZodError); +}); + +/// object +const objectSchema = z.object({ string: z.string() }); +test("object async parse", async () => { + const goodData = { string: "XXX" }; + const badData = { string: 12 }; + + const goodResult = await objectSchema.safeParseAsync(goodData); + expect(goodResult.success).toBe(true); + if (goodResult.success) expect(goodResult.data).toEqual(goodData); + + const badResult = await objectSchema.safeParseAsync(badData); + expect(badResult.success).toBe(false); + if (!badResult.success) expect(badResult.error).toBeInstanceOf(z.ZodError); +}); + +/// union +const unionSchema = z.union([z.string(), z.undefined()]); +test("union async parse", async () => { + const goodData = undefined; + const badData = null; + + const goodResult = await unionSchema.safeParseAsync(goodData); + expect(goodResult.success).toBe(true); + if (goodResult.success) expect(goodResult.data).toEqual(goodData); + + const badResult = await unionSchema.safeParseAsync(badData); + expect(badResult.success).toBe(false); + if (!badResult.success) expect(badResult.error).toBeInstanceOf(z.ZodError); +}); + +/// record +const recordSchema = z.record(z.object({})); +test("record async parse", async () => { + const goodData = { adsf: {}, asdf: {} }; + const badData = [{}]; + + const goodResult = await recordSchema.safeParseAsync(goodData); + expect(goodResult.success).toBe(true); + if (goodResult.success) expect(goodResult.data).toEqual(goodData); + + const badResult = await recordSchema.safeParseAsync(badData); + expect(badResult.success).toBe(false); + if (!badResult.success) expect(badResult.error).toBeInstanceOf(z.ZodError); +}); + +/// function +const functionSchema = z.function(); +test("function async parse", async () => { + const goodData = () => {}; + const badData = "XXX"; + + const goodResult = await functionSchema.safeParseAsync(goodData); + expect(goodResult.success).toBe(true); + if (goodResult.success) expect(typeof goodResult.data).toEqual("function"); + + const badResult = await functionSchema.safeParseAsync(badData); + expect(badResult.success).toBe(false); + if (!badResult.success) expect(badResult.error).toBeInstanceOf(z.ZodError); +}); + +/// literal +const literalSchema = z.literal("asdf"); +test("literal async parse", async () => { + const goodData = "asdf"; + const badData = "asdff"; + + const goodResult = await literalSchema.safeParseAsync(goodData); + expect(goodResult.success).toBe(true); + if (goodResult.success) expect(goodResult.data).toEqual(goodData); + + const badResult = await literalSchema.safeParseAsync(badData); + expect(badResult.success).toBe(false); + if (!badResult.success) expect(badResult.error).toBeInstanceOf(z.ZodError); +}); + +/// enum +const enumSchema = z.enum(["fish", "whale"]); +test("enum async parse", async () => { + const goodData = "whale"; + const badData = "leopard"; + + const goodResult = await enumSchema.safeParseAsync(goodData); + expect(goodResult.success).toBe(true); + if (goodResult.success) expect(goodResult.data).toEqual(goodData); + + const badResult = await enumSchema.safeParseAsync(badData); + expect(badResult.success).toBe(false); + if (!badResult.success) expect(badResult.error).toBeInstanceOf(z.ZodError); +}); + +/// nativeEnum +enum nativeEnumTest { + asdf = "qwer", +} +// @ts-ignore +const nativeEnumSchema = z.nativeEnum(nativeEnumTest); +test("nativeEnum async parse", async () => { + const goodData = nativeEnumTest.asdf; + const badData = "asdf"; + + const goodResult = await nativeEnumSchema.safeParseAsync(goodData); + expect(goodResult.success).toBe(true); + if (goodResult.success) expect(goodResult.data).toEqual(goodData); + + const badResult = await nativeEnumSchema.safeParseAsync(badData); + expect(badResult.success).toBe(false); + if (!badResult.success) expect(badResult.error).toBeInstanceOf(z.ZodError); +}); + +/// promise +const promiseSchema = z.promise(z.number()); +test("promise async parse good", async () => { + const goodData = Promise.resolve(123); + + const goodResult = await promiseSchema.safeParseAsync(goodData); + expect(goodResult.success).toBe(true); + if (goodResult.success) { + expect(goodResult.data).toBeInstanceOf(Promise); + const data = await goodResult.data; + expect(data).toEqual(123); + // expect(goodResult.data).resolves.toEqual(124); + // return goodResult.data; + } else { + throw new Error("success should be true"); + } +}); + +test("promise async parse bad", async () => { + const badData = Promise.resolve("XXX"); + const badResult = await promiseSchema.safeParseAsync(badData); + expect(badResult.success).toBe(true); + if (badResult.success) { + await expect(badResult.data).rejects.toBeInstanceOf(z.ZodError); + } else { + throw new Error("success should be true"); + } +}); + +test("async validation non-empty strings", async () => { + const base = z.object({ + hello: z.string().refine((x) => x && x.length > 0), + foo: z.string().refine((x) => x && x.length > 0), + }); + + const testval = { hello: "", foo: "" }; + const result1 = base.safeParse(testval); + const result2 = base.safeParseAsync(testval); + + const r1 = result1; + await result2.then((r2) => { + if (r1.success === false && r2.success === false) expect(r1.error.issues.length).toBe(r2.error.issues.length); // <--- r1 has length 2, r2 has length 1 + }); +}); + +test("async validation multiple errors 1", async () => { + const base = z.object({ + hello: z.string(), + foo: z.number(), + }); + + const testval = { hello: 3, foo: "hello" }; + const result1 = base.safeParse(testval); + const result2 = base.safeParseAsync(testval); + + const r1 = result1; + await result2.then((r2) => { + if (r1.success === false && r2.success === false) expect(r2.error.issues.length).toBe(r1.error.issues.length); + }); +}); + +test("async validation multiple errors 2", async () => { + const base = (is_async?: boolean) => + z.object({ + hello: z.string(), + foo: z.object({ + bar: z.number().refine(is_async ? async () => false : () => false), + }), + }); + + const testval = { hello: 3, foo: { bar: 4 } }; + const result1 = base().safeParse(testval); + const result2 = base(true).safeParseAsync(testval); + + const r1 = result1; + await result2.then((r2) => { + if (r1.success === false && r2.success === false) expect(r2.error.issues.length).toBe(r1.error.issues.length); + }); +}); + +test("ensure early async failure prevents follow-up refinement checks", async () => { + let count = 0; + const base = z.object({ + hello: z.string(), + foo: z + .number() + .refine(async () => { + count++; + return true; + }) + .refine(async () => { + count++; + return true; + }, "Good"), + }); + + const testval = { hello: "bye", foo: 3 }; + const result = await base.safeParseAsync(testval); + if (result.success === false) { + expect(result.error.issues.length).toBe(1); + expect(count).toBe(1); + } + + // await result.then((r) => { + // if (r.success === false) expect(r.error.issues.length).toBe(1); + // expect(count).toBe(2); + // }); +}); diff --git a/node_modules/zod/src/v3/tests/async-refinements.test.ts b/node_modules/zod/src/v3/tests/async-refinements.test.ts new file mode 100644 index 00000000..509475db --- /dev/null +++ b/node_modules/zod/src/v3/tests/async-refinements.test.ts @@ -0,0 +1,46 @@ +// @ts-ignore TS6133 +import { expect, test } from "vitest"; + +import * as z from "zod/v3"; + +test("parse async test", async () => { + const schema1 = z.string().refine(async (_val) => false); + expect(() => schema1.parse("asdf")).toThrow(); + + const schema2 = z.string().refine((_val) => Promise.resolve(true)); + return await expect(() => schema2.parse("asdf")).toThrow(); +}); + +test("parseAsync async test", async () => { + const schema1 = z.string().refine(async (_val) => true); + await schema1.parseAsync("asdf"); + + const schema2 = z.string().refine(async (_val) => false); + return await expect(schema2.parseAsync("asdf")).rejects.toBeDefined(); + // expect(async () => await schema2.parseAsync('asdf')).toThrow(); +}); + +test("parseAsync async test", async () => { + // expect.assertions(2); + + const schema1 = z.string().refine((_val) => Promise.resolve(true)); + const v1 = await schema1.parseAsync("asdf"); + expect(v1).toEqual("asdf"); + + const schema2 = z.string().refine((_val) => Promise.resolve(false)); + await expect(schema2.parseAsync("asdf")).rejects.toBeDefined(); + + const schema3 = z.string().refine((_val) => Promise.resolve(true)); + await expect(schema3.parseAsync("asdf")).resolves.toEqual("asdf"); + return await expect(schema3.parseAsync("qwer")).resolves.toEqual("qwer"); +}); + +test("parseAsync async with value", async () => { + const schema1 = z.string().refine(async (val) => { + return val.length > 5; + }); + await expect(schema1.parseAsync("asdf")).rejects.toBeDefined(); + + const v = await schema1.parseAsync("asdf123"); + return await expect(v).toEqual("asdf123"); +}); diff --git a/node_modules/zod/src/v3/tests/base.test.ts b/node_modules/zod/src/v3/tests/base.test.ts new file mode 100644 index 00000000..ab743d56 --- /dev/null +++ b/node_modules/zod/src/v3/tests/base.test.ts @@ -0,0 +1,29 @@ +// @ts-ignore TS6133 +import { expect, test } from "vitest"; + +import * as z from "zod/v3"; +import { util } from "../helpers/util.js"; + +test("type guard", () => { + const stringToNumber = z.string().transform((arg) => arg.length); + + const s1 = z.object({ + stringToNumber, + }); + type t1 = z.input; + + const data = { stringToNumber: "asdf" }; + const parsed = s1.safeParse(data); + if (parsed.success) { + util.assertEqual(true); + } +}); + +test("test this binding", () => { + const callback = (predicate: (val: string) => boolean) => { + return predicate("hello"); + }; + + expect(callback((value) => z.string().safeParse(value).success)).toBe(true); // true + expect(callback((value) => z.string().safeParse(value).success)).toBe(true); // true +}); diff --git a/node_modules/zod/src/v3/tests/bigint.test.ts b/node_modules/zod/src/v3/tests/bigint.test.ts new file mode 100644 index 00000000..9692f570 --- /dev/null +++ b/node_modules/zod/src/v3/tests/bigint.test.ts @@ -0,0 +1,55 @@ +// @ts-ignore TS6133 +import { expect, test } from "vitest"; + +import * as z from "zod/v3"; + +const gtFive = z.bigint().gt(BigInt(5)); +const gteFive = z.bigint().gte(BigInt(5)); +const ltFive = z.bigint().lt(BigInt(5)); +const lteFive = z.bigint().lte(BigInt(5)); +const positive = z.bigint().positive(); +const negative = z.bigint().negative(); +const nonnegative = z.bigint().nonnegative(); +const nonpositive = z.bigint().nonpositive(); +const multipleOfFive = z.bigint().multipleOf(BigInt(5)); + +test("passing validations", () => { + z.bigint().parse(BigInt(1)); + z.bigint().parse(BigInt(0)); + z.bigint().parse(BigInt(-1)); + gtFive.parse(BigInt(6)); + gteFive.parse(BigInt(5)); + gteFive.parse(BigInt(6)); + ltFive.parse(BigInt(4)); + lteFive.parse(BigInt(5)); + lteFive.parse(BigInt(4)); + positive.parse(BigInt(3)); + negative.parse(BigInt(-2)); + nonnegative.parse(BigInt(0)); + nonnegative.parse(BigInt(7)); + nonpositive.parse(BigInt(0)); + nonpositive.parse(BigInt(-12)); + multipleOfFive.parse(BigInt(15)); +}); + +test("failing validations", () => { + expect(() => gtFive.parse(BigInt(5))).toThrow(); + expect(() => gteFive.parse(BigInt(4))).toThrow(); + expect(() => ltFive.parse(BigInt(5))).toThrow(); + expect(() => lteFive.parse(BigInt(6))).toThrow(); + expect(() => positive.parse(BigInt(0))).toThrow(); + expect(() => positive.parse(BigInt(-2))).toThrow(); + expect(() => negative.parse(BigInt(0))).toThrow(); + expect(() => negative.parse(BigInt(3))).toThrow(); + expect(() => nonnegative.parse(BigInt(-1))).toThrow(); + expect(() => nonpositive.parse(BigInt(1))).toThrow(); + expect(() => multipleOfFive.parse(BigInt(13))).toThrow(); +}); + +test("min max getters", () => { + expect(z.bigint().min(BigInt(5)).minValue).toEqual(BigInt(5)); + expect(z.bigint().min(BigInt(5)).min(BigInt(10)).minValue).toEqual(BigInt(10)); + + expect(z.bigint().max(BigInt(5)).maxValue).toEqual(BigInt(5)); + expect(z.bigint().max(BigInt(5)).max(BigInt(1)).maxValue).toEqual(BigInt(1)); +}); diff --git a/node_modules/zod/src/v3/tests/branded.test.ts b/node_modules/zod/src/v3/tests/branded.test.ts new file mode 100644 index 00000000..b19786cf --- /dev/null +++ b/node_modules/zod/src/v3/tests/branded.test.ts @@ -0,0 +1,53 @@ +// @ts-ignore TS6133 +import { test } from "vitest"; + +import * as z from "zod/v3"; +import { util } from "../helpers/util.js"; + +test("branded types", () => { + const mySchema = z + .object({ + name: z.string(), + }) + .brand<"superschema">(); + + // simple branding + type MySchema = z.infer; + util.assertEqual(true); + + const doStuff = (arg: MySchema) => arg; + doStuff(mySchema.parse({ name: "hello there" })); + + // inheritance + const extendedSchema = mySchema.brand<"subschema">(); + type ExtendedSchema = z.infer; + util.assertEqual & z.BRAND<"subschema">>(true); + + doStuff(extendedSchema.parse({ name: "hello again" })); + + // number branding + const numberSchema = z.number().brand<42>(); + type NumberSchema = z.infer; + util.assertEqual(true); + + // symbol branding + const MyBrand: unique symbol = Symbol("hello"); + type MyBrand = typeof MyBrand; + const symbolBrand = z.number().brand<"sup">().brand(); + type SymbolBrand = z.infer; + // number & { [z.BRAND]: { sup: true, [MyBrand]: true } } + util.assertEqual & z.BRAND>(true); + + // keeping brands out of input types + const age = z.number().brand<"age">(); + + type Age = z.infer; + type AgeInput = z.input; + + util.assertEqual(false); + util.assertEqual(true); + util.assertEqual, Age>(true); + + // @ts-expect-error + doStuff({ name: "hello there!" }); +}); diff --git a/node_modules/zod/src/v3/tests/catch.test.ts b/node_modules/zod/src/v3/tests/catch.test.ts new file mode 100644 index 00000000..94d12aa2 --- /dev/null +++ b/node_modules/zod/src/v3/tests/catch.test.ts @@ -0,0 +1,220 @@ +// @ts-ignore TS6133 +import { expect, test } from "vitest"; + +import { z } from "zod/v3"; +import { util } from "../helpers/util.js"; + +test("basic catch", () => { + expect(z.string().catch("default").parse(undefined)).toBe("default"); +}); + +test("catch fn does not run when parsing succeeds", () => { + let isCalled = false; + const cb = () => { + isCalled = true; + return "asdf"; + }; + expect(z.string().catch(cb).parse("test")).toBe("test"); + expect(isCalled).toEqual(false); +}); + +test("basic catch async", async () => { + const result = await z.string().catch("default").parseAsync(1243); + expect(result).toBe("default"); +}); + +test("catch replace wrong types", () => { + expect(z.string().catch("default").parse(true)).toBe("default"); + expect(z.string().catch("default").parse(true)).toBe("default"); + expect(z.string().catch("default").parse(15)).toBe("default"); + expect(z.string().catch("default").parse([])).toBe("default"); + expect(z.string().catch("default").parse(new Map())).toBe("default"); + expect(z.string().catch("default").parse(new Set())).toBe("default"); + expect(z.string().catch("default").parse({})).toBe("default"); +}); + +test("catch with transform", () => { + const stringWithDefault = z + .string() + .transform((val) => val.toUpperCase()) + .catch("default"); + expect(stringWithDefault.parse(undefined)).toBe("default"); + expect(stringWithDefault.parse(15)).toBe("default"); + expect(stringWithDefault).toBeInstanceOf(z.ZodCatch); + expect(stringWithDefault._def.innerType).toBeInstanceOf(z.ZodEffects); + expect(stringWithDefault._def.innerType._def.schema).toBeInstanceOf(z.ZodSchema); + + type inp = z.input; + util.assertEqual(true); + type out = z.output; + util.assertEqual(true); +}); + +test("catch on existing optional", () => { + const stringWithDefault = z.string().optional().catch("asdf"); + expect(stringWithDefault.parse(undefined)).toBe(undefined); + expect(stringWithDefault.parse(15)).toBe("asdf"); + expect(stringWithDefault).toBeInstanceOf(z.ZodCatch); + expect(stringWithDefault._def.innerType).toBeInstanceOf(z.ZodOptional); + expect(stringWithDefault._def.innerType._def.innerType).toBeInstanceOf(z.ZodString); + + type inp = z.input; + util.assertEqual(true); + type out = z.output; + util.assertEqual(true); +}); + +test("optional on catch", () => { + const stringWithDefault = z.string().catch("asdf").optional(); + + type inp = z.input; + util.assertEqual(true); + type out = z.output; + util.assertEqual(true); +}); + +test("complex chain example", () => { + const complex = z + .string() + .catch("asdf") + .transform((val) => val + "!") + .transform((val) => val.toUpperCase()) + .catch("qwer") + .removeCatch() + .optional() + .catch("asdfasdf"); + + expect(complex.parse("qwer")).toBe("QWER!"); + expect(complex.parse(15)).toBe("ASDF!"); + expect(complex.parse(true)).toBe("ASDF!"); +}); + +test("removeCatch", () => { + const stringWithRemovedDefault = z.string().catch("asdf").removeCatch(); + + type out = z.output; + util.assertEqual(true); +}); + +test("nested", () => { + const inner = z.string().catch("asdf"); + const outer = z.object({ inner }).catch({ + inner: "asdf", + }); + type input = z.input; + util.assertEqual(true); + type out = z.output; + util.assertEqual(true); + expect(outer.parse(undefined)).toEqual({ inner: "asdf" }); + expect(outer.parse({})).toEqual({ inner: "asdf" }); + expect(outer.parse({ inner: undefined })).toEqual({ inner: "asdf" }); +}); + +test("chained catch", () => { + const stringWithDefault = z.string().catch("inner").catch("outer"); + const result = stringWithDefault.parse(undefined); + expect(result).toEqual("inner"); + const resultDiff = stringWithDefault.parse(5); + expect(resultDiff).toEqual("inner"); +}); + +test("factory", () => { + z.ZodCatch.create(z.string(), { + catch: "asdf", + }).parse(undefined); +}); + +test("native enum", () => { + enum Fruits { + apple = "apple", + orange = "orange", + } + + const schema = z.object({ + fruit: z.nativeEnum(Fruits).catch(Fruits.apple), + }); + + expect(schema.parse({})).toEqual({ fruit: Fruits.apple }); + expect(schema.parse({ fruit: 15 })).toEqual({ fruit: Fruits.apple }); +}); + +test("enum", () => { + const schema = z.object({ + fruit: z.enum(["apple", "orange"]).catch("apple"), + }); + + expect(schema.parse({})).toEqual({ fruit: "apple" }); + expect(schema.parse({ fruit: true })).toEqual({ fruit: "apple" }); + expect(schema.parse({ fruit: 15 })).toEqual({ fruit: "apple" }); +}); + +test("reported issues with nested usage", () => { + const schema = z.object({ + string: z.string(), + obj: z.object({ + sub: z.object({ + lit: z.literal("a"), + subCatch: z.number().catch(23), + }), + midCatch: z.number().catch(42), + }), + number: z.number().catch(0), + bool: z.boolean(), + }); + + try { + schema.parse({ + string: {}, + obj: { + sub: { + lit: "b", + subCatch: "24", + }, + midCatch: 444, + }, + number: "", + bool: "yes", + }); + } catch (error) { + const issues = (error as z.ZodError).issues; + + expect(issues.length).toEqual(3); + expect(issues[0].message).toMatch("string"); + expect(issues[1].message).toMatch("literal"); + expect(issues[2].message).toMatch("boolean"); + } +}); + +test("catch error", () => { + let catchError: z.ZodError | undefined = undefined; + + const schema = z.object({ + age: z.number(), + name: z.string().catch((ctx) => { + catchError = ctx.error; + + return "John Doe"; + }), + }); + + const result = schema.safeParse({ + age: null, + name: null, + }); + + expect(result.success).toEqual(false); + expect(!result.success && result.error.issues.length).toEqual(1); + expect(!result.success && result.error.issues[0].message).toMatch("number"); + + expect(catchError).toBeInstanceOf(z.ZodError); + expect(catchError !== undefined && (catchError as z.ZodError).issues.length).toEqual(1); + expect(catchError !== undefined && (catchError as z.ZodError).issues[0].message).toMatch("string"); +}); + +test("ctx.input", () => { + const schema = z.string().catch((ctx) => { + return String(ctx.input); + }); + + expect(schema.parse(123)).toEqual("123"); +}); diff --git a/node_modules/zod/src/v3/tests/coerce.test.ts b/node_modules/zod/src/v3/tests/coerce.test.ts new file mode 100644 index 00000000..1f530041 --- /dev/null +++ b/node_modules/zod/src/v3/tests/coerce.test.ts @@ -0,0 +1,133 @@ +// @ts-ignore TS6133 +import { expect, test } from "vitest"; + +import * as z from "zod/v3"; + +test("string coercion", () => { + const schema = z.coerce.string(); + expect(schema.parse("sup")).toEqual("sup"); + expect(schema.parse("")).toEqual(""); + expect(schema.parse(12)).toEqual("12"); + expect(schema.parse(0)).toEqual("0"); + expect(schema.parse(-12)).toEqual("-12"); + expect(schema.parse(3.14)).toEqual("3.14"); + expect(schema.parse(BigInt(15))).toEqual("15"); + expect(schema.parse(Number.NaN)).toEqual("NaN"); + expect(schema.parse(Number.POSITIVE_INFINITY)).toEqual("Infinity"); + expect(schema.parse(Number.NEGATIVE_INFINITY)).toEqual("-Infinity"); + expect(schema.parse(true)).toEqual("true"); + expect(schema.parse(false)).toEqual("false"); + expect(schema.parse(null)).toEqual("null"); + expect(schema.parse(undefined)).toEqual("undefined"); + expect(schema.parse({ hello: "world!" })).toEqual("[object Object]"); + expect(schema.parse(["item", "another_item"])).toEqual("item,another_item"); + expect(schema.parse([])).toEqual(""); + expect(schema.parse(new Date("2022-01-01T00:00:00.000Z"))).toEqual(new Date("2022-01-01T00:00:00.000Z").toString()); +}); + +test("number coercion", () => { + const schema = z.coerce.number(); + expect(schema.parse("12")).toEqual(12); + expect(schema.parse("0")).toEqual(0); + expect(schema.parse("-12")).toEqual(-12); + expect(schema.parse("3.14")).toEqual(3.14); + expect(schema.parse("")).toEqual(0); + expect(() => schema.parse("NOT_A_NUMBER")).toThrow(); // z.ZodError + expect(schema.parse(12)).toEqual(12); + expect(schema.parse(0)).toEqual(0); + expect(schema.parse(-12)).toEqual(-12); + expect(schema.parse(3.14)).toEqual(3.14); + expect(schema.parse(BigInt(15))).toEqual(15); + expect(() => schema.parse(Number.NaN)).toThrow(); // z.ZodError + expect(schema.parse(Number.POSITIVE_INFINITY)).toEqual(Number.POSITIVE_INFINITY); + expect(schema.parse(Number.NEGATIVE_INFINITY)).toEqual(Number.NEGATIVE_INFINITY); + expect(schema.parse(true)).toEqual(1); + expect(schema.parse(false)).toEqual(0); + expect(schema.parse(null)).toEqual(0); + expect(() => schema.parse(undefined)).toThrow(); // z.ZodError + expect(() => schema.parse({ hello: "world!" })).toThrow(); // z.ZodError + expect(() => schema.parse(["item", "another_item"])).toThrow(); // z.ZodError + expect(schema.parse([])).toEqual(0); + expect(schema.parse(new Date(1670139203496))).toEqual(1670139203496); +}); + +test("boolean coercion", () => { + const schema = z.coerce.boolean(); + expect(schema.parse("true")).toEqual(true); + expect(schema.parse("false")).toEqual(true); + expect(schema.parse("0")).toEqual(true); + expect(schema.parse("1")).toEqual(true); + expect(schema.parse("")).toEqual(false); + expect(schema.parse(1)).toEqual(true); + expect(schema.parse(0)).toEqual(false); + expect(schema.parse(-1)).toEqual(true); + expect(schema.parse(3.14)).toEqual(true); + expect(schema.parse(BigInt(15))).toEqual(true); + expect(schema.parse(Number.NaN)).toEqual(false); + expect(schema.parse(Number.POSITIVE_INFINITY)).toEqual(true); + expect(schema.parse(Number.NEGATIVE_INFINITY)).toEqual(true); + expect(schema.parse(true)).toEqual(true); + expect(schema.parse(false)).toEqual(false); + expect(schema.parse(null)).toEqual(false); + expect(schema.parse(undefined)).toEqual(false); + expect(schema.parse({ hello: "world!" })).toEqual(true); + expect(schema.parse(["item", "another_item"])).toEqual(true); + expect(schema.parse([])).toEqual(true); + expect(schema.parse(new Date(1670139203496))).toEqual(true); +}); + +test("bigint coercion", () => { + const schema = z.coerce.bigint(); + expect(schema.parse("5")).toEqual(BigInt(5)); + expect(schema.parse("0")).toEqual(BigInt(0)); + expect(schema.parse("-5")).toEqual(BigInt(-5)); + expect(() => schema.parse("3.14")).toThrow(); // not a z.ZodError! + expect(schema.parse("")).toEqual(BigInt(0)); + expect(() => schema.parse("NOT_A_NUMBER")).toThrow(); // not a z.ZodError! + expect(schema.parse(5)).toEqual(BigInt(5)); + expect(schema.parse(0)).toEqual(BigInt(0)); + expect(schema.parse(-5)).toEqual(BigInt(-5)); + expect(() => schema.parse(3.14)).toThrow(); // not a z.ZodError! + expect(schema.parse(BigInt(5))).toEqual(BigInt(5)); + expect(() => schema.parse(Number.NaN)).toThrow(); // not a z.ZodError! + expect(() => schema.parse(Number.POSITIVE_INFINITY)).toThrow(); // not a z.ZodError! + expect(() => schema.parse(Number.NEGATIVE_INFINITY)).toThrow(); // not a z.ZodError! + expect(schema.parse(true)).toEqual(BigInt(1)); + expect(schema.parse(false)).toEqual(BigInt(0)); + expect(() => schema.parse(null)).toThrow(); // not a z.ZodError! + expect(() => schema.parse(undefined)).toThrow(); // not a z.ZodError! + expect(() => schema.parse({ hello: "world!" })).toThrow(); // not a z.ZodError! + expect(() => schema.parse(["item", "another_item"])).toThrow(); // not a z.ZodError! + expect(schema.parse([])).toEqual(BigInt(0)); + expect(schema.parse(new Date(1670139203496))).toEqual(BigInt(1670139203496)); +}); + +test("date coercion", () => { + const schema = z.coerce.date(); + expect(schema.parse(new Date().toDateString())).toBeInstanceOf(Date); + expect(schema.parse(new Date().toISOString())).toBeInstanceOf(Date); + expect(schema.parse(new Date().toUTCString())).toBeInstanceOf(Date); + expect(schema.parse("5")).toBeInstanceOf(Date); + expect(schema.parse("2000-01-01")).toBeInstanceOf(Date); + // expect(schema.parse("0")).toBeInstanceOf(Date); + // expect(schema.parse("-5")).toBeInstanceOf(Date); + // expect(schema.parse("3.14")).toBeInstanceOf(Date); + expect(() => schema.parse("")).toThrow(); // z.ZodError + expect(() => schema.parse("NOT_A_DATE")).toThrow(); // z.ZodError + expect(schema.parse(5)).toBeInstanceOf(Date); + expect(schema.parse(0)).toBeInstanceOf(Date); + expect(schema.parse(-5)).toBeInstanceOf(Date); + expect(schema.parse(3.14)).toBeInstanceOf(Date); + expect(() => schema.parse(BigInt(5))).toThrow(); // not a z.ZodError! + expect(() => schema.parse(Number.NaN)).toThrow(); // z.ZodError + expect(() => schema.parse(Number.POSITIVE_INFINITY)).toThrow(); // z.ZodError + expect(() => schema.parse(Number.NEGATIVE_INFINITY)).toThrow(); // z.ZodError + expect(schema.parse(true)).toBeInstanceOf(Date); + expect(schema.parse(false)).toBeInstanceOf(Date); + expect(schema.parse(null)).toBeInstanceOf(Date); + expect(() => schema.parse(undefined)).toThrow(); // z.ZodError + expect(() => schema.parse({ hello: "world!" })).toThrow(); // z.ZodError + expect(() => schema.parse(["item", "another_item"])).toThrow(); // z.ZodError + expect(() => schema.parse([])).toThrow(); // z.ZodError + expect(schema.parse(new Date())).toBeInstanceOf(Date); +}); diff --git a/node_modules/zod/src/v3/tests/complex.test.ts b/node_modules/zod/src/v3/tests/complex.test.ts new file mode 100644 index 00000000..1d030332 --- /dev/null +++ b/node_modules/zod/src/v3/tests/complex.test.ts @@ -0,0 +1,70 @@ +import { expect, test } from "vitest"; +import * as z from "zod/v3"; + +const crazySchema = z.object({ + tuple: z.tuple([ + z.string().nullable().optional(), + z.number().nullable().optional(), + z.boolean().nullable().optional(), + z.null().nullable().optional(), + z.undefined().nullable().optional(), + z.literal("1234").nullable().optional(), + ]), + merged: z + .object({ + k1: z.string().optional(), + }) + .merge(z.object({ k1: z.string().nullable(), k2: z.number() })), + union: z.array(z.union([z.literal("asdf"), z.literal(12)])).nonempty(), + array: z.array(z.number()), + // sumTransformer: z.transformer(z.array(z.number()), z.number(), (arg) => { + // return arg.reduce((a, b) => a + b, 0); + // }), + sumMinLength: z.array(z.number()).refine((arg) => arg.length > 5), + intersection: z.intersection(z.object({ p1: z.string().optional() }), z.object({ p1: z.number().optional() })), + enum: z.intersection(z.enum(["zero", "one"]), z.enum(["one", "two"])), + nonstrict: z.object({ points: z.number() }).nonstrict(), + numProm: z.promise(z.number()), + lenfun: z.function(z.tuple([z.string()]), z.boolean()), +}); + +// const asyncCrazySchema = crazySchema.extend({ +// // async_transform: z.transformer( +// // z.array(z.number()), +// // z.number(), +// // async (arg) => { +// // return arg.reduce((a, b) => a + b, 0); +// // } +// // ), +// async_refine: z.array(z.number()).refine(async (arg) => arg.length > 5), +// }); + +test("parse", () => { + const input = { + tuple: ["asdf", 1234, true, null, undefined, "1234"], + merged: { k1: "asdf", k2: 12 }, + union: ["asdf", 12, "asdf", 12, "asdf", 12], + array: [12, 15, 16], + // sumTransformer: [12, 15, 16], + sumMinLength: [12, 15, 16, 98, 24, 63], + intersection: {}, + enum: "one", + nonstrict: { points: 1234 }, + numProm: Promise.resolve(12), + lenfun: (x: string) => x.length, + }; + + const result = crazySchema.parse(input); + + // Verify the parsed result structure + expect(result.tuple).toEqual(input.tuple); + expect(result.merged).toEqual(input.merged); + expect(result.union).toEqual(input.union); + expect(result.array).toEqual(input.array); + expect(result.sumMinLength).toEqual(input.sumMinLength); + expect(result.intersection).toEqual(input.intersection); + expect(result.enum).toEqual(input.enum); + expect(result.nonstrict).toEqual(input.nonstrict); + expect(result.numProm).toBeInstanceOf(Promise); + expect(typeof result.lenfun).toBe("function"); +}); diff --git a/node_modules/zod/src/v3/tests/custom.test.ts b/node_modules/zod/src/v3/tests/custom.test.ts new file mode 100644 index 00000000..b24b6762 --- /dev/null +++ b/node_modules/zod/src/v3/tests/custom.test.ts @@ -0,0 +1,31 @@ +// @ts-ignore TS6133 +import { expect, test } from "vitest"; + +import * as z from "zod/v3"; + +test("passing validations", () => { + const example1 = z.custom((x) => typeof x === "number"); + example1.parse(1234); + expect(() => example1.parse({})).toThrow(); +}); + +test("string params", () => { + const example1 = z.custom((x) => typeof x !== "number", "customerr"); + const result = example1.safeParse(1234); + expect(result.success).toEqual(false); + // @ts-ignore + expect(JSON.stringify(result.error).includes("customerr")).toEqual(true); +}); + +test("async validations", async () => { + const example1 = z.custom(async (x) => { + return typeof x === "number"; + }); + const r1 = await example1.safeParseAsync(1234); + expect(r1.success).toEqual(true); + expect(r1.data).toEqual(1234); + + const r2 = await example1.safeParseAsync("asdf"); + expect(r2.success).toEqual(false); + expect(r2.error!.issues.length).toEqual(1); +}); diff --git a/node_modules/zod/src/v3/tests/date.test.ts b/node_modules/zod/src/v3/tests/date.test.ts new file mode 100644 index 00000000..c86dc84f --- /dev/null +++ b/node_modules/zod/src/v3/tests/date.test.ts @@ -0,0 +1,32 @@ +// @ts-ignore TS6133 +import { expect, test } from "vitest"; + +import * as z from "zod/v3"; + +const beforeBenchmarkDate = new Date(2022, 10, 4); +const benchmarkDate = new Date(2022, 10, 5); +const afterBenchmarkDate = new Date(2022, 10, 6); + +const minCheck = z.date().min(benchmarkDate); +const maxCheck = z.date().max(benchmarkDate); + +test("passing validations", () => { + minCheck.parse(benchmarkDate); + minCheck.parse(afterBenchmarkDate); + + maxCheck.parse(benchmarkDate); + maxCheck.parse(beforeBenchmarkDate); +}); + +test("failing validations", () => { + expect(() => minCheck.parse(beforeBenchmarkDate)).toThrow(); + expect(() => maxCheck.parse(afterBenchmarkDate)).toThrow(); +}); + +test("min max getters", () => { + expect(minCheck.minDate).toEqual(benchmarkDate); + expect(minCheck.min(afterBenchmarkDate).minDate).toEqual(afterBenchmarkDate); + + expect(maxCheck.maxDate).toEqual(benchmarkDate); + expect(maxCheck.max(beforeBenchmarkDate).maxDate).toEqual(beforeBenchmarkDate); +}); diff --git a/node_modules/zod/src/v3/tests/deepmasking.test.ts b/node_modules/zod/src/v3/tests/deepmasking.test.ts new file mode 100644 index 00000000..d707e79a --- /dev/null +++ b/node_modules/zod/src/v3/tests/deepmasking.test.ts @@ -0,0 +1,186 @@ +// @ts-ignore TS6133 +import { test } from "vitest"; + +import * as z from "zod/v3"; + +test("test", () => { + z; +}); + +// const fish = z.object({ +// name: z.string(), +// props: z.object({ +// color: z.string(), +// numScales: z.number(), +// }), +// }); + +// const nonStrict = z +// .object({ +// name: z.string(), +// color: z.string(), +// }) +// .nonstrict(); + +// test('object pick type', () => { +// const modNonStrictFish = nonStrict.omit({ name: true }); +// modNonStrictFish.parse({ color: 'asdf' }); + +// const bad1 = () => fish.pick({ props: { unknown: true } } as any); +// const bad2 = () => fish.omit({ name: true, props: { unknown: true } } as any); + +// expect(bad1).toThrow(); +// expect(bad2).toThrow(); +// }); + +// test('f1', () => { +// const f1 = fish.pick(true); +// f1.parse({ name: 'a', props: { color: 'b', numScales: 3 } }); +// }); +// test('f2', () => { +// const f2 = fish.pick({ props: true }); +// f2.parse({ props: { color: 'asdf', numScales: 1 } }); +// const badcheck2 = () => f2.parse({ name: 'a', props: { color: 'b', numScales: 3 } } as any); +// expect(badcheck2).toThrow(); +// }); +// test('f3', () => { +// const f3 = fish.pick({ props: { color: true } }); +// f3.parse({ props: { color: 'b' } }); +// const badcheck3 = () => f3.parse({ name: 'a', props: { color: 'b', numScales: 3 } } as any); +// expect(badcheck3).toThrow(); +// }); +// test('f4', () => { +// const badcheck4 = () => fish.pick({ props: { color: true, unknown: true } }); +// expect(badcheck4).toThrow(); +// }); +// test('f6', () => { +// const f6 = fish.omit({ props: true }); +// const badcheck6 = () => f6.parse({ name: 'a', props: { color: 'b', numScales: 3 } } as any); +// f6.parse({ name: 'adsf' }); +// expect(badcheck6).toThrow(); +// }); +// test('f7', () => { +// const f7 = fish.omit({ props: { color: true } }); +// f7.parse({ name: 'a', props: { numScales: 3 } }); +// const badcheck7 = () => f7.parse({ name: 'a', props: { color: 'b', numScales: 3 } } as any); +// expect(badcheck7).toThrow(); +// }); +// test('f8', () => { +// const badcheck8 = () => fish.omit({ props: { color: true, unknown: true } }); +// expect(badcheck8).toThrow(); +// }); +// test('f9', () => { +// const f9 = nonStrict.pick(true); +// f9.parse({ name: 'a', color: 'asdf' }); +// }); +// test('f10', () => { +// const f10 = nonStrict.pick({ name: true }); +// f10.parse({ name: 'a' }); +// const val = f10.parse({ name: 'a', color: 'b' }); +// expect(val).toEqual({ name: 'a' }); +// }); +// test('f12', () => { +// const badfcheck12 = () => nonStrict.omit({ color: true, asdf: true }); +// expect(badfcheck12).toThrow(); +// }); + +// test('array masking', () => { +// const fishArray = z.array(fish); +// const modFishArray = fishArray.pick({ +// name: true, +// props: { +// numScales: true, +// }, +// }); + +// modFishArray.parse([{ name: 'fish', props: { numScales: 12 } }]); +// const bad1 = () => modFishArray.parse([{ name: 'fish', props: { numScales: 12, color: 'asdf' } }] as any); +// expect(bad1).toThrow(); +// }); + +// test('array masking', () => { +// const fishArray = z.array(fish); +// const fail = () => +// fishArray.pick({ +// name: true, +// props: { +// whatever: true, +// }, +// } as any); +// expect(fail).toThrow(); +// }); + +// test('array masking', () => { +// const fishArray = z.array(fish); +// const fail = () => +// fishArray.omit({ +// whateve: true, +// } as any); +// expect(fail).toThrow(); +// }); + +// test('array masking', () => { +// const fishArray = z.array(fish); +// const modFishList = fishArray.omit({ +// name: true, +// props: { +// color: true, +// }, +// }); + +// modFishList.parse([{ props: { numScales: 12 } }]); +// const fail = () => modFishList.parse([{ name: 'hello', props: { numScales: 12 } }] as any); +// expect(fail).toThrow(); +// }); + +// test('primitive array masking', () => { +// const fishArray = z.array(z.number()); +// const fail = () => fishArray.pick({} as any); +// expect(fail).toThrow(); +// }); + +// test('other array masking', () => { +// const fishArray = z.array(z.array(z.number())); +// const fail = () => fishArray.pick({} as any); +// expect(fail).toThrow(); +// }); + +// test('invalid mask #1', () => { +// const fail = () => fish.pick(1 as any); +// expect(fail).toThrow(); +// }); + +// test('invalid mask #2', () => { +// const fail = () => fish.pick([] as any); +// expect(fail).toThrow(); +// }); + +// test('invalid mask #3', () => { +// const fail = () => fish.pick(false as any); +// expect(fail).toThrow(); +// }); + +// test('invalid mask #4', () => { +// const fail = () => fish.pick('asdf' as any); +// expect(fail).toThrow(); +// }); + +// test('invalid mask #5', () => { +// const fail = () => fish.omit(1 as any); +// expect(fail).toThrow(); +// }); + +// test('invalid mask #6', () => { +// const fail = () => fish.omit([] as any); +// expect(fail).toThrow(); +// }); + +// test('invalid mask #7', () => { +// const fail = () => fish.omit(false as any); +// expect(fail).toThrow(); +// }); + +// test('invalid mask #8', () => { +// const fail = () => fish.omit('asdf' as any); +// expect(fail).toThrow(); +// }); diff --git a/node_modules/zod/src/v3/tests/default.test.ts b/node_modules/zod/src/v3/tests/default.test.ts new file mode 100644 index 00000000..29e007c9 --- /dev/null +++ b/node_modules/zod/src/v3/tests/default.test.ts @@ -0,0 +1,112 @@ +// @ts-ignore TS6133 +import { expect, test } from "vitest"; + +import { z } from "zod/v3"; +import { util } from "../helpers/util.js"; + +test("basic defaults", () => { + expect(z.string().default("default").parse(undefined)).toBe("default"); +}); + +test("default with transform", () => { + const stringWithDefault = z + .string() + .transform((val) => val.toUpperCase()) + .default("default"); + expect(stringWithDefault.parse(undefined)).toBe("DEFAULT"); + expect(stringWithDefault).toBeInstanceOf(z.ZodDefault); + expect(stringWithDefault._def.innerType).toBeInstanceOf(z.ZodEffects); + expect(stringWithDefault._def.innerType._def.schema).toBeInstanceOf(z.ZodSchema); + + type inp = z.input; + util.assertEqual(true); + type out = z.output; + util.assertEqual(true); +}); + +test("default on existing optional", () => { + const stringWithDefault = z.string().optional().default("asdf"); + expect(stringWithDefault.parse(undefined)).toBe("asdf"); + expect(stringWithDefault).toBeInstanceOf(z.ZodDefault); + expect(stringWithDefault._def.innerType).toBeInstanceOf(z.ZodOptional); + expect(stringWithDefault._def.innerType._def.innerType).toBeInstanceOf(z.ZodString); + + type inp = z.input; + util.assertEqual(true); + type out = z.output; + util.assertEqual(true); +}); + +test("optional on default", () => { + const stringWithDefault = z.string().default("asdf").optional(); + + type inp = z.input; + util.assertEqual(true); + type out = z.output; + util.assertEqual(true); +}); + +test("complex chain example", () => { + const complex = z + .string() + .default("asdf") + .transform((val) => val.toUpperCase()) + .default("qwer") + .removeDefault() + .optional() + .default("asdfasdf"); + + expect(complex.parse(undefined)).toBe("ASDFASDF"); +}); + +test("removeDefault", () => { + const stringWithRemovedDefault = z.string().default("asdf").removeDefault(); + + type out = z.output; + util.assertEqual(true); +}); + +test("nested", () => { + const inner = z.string().default("asdf"); + const outer = z.object({ inner }).default({ + inner: undefined, + }); + type input = z.input; + util.assertEqual(true); + type out = z.output; + util.assertEqual(true); + expect(outer.parse(undefined)).toEqual({ inner: "asdf" }); + expect(outer.parse({})).toEqual({ inner: "asdf" }); + expect(outer.parse({ inner: undefined })).toEqual({ inner: "asdf" }); +}); + +test("chained defaults", () => { + const stringWithDefault = z.string().default("inner").default("outer"); + const result = stringWithDefault.parse(undefined); + expect(result).toEqual("outer"); +}); + +test("factory", () => { + expect(z.ZodDefault.create(z.string(), { default: "asdf" }).parse(undefined)).toEqual("asdf"); +}); + +test("native enum", () => { + enum Fruits { + apple = "apple", + orange = "orange", + } + + const schema = z.object({ + fruit: z.nativeEnum(Fruits).default(Fruits.apple), + }); + + expect(schema.parse({})).toEqual({ fruit: Fruits.apple }); +}); + +test("enum", () => { + const schema = z.object({ + fruit: z.enum(["apple", "orange"]).default("apple"), + }); + + expect(schema.parse({})).toEqual({ fruit: "apple" }); +}); diff --git a/node_modules/zod/src/v3/tests/description.test.ts b/node_modules/zod/src/v3/tests/description.test.ts new file mode 100644 index 00000000..1edaa1cc --- /dev/null +++ b/node_modules/zod/src/v3/tests/description.test.ts @@ -0,0 +1,33 @@ +// @ts-ignore TS6133 +import { expect, test } from "vitest"; + +import * as z from "zod/v3"; + +const description = "a description"; + +test("passing `description` to schema should add a description", () => { + expect(z.string({ description }).description).toEqual(description); + expect(z.number({ description }).description).toEqual(description); + expect(z.boolean({ description }).description).toEqual(description); +}); + +test("`.describe` should add a description", () => { + expect(z.string().describe(description).description).toEqual(description); + expect(z.number().describe(description).description).toEqual(description); + expect(z.boolean().describe(description).description).toEqual(description); +}); + +test("description should carry over to chained schemas", () => { + const schema = z.string({ description }); + expect(schema.description).toEqual(description); + expect(schema.optional().description).toEqual(description); + expect(schema.optional().nullable().default("default").description).toEqual(description); +}); + +test("description should not carry over to chained array schema", () => { + const schema = z.string().describe(description); + + expect(schema.description).toEqual(description); + expect(schema.array().description).toEqual(undefined); + expect(z.array(schema).description).toEqual(undefined); +}); diff --git a/node_modules/zod/src/v3/tests/discriminated-unions.test.ts b/node_modules/zod/src/v3/tests/discriminated-unions.test.ts new file mode 100644 index 00000000..7fb5cfef --- /dev/null +++ b/node_modules/zod/src/v3/tests/discriminated-unions.test.ts @@ -0,0 +1,315 @@ +// @ts-ignore TS6133 +import { expect, test } from "vitest"; + +import * as z from "zod/v3"; + +test("valid", () => { + expect( + z + .discriminatedUnion("type", [ + z.object({ type: z.literal("a"), a: z.string() }), + z.object({ type: z.literal("b"), b: z.string() }), + ]) + .parse({ type: "a", a: "abc" }) + ).toEqual({ type: "a", a: "abc" }); +}); + +test("valid - discriminator value of various primitive types", () => { + const schema = z.discriminatedUnion("type", [ + z.object({ type: z.literal("1"), val: z.literal(1) }), + z.object({ type: z.literal(1), val: z.literal(2) }), + z.object({ type: z.literal(BigInt(1)), val: z.literal(3) }), + z.object({ type: z.literal("true"), val: z.literal(4) }), + z.object({ type: z.literal(true), val: z.literal(5) }), + z.object({ type: z.literal("null"), val: z.literal(6) }), + z.object({ type: z.literal(null), val: z.literal(7) }), + z.object({ type: z.literal("undefined"), val: z.literal(8) }), + z.object({ type: z.literal(undefined), val: z.literal(9) }), + z.object({ type: z.literal("transform"), val: z.literal(10) }), + z.object({ type: z.literal("refine"), val: z.literal(11) }), + z.object({ type: z.literal("superRefine"), val: z.literal(12) }), + ]); + + expect(schema.parse({ type: "1", val: 1 })).toEqual({ type: "1", val: 1 }); + expect(schema.parse({ type: 1, val: 2 })).toEqual({ type: 1, val: 2 }); + expect(schema.parse({ type: BigInt(1), val: 3 })).toEqual({ + type: BigInt(1), + val: 3, + }); + expect(schema.parse({ type: "true", val: 4 })).toEqual({ + type: "true", + val: 4, + }); + expect(schema.parse({ type: true, val: 5 })).toEqual({ + type: true, + val: 5, + }); + expect(schema.parse({ type: "null", val: 6 })).toEqual({ + type: "null", + val: 6, + }); + expect(schema.parse({ type: null, val: 7 })).toEqual({ + type: null, + val: 7, + }); + expect(schema.parse({ type: "undefined", val: 8 })).toEqual({ + type: "undefined", + val: 8, + }); + expect(schema.parse({ type: undefined, val: 9 })).toEqual({ + type: undefined, + val: 9, + }); +}); + +test("invalid - null", () => { + try { + z.discriminatedUnion("type", [ + z.object({ type: z.literal("a"), a: z.string() }), + z.object({ type: z.literal("b"), b: z.string() }), + ]).parse(null); + throw new Error(); + } catch (e: any) { + expect(JSON.parse(e.message)).toEqual([ + { + code: z.ZodIssueCode.invalid_type, + expected: z.ZodParsedType.object, + message: "Expected object, received null", + received: z.ZodParsedType.null, + path: [], + }, + ]); + } +}); + +test("invalid discriminator value", () => { + try { + z.discriminatedUnion("type", [ + z.object({ type: z.literal("a"), a: z.string() }), + z.object({ type: z.literal("b"), b: z.string() }), + ]).parse({ type: "x", a: "abc" }); + throw new Error(); + } catch (e: any) { + expect(JSON.parse(e.message)).toEqual([ + { + code: z.ZodIssueCode.invalid_union_discriminator, + options: ["a", "b"], + message: "Invalid discriminator value. Expected 'a' | 'b'", + path: ["type"], + }, + ]); + } +}); + +test("valid discriminator value, invalid data", () => { + try { + z.discriminatedUnion("type", [ + z.object({ type: z.literal("a"), a: z.string() }), + z.object({ type: z.literal("b"), b: z.string() }), + ]).parse({ type: "a", b: "abc" }); + throw new Error(); + } catch (e: any) { + expect(JSON.parse(e.message)).toEqual([ + { + code: z.ZodIssueCode.invalid_type, + expected: z.ZodParsedType.string, + message: "Required", + path: ["a"], + received: z.ZodParsedType.undefined, + }, + ]); + } +}); + +test("wrong schema - missing discriminator", () => { + try { + z.discriminatedUnion("type", [ + z.object({ type: z.literal("a"), a: z.string() }), + z.object({ b: z.string() }) as any, + ]); + throw new Error(); + } catch (e: any) { + expect(e.message.includes("could not be extracted")).toBe(true); + } +}); + +test("wrong schema - duplicate discriminator values", () => { + try { + z.discriminatedUnion("type", [ + z.object({ type: z.literal("a"), a: z.string() }), + z.object({ type: z.literal("a"), b: z.string() }), + ]); + throw new Error(); + } catch (e: any) { + expect(e.message.includes("has duplicate value")).toEqual(true); + } +}); + +test("async - valid", async () => { + expect( + await z + .discriminatedUnion("type", [ + z.object({ + type: z.literal("a"), + a: z + .string() + .refine(async () => true) + .transform(async (val) => Number(val)), + }), + z.object({ + type: z.literal("b"), + b: z.string(), + }), + ]) + .parseAsync({ type: "a", a: "1" }) + ).toEqual({ type: "a", a: 1 }); +}); + +test("async - invalid", async () => { + try { + await z + .discriminatedUnion("type", [ + z.object({ + type: z.literal("a"), + a: z + .string() + .refine(async () => true) + .transform(async (val) => val), + }), + z.object({ + type: z.literal("b"), + b: z.string(), + }), + ]) + .parseAsync({ type: "a", a: 1 }); + throw new Error(); + } catch (e: any) { + expect(JSON.parse(e.message)).toEqual([ + { + code: "invalid_type", + expected: "string", + received: "number", + path: ["a"], + message: "Expected string, received number", + }, + ]); + } +}); + +test("valid - literals with .default or .preprocess", () => { + const schema = z.discriminatedUnion("type", [ + z.object({ + type: z.literal("foo").default("foo"), + a: z.string(), + }), + z.object({ + type: z.literal("custom"), + method: z.string(), + }), + z.object({ + type: z.preprocess((val) => String(val), z.literal("bar")), + c: z.string(), + }), + ]); + expect(schema.parse({ type: "foo", a: "foo" })).toEqual({ + type: "foo", + a: "foo", + }); +}); + +test("enum and nativeEnum", () => { + enum MyEnum { + d = 0, + e = "e", + } + + const schema = z.discriminatedUnion("key", [ + z.object({ + key: z.literal("a"), + // Add other properties specific to this option + }), + z.object({ + key: z.enum(["b", "c"]), + // Add other properties specific to this option + }), + z.object({ + key: z.nativeEnum(MyEnum), + // Add other properties specific to this option + }), + ]); + + // type schema = z.infer; + + schema.parse({ key: "a" }); + schema.parse({ key: "b" }); + schema.parse({ key: "c" }); + schema.parse({ key: MyEnum.d }); + schema.parse({ key: MyEnum.e }); + schema.parse({ key: "e" }); +}); + +test("branded", () => { + const schema = z.discriminatedUnion("key", [ + z.object({ + key: z.literal("a"), + // Add other properties specific to this option + }), + z.object({ + key: z.literal("b").brand("asdfaf"), + // Add other properties specific to this option + }), + ]); + + // type schema = z.infer; + + schema.parse({ key: "a" }); + schema.parse({ key: "b" }); + expect(() => { + schema.parse({ key: "c" }); + }).toThrow(); +}); + +test("optional and nullable", () => { + const schema = z.discriminatedUnion("key", [ + z.object({ + key: z.literal("a").optional(), + a: z.literal(true), + }), + z.object({ + key: z.literal("b").nullable(), + b: z.literal(true), + // Add other properties specific to this option + }), + ]); + + type schema = z.infer; + z.util.assertEqual(true); + + schema.parse({ key: "a", a: true }); + schema.parse({ key: undefined, a: true }); + schema.parse({ key: "b", b: true }); + schema.parse({ key: null, b: true }); + expect(() => { + schema.parse({ key: null, a: true }); + }).toThrow(); + expect(() => { + schema.parse({ key: "b", a: true }); + }).toThrow(); + + const value = schema.parse({ key: null, b: true }); + + if (!("key" in value)) value.a; + if (value.key === undefined) value.a; + if (value.key === "a") value.a; + if (value.key === "b") value.b; + if (value.key === null) value.b; +}); + +test("readonly array of options", () => { + const options = [ + z.object({ type: z.literal("x"), val: z.literal(1) }), + z.object({ type: z.literal("y"), val: z.literal(2) }), + ] as const; + + expect(z.discriminatedUnion("type", options).parse({ type: "x", val: 1 })).toEqual({ type: "x", val: 1 }); +}); diff --git a/node_modules/zod/src/v3/tests/enum.test.ts b/node_modules/zod/src/v3/tests/enum.test.ts new file mode 100644 index 00000000..53f4a3e8 --- /dev/null +++ b/node_modules/zod/src/v3/tests/enum.test.ts @@ -0,0 +1,80 @@ +// @ts-ignore TS6133 +import { expect, test } from "vitest"; + +import * as z from "zod/v3"; +import { util } from "../helpers/util.js"; + +test("create enum", () => { + const MyEnum = z.enum(["Red", "Green", "Blue"]); + expect(MyEnum.Values.Red).toEqual("Red"); + expect(MyEnum.Enum.Red).toEqual("Red"); + expect(MyEnum.enum.Red).toEqual("Red"); +}); + +test("infer enum", () => { + const MyEnum = z.enum(["Red", "Green", "Blue"]); + type MyEnum = z.infer; + util.assertEqual(true); +}); + +test("get options", () => { + expect(z.enum(["tuna", "trout"]).options).toEqual(["tuna", "trout"]); +}); + +test("readonly enum", () => { + const HTTP_SUCCESS = ["200", "201"] as const; + const arg = z.enum(HTTP_SUCCESS); + type arg = z.infer; + util.assertEqual(true); + + arg.parse("201"); + expect(() => arg.parse("202")).toThrow(); +}); + +test("error params", () => { + const result = z.enum(["test"], { required_error: "REQUIRED" }).safeParse(undefined); + expect(result.success).toEqual(false); + if (!result.success) { + expect(result.error.issues[0].message).toEqual("REQUIRED"); + } +}); + +test("extract/exclude", () => { + const foods = ["Pasta", "Pizza", "Tacos", "Burgers", "Salad"] as const; + const FoodEnum = z.enum(foods); + const ItalianEnum = FoodEnum.extract(["Pasta", "Pizza"]); + const UnhealthyEnum = FoodEnum.exclude(["Salad"]); + const EmptyFoodEnum = FoodEnum.exclude(foods); + + util.assertEqual, "Pasta" | "Pizza">(true); + util.assertEqual, "Pasta" | "Pizza" | "Tacos" | "Burgers">(true); + // @ts-expect-error TS2344 + util.assertEqual>(true); + util.assertEqual, never>(true); +}); + +test("error map in extract/exclude", () => { + const foods = ["Pasta", "Pizza", "Tacos", "Burgers", "Salad"] as const; + const FoodEnum = z.enum(foods, { + errorMap: () => ({ message: "This is not food!" }), + }); + const ItalianEnum = FoodEnum.extract(["Pasta", "Pizza"]); + const foodsError = FoodEnum.safeParse("Cucumbers"); + const italianError = ItalianEnum.safeParse("Tacos"); + if (!foodsError.success && !italianError.success) { + expect(foodsError.error.issues[0].message).toEqual(italianError.error.issues[0].message); + } + + const UnhealthyEnum = FoodEnum.exclude(["Salad"], { + errorMap: () => ({ message: "This is not healthy food!" }), + }); + const unhealthyError = UnhealthyEnum.safeParse("Salad"); + if (!unhealthyError.success) { + expect(unhealthyError.error.issues[0].message).toEqual("This is not healthy food!"); + } +}); + +test("readonly in ZodEnumDef", () => { + let _t!: z.ZodEnumDef; + _t; +}); diff --git a/node_modules/zod/src/v3/tests/error.test.ts b/node_modules/zod/src/v3/tests/error.test.ts new file mode 100644 index 00000000..5caaa6d8 --- /dev/null +++ b/node_modules/zod/src/v3/tests/error.test.ts @@ -0,0 +1,551 @@ +// @ts-ignore TS6133 +import { expect, test } from "vitest"; + +import * as z from "zod/v3"; +import { ZodError, ZodIssueCode } from "../ZodError.js"; +import { ZodParsedType } from "../helpers/util.js"; + +test("error creation", () => { + const err1 = ZodError.create([]); + err1.addIssue({ + code: ZodIssueCode.invalid_type, + expected: ZodParsedType.object, + received: ZodParsedType.string, + path: [], + message: "", + fatal: true, + }); + err1.isEmpty; + + const err2 = ZodError.create(err1.issues); + const err3 = new ZodError([]); + err3.addIssues(err1.issues); + err3.addIssue(err1.issues[0]); + err1.message; + err2.message; + err3.message; +}); + +const errorMap: z.ZodErrorMap = (error, ctx) => { + if (error.code === ZodIssueCode.invalid_type) { + if (error.expected === "string") { + return { message: "bad type!" }; + } + } + if (error.code === ZodIssueCode.custom) { + return { message: `less-than-${error.params?.minimum}` }; + } + return { message: ctx.defaultError }; +}; + +test("type error with custom error map", () => { + try { + z.string().parse(234, { errorMap }); + } catch (err) { + const zerr: z.ZodError = err as any; + + expect(zerr.issues[0].code).toEqual(z.ZodIssueCode.invalid_type); + expect(zerr.issues[0].message).toEqual(`bad type!`); + } +}); + +test("refinement fail with params", () => { + try { + z.number() + .refine((val) => val >= 3, { + params: { minimum: 3 }, + }) + .parse(2, { errorMap }); + } catch (err) { + const zerr: z.ZodError = err as any; + expect(zerr.issues[0].code).toEqual(z.ZodIssueCode.custom); + expect(zerr.issues[0].message).toEqual(`less-than-3`); + } +}); + +test("custom error with custom errormap", () => { + try { + z.string() + .refine((val) => val.length > 12, { + params: { minimum: 13 }, + message: "override", + }) + .parse("asdf", { errorMap }); + } catch (err) { + const zerr: z.ZodError = err as any; + expect(zerr.issues[0].message).toEqual("override"); + } +}); + +test("default error message", () => { + try { + z.number() + .refine((x) => x > 3) + .parse(2); + } catch (err) { + const zerr: z.ZodError = err as any; + expect(zerr.issues.length).toEqual(1); + expect(zerr.issues[0].message).toEqual("Invalid input"); + } +}); + +test("override error in refine", () => { + try { + z.number() + .refine((x) => x > 3, "override") + .parse(2); + } catch (err) { + const zerr: z.ZodError = err as any; + expect(zerr.issues.length).toEqual(1); + expect(zerr.issues[0].message).toEqual("override"); + } +}); + +test("override error in refinement", () => { + try { + z.number() + .refine((x) => x > 3, { + message: "override", + }) + .parse(2); + } catch (err) { + const zerr: z.ZodError = err as any; + expect(zerr.issues.length).toEqual(1); + expect(zerr.issues[0].message).toEqual("override"); + } +}); + +test("array minimum", () => { + try { + z.array(z.string()).min(3, "tooshort").parse(["asdf", "qwer"]); + } catch (err) { + const zerr: ZodError = err as any; + expect(zerr.issues[0].code).toEqual(ZodIssueCode.too_small); + expect(zerr.issues[0].message).toEqual("tooshort"); + } + try { + z.array(z.string()).min(3).parse(["asdf", "qwer"]); + } catch (err) { + const zerr: ZodError = err as any; + expect(zerr.issues[0].code).toEqual(ZodIssueCode.too_small); + expect(zerr.issues[0].message).toEqual(`Array must contain at least 3 element(s)`); + } +}); + +// implement test for semi-smart union logic that checks for type error on either left or right +// test("union smart errors", () => { +// // expect.assertions(2); + +// const p1 = z +// .union([z.string(), z.number().refine((x) => x > 0)]) +// .safeParse(-3.2); + +// if (p1.success === true) throw new Error(); +// expect(p1.success).toBe(false); +// expect(p1.error.issues[0].code).toEqual(ZodIssueCode.custom); + +// const p2 = z.union([z.string(), z.number()]).safeParse(false); +// // .catch(err => expect(err.issues[0].code).toEqual(ZodIssueCode.invalid_union)); +// if (p2.success === true) throw new Error(); +// expect(p2.success).toBe(false); +// expect(p2.error.issues[0].code).toEqual(ZodIssueCode.invalid_union); +// }); + +test("custom path in custom error map", () => { + const schema = z.object({ + items: z.array(z.string()).refine((data) => data.length > 3, { + path: ["items-too-few"], + }), + }); + + const errorMap: z.ZodErrorMap = (error) => { + expect(error.path.length).toBe(2); + return { message: "doesnt matter" }; + }; + const result = schema.safeParse({ items: ["first"] }, { errorMap }); + expect(result.success).toEqual(false); + if (!result.success) { + expect(result.error.issues[0].path).toEqual(["items", "items-too-few"]); + } +}); + +test("error metadata from value", () => { + const dynamicRefine = z.string().refine( + (val) => val === val.toUpperCase(), + (val) => ({ params: { val } }) + ); + + const result = dynamicRefine.safeParse("asdf"); + expect(result.success).toEqual(false); + if (!result.success) { + const sub = result.error.issues[0]; + expect(result.error.issues[0].code).toEqual("custom"); + if (sub.code === "custom") { + expect(sub.params!.val).toEqual("asdf"); + } + } +}); + +// test("don't call refine after validation failed", () => { +// const asdf = z +// .union([ +// z.number(), +// z.string().transform(z.number(), (val) => { +// return parseFloat(val); +// }), +// ]) +// .refine((v) => v >= 1); + +// expect(() => asdf.safeParse("foo")).not.toThrow(); +// }); + +test("root level formatting", () => { + const schema = z.string().email(); + const result = schema.safeParse("asdfsdf"); + expect(result.success).toEqual(false); + if (!result.success) { + expect(result.error.format()._errors).toEqual(["Invalid email"]); + } +}); + +test("custom path", () => { + const schema = z + .object({ + password: z.string(), + confirm: z.string(), + }) + .refine((val) => val.confirm === val.password, { path: ["confirm"] }); + + const result = schema.safeParse({ + password: "peanuts", + confirm: "qeanuts", + }); + + expect(result.success).toEqual(false); + if (!result.success) { + // nested errors + const error = result.error.format(); + expect(error._errors).toEqual([]); + expect(error.password?._errors).toEqual(undefined); + expect(error.confirm?._errors).toEqual(["Invalid input"]); + } +}); + +test("custom path", () => { + const schema = z + .object({ + password: z.string().min(6), + confirm: z.string().min(6), + }) + .refine((val) => val.confirm === val.password); + + const result = schema.safeParse({ + password: "qwer", + confirm: "asdf", + }); + + expect(result.success).toEqual(false); + if (!result.success) { + expect(result.error.issues.length).toEqual(3); + } +}); + +const schema = z.object({ + inner: z.object({ + name: z + .string() + .refine((val) => val.length > 5) + .array() + .refine((val) => val.length <= 1), + }), +}); + +test("no abort early on refinements", () => { + const invalidItem = { + inner: { name: ["aasd", "asdfasdfasfd"] }, + }; + + const result1 = schema.safeParse(invalidItem); + expect(result1.success).toEqual(false); + if (!result1.success) { + expect(result1.error.issues.length).toEqual(2); + } +}); +test("formatting", () => { + const invalidItem = { + inner: { name: ["aasd", "asdfasdfasfd"] }, + }; + const invalidArray = { + inner: { name: ["asdfasdf", "asdfasdfasfd"] }, + }; + const result1 = schema.safeParse(invalidItem); + const result2 = schema.safeParse(invalidArray); + + expect(result1.success).toEqual(false); + expect(result2.success).toEqual(false); + if (!result1.success) { + const error = result1.error.format(); + + expect(error._errors).toEqual([]); + expect(error.inner?._errors).toEqual([]); + // expect(error.inner?.name?._errors).toEqual(["Invalid input"]); + // expect(error.inner?.name?.[0]._errors).toEqual(["Invalid input"]); + expect(error.inner?.name?.[1]).toEqual(undefined); + } + if (!result2.success) { + type FormattedError = z.inferFormattedError; + const error: FormattedError = result2.error.format(); + expect(error._errors).toEqual([]); + expect(error.inner?._errors).toEqual([]); + expect(error.inner?.name?._errors).toEqual(["Invalid input"]); + expect(error.inner?.name?.[0]).toEqual(undefined); + expect(error.inner?.name?.[1]).toEqual(undefined); + expect(error.inner?.name?.[2]).toEqual(undefined); + } + + // test custom mapper + if (!result2.success) { + type FormattedError = z.inferFormattedError; + const error: FormattedError = result2.error.format(() => 5); + expect(error._errors).toEqual([]); + expect(error.inner?._errors).toEqual([]); + expect(error.inner?.name?._errors).toEqual([5]); + } +}); + +test("formatting with nullable and optional fields", () => { + const nameSchema = z.string().refine((val) => val.length > 5); + const schema = z.object({ + nullableObject: z.object({ name: nameSchema }).nullable(), + nullableArray: z.array(nameSchema).nullable(), + nullableTuple: z.tuple([nameSchema, nameSchema, z.number()]).nullable(), + optionalObject: z.object({ name: nameSchema }).optional(), + optionalArray: z.array(nameSchema).optional(), + optionalTuple: z.tuple([nameSchema, nameSchema, z.number()]).optional(), + }); + const invalidItem = { + nullableObject: { name: "abcd" }, + nullableArray: ["abcd"], + nullableTuple: ["abcd", "abcd", 1], + optionalObject: { name: "abcd" }, + optionalArray: ["abcd"], + optionalTuple: ["abcd", "abcd", 1], + }; + const result = schema.safeParse(invalidItem); + expect(result.success).toEqual(false); + if (!result.success) { + type FormattedError = z.inferFormattedError; + const error: FormattedError = result.error.format(); + expect(error._errors).toEqual([]); + expect(error.nullableObject?._errors).toEqual([]); + expect(error.nullableObject?.name?._errors).toEqual(["Invalid input"]); + expect(error.nullableArray?._errors).toEqual([]); + expect(error.nullableArray?.[0]?._errors).toEqual(["Invalid input"]); + expect(error.nullableTuple?._errors).toEqual([]); + expect(error.nullableTuple?.[0]?._errors).toEqual(["Invalid input"]); + expect(error.nullableTuple?.[1]?._errors).toEqual(["Invalid input"]); + expect(error.optionalObject?._errors).toEqual([]); + expect(error.optionalObject?.name?._errors).toEqual(["Invalid input"]); + expect(error.optionalArray?._errors).toEqual([]); + expect(error.optionalArray?.[0]?._errors).toEqual(["Invalid input"]); + expect(error.optionalTuple?._errors).toEqual([]); + expect(error.optionalTuple?.[0]?._errors).toEqual(["Invalid input"]); + expect(error.optionalTuple?.[1]?._errors).toEqual(["Invalid input"]); + } +}); + +const stringWithCustomError = z.string({ + errorMap: (issue, ctx) => ({ + message: issue.code === "invalid_type" ? (ctx.data ? "Invalid name" : "Name is required") : ctx.defaultError, + }), +}); + +test("schema-bound error map", () => { + const result = stringWithCustomError.safeParse(1234); + expect(result.success).toEqual(false); + if (!result.success) { + expect(result.error.issues[0].message).toEqual("Invalid name"); + } + + const result2 = stringWithCustomError.safeParse(undefined); + expect(result2.success).toEqual(false); + if (!result2.success) { + expect(result2.error.issues[0].message).toEqual("Name is required"); + } + + // support contextual override + const result3 = stringWithCustomError.safeParse(undefined, { + errorMap: () => ({ message: "OVERRIDE" }), + }); + expect(result3.success).toEqual(false); + if (!result3.success) { + expect(result3.error.issues[0].message).toEqual("OVERRIDE"); + } +}); + +test("overrideErrorMap", () => { + // support overrideErrorMap + z.setErrorMap(() => ({ message: "OVERRIDE" })); + const result4 = stringWithCustomError.min(10).safeParse("tooshort"); + expect(result4.success).toEqual(false); + if (!result4.success) { + expect(result4.error.issues[0].message).toEqual("OVERRIDE"); + } + z.setErrorMap(z.defaultErrorMap); +}); + +test("invalid and required", () => { + const str = z.string({ + invalid_type_error: "Invalid name", + required_error: "Name is required", + }); + const result1 = str.safeParse(1234); + expect(result1.success).toEqual(false); + if (!result1.success) { + expect(result1.error.issues[0].message).toEqual("Invalid name"); + } + const result2 = str.safeParse(undefined); + expect(result2.success).toEqual(false); + if (!result2.success) { + expect(result2.error.issues[0].message).toEqual("Name is required"); + } +}); + +test("Fallback to default required error", () => { + const str = z.string({ + invalid_type_error: "Invalid name", + // required_error: "Name is required", + }); + + const result2 = str.safeParse(undefined); + expect(result2.success).toEqual(false); + if (!result2.success) { + expect(result2.error.issues[0].message).toEqual("Required"); + } +}); + +test("invalid and required and errorMap", () => { + expect(() => { + return z.string({ + invalid_type_error: "Invalid name", + required_error: "Name is required", + errorMap: () => ({ message: "OVERRIDE" }), + }); + }).toThrow(); +}); + +test("strict error message", () => { + const errorMsg = "Invalid object"; + const obj = z.object({ x: z.string() }).strict(errorMsg); + const result = obj.safeParse({ x: "a", y: "b" }); + expect(result.success).toEqual(false); + if (!result.success) { + expect(result.error.issues[0].message).toEqual(errorMsg); + } +}); + +test("enum error message, invalid enum elementstring", () => { + try { + z.enum(["Tuna", "Trout"]).parse("Salmon"); + } catch (err) { + const zerr: z.ZodError = err as any; + expect(zerr.issues.length).toEqual(1); + expect(zerr.issues[0].message).toEqual("Invalid enum value. Expected 'Tuna' | 'Trout', received 'Salmon'"); + } +}); + +test("enum error message, invalid type", () => { + try { + z.enum(["Tuna", "Trout"]).parse(12); + } catch (err) { + const zerr: z.ZodError = err as any; + expect(zerr.issues.length).toEqual(1); + expect(zerr.issues[0].message).toEqual("Expected 'Tuna' | 'Trout', received number"); + } +}); + +test("nativeEnum default error message", () => { + enum Fish { + Tuna = "Tuna", + Trout = "Trout", + } + try { + z.nativeEnum(Fish).parse("Salmon"); + } catch (err) { + const zerr: z.ZodError = err as any; + expect(zerr.issues.length).toEqual(1); + expect(zerr.issues[0].message).toEqual("Invalid enum value. Expected 'Tuna' | 'Trout', received 'Salmon'"); + } +}); + +test("literal default error message", () => { + try { + z.literal("Tuna").parse("Trout"); + } catch (err) { + const zerr: z.ZodError = err as any; + expect(zerr.issues.length).toEqual(1); + expect(zerr.issues[0].message).toEqual(`Invalid literal value, expected "Tuna"`); + } +}); + +test("literal bigint default error message", () => { + try { + z.literal(BigInt(12)).parse(BigInt(13)); + } catch (err) { + const zerr: z.ZodError = err as any; + expect(zerr.issues.length).toEqual(1); + expect(zerr.issues[0].message).toEqual(`Invalid literal value, expected "12"`); + } +}); + +test("enum with message returns the custom error message", () => { + const schema = z.enum(["apple", "banana"], { + message: "the value provided is invalid", + }); + + const result1 = schema.safeParse("berries"); + expect(result1.success).toEqual(false); + if (!result1.success) { + expect(result1.error.issues[0].message).toEqual("the value provided is invalid"); + } + + const result2 = schema.safeParse(undefined); + expect(result2.success).toEqual(false); + if (!result2.success) { + expect(result2.error.issues[0].message).toEqual("the value provided is invalid"); + } + + const result3 = schema.safeParse("banana"); + expect(result3.success).toEqual(true); + + const result4 = schema.safeParse(null); + expect(result4.success).toEqual(false); + if (!result4.success) { + expect(result4.error.issues[0].message).toEqual("the value provided is invalid"); + } +}); + +test("when the message is falsy, it is used as is provided", () => { + const schema = z.string().max(1, { message: "" }); + const result = schema.safeParse("asdf"); + expect(result.success).toEqual(false); + if (!result.success) { + expect(result.error.issues[0].message).toEqual(""); + } +}); + +// test("dont short circuit on continuable errors", () => { +// const user = z +// .object({ +// password: z.string().min(6), +// confirm: z.string(), +// }) +// .refine((data) => data.password === data.confirm, { +// message: "Passwords don't match", +// path: ["confirm"], +// }); +// const result = user.safeParse({ password: "asdf", confirm: "qwer" }); +// if (!result.success) { +// expect(result.error.issues.length).toEqual(2); +// } +// }); diff --git a/node_modules/zod/src/v3/tests/firstparty.test.ts b/node_modules/zod/src/v3/tests/firstparty.test.ts new file mode 100644 index 00000000..017a1c13 --- /dev/null +++ b/node_modules/zod/src/v3/tests/firstparty.test.ts @@ -0,0 +1,87 @@ +// @ts-ignore TS6133 +import { test } from "vitest"; + +import * as z from "zod/v3"; +import { util } from "../helpers/util.js"; + +test("first party switch", () => { + const myType = z.string() as z.ZodFirstPartySchemaTypes; + const def = myType._def; + + switch (def.typeName) { + case z.ZodFirstPartyTypeKind.ZodString: + break; + case z.ZodFirstPartyTypeKind.ZodNumber: + break; + case z.ZodFirstPartyTypeKind.ZodNaN: + break; + case z.ZodFirstPartyTypeKind.ZodBigInt: + break; + case z.ZodFirstPartyTypeKind.ZodBoolean: + break; + case z.ZodFirstPartyTypeKind.ZodDate: + break; + case z.ZodFirstPartyTypeKind.ZodUndefined: + break; + case z.ZodFirstPartyTypeKind.ZodNull: + break; + case z.ZodFirstPartyTypeKind.ZodAny: + break; + case z.ZodFirstPartyTypeKind.ZodUnknown: + break; + case z.ZodFirstPartyTypeKind.ZodNever: + break; + case z.ZodFirstPartyTypeKind.ZodVoid: + break; + case z.ZodFirstPartyTypeKind.ZodArray: + break; + case z.ZodFirstPartyTypeKind.ZodObject: + break; + case z.ZodFirstPartyTypeKind.ZodUnion: + break; + case z.ZodFirstPartyTypeKind.ZodDiscriminatedUnion: + break; + case z.ZodFirstPartyTypeKind.ZodIntersection: + break; + case z.ZodFirstPartyTypeKind.ZodTuple: + break; + case z.ZodFirstPartyTypeKind.ZodRecord: + break; + case z.ZodFirstPartyTypeKind.ZodMap: + break; + case z.ZodFirstPartyTypeKind.ZodSet: + break; + case z.ZodFirstPartyTypeKind.ZodFunction: + break; + case z.ZodFirstPartyTypeKind.ZodLazy: + break; + case z.ZodFirstPartyTypeKind.ZodLiteral: + break; + case z.ZodFirstPartyTypeKind.ZodEnum: + break; + case z.ZodFirstPartyTypeKind.ZodEffects: + break; + case z.ZodFirstPartyTypeKind.ZodNativeEnum: + break; + case z.ZodFirstPartyTypeKind.ZodOptional: + break; + case z.ZodFirstPartyTypeKind.ZodNullable: + break; + case z.ZodFirstPartyTypeKind.ZodDefault: + break; + case z.ZodFirstPartyTypeKind.ZodCatch: + break; + case z.ZodFirstPartyTypeKind.ZodPromise: + break; + case z.ZodFirstPartyTypeKind.ZodBranded: + break; + case z.ZodFirstPartyTypeKind.ZodPipeline: + break; + case z.ZodFirstPartyTypeKind.ZodSymbol: + break; + case z.ZodFirstPartyTypeKind.ZodReadonly: + break; + default: + util.assertNever(def); + } +}); diff --git a/node_modules/zod/src/v3/tests/firstpartyschematypes.test.ts b/node_modules/zod/src/v3/tests/firstpartyschematypes.test.ts new file mode 100644 index 00000000..ad397d8b --- /dev/null +++ b/node_modules/zod/src/v3/tests/firstpartyschematypes.test.ts @@ -0,0 +1,21 @@ +// @ts-ignore TS6133 +import { test } from "vitest"; + +import type { ZodFirstPartySchemaTypes, ZodFirstPartyTypeKind } from "zod/v3"; +import { util } from "../helpers/util.js"; + +test("Identify missing [ZodFirstPartySchemaTypes]", () => { + type ZodFirstPartySchemaForType = ZodFirstPartySchemaTypes extends infer Schema + ? Schema extends { _def: { typeName: T } } + ? Schema + : never + : never; + type ZodMappedTypes = { + [key in ZodFirstPartyTypeKind]: ZodFirstPartySchemaForType; + }; + type ZodFirstPartySchemaTypesMissingFromUnion = keyof { + [key in keyof ZodMappedTypes as ZodMappedTypes[key] extends { _def: never } ? key : never]: unknown; + }; + + util.assertEqual(true); +}); diff --git a/node_modules/zod/src/v3/tests/function.test.ts b/node_modules/zod/src/v3/tests/function.test.ts new file mode 100644 index 00000000..9a9e193b --- /dev/null +++ b/node_modules/zod/src/v3/tests/function.test.ts @@ -0,0 +1,261 @@ +// @ts-ignore TS6133 +import { expect, test } from "vitest"; + +import * as z from "zod/v3"; +import { util } from "../helpers/util.js"; + +const args1 = z.tuple([z.string()]); +const returns1 = z.number(); +const func1 = z.function(args1, returns1); + +test("function parsing", () => { + const parsed = func1.parse((arg: any) => arg.length); + const result = parsed("asdf"); + expect(result).toBe(4); +}); + +test("parsed function fail 1", () => { + const parsed = func1.parse((x: string) => x); + expect(() => parsed("asdf")).toThrow(); +}); + +test("parsed function fail 2", () => { + const parsed = func1.parse((x: string) => x); + expect(() => parsed(13 as any)).toThrow(); +}); + +test("function inference 1", () => { + type func1 = z.TypeOf; + util.assertEqual number>(true); +}); + +test("method parsing", () => { + const methodObject = z.object({ + property: z.number(), + method: z.function().args(z.string()).returns(z.number()), + }); + const methodInstance = { + property: 3, + method: function (s: string) { + return s.length + this.property; + }, + }; + const parsed = methodObject.parse(methodInstance); + expect(parsed.method("length=8")).toBe(11); // 8 length + 3 property +}); + +test("async method parsing", async () => { + const methodObject = z.object({ + property: z.number(), + method: z.function().args(z.string()).returns(z.promise(z.number())), + }); + const methodInstance = { + property: 3, + method: async function (s: string) { + return s.length + this.property; + }, + }; + const parsed = methodObject.parse(methodInstance); + expect(await parsed.method("length=8")).toBe(11); // 8 length + 3 property +}); + +test("args method", () => { + const t1 = z.function(); + type t1 = z.infer; + util.assertEqual unknown>(true); + + const t2 = t1.args(z.string()); + type t2 = z.infer; + util.assertEqual unknown>(true); + + const t3 = t2.returns(z.boolean()); + type t3 = z.infer; + util.assertEqual boolean>(true); +}); + +const args2 = z.tuple([ + z.object({ + f1: z.number(), + f2: z.string().nullable(), + f3: z.array(z.boolean().optional()).optional(), + }), +]); +const returns2 = z.union([z.string(), z.number()]); + +const func2 = z.function(args2, returns2); + +test("function inference 2", () => { + type func2 = z.TypeOf; + util.assertEqual< + func2, + (arg: { + f1: number; + f2: string | null; + f3?: (boolean | undefined)[] | undefined; + }) => string | number + >(true); +}); + +test("valid function run", () => { + const validFunc2Instance = func2.validate((_x) => { + return "adf" as any; + }); + + const checker = () => { + validFunc2Instance({ + f1: 21, + f2: "asdf", + f3: [true, false], + }); + }; + + checker(); +}); + +test("input validation error", () => { + const invalidFuncInstance = func2.validate((_x) => { + return "adf" as any; + }); + + const checker = () => { + invalidFuncInstance("Invalid_input" as any); + }; + + expect(checker).toThrow(); +}); + +test("output validation error", () => { + const invalidFuncInstance = func2.validate((_x) => { + return ["this", "is", "not", "valid", "output"] as any; + }); + + const checker = () => { + invalidFuncInstance({ + f1: 21, + f2: "asdf", + f3: [true, false], + }); + }; + + expect(checker).toThrow(); +}); + +z.function(z.tuple([z.string()])).args()._def.args; + +test("special function error codes", () => { + const checker = z.function(z.tuple([z.string()]), z.boolean()).implement((arg) => { + return arg.length as any; + }); + try { + checker("12" as any); + } catch (err) { + const zerr = err as z.ZodError; + const first = zerr.issues[0]; + if (first.code !== z.ZodIssueCode.invalid_return_type) throw new Error(); + + expect(first.returnTypeError).toBeInstanceOf(z.ZodError); + } + + try { + checker(12 as any); + } catch (err) { + const zerr = err as z.ZodError; + const first = zerr.issues[0]; + if (first.code !== z.ZodIssueCode.invalid_arguments) throw new Error(); + expect(first.argumentsError).toBeInstanceOf(z.ZodError); + } +}); + +test("function with async refinements", async () => { + const func = z + .function() + .args(z.string().refine(async (val) => val.length > 10)) + .returns(z.promise(z.number().refine(async (val) => val > 10))) + .implement(async (val) => { + return val.length; + }); + const results = []; + try { + await func("asdfasdf"); + results.push("success"); + } catch (_err) { + results.push("fail"); + } + try { + await func("asdflkjasdflkjsf"); + results.push("success"); + } catch (_err) { + results.push("fail"); + } + + expect(results).toEqual(["fail", "success"]); +}); + +test("non async function with async refinements should fail", async () => { + const func = z + .function() + .args(z.string().refine(async (val) => val.length > 10)) + .returns(z.number().refine(async (val) => val > 10)) + .implement((val) => { + return val.length; + }); + + const results = []; + try { + await func("asdasdfasdffasdf"); + results.push("success"); + } catch (_err) { + results.push("fail"); + } + + expect(results).toEqual(["fail"]); +}); + +test("allow extra parameters", () => { + const maxLength5 = z + .function() + .args(z.string()) + .returns(z.boolean()) + .implement((str, _arg, _qewr) => { + return str.length <= 5; + }); + + const filteredList = ["apple", "orange", "pear", "banana", "strawberry"].filter(maxLength5); + expect(filteredList.length).toEqual(2); +}); + +test("params and returnType getters", () => { + const func = z.function().args(z.string()).returns(z.string()); + + const paramResult = func.parameters().items[0].parse("asdf"); + expect(paramResult).toBe("asdf"); + + const returnResult = func.returnType().parse("asdf"); + expect(returnResult).toBe("asdf"); +}); + +test("inference with transforms", () => { + const funcSchema = z + .function() + .args(z.string().transform((val) => val.length)) + .returns(z.object({ val: z.number() })); + const myFunc = funcSchema.implement((val) => { + return { val, extra: "stuff" }; + }); + myFunc("asdf"); + + util.assertEqual { val: number; extra: string }>(true); +}); + +test("fallback to OuterTypeOfFunction", () => { + const funcSchema = z + .function() + .args(z.string().transform((val) => val.length)) + .returns(z.object({ arg: z.number() }).transform((val) => val.arg)); + + const myFunc = funcSchema.implement((val) => { + return { arg: val, arg2: false }; + }); + + util.assertEqual number>(true); +}); diff --git a/node_modules/zod/src/v3/tests/generics.test.ts b/node_modules/zod/src/v3/tests/generics.test.ts new file mode 100644 index 00000000..e0af470f --- /dev/null +++ b/node_modules/zod/src/v3/tests/generics.test.ts @@ -0,0 +1,48 @@ +// @ts-ignore TS6133 +import { expect, test } from "vitest"; + +import * as z from "zod/v3"; +import { util } from "../helpers/util.js"; + +test("generics", () => { + async function stripOuter(schema: TData, data: unknown) { + return z + .object({ + nested: schema, // as z.ZodTypeAny, + }) + .transform((data) => { + return data.nested!; + }) + .parse({ nested: data }); + } + + const result = stripOuter(z.object({ a: z.string() }), { a: "asdf" }); + util.assertEqual>(true); +}); + +// test("assignability", () => { +// const createSchemaAndParse = ( +// key: K, +// valueSchema: VS, +// data: unknown +// ) => { +// const schema = z.object({ +// [key]: valueSchema, +// } as { [k in K]: VS }); +// return { [key]: valueSchema }; +// const parsed = schema.parse(data); +// return parsed; +// // const inferred: z.infer> = parsed; +// // return inferred; +// }; +// const parsed = createSchemaAndParse("foo", z.string(), { foo: "" }); +// util.assertEqual(true); +// }); + +test("nested no undefined", () => { + const inner = z.string().or(z.array(z.string())); + const outer = z.object({ inner }); + type outerSchema = z.infer; + z.util.assertEqual(true); + expect(outer.safeParse({ inner: undefined }).success).toEqual(false); +}); diff --git a/node_modules/zod/src/v3/tests/instanceof.test.ts b/node_modules/zod/src/v3/tests/instanceof.test.ts new file mode 100644 index 00000000..de66f3f0 --- /dev/null +++ b/node_modules/zod/src/v3/tests/instanceof.test.ts @@ -0,0 +1,37 @@ +// @ts-ignore TS6133 +import { expect, test } from "vitest"; + +import * as z from "zod/v3"; +import { util } from "../helpers/util.js"; + +test("instanceof", async () => { + class Test {} + class Subtest extends Test {} + abstract class AbstractBar { + constructor(public val: string) {} + } + class Bar extends AbstractBar {} + + const TestSchema = z.instanceof(Test); + const SubtestSchema = z.instanceof(Subtest); + const AbstractSchema = z.instanceof(AbstractBar); + const BarSchema = z.instanceof(Bar); + + TestSchema.parse(new Test()); + TestSchema.parse(new Subtest()); + SubtestSchema.parse(new Subtest()); + AbstractSchema.parse(new Bar("asdf")); + const bar = BarSchema.parse(new Bar("asdf")); + expect(bar.val).toEqual("asdf"); + + await expect(() => SubtestSchema.parse(new Test())).toThrow(/Input not instance of Subtest/); + await expect(() => TestSchema.parse(12)).toThrow(/Input not instance of Test/); + + util.assertEqual>(true); +}); + +test("instanceof fatal", () => { + const schema = z.instanceof(Date).refine((d) => d.toString()); + const res = schema.safeParse(null); + expect(res.success).toBe(false); +}); diff --git a/node_modules/zod/src/v3/tests/intersection.test.ts b/node_modules/zod/src/v3/tests/intersection.test.ts new file mode 100644 index 00000000..6d7936c1 --- /dev/null +++ b/node_modules/zod/src/v3/tests/intersection.test.ts @@ -0,0 +1,110 @@ +// @ts-ignore TS6133 +import { expect, test } from "vitest"; + +import * as z from "zod/v3"; + +test("object intersection", () => { + const BaseTeacher = z.object({ + subjects: z.array(z.string()), + }); + const HasID = z.object({ id: z.string() }); + + const Teacher = z.intersection(BaseTeacher.passthrough(), HasID); // BaseTeacher.merge(HasID); + const data = { + subjects: ["math"], + id: "asdfasdf", + }; + expect(Teacher.parse(data)).toEqual(data); + expect(() => Teacher.parse({ subject: data.subjects })).toThrow(); + expect(Teacher.parse({ ...data, extra: 12 })).toEqual({ ...data, extra: 12 }); + + expect(() => z.intersection(BaseTeacher.strict(), HasID).parse({ ...data, extra: 12 })).toThrow(); +}); + +test("deep intersection", () => { + const Animal = z.object({ + properties: z.object({ + is_animal: z.boolean(), + }), + }); + const Cat = z + .object({ + properties: z.object({ + jumped: z.boolean(), + }), + }) + .and(Animal); + + type _Cat = z.infer; + // const cat:Cat = 'asdf' as any; + const cat = Cat.parse({ properties: { is_animal: true, jumped: true } }); + expect(cat.properties).toEqual({ is_animal: true, jumped: true }); +}); + +test("deep intersection of arrays", async () => { + const Author = z.object({ + posts: z.array( + z.object({ + post_id: z.number(), + }) + ), + }); + const Registry = z + .object({ + posts: z.array( + z.object({ + title: z.string(), + }) + ), + }) + .and(Author); + + const posts = [ + { post_id: 1, title: "Novels" }, + { post_id: 2, title: "Fairy tales" }, + ]; + const cat = Registry.parse({ posts }); + expect(cat.posts).toEqual(posts); + const asyncCat = await Registry.parseAsync({ posts }); + expect(asyncCat.posts).toEqual(posts); +}); + +test("invalid intersection types", async () => { + const numberIntersection = z.intersection( + z.number(), + z.number().transform((x) => x + 1) + ); + + const syncResult = numberIntersection.safeParse(1234); + expect(syncResult.success).toEqual(false); + if (!syncResult.success) { + expect(syncResult.error.issues[0].code).toEqual(z.ZodIssueCode.invalid_intersection_types); + } + + const asyncResult = await numberIntersection.spa(1234); + expect(asyncResult.success).toEqual(false); + if (!asyncResult.success) { + expect(asyncResult.error.issues[0].code).toEqual(z.ZodIssueCode.invalid_intersection_types); + } +}); + +test("invalid array merge", async () => { + const stringArrInt = z.intersection( + z.string().array(), + z + .string() + .array() + .transform((val) => [...val, "asdf"]) + ); + const syncResult = stringArrInt.safeParse(["asdf", "qwer"]); + expect(syncResult.success).toEqual(false); + if (!syncResult.success) { + expect(syncResult.error.issues[0].code).toEqual(z.ZodIssueCode.invalid_intersection_types); + } + + const asyncResult = await stringArrInt.spa(["asdf", "qwer"]); + expect(asyncResult.success).toEqual(false); + if (!asyncResult.success) { + expect(asyncResult.error.issues[0].code).toEqual(z.ZodIssueCode.invalid_intersection_types); + } +}); diff --git a/node_modules/zod/src/v3/tests/language-server.source.ts b/node_modules/zod/src/v3/tests/language-server.source.ts new file mode 100644 index 00000000..cbe818bb --- /dev/null +++ b/node_modules/zod/src/v3/tests/language-server.source.ts @@ -0,0 +1,76 @@ +import * as z from "zod/v3"; + +export const filePath = __filename; + +// z.object() + +export const Test = z.object({ + f1: z.number(), +}); + +export type Test = z.infer; + +export const instanceOfTest: Test = { + f1: 1, +}; + +// z.object().merge() + +export const TestMerge = z + .object({ + f2: z.string().optional(), + }) + .merge(Test); + +export type TestMerge = z.infer; + +export const instanceOfTestMerge: TestMerge = { + f1: 1, + f2: "string", +}; + +// z.union() + +export const TestUnion = z.union([ + z.object({ + f2: z.string().optional(), + }), + Test, +]); + +export type TestUnion = z.infer; + +export const instanceOfTestUnion: TestUnion = { + f1: 1, + f2: "string", +}; + +// z.object().partial() + +export const TestPartial = Test.partial(); + +export type TestPartial = z.infer; + +export const instanceOfTestPartial: TestPartial = { + f1: 1, +}; + +// z.object().pick() + +export const TestPick = TestMerge.pick({ f1: true }); + +export type TestPick = z.infer; + +export const instanceOfTestPick: TestPick = { + f1: 1, +}; + +// z.object().omit() + +export const TestOmit = TestMerge.omit({ f2: true }); + +export type TestOmit = z.infer; + +export const instanceOfTestOmit: TestOmit = { + f1: 1, +}; diff --git a/node_modules/zod/src/v3/tests/language-server.test.ts b/node_modules/zod/src/v3/tests/language-server.test.ts new file mode 100644 index 00000000..851fdc48 --- /dev/null +++ b/node_modules/zod/src/v3/tests/language-server.test.ts @@ -0,0 +1,207 @@ +import { test } from "vitest"; +// import path from "path"; +// import { Node, Project, SyntaxKind } from "ts-morph"; + +// import { filePath } from "./language-server.source"; + +// The following tool is helpful for understanding the TypeScript AST associated with these tests: +// https://ts-ast-viewer.com/ (just copy the contents of language-server.source into the viewer) + +test("", () => {}); +// describe("Executing Go To Definition (and therefore Find Usages and Rename Refactoring) using an IDE works on inferred object properties", () => { +// // Compile file developmentEnvironment.source +// const project = new Project({ +// tsConfigFilePath: path.join(__dirname, "..", "..", "tsconfig.json"), +// skipAddingFilesFromTsConfig: true, +// }); +// const sourceFile = project.addSourceFileAtPath(filePath); + +// test("works for object properties inferred from z.object()", () => { +// // Find usage of Test.f1 property +// const instanceVariable = +// sourceFile.getVariableDeclarationOrThrow("instanceOfTest"); +// const propertyBeingAssigned = getPropertyBeingAssigned( +// instanceVariable, +// "f1" +// ); + +// // Find definition of Test.f1 property +// const definitionOfProperty = propertyBeingAssigned?.getDefinitionNodes()[0]; +// const parentOfProperty = definitionOfProperty?.getFirstAncestorByKind( +// SyntaxKind.VariableDeclaration +// ); + +// // Assert that find definition returned the Zod definition of Test +// expect(definitionOfProperty?.getText()).toEqual("f1: z.number()"); +// expect(parentOfProperty?.getName()).toEqual("Test"); +// }); + +// // test("works for first object properties inferred from z.object().merge()", () => { +// // // Find usage of TestMerge.f1 property +// // const instanceVariable = sourceFile.getVariableDeclarationOrThrow( +// // "instanceOfTestMerge" +// // ); +// // const propertyBeingAssigned = getPropertyBeingAssigned( +// // instanceVariable, +// // "f1" +// // ); + +// // // Find definition of TestMerge.f1 property +// // const definitionOfProperty = propertyBeingAssigned?.getDefinitionNodes()[0]; +// // const parentOfProperty = definitionOfProperty?.getFirstAncestorByKind( +// // SyntaxKind.VariableDeclaration +// // ); + +// // // Assert that find definition returned the Zod definition of Test +// // expect(definitionOfProperty?.getText()).toEqual("f1: z.number()"); +// // expect(parentOfProperty?.getName()).toEqual("Test"); +// // }); + +// // test("works for second object properties inferred from z.object().merge()", () => { +// // // Find usage of TestMerge.f2 property +// // const instanceVariable = sourceFile.getVariableDeclarationOrThrow( +// // "instanceOfTestMerge" +// // ); +// // const propertyBeingAssigned = getPropertyBeingAssigned( +// // instanceVariable, +// // "f2" +// // ); + +// // // Find definition of TestMerge.f2 property +// // const definitionOfProperty = propertyBeingAssigned?.getDefinitionNodes()[0]; +// // const parentOfProperty = definitionOfProperty?.getFirstAncestorByKind( +// // SyntaxKind.VariableDeclaration +// // ); + +// // // Assert that find definition returned the Zod definition of TestMerge +// // expect(definitionOfProperty?.getText()).toEqual( +// // "f2: z.string().optional()" +// // ); +// // expect(parentOfProperty?.getName()).toEqual("TestMerge"); +// // }); + +// test("works for first object properties inferred from z.union()", () => { +// // Find usage of TestUnion.f1 property +// const instanceVariable = sourceFile.getVariableDeclarationOrThrow( +// "instanceOfTestUnion" +// ); +// const propertyBeingAssigned = getPropertyBeingAssigned( +// instanceVariable, +// "f1" +// ); + +// // Find definition of TestUnion.f1 property +// const definitionOfProperty = propertyBeingAssigned?.getDefinitionNodes()[0]; +// const parentOfProperty = definitionOfProperty?.getFirstAncestorByKind( +// SyntaxKind.VariableDeclaration +// ); + +// // Assert that find definition returned the Zod definition of Test +// expect(definitionOfProperty?.getText()).toEqual("f1: z.number()"); +// expect(parentOfProperty?.getName()).toEqual("Test"); +// }); + +// test("works for second object properties inferred from z.union()", () => { +// // Find usage of TestUnion.f2 property +// const instanceVariable = sourceFile.getVariableDeclarationOrThrow( +// "instanceOfTestUnion" +// ); +// const propertyBeingAssigned = getPropertyBeingAssigned( +// instanceVariable, +// "f2" +// ); + +// // Find definition of TestUnion.f2 property +// const definitionOfProperty = propertyBeingAssigned?.getDefinitionNodes()[0]; +// const parentOfProperty = definitionOfProperty?.getFirstAncestorByKind( +// SyntaxKind.VariableDeclaration +// ); + +// // Assert that find definition returned the Zod definition of TestUnion +// expect(definitionOfProperty?.getText()).toEqual( +// "f2: z.string().optional()" +// ); +// expect(parentOfProperty?.getName()).toEqual("TestUnion"); +// }); + +// test("works for object properties inferred from z.object().partial()", () => { +// // Find usage of TestPartial.f1 property +// const instanceVariable = sourceFile.getVariableDeclarationOrThrow( +// "instanceOfTestPartial" +// ); +// const propertyBeingAssigned = getPropertyBeingAssigned( +// instanceVariable, +// "f1" +// ); + +// // Find definition of TestPartial.f1 property +// const definitionOfProperty = propertyBeingAssigned?.getDefinitionNodes()[0]; +// const parentOfProperty = definitionOfProperty?.getFirstAncestorByKind( +// SyntaxKind.VariableDeclaration +// ); + +// // Assert that find definition returned the Zod definition of Test +// expect(definitionOfProperty?.getText()).toEqual("f1: z.number()"); +// expect(parentOfProperty?.getName()).toEqual("Test"); +// }); + +// test("works for object properties inferred from z.object().pick()", () => { +// // Find usage of TestPick.f1 property +// const instanceVariable = +// sourceFile.getVariableDeclarationOrThrow("instanceOfTestPick"); +// const propertyBeingAssigned = getPropertyBeingAssigned( +// instanceVariable, +// "f1" +// ); + +// // Find definition of TestPick.f1 property +// const definitionOfProperty = propertyBeingAssigned?.getDefinitionNodes()[0]; +// const parentOfProperty = definitionOfProperty?.getFirstAncestorByKind( +// SyntaxKind.VariableDeclaration +// ); + +// // Assert that find definition returned the Zod definition of Test +// expect(definitionOfProperty?.getText()).toEqual("f1: z.number()"); +// expect(parentOfProperty?.getName()).toEqual("Test"); +// }); + +// test("works for object properties inferred from z.object().omit()", () => { +// // Find usage of TestOmit.f1 property +// const instanceVariable = +// sourceFile.getVariableDeclarationOrThrow("instanceOfTestOmit"); +// const propertyBeingAssigned = getPropertyBeingAssigned( +// instanceVariable, +// "f1" +// ); + +// // Find definition of TestOmit.f1 property +// const definitionOfProperty = propertyBeingAssigned?.getDefinitionNodes()[0]; +// const parentOfProperty = definitionOfProperty?.getFirstAncestorByKind( +// SyntaxKind.VariableDeclaration +// ); + +// // Assert that find definition returned the Zod definition of Test +// expect(definitionOfProperty?.getText()).toEqual("f1: z.number()"); +// expect(parentOfProperty?.getName()).toEqual("Test"); +// }); +// }); + +// const getPropertyBeingAssigned = (node: Node, name: string) => { +// const propertyAssignment = node.forEachDescendant((descendent) => +// Node.isPropertyAssignment(descendent) && descendent.getName() == name +// ? descendent +// : undefined +// ); + +// if (propertyAssignment == null) +// fail(`Could not find property assignment with name ${name}`); + +// const propertyLiteral = propertyAssignment.getFirstDescendantByKind( +// SyntaxKind.Identifier +// ); + +// if (propertyLiteral == null) +// fail(`Could not find property literal with name ${name}`); + +// return propertyLiteral; +// }; diff --git a/node_modules/zod/src/v3/tests/literal.test.ts b/node_modules/zod/src/v3/tests/literal.test.ts new file mode 100644 index 00000000..d166a24f --- /dev/null +++ b/node_modules/zod/src/v3/tests/literal.test.ts @@ -0,0 +1,36 @@ +// @ts-ignore TS6133 +import { expect, test } from "vitest"; + +import * as z from "zod/v3"; + +const literalTuna = z.literal("tuna"); +const literalFortyTwo = z.literal(42); +const literalTrue = z.literal(true); + +const terrificSymbol = Symbol("terrific"); +const literalTerrificSymbol = z.literal(terrificSymbol); + +test("passing validations", () => { + literalTuna.parse("tuna"); + literalFortyTwo.parse(42); + literalTrue.parse(true); + literalTerrificSymbol.parse(terrificSymbol); +}); + +test("failing validations", () => { + expect(() => literalTuna.parse("shark")).toThrow(); + expect(() => literalFortyTwo.parse(43)).toThrow(); + expect(() => literalTrue.parse(false)).toThrow(); + expect(() => literalTerrificSymbol.parse(Symbol("terrific"))).toThrow(); +}); + +test("invalid_literal should have `received` field with data", () => { + const data = "shark"; + const result = literalTuna.safeParse(data); + if (!result.success) { + const issue = result.error.issues[0]; + if (issue.code === "invalid_literal") { + expect(issue.received).toBe(data); + } + } +}); diff --git a/node_modules/zod/src/v3/tests/map.test.ts b/node_modules/zod/src/v3/tests/map.test.ts new file mode 100644 index 00000000..94718190 --- /dev/null +++ b/node_modules/zod/src/v3/tests/map.test.ts @@ -0,0 +1,110 @@ +// @ts-ignore TS6133 +import { expect, test } from "vitest"; + +import * as z from "zod/v3"; +import { ZodIssueCode } from "zod/v3"; +import { util } from "../helpers/util.js"; + +const stringMap = z.map(z.string(), z.string()); +type stringMap = z.infer; + +test("type inference", () => { + util.assertEqual>(true); +}); + +test("valid parse", () => { + const result = stringMap.safeParse( + new Map([ + ["first", "foo"], + ["second", "bar"], + ]) + ); + expect(result.success).toEqual(true); + if (result.success) { + expect(result.data.has("first")).toEqual(true); + expect(result.data.has("second")).toEqual(true); + expect(result.data.get("first")).toEqual("foo"); + expect(result.data.get("second")).toEqual("bar"); + } +}); + +test("valid parse async", async () => { + const result = await stringMap.spa( + new Map([ + ["first", "foo"], + ["second", "bar"], + ]) + ); + expect(result.success).toEqual(true); + if (result.success) { + expect(result.data.has("first")).toEqual(true); + expect(result.data.has("second")).toEqual(true); + expect(result.data.get("first")).toEqual("foo"); + expect(result.data.get("second")).toEqual("bar"); + } +}); + +test("throws when a Set is given", () => { + const result = stringMap.safeParse(new Set([])); + expect(result.success).toEqual(false); + if (result.success === false) { + expect(result.error.issues.length).toEqual(1); + expect(result.error.issues[0].code).toEqual(ZodIssueCode.invalid_type); + } +}); + +test("throws when the given map has invalid key and invalid input", () => { + const result = stringMap.safeParse(new Map([[42, Symbol()]])); + expect(result.success).toEqual(false); + if (result.success === false) { + expect(result.error.issues.length).toEqual(2); + expect(result.error.issues[0].code).toEqual(ZodIssueCode.invalid_type); + expect(result.error.issues[0].path).toEqual([0, "key"]); + expect(result.error.issues[1].code).toEqual(ZodIssueCode.invalid_type); + expect(result.error.issues[1].path).toEqual([0, "value"]); + } +}); + +test("throws when the given map has multiple invalid entries", () => { + // const result = stringMap.safeParse(new Map([[42, Symbol()]])); + + const result = stringMap.safeParse( + new Map([ + [1, "foo"], + ["bar", 2], + ] as [any, any][]) as Map + ); + + // const result = stringMap.safeParse(new Map([[42, Symbol()]])); + expect(result.success).toEqual(false); + if (result.success === false) { + expect(result.error.issues.length).toEqual(2); + expect(result.error.issues[0].code).toEqual(ZodIssueCode.invalid_type); + expect(result.error.issues[0].path).toEqual([0, "key"]); + expect(result.error.issues[1].code).toEqual(ZodIssueCode.invalid_type); + expect(result.error.issues[1].path).toEqual([1, "value"]); + } +}); + +test("dirty", async () => { + const map = z.map( + z.string().refine((val) => val === val.toUpperCase(), { + message: "Keys must be uppercase", + }), + z.string() + ); + const result = await map.spa( + new Map([ + ["first", "foo"], + ["second", "bar"], + ]) + ); + expect(result.success).toEqual(false); + if (!result.success) { + expect(result.error.issues.length).toEqual(2); + expect(result.error.issues[0].code).toEqual(z.ZodIssueCode.custom); + expect(result.error.issues[0].message).toEqual("Keys must be uppercase"); + expect(result.error.issues[1].code).toEqual(z.ZodIssueCode.custom); + expect(result.error.issues[1].message).toEqual("Keys must be uppercase"); + } +}); diff --git a/node_modules/zod/src/v3/tests/masking.test.ts b/node_modules/zod/src/v3/tests/masking.test.ts new file mode 100644 index 00000000..63817e2c --- /dev/null +++ b/node_modules/zod/src/v3/tests/masking.test.ts @@ -0,0 +1,4 @@ +// @ts-ignore TS6133 +import { test } from "vitest"; + +test("masking test", () => {}); diff --git a/node_modules/zod/src/v3/tests/mocker.test.ts b/node_modules/zod/src/v3/tests/mocker.test.ts new file mode 100644 index 00000000..3a2506b9 --- /dev/null +++ b/node_modules/zod/src/v3/tests/mocker.test.ts @@ -0,0 +1,19 @@ +// @ts-ignore TS6133 +import { test } from "vitest"; + +import { Mocker } from "./Mocker.js"; + +test("mocker", () => { + const mocker = new Mocker(); + mocker.string; + mocker.number; + mocker.boolean; + mocker.null; + mocker.undefined; + mocker.stringOptional; + mocker.stringNullable; + mocker.numberOptional; + mocker.numberNullable; + mocker.booleanOptional; + mocker.booleanNullable; +}); diff --git a/node_modules/zod/src/v3/tests/nan.test.ts b/node_modules/zod/src/v3/tests/nan.test.ts new file mode 100644 index 00000000..ce1214eb --- /dev/null +++ b/node_modules/zod/src/v3/tests/nan.test.ts @@ -0,0 +1,24 @@ +// @ts-ignore TS6133 +import { expect, test } from "vitest"; + +import * as z from "zod/v3"; + +const schema = z.nan(); + +test("passing validations", () => { + const result1 = schema.parse(Number.NaN); + expect(Number.isNaN(result1)).toBe(true); + + const result2 = schema.parse(Number("Not a number")); + expect(Number.isNaN(result2)).toBe(true); +}); + +test("failing validations", () => { + expect(() => schema.parse(5)).toThrow(); + expect(() => schema.parse("John")).toThrow(); + expect(() => schema.parse(true)).toThrow(); + expect(() => schema.parse(null)).toThrow(); + expect(() => schema.parse(undefined)).toThrow(); + expect(() => schema.parse({})).toThrow(); + expect(() => schema.parse([])).toThrow(); +}); diff --git a/node_modules/zod/src/v3/tests/nativeEnum.test.ts b/node_modules/zod/src/v3/tests/nativeEnum.test.ts new file mode 100644 index 00000000..61eb37a1 --- /dev/null +++ b/node_modules/zod/src/v3/tests/nativeEnum.test.ts @@ -0,0 +1,87 @@ +// @ts-ignore TS6133 +import { expect, test } from "vitest"; + +import * as z from "zod/v3"; +import { util } from "../helpers/util.js"; + +test("nativeEnum test with consts", () => { + const Fruits: { Apple: "apple"; Banana: "banana" } = { + Apple: "apple", + Banana: "banana", + }; + const fruitEnum = z.nativeEnum(Fruits); + type fruitEnum = z.infer; + fruitEnum.parse("apple"); + fruitEnum.parse("banana"); + fruitEnum.parse(Fruits.Apple); + fruitEnum.parse(Fruits.Banana); + util.assertEqual(true); +}); + +test("nativeEnum test with real enum", () => { + enum Fruits { + Apple = "apple", + Banana = "banana", + } + // @ts-ignore + const fruitEnum = z.nativeEnum(Fruits); + type fruitEnum = z.infer; + fruitEnum.parse("apple"); + fruitEnum.parse("banana"); + fruitEnum.parse(Fruits.Apple); + fruitEnum.parse(Fruits.Banana); + util.assertIs(true); +}); + +test("nativeEnum test with const with numeric keys", () => { + const FruitValues = { + Apple: 10, + Banana: 20, + // @ts-ignore + } as const; + const fruitEnum = z.nativeEnum(FruitValues); + type fruitEnum = z.infer; + fruitEnum.parse(10); + fruitEnum.parse(20); + fruitEnum.parse(FruitValues.Apple); + fruitEnum.parse(FruitValues.Banana); + util.assertEqual(true); +}); + +test("from enum", () => { + enum Fruits { + Cantaloupe = 0, + Apple = "apple", + Banana = "banana", + } + + const FruitEnum = z.nativeEnum(Fruits as any); + type _FruitEnum = z.infer; + FruitEnum.parse(Fruits.Cantaloupe); + FruitEnum.parse(Fruits.Apple); + FruitEnum.parse("apple"); + FruitEnum.parse(0); + expect(() => FruitEnum.parse(1)).toThrow(); + expect(() => FruitEnum.parse("Apple")).toThrow(); + expect(() => FruitEnum.parse("Cantaloupe")).toThrow(); +}); + +test("from const", () => { + const Greek = { + Alpha: "a", + Beta: "b", + Gamma: 3, + // @ts-ignore + } as const; + + const GreekEnum = z.nativeEnum(Greek); + type _GreekEnum = z.infer; + GreekEnum.parse("a"); + GreekEnum.parse("b"); + GreekEnum.parse(3); + expect(() => GreekEnum.parse("v")).toThrow(); + expect(() => GreekEnum.parse("Alpha")).toThrow(); + expect(() => GreekEnum.parse(2)).toThrow(); + + expect(GreekEnum.enum.Alpha).toEqual("a"); +}); diff --git a/node_modules/zod/src/v3/tests/nullable.test.ts b/node_modules/zod/src/v3/tests/nullable.test.ts new file mode 100644 index 00000000..90c1eed4 --- /dev/null +++ b/node_modules/zod/src/v3/tests/nullable.test.ts @@ -0,0 +1,42 @@ +// @ts-ignore TS6133 +import { expect, test } from "vitest"; + +import * as z from "zod/v3"; + +function checkErrors(a: z.ZodTypeAny, bad: any) { + let expected: any; + try { + a.parse(bad); + } catch (error) { + expected = (error as z.ZodError).formErrors; + } + try { + a.nullable().parse(bad); + } catch (error) { + expect((error as z.ZodError).formErrors).toEqual(expected); + } +} + +test("Should have error messages appropriate for the underlying type", () => { + checkErrors(z.string().min(2), 1); + z.string().min(2).nullable().parse(null); + checkErrors(z.number().gte(2), 1); + z.number().gte(2).nullable().parse(null); + checkErrors(z.boolean(), ""); + z.boolean().nullable().parse(null); + checkErrors(z.null(), null); + z.null().nullable().parse(null); + checkErrors(z.null(), {}); + z.null().nullable().parse(null); + checkErrors(z.object({}), 1); + z.object({}).nullable().parse(null); + checkErrors(z.tuple([]), 1); + z.tuple([]).nullable().parse(null); + checkErrors(z.unknown(), 1); + z.unknown().nullable().parse(null); +}); + +test("unwrap", () => { + const unwrapped = z.string().nullable().unwrap(); + expect(unwrapped).toBeInstanceOf(z.ZodString); +}); diff --git a/node_modules/zod/src/v3/tests/number.test.ts b/node_modules/zod/src/v3/tests/number.test.ts new file mode 100644 index 00000000..db3f73b2 --- /dev/null +++ b/node_modules/zod/src/v3/tests/number.test.ts @@ -0,0 +1,176 @@ +// @ts-ignore TS6133 +import { expect, test } from "vitest"; + +import * as z from "zod/v3"; + +const gtFive = z.number().gt(5); +const gteFive = z.number().gte(-5).gte(5); +const minFive = z.number().min(0).min(5); +const ltFive = z.number().lte(10).lt(5); +const lteFive = z.number().lte(5); +const maxFive = z.number().max(10).max(5); +const intNum = z.number().int(); +const positive = z.number().positive(); +const negative = z.number().negative(); +const nonpositive = z.number().nonpositive(); +const nonnegative = z.number().nonnegative(); +const multipleOfFive = z.number().multipleOf(5); +const multipleOfNegativeFive = z.number().multipleOf(-5); +const finite = z.number().finite(); +const safe = z.number().safe(); +const stepPointOne = z.number().step(0.1); +const stepPointZeroZeroZeroOne = z.number().step(0.0001); +const stepSixPointFour = z.number().step(6.4); + +test("passing validations", () => { + z.number().parse(1); + z.number().parse(1.5); + z.number().parse(0); + z.number().parse(-1.5); + z.number().parse(-1); + z.number().parse(Number.POSITIVE_INFINITY); + z.number().parse(Number.NEGATIVE_INFINITY); + gtFive.parse(6); + gtFive.parse(Number.POSITIVE_INFINITY); + gteFive.parse(5); + gteFive.parse(Number.POSITIVE_INFINITY); + minFive.parse(5); + minFive.parse(Number.POSITIVE_INFINITY); + ltFive.parse(4); + ltFive.parse(Number.NEGATIVE_INFINITY); + lteFive.parse(5); + lteFive.parse(Number.NEGATIVE_INFINITY); + maxFive.parse(5); + maxFive.parse(Number.NEGATIVE_INFINITY); + intNum.parse(4); + positive.parse(1); + positive.parse(Number.POSITIVE_INFINITY); + negative.parse(-1); + negative.parse(Number.NEGATIVE_INFINITY); + nonpositive.parse(0); + nonpositive.parse(-1); + nonpositive.parse(Number.NEGATIVE_INFINITY); + nonnegative.parse(0); + nonnegative.parse(1); + nonnegative.parse(Number.POSITIVE_INFINITY); + multipleOfFive.parse(15); + multipleOfFive.parse(-15); + multipleOfNegativeFive.parse(-15); + multipleOfNegativeFive.parse(15); + finite.parse(123); + safe.parse(Number.MIN_SAFE_INTEGER); + safe.parse(Number.MAX_SAFE_INTEGER); + stepPointOne.parse(6); + stepPointOne.parse(6.1); + stepPointOne.parse(6.1); + stepSixPointFour.parse(12.8); + stepPointZeroZeroZeroOne.parse(3.01); +}); + +test("failing validations", () => { + expect(() => ltFive.parse(5)).toThrow(); + expect(() => lteFive.parse(6)).toThrow(); + expect(() => maxFive.parse(6)).toThrow(); + expect(() => gtFive.parse(5)).toThrow(); + expect(() => gteFive.parse(4)).toThrow(); + expect(() => minFive.parse(4)).toThrow(); + expect(() => intNum.parse(3.14)).toThrow(); + expect(() => positive.parse(0)).toThrow(); + expect(() => positive.parse(-1)).toThrow(); + expect(() => negative.parse(0)).toThrow(); + expect(() => negative.parse(1)).toThrow(); + expect(() => nonpositive.parse(1)).toThrow(); + expect(() => nonnegative.parse(-1)).toThrow(); + expect(() => multipleOfFive.parse(7.5)).toThrow(); + expect(() => multipleOfFive.parse(-7.5)).toThrow(); + expect(() => multipleOfNegativeFive.parse(-7.5)).toThrow(); + expect(() => multipleOfNegativeFive.parse(7.5)).toThrow(); + expect(() => finite.parse(Number.POSITIVE_INFINITY)).toThrow(); + expect(() => finite.parse(Number.NEGATIVE_INFINITY)).toThrow(); + expect(() => safe.parse(Number.MIN_SAFE_INTEGER - 1)).toThrow(); + expect(() => safe.parse(Number.MAX_SAFE_INTEGER + 1)).toThrow(); + + expect(() => stepPointOne.parse(6.11)).toThrow(); + expect(() => stepPointOne.parse(6.1000000001)).toThrow(); + expect(() => stepSixPointFour.parse(6.41)).toThrow(); +}); + +test("parse NaN", () => { + expect(() => z.number().parse(Number.NaN)).toThrow(); +}); + +test("min max getters", () => { + expect(z.number().minValue).toBeNull; + expect(ltFive.minValue).toBeNull; + expect(lteFive.minValue).toBeNull; + expect(maxFive.minValue).toBeNull; + expect(negative.minValue).toBeNull; + expect(nonpositive.minValue).toBeNull; + expect(intNum.minValue).toBeNull; + expect(multipleOfFive.minValue).toBeNull; + expect(finite.minValue).toBeNull; + expect(gtFive.minValue).toEqual(5); + expect(gteFive.minValue).toEqual(5); + expect(minFive.minValue).toEqual(5); + expect(minFive.min(10).minValue).toEqual(10); + expect(positive.minValue).toEqual(0); + expect(nonnegative.minValue).toEqual(0); + expect(safe.minValue).toEqual(Number.MIN_SAFE_INTEGER); + + expect(z.number().maxValue).toBeNull; + expect(gtFive.maxValue).toBeNull; + expect(gteFive.maxValue).toBeNull; + expect(minFive.maxValue).toBeNull; + expect(positive.maxValue).toBeNull; + expect(nonnegative.maxValue).toBeNull; + expect(intNum.minValue).toBeNull; + expect(multipleOfFive.minValue).toBeNull; + expect(finite.minValue).toBeNull; + expect(ltFive.maxValue).toEqual(5); + expect(lteFive.maxValue).toEqual(5); + expect(maxFive.maxValue).toEqual(5); + expect(maxFive.max(1).maxValue).toEqual(1); + expect(negative.maxValue).toEqual(0); + expect(nonpositive.maxValue).toEqual(0); + expect(safe.maxValue).toEqual(Number.MAX_SAFE_INTEGER); +}); + +test("int getter", () => { + expect(z.number().isInt).toEqual(false); + expect(z.number().multipleOf(1.5).isInt).toEqual(false); + expect(gtFive.isInt).toEqual(false); + expect(gteFive.isInt).toEqual(false); + expect(minFive.isInt).toEqual(false); + expect(positive.isInt).toEqual(false); + expect(nonnegative.isInt).toEqual(false); + expect(finite.isInt).toEqual(false); + expect(ltFive.isInt).toEqual(false); + expect(lteFive.isInt).toEqual(false); + expect(maxFive.isInt).toEqual(false); + expect(negative.isInt).toEqual(false); + expect(nonpositive.isInt).toEqual(false); + expect(safe.isInt).toEqual(false); + + expect(intNum.isInt).toEqual(true); + expect(multipleOfFive.isInt).toEqual(true); +}); + +test("finite getter", () => { + expect(z.number().isFinite).toEqual(false); + expect(gtFive.isFinite).toEqual(false); + expect(gteFive.isFinite).toEqual(false); + expect(minFive.isFinite).toEqual(false); + expect(positive.isFinite).toEqual(false); + expect(nonnegative.isFinite).toEqual(false); + expect(ltFive.isFinite).toEqual(false); + expect(lteFive.isFinite).toEqual(false); + expect(maxFive.isFinite).toEqual(false); + expect(negative.isFinite).toEqual(false); + expect(nonpositive.isFinite).toEqual(false); + + expect(finite.isFinite).toEqual(true); + expect(intNum.isFinite).toEqual(true); + expect(multipleOfFive.isFinite).toEqual(true); + expect(z.number().min(5).max(10).isFinite).toEqual(true); + expect(safe.isFinite).toEqual(true); +}); diff --git a/node_modules/zod/src/v3/tests/object-augmentation.test.ts b/node_modules/zod/src/v3/tests/object-augmentation.test.ts new file mode 100644 index 00000000..964ea3da --- /dev/null +++ b/node_modules/zod/src/v3/tests/object-augmentation.test.ts @@ -0,0 +1,29 @@ +// @ts-ignore TS6133 +import { expect, test } from "vitest"; + +import * as z from "zod/v3"; + +test("object augmentation", () => { + const Animal = z + .object({ + species: z.string(), + }) + .augment({ + population: z.number(), + }); + // overwrites `species` + const ModifiedAnimal = Animal.augment({ + species: z.array(z.string()), + }); + ModifiedAnimal.parse({ + species: ["asd"], + population: 1324, + }); + + const bad = () => + ModifiedAnimal.parse({ + species: "asdf", + population: 1324, + } as any); + expect(bad).toThrow(); +}); diff --git a/node_modules/zod/src/v3/tests/object-in-es5-env.test.ts b/node_modules/zod/src/v3/tests/object-in-es5-env.test.ts new file mode 100644 index 00000000..293ebf0c --- /dev/null +++ b/node_modules/zod/src/v3/tests/object-in-es5-env.test.ts @@ -0,0 +1,29 @@ +// @ts-ignore TS6133 +import { expect, test } from "vitest"; + +import * as z from "zod/v3"; + +const RealSet = Set; +const RealMap = Map; +const RealDate = Date; + +test("doesn’t throw when Date is undefined", () => { + delete (globalThis as any).Date; + const result = z.object({}).safeParse({}); + expect(result.success).toEqual(true); + globalThis.Date = RealDate; +}); + +test("doesn’t throw when Set is undefined", () => { + delete (globalThis as any).Set; + const result = z.object({}).safeParse({}); + expect(result.success).toEqual(true); + globalThis.Set = RealSet; +}); + +test("doesn’t throw when Map is undefined", () => { + delete (globalThis as any).Map; + const result = z.object({}).safeParse({}); + expect(result.success).toEqual(true); + globalThis.Map = RealMap; +}); diff --git a/node_modules/zod/src/v3/tests/object.test.ts b/node_modules/zod/src/v3/tests/object.test.ts new file mode 100644 index 00000000..1427dc27 --- /dev/null +++ b/node_modules/zod/src/v3/tests/object.test.ts @@ -0,0 +1,434 @@ +// @ts-ignore TS6133 +import { expect, test } from "vitest"; + +import * as z from "zod/v3"; +import { util } from "../helpers/util.js"; + +const Test = z.object({ + f1: z.number(), + f2: z.string().optional(), + f3: z.string().nullable(), + f4: z.array(z.object({ t: z.union([z.string(), z.boolean()]) })), +}); + +test("object type inference", () => { + type TestType = { + f1: number; + f2?: string | undefined; + f3: string | null; + f4: { t: string | boolean }[]; + }; + + util.assertEqual, TestType>(true); +}); + +test("unknown throw", () => { + const asdf: unknown = 35; + expect(() => Test.parse(asdf)).toThrow(); +}); + +test("shape() should return schema of particular key", () => { + const f1Schema = Test.shape.f1; + const f2Schema = Test.shape.f2; + const f3Schema = Test.shape.f3; + const f4Schema = Test.shape.f4; + + expect(f1Schema).toBeInstanceOf(z.ZodNumber); + expect(f2Schema).toBeInstanceOf(z.ZodOptional); + expect(f3Schema).toBeInstanceOf(z.ZodNullable); + expect(f4Schema).toBeInstanceOf(z.ZodArray); +}); + +test("correct parsing", () => { + Test.parse({ + f1: 12, + f2: "string", + f3: "string", + f4: [ + { + t: "string", + }, + ], + }); + + Test.parse({ + f1: 12, + f3: null, + f4: [ + { + t: false, + }, + ], + }); +}); + +test("incorrect #1", () => { + expect(() => Test.parse({} as any)).toThrow(); +}); + +test("nonstrict by default", () => { + z.object({ points: z.number() }).parse({ + points: 2314, + unknown: "asdf", + }); +}); + +const data = { + points: 2314, + unknown: "asdf", +}; + +test("strip by default", () => { + const val = z.object({ points: z.number() }).parse(data); + expect(val).toEqual({ points: 2314 }); +}); + +test("unknownkeys override", () => { + const val = z.object({ points: z.number() }).strict().passthrough().strip().nonstrict().parse(data); + + expect(val).toEqual(data); +}); + +test("passthrough unknown", () => { + const val = z.object({ points: z.number() }).passthrough().parse(data); + + expect(val).toEqual(data); +}); + +test("strip unknown", () => { + const val = z.object({ points: z.number() }).strip().parse(data); + + expect(val).toEqual({ points: 2314 }); +}); + +test("strict", () => { + const val = z.object({ points: z.number() }).strict().safeParse(data); + + expect(val.success).toEqual(false); +}); + +test("catchall inference", () => { + const o1 = z + .object({ + first: z.string(), + }) + .catchall(z.number()); + + const d1 = o1.parse({ first: "asdf", num: 1243 }); + util.assertEqual(true); + util.assertEqual(true); +}); + +test("catchall overrides strict", () => { + const o1 = z.object({ first: z.string().optional() }).strict().catchall(z.number()); + + // should run fine + // setting a catchall overrides the unknownKeys behavior + o1.parse({ + asdf: 1234, + }); + + // should only run catchall validation + // against unknown keys + o1.parse({ + first: "asdf", + asdf: 1234, + }); +}); + +test("catchall overrides strict", () => { + const o1 = z + .object({ + first: z.string(), + }) + .strict() + .catchall(z.number()); + + // should run fine + // setting a catchall overrides the unknownKeys behavior + o1.parse({ + first: "asdf", + asdf: 1234, + }); +}); + +test("test that optional keys are unset", () => { + const SNamedEntity = z.object({ + id: z.string(), + set: z.string().optional(), + unset: z.string().optional(), + }); + const result = SNamedEntity.parse({ + id: "asdf", + set: undefined, + }); + // eslint-disable-next-line ban/ban + expect(Object.keys(result)).toEqual(["id", "set"]); +}); + +test("test catchall parsing", async () => { + const result = z.object({ name: z.string() }).catchall(z.number()).parse({ name: "Foo", validExtraKey: 61 }); + + expect(result).toEqual({ name: "Foo", validExtraKey: 61 }); + + const result2 = z + .object({ name: z.string() }) + .catchall(z.number()) + .safeParse({ name: "Foo", validExtraKey: 61, invalid: "asdf" }); + + expect(result2.success).toEqual(false); +}); + +test("test nonexistent keys", async () => { + const Schema = z.union([z.object({ a: z.string() }), z.object({ b: z.number() })]); + const obj = { a: "A" }; + const result = await Schema.spa(obj); // Works with 1.11.10, breaks with 2.0.0-beta.21 + expect(result.success).toBe(true); +}); + +test("test async union", async () => { + const Schema2 = z.union([ + z.object({ + ty: z.string(), + }), + z.object({ + ty: z.number(), + }), + ]); + + const obj = { ty: "A" }; + const result = await Schema2.spa(obj); // Works with 1.11.10, breaks with 2.0.0-beta.21 + expect(result.success).toEqual(true); +}); + +test("test inferred merged type", async () => { + const asdf = z.object({ a: z.string() }).merge(z.object({ a: z.number() })); + type asdf = z.infer; + util.assertEqual(true); +}); + +test("inferred merged object type with optional properties", async () => { + const Merged = z + .object({ a: z.string(), b: z.string().optional() }) + .merge(z.object({ a: z.string().optional(), b: z.string() })); + type Merged = z.infer; + util.assertEqual(true); + // todo + // util.assertEqual(true); +}); + +test("inferred unioned object type with optional properties", async () => { + const Unioned = z.union([ + z.object({ a: z.string(), b: z.string().optional() }), + z.object({ a: z.string().optional(), b: z.string() }), + ]); + type Unioned = z.infer; + util.assertEqual(true); +}); + +test("inferred enum type", async () => { + const Enum = z.object({ a: z.string(), b: z.string().optional() }).keyof(); + + expect(Enum.Values).toEqual({ + a: "a", + b: "b", + }); + expect(Enum.enum).toEqual({ + a: "a", + b: "b", + }); + expect(Enum._def.values).toEqual(["a", "b"]); + type Enum = z.infer; + util.assertEqual(true); +}); + +test("inferred partial object type with optional properties", async () => { + const Partial = z.object({ a: z.string(), b: z.string().optional() }).partial(); + type Partial = z.infer; + util.assertEqual(true); +}); + +test("inferred picked object type with optional properties", async () => { + const Picked = z.object({ a: z.string(), b: z.string().optional() }).pick({ b: true }); + type Picked = z.infer; + util.assertEqual(true); +}); + +test("inferred type for unknown/any keys", () => { + const myType = z.object({ + anyOptional: z.any().optional(), + anyRequired: z.any(), + unknownOptional: z.unknown().optional(), + unknownRequired: z.unknown(), + }); + type myType = z.infer; + util.assertEqual< + myType, + { + anyOptional?: any; + anyRequired?: any; + unknownOptional?: unknown; + unknownRequired?: unknown; + } + >(true); +}); + +test("setKey", () => { + const base = z.object({ name: z.string() }); + const withNewKey = base.setKey("age", z.number()); + + type withNewKey = z.infer; + util.assertEqual(true); + withNewKey.parse({ name: "asdf", age: 1234 }); +}); + +test("strictcreate", async () => { + const strictObj = z.strictObject({ + name: z.string(), + }); + + const syncResult = strictObj.safeParse({ name: "asdf", unexpected: 13 }); + expect(syncResult.success).toEqual(false); + + const asyncResult = await strictObj.spa({ name: "asdf", unexpected: 13 }); + expect(asyncResult.success).toEqual(false); +}); + +test("object with refine", async () => { + const schema = z + .object({ + a: z.string().default("foo"), + b: z.number(), + }) + .refine(() => true); + expect(schema.parse({ b: 5 })).toEqual({ b: 5, a: "foo" }); + const result = await schema.parseAsync({ b: 5 }); + expect(result).toEqual({ b: 5, a: "foo" }); +}); + +test("intersection of object with date", async () => { + const schema = z.object({ + a: z.date(), + }); + expect(schema.and(schema).parse({ a: new Date(1637353595983) })).toEqual({ + a: new Date(1637353595983), + }); + const result = await schema.parseAsync({ a: new Date(1637353595983) }); + expect(result).toEqual({ a: new Date(1637353595983) }); +}); + +test("intersection of object with refine with date", async () => { + const schema = z + .object({ + a: z.date(), + }) + .refine(() => true); + expect(schema.and(schema).parse({ a: new Date(1637353595983) })).toEqual({ + a: new Date(1637353595983), + }); + const result = await schema.parseAsync({ a: new Date(1637353595983) }); + expect(result).toEqual({ a: new Date(1637353595983) }); +}); + +test("constructor key", () => { + const person = z + .object({ + name: z.string(), + }) + .strict(); + + expect(() => + person.parse({ + name: "bob dylan", + constructor: 61, + }) + ).toThrow(); +}); + +test("constructor key", () => { + const Example = z.object({ + prop: z.string(), + opt: z.number().optional(), + arr: z.string().array(), + }); + + type Example = z.infer; + util.assertEqual(true); +}); + +test("unknownkeys merging", () => { + // This one is "strict" + const schemaA = z + .object({ + a: z.string(), + }) + .strict(); + + // This one is "strip" + const schemaB = z + .object({ + b: z.string(), + }) + .catchall(z.string()); + + const mergedSchema = schemaA.merge(schemaB); + type mergedSchema = typeof mergedSchema; + util.assertEqual(true); + expect(mergedSchema._def.unknownKeys).toEqual("strip"); + + util.assertEqual(true); + expect(mergedSchema._def.catchall instanceof z.ZodString).toEqual(true); +}); + +const personToExtend = z.object({ + firstName: z.string(), + lastName: z.string(), +}); + +test("extend() should return schema with new key", () => { + const PersonWithNickname = personToExtend.extend({ nickName: z.string() }); + type PersonWithNickname = z.infer; + + const expected = { firstName: "f", nickName: "n", lastName: "l" }; + const actual = PersonWithNickname.parse(expected); + + expect(actual).toEqual(expected); + util.assertEqual(true); + util.assertEqual(true); +}); + +test("extend() should have power to override existing key", () => { + const PersonWithNumberAsLastName = personToExtend.extend({ + lastName: z.number(), + }); + type PersonWithNumberAsLastName = z.infer; + + const expected = { firstName: "f", lastName: 42 }; + const actual = PersonWithNumberAsLastName.parse(expected); + + expect(actual).toEqual(expected); + util.assertEqual(true); +}); + +test("passthrough index signature", () => { + const a = z.object({ a: z.string() }); + type a = z.infer; + util.assertEqual<{ a: string }, a>(true); + const b = a.passthrough(); + type b = z.infer; + util.assertEqual<{ a: string } & { [k: string]: unknown }, b>(true); +}); + +test("xor", () => { + type Without = { [P in Exclude]?: never }; + type XOR = T extends object ? (U extends object ? (Without & U) | (Without & T) : U) : T; + + type A = { name: string; a: number }; + type B = { name: string; b: number }; + type C = XOR; + type Outer = { data: C }; + + const _Outer: z.ZodType = z.object({ + data: z.union([z.object({ name: z.string(), a: z.number() }), z.object({ name: z.string(), b: z.number() })]), + }); +}); diff --git a/node_modules/zod/src/v3/tests/optional.test.ts b/node_modules/zod/src/v3/tests/optional.test.ts new file mode 100644 index 00000000..016c954f --- /dev/null +++ b/node_modules/zod/src/v3/tests/optional.test.ts @@ -0,0 +1,42 @@ +// @ts-ignore TS6133 +import { expect, test } from "vitest"; + +import * as z from "zod/v3"; + +function checkErrors(a: z.ZodTypeAny, bad: any) { + let expected: any; + try { + a.parse(bad); + } catch (error) { + expected = (error as z.ZodError).formErrors; + } + try { + a.optional().parse(bad); + } catch (error) { + expect((error as z.ZodError).formErrors).toEqual(expected); + } +} + +test("Should have error messages appropriate for the underlying type", () => { + checkErrors(z.string().min(2), 1); + z.string().min(2).optional().parse(undefined); + checkErrors(z.number().gte(2), 1); + z.number().gte(2).optional().parse(undefined); + checkErrors(z.boolean(), ""); + z.boolean().optional().parse(undefined); + checkErrors(z.undefined(), null); + z.undefined().optional().parse(undefined); + checkErrors(z.null(), {}); + z.null().optional().parse(undefined); + checkErrors(z.object({}), 1); + z.object({}).optional().parse(undefined); + checkErrors(z.tuple([]), 1); + z.tuple([]).optional().parse(undefined); + checkErrors(z.unknown(), 1); + z.unknown().optional().parse(undefined); +}); + +test("unwrap", () => { + const unwrapped = z.string().optional().unwrap(); + expect(unwrapped).toBeInstanceOf(z.ZodString); +}); diff --git a/node_modules/zod/src/v3/tests/parseUtil.test.ts b/node_modules/zod/src/v3/tests/parseUtil.test.ts new file mode 100644 index 00000000..8882d4c3 --- /dev/null +++ b/node_modules/zod/src/v3/tests/parseUtil.test.ts @@ -0,0 +1,23 @@ +// @ts-ignore TS6133 +import { expect, test } from "vitest"; + +import { type SyncParseReturnType, isAborted, isDirty, isValid } from "../helpers/parseUtil.js"; + +test("parseUtil isInvalid should use structural typing", () => { + // Test for issue #556: https://github.com/colinhacks/zod/issues/556 + const aborted: SyncParseReturnType = { status: "aborted" }; + const dirty: SyncParseReturnType = { status: "dirty", value: "whatever" }; + const valid: SyncParseReturnType = { status: "valid", value: "whatever" }; + + expect(isAborted(aborted)).toBe(true); + expect(isAborted(dirty)).toBe(false); + expect(isAborted(valid)).toBe(false); + + expect(isDirty(aborted)).toBe(false); + expect(isDirty(dirty)).toBe(true); + expect(isDirty(valid)).toBe(false); + + expect(isValid(aborted)).toBe(false); + expect(isValid(dirty)).toBe(false); + expect(isValid(valid)).toBe(true); +}); diff --git a/node_modules/zod/src/v3/tests/parser.test.ts b/node_modules/zod/src/v3/tests/parser.test.ts new file mode 100644 index 00000000..6e685f9f --- /dev/null +++ b/node_modules/zod/src/v3/tests/parser.test.ts @@ -0,0 +1,41 @@ +// @ts-ignore TS6133 +import { expect, test } from "vitest"; + +import * as z from "zod/v3"; + +test("parse strict object with unknown keys", () => { + expect(() => + z + .object({ name: z.string() }) + .strict() + .parse({ name: "bill", unknownKey: 12 } as any) + ).toThrow(); +}); + +test("parse nonstrict object with unknown keys", () => { + z.object({ name: z.string() }).nonstrict().parse({ name: "bill", unknownKey: 12 }); +}); + +test("invalid left side of intersection", () => { + expect(() => z.intersection(z.string(), z.number()).parse(12 as any)).toThrow(); +}); + +test("invalid right side of intersection", () => { + expect(() => z.intersection(z.string(), z.number()).parse("12" as any)).toThrow(); +}); + +test("parsing non-array in tuple schema", () => { + expect(() => z.tuple([]).parse("12" as any)).toThrow(); +}); + +test("incorrect num elements in tuple", () => { + expect(() => z.tuple([]).parse(["asdf"] as any)).toThrow(); +}); + +test("invalid enum value", () => { + expect(() => z.enum(["Blue"]).parse("Red" as any)).toThrow(); +}); + +test("parsing unknown", () => { + z.string().parse("Red" as unknown); +}); diff --git a/node_modules/zod/src/v3/tests/partials.test.ts b/node_modules/zod/src/v3/tests/partials.test.ts new file mode 100644 index 00000000..a2fb6ed9 --- /dev/null +++ b/node_modules/zod/src/v3/tests/partials.test.ts @@ -0,0 +1,243 @@ +// @ts-ignore TS6133 +import { expect, test } from "vitest"; + +import * as z from "zod/v3"; +import { ZodNullable, ZodOptional } from "zod/v3"; +import { util } from "../helpers/util.js"; + +const nested = z.object({ + name: z.string(), + age: z.number(), + outer: z.object({ + inner: z.string(), + }), + array: z.array(z.object({ asdf: z.string() })), +}); + +test("shallow inference", () => { + const shallow = nested.partial(); + type shallow = z.infer; + type correct = { + name?: string | undefined; + age?: number | undefined; + outer?: { inner: string } | undefined; + array?: { asdf: string }[]; + }; + util.assertEqual(true); +}); + +test("shallow partial parse", () => { + const shallow = nested.partial(); + shallow.parse({}); + shallow.parse({ + name: "asdf", + age: 23143, + }); +}); + +test("deep partial inference", () => { + const deep = nested.deepPartial(); + const asdf = deep.shape.array.unwrap().element.shape.asdf.unwrap(); + asdf.parse("asdf"); + type deep = z.infer; + type correct = { + array?: { asdf?: string }[]; + name?: string | undefined; + age?: number | undefined; + outer?: { inner?: string | undefined } | undefined; + }; + + util.assertEqual(true); +}); + +test("deep partial parse", () => { + const deep = nested.deepPartial(); + + expect(deep.shape.name instanceof z.ZodOptional).toBe(true); + expect(deep.shape.outer instanceof z.ZodOptional).toBe(true); + expect(deep.shape.outer._def.innerType instanceof z.ZodObject).toBe(true); + expect(deep.shape.outer._def.innerType.shape.inner instanceof z.ZodOptional).toBe(true); + expect(deep.shape.outer._def.innerType.shape.inner._def.innerType instanceof z.ZodString).toBe(true); +}); + +test("deep partial runtime tests", () => { + const deep = nested.deepPartial(); + deep.parse({}); + deep.parse({ + outer: {}, + }); + deep.parse({ + name: "asdf", + age: 23143, + outer: { + inner: "adsf", + }, + }); +}); + +test("deep partial optional/nullable", () => { + const schema = z + .object({ + name: z.string().optional(), + age: z.number().nullable(), + }) + .deepPartial(); + + expect(schema.shape.name.unwrap()).toBeInstanceOf(ZodOptional); + expect(schema.shape.age.unwrap()).toBeInstanceOf(ZodNullable); +}); + +test("deep partial tuple", () => { + const schema = z + .object({ + tuple: z.tuple([ + z.object({ + name: z.string().optional(), + age: z.number().nullable(), + }), + ]), + }) + .deepPartial(); + + expect(schema.shape.tuple.unwrap().items[0].shape.name).toBeInstanceOf(ZodOptional); +}); + +test("deep partial inference", () => { + const mySchema = z.object({ + name: z.string(), + array: z.array(z.object({ asdf: z.string() })), + tuple: z.tuple([z.object({ value: z.string() })]), + }); + + const partialed = mySchema.deepPartial(); + type partialed = z.infer; + type expected = { + name?: string | undefined; + array?: + | { + asdf?: string | undefined; + }[] + | undefined; + tuple?: [{ value?: string }] | undefined; + }; + util.assertEqual(true); +}); + +test("required", () => { + const object = z.object({ + name: z.string(), + age: z.number().optional(), + field: z.string().optional().default("asdf"), + nullableField: z.number().nullable(), + nullishField: z.string().nullish(), + }); + + const requiredObject = object.required(); + expect(requiredObject.shape.name).toBeInstanceOf(z.ZodString); + expect(requiredObject.shape.age).toBeInstanceOf(z.ZodNumber); + expect(requiredObject.shape.field).toBeInstanceOf(z.ZodDefault); + expect(requiredObject.shape.nullableField).toBeInstanceOf(z.ZodNullable); + expect(requiredObject.shape.nullishField).toBeInstanceOf(z.ZodNullable); +}); + +test("required inference", () => { + const object = z.object({ + name: z.string(), + age: z.number().optional(), + field: z.string().optional().default("asdf"), + nullableField: z.number().nullable(), + nullishField: z.string().nullish(), + }); + + const requiredObject = object.required(); + + type required = z.infer; + type expected = { + name: string; + age: number; + field: string; + nullableField: number | null; + nullishField: string | null; + }; + util.assertEqual(true); +}); + +test("required with mask", () => { + const object = z.object({ + name: z.string(), + age: z.number().optional(), + field: z.string().optional().default("asdf"), + country: z.string().optional(), + }); + + const requiredObject = object.required({ age: true }); + expect(requiredObject.shape.name).toBeInstanceOf(z.ZodString); + expect(requiredObject.shape.age).toBeInstanceOf(z.ZodNumber); + expect(requiredObject.shape.field).toBeInstanceOf(z.ZodDefault); + expect(requiredObject.shape.country).toBeInstanceOf(z.ZodOptional); +}); + +test("required with mask -- ignore falsy values", () => { + const object = z.object({ + name: z.string(), + age: z.number().optional(), + field: z.string().optional().default("asdf"), + country: z.string().optional(), + }); + + // @ts-expect-error + const requiredObject = object.required({ age: true, country: false }); + expect(requiredObject.shape.name).toBeInstanceOf(z.ZodString); + expect(requiredObject.shape.age).toBeInstanceOf(z.ZodNumber); + expect(requiredObject.shape.field).toBeInstanceOf(z.ZodDefault); + expect(requiredObject.shape.country).toBeInstanceOf(z.ZodOptional); +}); + +test("partial with mask", async () => { + const object = z.object({ + name: z.string(), + age: z.number().optional(), + field: z.string().optional().default("asdf"), + country: z.string(), + }); + + const masked = object.partial({ age: true, field: true, name: true }).strict(); + + expect(masked.shape.name).toBeInstanceOf(z.ZodOptional); + expect(masked.shape.age).toBeInstanceOf(z.ZodOptional); + expect(masked.shape.field).toBeInstanceOf(z.ZodOptional); + expect(masked.shape.country).toBeInstanceOf(z.ZodString); + + masked.parse({ country: "US" }); + await masked.parseAsync({ country: "US" }); +}); + +test("partial with mask -- ignore falsy values", async () => { + const object = z.object({ + name: z.string(), + age: z.number().optional(), + field: z.string().optional().default("asdf"), + country: z.string(), + }); + + // @ts-expect-error + const masked = object.partial({ name: true, country: false }).strict(); + + expect(masked.shape.name).toBeInstanceOf(z.ZodOptional); + expect(masked.shape.age).toBeInstanceOf(z.ZodOptional); + expect(masked.shape.field).toBeInstanceOf(z.ZodDefault); + expect(masked.shape.country).toBeInstanceOf(z.ZodString); + + masked.parse({ country: "US" }); + await masked.parseAsync({ country: "US" }); +}); + +test("deeppartial array", () => { + const schema = z.object({ array: z.string().array().min(42) }).deepPartial(); + + // works as expected + schema.parse({}); + + // should be false, but is true + expect(schema.safeParse({ array: [] }).success).toBe(false); +}); diff --git a/node_modules/zod/src/v3/tests/pickomit.test.ts b/node_modules/zod/src/v3/tests/pickomit.test.ts new file mode 100644 index 00000000..b1056e5a --- /dev/null +++ b/node_modules/zod/src/v3/tests/pickomit.test.ts @@ -0,0 +1,111 @@ +// @ts-ignore TS6133 +import { expect, test } from "vitest"; + +import * as z from "zod/v3"; +import { util } from "../helpers/util.js"; + +const fish = z.object({ + name: z.string(), + age: z.number(), + nested: z.object({}), +}); + +test("pick type inference", () => { + const nameonlyFish = fish.pick({ name: true }); + type nameonlyFish = z.infer; + util.assertEqual(true); +}); + +test("pick parse - success", () => { + const nameonlyFish = fish.pick({ name: true }); + nameonlyFish.parse({ name: "bob" }); + + // @ts-expect-error checking runtime picks `name` only. + const anotherNameonlyFish = fish.pick({ name: true, age: false }); + anotherNameonlyFish.parse({ name: "bob" }); +}); + +test("pick parse - fail", () => { + fish.pick({ name: true }).parse({ name: "12" } as any); + fish.pick({ name: true }).parse({ name: "bob", age: 12 } as any); + fish.pick({ age: true }).parse({ age: 12 } as any); + + const nameonlyFish = fish.pick({ name: true }).strict(); + const bad1 = () => nameonlyFish.parse({ name: 12 } as any); + const bad2 = () => nameonlyFish.parse({ name: "bob", age: 12 } as any); + const bad3 = () => nameonlyFish.parse({ age: 12 } as any); + + // @ts-expect-error checking runtime picks `name` only. + const anotherNameonlyFish = fish.pick({ name: true, age: false }).strict(); + const bad4 = () => anotherNameonlyFish.parse({ name: "bob", age: 12 } as any); + + expect(bad1).toThrow(); + expect(bad2).toThrow(); + expect(bad3).toThrow(); + expect(bad4).toThrow(); +}); + +test("omit type inference", () => { + const nonameFish = fish.omit({ name: true }); + type nonameFish = z.infer; + util.assertEqual(true); +}); + +test("omit parse - success", () => { + const nonameFish = fish.omit({ name: true }); + nonameFish.parse({ age: 12, nested: {} }); + + // @ts-expect-error checking runtime omits `name` only. + const anotherNonameFish = fish.omit({ name: true, age: false }); + anotherNonameFish.parse({ age: 12, nested: {} }); +}); + +test("omit parse - fail", () => { + const nonameFish = fish.omit({ name: true }); + const bad1 = () => nonameFish.parse({ name: 12 } as any); + const bad2 = () => nonameFish.parse({ age: 12 } as any); + const bad3 = () => nonameFish.parse({} as any); + + // @ts-expect-error checking runtime omits `name` only. + const anotherNonameFish = fish.omit({ name: true, age: false }); + const bad4 = () => anotherNonameFish.parse({ nested: {} } as any); + + expect(bad1).toThrow(); + expect(bad2).toThrow(); + expect(bad3).toThrow(); + expect(bad4).toThrow(); +}); + +test("nonstrict inference", () => { + const laxfish = fish.pick({ name: true }).catchall(z.any()); + type laxfish = z.infer; + util.assertEqual(true); +}); + +test("nonstrict parsing - pass", () => { + const laxfish = fish.passthrough().pick({ name: true }); + laxfish.parse({ name: "asdf", whatever: "asdf" }); + laxfish.parse({ name: "asdf", age: 12, nested: {} }); +}); + +test("nonstrict parsing - fail", () => { + const laxfish = fish.passthrough().pick({ name: true }); + const bad = () => laxfish.parse({ whatever: "asdf" } as any); + expect(bad).toThrow(); +}); + +test("pick/omit/required/partial - do not allow unknown keys", () => { + const schema = z.object({ + name: z.string(), + age: z.number(), + }); + + // @ts-expect-error + schema.pick({ $unknown: true }); + // @ts-expect-error + schema.omit({ $unknown: true }); + // @ts-expect-error + schema.required({ $unknown: true }); + // @ts-expect-error + schema.partial({ $unknown: true }); +}); diff --git a/node_modules/zod/src/v3/tests/pipeline.test.ts b/node_modules/zod/src/v3/tests/pipeline.test.ts new file mode 100644 index 00000000..cc94fc55 --- /dev/null +++ b/node_modules/zod/src/v3/tests/pipeline.test.ts @@ -0,0 +1,29 @@ +// @ts-ignore TS6133 +import { expect, test } from "vitest"; + +import * as z from "zod/v3"; + +test("string to number pipeline", () => { + const schema = z.string().transform(Number).pipe(z.number()); + expect(schema.parse("1234")).toEqual(1234); +}); + +test("string to number pipeline async", async () => { + const schema = z + .string() + .transform(async (val) => Number(val)) + .pipe(z.number()); + expect(await schema.parseAsync("1234")).toEqual(1234); +}); + +test("break if dirty", () => { + const schema = z + .string() + .refine((c) => c === "1234") + .transform(async (val) => Number(val)) + .pipe(z.number().refine((v) => v < 100)); + const r1: any = schema.safeParse("12345"); + expect(r1.error.issues.length).toBe(1); + const r2: any = schema.safeParse("3"); + expect(r2.error.issues.length).toBe(1); +}); diff --git a/node_modules/zod/src/v3/tests/preprocess.test.ts b/node_modules/zod/src/v3/tests/preprocess.test.ts new file mode 100644 index 00000000..7e1b5a1d --- /dev/null +++ b/node_modules/zod/src/v3/tests/preprocess.test.ts @@ -0,0 +1,186 @@ +// @ts-ignore TS6133 +import { expect, test } from "vitest"; + +import * as z from "zod/v3"; +import { util } from "../helpers/util.js"; + +test("preprocess", () => { + const schema = z.preprocess((data) => [data], z.string().array()); + + const value = schema.parse("asdf"); + expect(value).toEqual(["asdf"]); + util.assertEqual<(typeof schema)["_input"], unknown>(true); +}); + +test("async preprocess", async () => { + const schema = z.preprocess(async (data) => [data], z.string().array()); + + const value = await schema.parseAsync("asdf"); + expect(value).toEqual(["asdf"]); +}); + +test("preprocess ctx.addIssue with parse", () => { + expect(() => { + z.preprocess((data, ctx) => { + ctx.addIssue({ + code: "custom", + message: `${data} is not one of our allowed strings`, + }); + return data; + }, z.string()).parse("asdf"); + }).toThrow( + JSON.stringify( + [ + { + code: "custom", + message: "asdf is not one of our allowed strings", + path: [], + }, + ], + null, + 2 + ) + ); +}); + +test("preprocess ctx.addIssue non-fatal by default", () => { + try { + z.preprocess((data, ctx) => { + ctx.addIssue({ + code: "custom", + message: `custom error`, + }); + return data; + }, z.string()).parse(1234); + } catch (err) { + z.ZodError.assert(err); + expect(err.issues.length).toEqual(2); + } +}); + +test("preprocess ctx.addIssue fatal true", () => { + try { + z.preprocess((data, ctx) => { + ctx.addIssue({ + code: "custom", + message: `custom error`, + fatal: true, + }); + return data; + }, z.string()).parse(1234); + } catch (err) { + z.ZodError.assert(err); + expect(err.issues.length).toEqual(1); + } +}); + +test("async preprocess ctx.addIssue with parse", async () => { + const schema = z.preprocess(async (data, ctx) => { + ctx.addIssue({ + code: "custom", + message: `custom error`, + }); + return data; + }, z.string()); + + expect(await schema.safeParseAsync("asdf")).toMatchInlineSnapshot(` + { + "error": [ZodError: [ + { + "code": "custom", + "message": "custom error", + "path": [] + } + ]], + "success": false, + } + `); +}); + +test("preprocess ctx.addIssue with parseAsync", async () => { + const result = await z + .preprocess(async (data, ctx) => { + ctx.addIssue({ + code: "custom", + message: `${data} is not one of our allowed strings`, + }); + return data; + }, z.string()) + .safeParseAsync("asdf"); + + expect(JSON.parse(JSON.stringify(result))).toEqual({ + success: false, + error: { + issues: [ + { + code: "custom", + message: "asdf is not one of our allowed strings", + path: [], + }, + ], + name: "ZodError", + }, + }); +}); + +test("z.NEVER in preprocess", () => { + const foo = z.preprocess((val, ctx) => { + if (!val) { + ctx.addIssue({ code: z.ZodIssueCode.custom, message: "bad" }); + return z.NEVER; + } + return val; + }, z.number()); + + type foo = z.infer; + util.assertEqual(true); + const arg = foo.safeParse(undefined); + expect(arg.error!.issues).toHaveLength(2); + expect(arg.error!.issues[0].message).toEqual("bad"); +}); +test("preprocess as the second property of object", () => { + const schema = z.object({ + nonEmptyStr: z.string().min(1), + positiveNum: z.preprocess((v) => Number(v), z.number().positive()), + }); + const result = schema.safeParse({ + nonEmptyStr: "", + positiveNum: "", + }); + expect(result.success).toEqual(false); + if (!result.success) { + expect(result.error.issues.length).toEqual(2); + expect(result.error.issues[0].code).toEqual(z.ZodIssueCode.too_small); + expect(result.error.issues[1].code).toEqual(z.ZodIssueCode.too_small); + } +}); + +test("preprocess validates with sibling errors", () => { + expect(() => { + z.object({ + // Must be first + missing: z.string().refine(() => false), + preprocess: z.preprocess((data: any) => data?.trim(), z.string().regex(/ asdf/)), + }).parse({ preprocess: " asdf" }); + }).toThrow( + JSON.stringify( + [ + { + code: "invalid_type", + expected: "string", + received: "undefined", + path: ["missing"], + message: "Required", + }, + { + validation: "regex", + code: "invalid_string", + message: "Invalid", + path: ["preprocess"], + }, + ], + null, + 2 + ) + ); +}); diff --git a/node_modules/zod/src/v3/tests/primitive.test.ts b/node_modules/zod/src/v3/tests/primitive.test.ts new file mode 100644 index 00000000..48e36a21 --- /dev/null +++ b/node_modules/zod/src/v3/tests/primitive.test.ts @@ -0,0 +1,440 @@ +// @ts-ignore TS6133 +import { expect, test } from "vitest"; + +import * as z from "zod/v3"; +import { util } from "../helpers/util.js"; +import { Mocker } from "./Mocker.js"; + +const literalStringSchema = z.literal("asdf"); +const literalNumberSchema = z.literal(12); +const literalBooleanSchema = z.literal(true); +const literalBigIntSchema = z.literal(BigInt(42)); +const MySymbol = Symbol("stuff"); +const literalSymbolSchema = z.literal(MySymbol); +const stringSchema = z.string(); +const numberSchema = z.number(); +const bigintSchema = z.bigint(); +const booleanSchema = z.boolean(); +const dateSchema = z.date(); +const symbolSchema = z.symbol(); + +const nullSchema = z.null(); +const undefinedSchema = z.undefined(); +const stringSchemaOptional = z.string().optional(); +const stringSchemaNullable = z.string().nullable(); +const numberSchemaOptional = z.number().optional(); +const numberSchemaNullable = z.number().nullable(); +const bigintSchemaOptional = z.bigint().optional(); +const bigintSchemaNullable = z.bigint().nullable(); +const booleanSchemaOptional = z.boolean().optional(); +const booleanSchemaNullable = z.boolean().nullable(); +const dateSchemaOptional = z.date().optional(); +const dateSchemaNullable = z.date().nullable(); +const symbolSchemaOptional = z.symbol().optional(); +const symbolSchemaNullable = z.symbol().nullable(); + +const val = new Mocker(); + +test("literal string correct", () => { + expect(literalStringSchema.parse("asdf")).toBe("asdf"); +}); + +test("literal string incorrect", () => { + const f = () => literalStringSchema.parse("not_asdf"); + expect(f).toThrow(); +}); + +test("literal string number", () => { + const f = () => literalStringSchema.parse(123); + expect(f).toThrow(); +}); + +test("literal string boolean", () => { + const f = () => literalStringSchema.parse(true); + expect(f).toThrow(); +}); + +test("literal string boolean", () => { + const f = () => literalStringSchema.parse(true); + expect(f).toThrow(); +}); + +test("literal string object", () => { + const f = () => literalStringSchema.parse({}); + expect(f).toThrow(); +}); + +test("literal number correct", () => { + expect(literalNumberSchema.parse(12)).toBe(12); +}); + +test("literal number incorrect", () => { + const f = () => literalNumberSchema.parse(13); + expect(f).toThrow(); +}); + +test("literal number number", () => { + const f = () => literalNumberSchema.parse(val.string); + expect(f).toThrow(); +}); + +test("literal number boolean", () => { + const f = () => literalNumberSchema.parse(val.boolean); + expect(f).toThrow(); +}); + +test("literal number object", () => { + const f = () => literalStringSchema.parse({}); + expect(f).toThrow(); +}); + +test("literal boolean correct", () => { + expect(literalBooleanSchema.parse(true)).toBe(true); +}); + +test("literal boolean incorrect", () => { + const f = () => literalBooleanSchema.parse(false); + expect(f).toThrow(); +}); + +test("literal boolean number", () => { + const f = () => literalBooleanSchema.parse("asdf"); + expect(f).toThrow(); +}); + +test("literal boolean boolean", () => { + const f = () => literalBooleanSchema.parse(123); + expect(f).toThrow(); +}); + +test("literal boolean object", () => { + const f = () => literalBooleanSchema.parse({}); + expect(f).toThrow(); +}); + +test("literal bigint correct", () => { + expect(literalBigIntSchema.parse(BigInt(42))).toBe(BigInt(42)); +}); + +test("literal bigint incorrect", () => { + const f = () => literalBigIntSchema.parse(BigInt(43)); + expect(f).toThrow(); +}); + +test("literal bigint number", () => { + const f = () => literalBigIntSchema.parse("asdf"); + expect(f).toThrow(); +}); + +test("literal bigint boolean", () => { + const f = () => literalBigIntSchema.parse(123); + expect(f).toThrow(); +}); + +test("literal bigint object", () => { + const f = () => literalBigIntSchema.parse({}); + expect(f).toThrow(); +}); + +test("literal symbol", () => { + util.assertEqual, typeof MySymbol>(true); + literalSymbolSchema.parse(MySymbol); + expect(() => literalSymbolSchema.parse(Symbol("asdf"))).toThrow(); +}); + +test("parse stringSchema string", () => { + stringSchema.parse(val.string); +}); + +test("parse stringSchema number", () => { + const f = () => stringSchema.parse(val.number); + expect(f).toThrow(); +}); + +test("parse stringSchema boolean", () => { + const f = () => stringSchema.parse(val.boolean); + expect(f).toThrow(); +}); + +test("parse stringSchema undefined", () => { + const f = () => stringSchema.parse(val.undefined); + expect(f).toThrow(); +}); + +test("parse stringSchema null", () => { + const f = () => stringSchema.parse(val.null); + expect(f).toThrow(); +}); + +test("parse numberSchema string", () => { + const f = () => numberSchema.parse(val.string); + expect(f).toThrow(); +}); + +test("parse numberSchema number", () => { + numberSchema.parse(val.number); +}); + +test("parse numberSchema bigint", () => { + const f = () => numberSchema.parse(val.bigint); + expect(f).toThrow(); +}); + +test("parse numberSchema boolean", () => { + const f = () => numberSchema.parse(val.boolean); + expect(f).toThrow(); +}); + +test("parse numberSchema undefined", () => { + const f = () => numberSchema.parse(val.undefined); + expect(f).toThrow(); +}); + +test("parse numberSchema null", () => { + const f = () => numberSchema.parse(val.null); + expect(f).toThrow(); +}); + +test("parse bigintSchema string", () => { + const f = () => bigintSchema.parse(val.string); + expect(f).toThrow(); +}); + +test("parse bigintSchema number", () => { + const f = () => bigintSchema.parse(val.number); + expect(f).toThrow(); +}); + +test("parse bigintSchema bigint", () => { + bigintSchema.parse(val.bigint); +}); + +test("parse bigintSchema boolean", () => { + const f = () => bigintSchema.parse(val.boolean); + expect(f).toThrow(); +}); + +test("parse bigintSchema undefined", () => { + const f = () => bigintSchema.parse(val.undefined); + expect(f).toThrow(); +}); + +test("parse bigintSchema null", () => { + const f = () => bigintSchema.parse(val.null); + expect(f).toThrow(); +}); + +test("parse booleanSchema string", () => { + const f = () => booleanSchema.parse(val.string); + expect(f).toThrow(); +}); + +test("parse booleanSchema number", () => { + const f = () => booleanSchema.parse(val.number); + expect(f).toThrow(); +}); + +test("parse booleanSchema boolean", () => { + booleanSchema.parse(val.boolean); +}); + +test("parse booleanSchema undefined", () => { + const f = () => booleanSchema.parse(val.undefined); + expect(f).toThrow(); +}); + +test("parse booleanSchema null", () => { + const f = () => booleanSchema.parse(val.null); + expect(f).toThrow(); +}); + +// ============== + +test("parse dateSchema string", () => { + const f = () => dateSchema.parse(val.string); + expect(f).toThrow(); +}); + +test("parse dateSchema number", () => { + const f = () => dateSchema.parse(val.number); + expect(f).toThrow(); +}); + +test("parse dateSchema boolean", () => { + const f = () => dateSchema.parse(val.boolean); + expect(f).toThrow(); +}); + +test("parse dateSchema date", () => { + dateSchema.parse(val.date); +}); + +test("parse dateSchema undefined", () => { + const f = () => dateSchema.parse(val.undefined); + expect(f).toThrow(); +}); + +test("parse dateSchema null", () => { + const f = () => dateSchema.parse(val.null); + expect(f).toThrow(); +}); + +test("parse dateSchema invalid date", async () => { + try { + await dateSchema.parseAsync(new Date("invalid")); + } catch (err) { + expect((err as z.ZodError).issues[0].code).toEqual(z.ZodIssueCode.invalid_date); + } +}); +// ============== + +test("parse symbolSchema string", () => { + const f = () => symbolSchema.parse(val.string); + expect(f).toThrow(); +}); + +test("parse symbolSchema number", () => { + const f = () => symbolSchema.parse(val.number); + expect(f).toThrow(); +}); + +test("parse symbolSchema boolean", () => { + const f = () => symbolSchema.parse(val.boolean); + expect(f).toThrow(); +}); + +test("parse symbolSchema date", () => { + const f = () => symbolSchema.parse(val.date); + expect(f).toThrow(); +}); + +test("parse symbolSchema symbol", () => { + symbolSchema.parse(val.symbol); +}); + +test("parse symbolSchema undefined", () => { + const f = () => symbolSchema.parse(val.undefined); + expect(f).toThrow(); +}); + +test("parse symbolSchema null", () => { + const f = () => symbolSchema.parse(val.null); + expect(f).toThrow(); +}); + +// ============== + +test("parse undefinedSchema string", () => { + const f = () => undefinedSchema.parse(val.string); + expect(f).toThrow(); +}); + +test("parse undefinedSchema number", () => { + const f = () => undefinedSchema.parse(val.number); + expect(f).toThrow(); +}); + +test("parse undefinedSchema boolean", () => { + const f = () => undefinedSchema.parse(val.boolean); + expect(f).toThrow(); +}); + +test("parse undefinedSchema undefined", () => { + undefinedSchema.parse(val.undefined); +}); + +test("parse undefinedSchema null", () => { + const f = () => undefinedSchema.parse(val.null); + expect(f).toThrow(); +}); + +test("parse nullSchema string", () => { + const f = () => nullSchema.parse(val.string); + expect(f).toThrow(); +}); + +test("parse nullSchema number", () => { + const f = () => nullSchema.parse(val.number); + expect(f).toThrow(); +}); + +test("parse nullSchema boolean", () => { + const f = () => nullSchema.parse(val.boolean); + expect(f).toThrow(); +}); + +test("parse nullSchema undefined", () => { + const f = () => nullSchema.parse(val.undefined); + expect(f).toThrow(); +}); + +test("parse nullSchema null", () => { + nullSchema.parse(val.null); +}); + +test("primitive inference", () => { + util.assertEqual, "asdf">(true); + util.assertEqual, 12>(true); + util.assertEqual, true>(true); + util.assertEqual, bigint>(true); + util.assertEqual, string>(true); + util.assertEqual, number>(true); + util.assertEqual, bigint>(true); + util.assertEqual, boolean>(true); + util.assertEqual, Date>(true); + util.assertEqual, symbol>(true); + + util.assertEqual, null>(true); + util.assertEqual, undefined>(true); + util.assertEqual, string | undefined>(true); + util.assertEqual, string | null>(true); + util.assertEqual, number | undefined>(true); + util.assertEqual, number | null>(true); + util.assertEqual, bigint | undefined>(true); + util.assertEqual, bigint | null>(true); + util.assertEqual, boolean | undefined>(true); + util.assertEqual, boolean | null>(true); + util.assertEqual, Date | undefined>(true); + util.assertEqual, Date | null>(true); + util.assertEqual, symbol | undefined>(true); + util.assertEqual, symbol | null>(true); + + // [ + // literalStringSchemaTest, + // literalNumberSchemaTest, + // literalBooleanSchemaTest, + // literalBigIntSchemaTest, + // stringSchemaTest, + // numberSchemaTest, + // bigintSchemaTest, + // booleanSchemaTest, + // dateSchemaTest, + // symbolSchemaTest, + + // nullSchemaTest, + // undefinedSchemaTest, + // stringSchemaOptionalTest, + // stringSchemaNullableTest, + // numberSchemaOptionalTest, + // numberSchemaNullableTest, + // bigintSchemaOptionalTest, + // bigintSchemaNullableTest, + // booleanSchemaOptionalTest, + // booleanSchemaNullableTest, + // dateSchemaOptionalTest, + // dateSchemaNullableTest, + // symbolSchemaOptionalTest, + // symbolSchemaNullableTest, + + // ]; +}); + +test("get literal value", () => { + expect(literalStringSchema.value).toEqual("asdf"); +}); + +test("optional convenience method", () => { + z.ostring().parse(undefined); + z.onumber().parse(undefined); + z.oboolean().parse(undefined); +}); diff --git a/node_modules/zod/src/v3/tests/promise.test.ts b/node_modules/zod/src/v3/tests/promise.test.ts new file mode 100644 index 00000000..23b6de17 --- /dev/null +++ b/node_modules/zod/src/v3/tests/promise.test.ts @@ -0,0 +1,90 @@ +// @ts-ignore TS6133 +import { expect, test } from "vitest"; + +import * as z from "zod/v3"; +import { util } from "../helpers/util.js"; + +const promSchema = z.promise( + z.object({ + name: z.string(), + age: z.number(), + }) +); + +test("promise inference", () => { + type promSchemaType = z.infer; + util.assertEqual>(true); +}); + +test("promise parsing success", async () => { + const pr = promSchema.parse(Promise.resolve({ name: "Bobby", age: 10 })); + expect(pr).toBeInstanceOf(Promise); + const result = await pr; + expect(typeof result).toBe("object"); + expect(typeof result.age).toBe("number"); + expect(typeof result.name).toBe("string"); +}); + +test("promise parsing success 2", () => { + const fakePromise = { + then() { + return this; + }, + catch() { + return this; + }, + }; + promSchema.parse(fakePromise); +}); + +test("promise parsing fail", async () => { + const bad = promSchema.parse(Promise.resolve({ name: "Bobby", age: "10" })); + // return await expect(bad).resolves.toBe({ name: 'Bobby', age: '10' }); + return await expect(bad).rejects.toBeInstanceOf(z.ZodError); + // done(); +}); + +test("promise parsing fail 2", async () => { + const failPromise = promSchema.parse(Promise.resolve({ name: "Bobby", age: "10" })); + await expect(failPromise).rejects.toBeInstanceOf(z.ZodError); + // done();/z +}); + +test("promise parsing fail", () => { + const bad = () => promSchema.parse({ then: () => {}, catch: {} }); + expect(bad).toThrow(); +}); + +// test('sync promise parsing', () => { +// expect(() => z.promise(z.string()).parse(Promise.resolve('asfd'))).toThrow(); +// }); + +const asyncFunction = z.function(z.tuple([]), promSchema); + +test("async function pass", async () => { + const validatedFunction = asyncFunction.implement(async () => { + return { name: "jimmy", age: 14 }; + }); + await expect(validatedFunction()).resolves.toEqual({ + name: "jimmy", + age: 14, + }); +}); + +test("async function fail", async () => { + const validatedFunction = asyncFunction.implement(() => { + return Promise.resolve("asdf" as any); + }); + await expect(validatedFunction()).rejects.toBeInstanceOf(z.ZodError); +}); + +test("async promise parsing", () => { + const res = z.promise(z.number()).parseAsync(Promise.resolve(12)); + expect(res).toBeInstanceOf(Promise); +}); + +test("resolves", () => { + const foo = z.literal("foo"); + const res = z.promise(foo); + expect(res.unwrap()).toEqual(foo); +}); diff --git a/node_modules/zod/src/v3/tests/readonly.test.ts b/node_modules/zod/src/v3/tests/readonly.test.ts new file mode 100644 index 00000000..5078955f --- /dev/null +++ b/node_modules/zod/src/v3/tests/readonly.test.ts @@ -0,0 +1,194 @@ +// @ts-ignore TS6133 +import { expect, test } from "vitest"; + +import * as z from "zod/v3"; +import { util } from "../helpers/util.js"; + +enum testEnum { + A = 0, + B = 1, +} + +const schemas = [ + z.string().readonly(), + z.number().readonly(), + z.nan().readonly(), + z.bigint().readonly(), + z.boolean().readonly(), + z.date().readonly(), + z.undefined().readonly(), + z.null().readonly(), + z.any().readonly(), + z.unknown().readonly(), + z.void().readonly(), + z.function().args(z.string(), z.number()).readonly(), + + z.array(z.string()).readonly(), + z.tuple([z.string(), z.number()]).readonly(), + z.map(z.string(), z.date()).readonly(), + z.set(z.promise(z.string())).readonly(), + z.record(z.string()).readonly(), + z.record(z.string(), z.number()).readonly(), + z.object({ a: z.string(), 1: z.number() }).readonly(), + z.nativeEnum(testEnum).readonly(), + z.promise(z.string()).readonly(), +] as const; + +test("flat inference", () => { + util.assertEqual, string>(true); + util.assertEqual, number>(true); + util.assertEqual, number>(true); + util.assertEqual, bigint>(true); + util.assertEqual, boolean>(true); + util.assertEqual, Date>(true); + util.assertEqual, undefined>(true); + util.assertEqual, null>(true); + util.assertEqual, any>(true); + util.assertEqual, Readonly>(true); + util.assertEqual, void>(true); + util.assertEqual, (args_0: string, args_1: number, ...args_2: unknown[]) => unknown>( + true + ); + util.assertEqual, readonly string[]>(true); + + util.assertEqual, readonly [string, number]>(true); + util.assertEqual, ReadonlyMap>(true); + util.assertEqual, ReadonlySet>>(true); + util.assertEqual, Readonly>>(true); + util.assertEqual, Readonly>>(true); + util.assertEqual, { readonly a: string; readonly 1: number }>(true); + util.assertEqual, Readonly>(true); + util.assertEqual, Promise>(true); +}); + +// test("deep inference", () => { +// util.assertEqual, string>(true); +// util.assertEqual, number>(true); +// util.assertEqual, number>(true); +// util.assertEqual, bigint>(true); +// util.assertEqual, boolean>(true); +// util.assertEqual, Date>(true); +// util.assertEqual, undefined>(true); +// util.assertEqual, null>(true); +// util.assertEqual, any>(true); +// util.assertEqual< +// z.infer<(typeof deepReadonlySchemas_0)[9]>, +// Readonly +// >(true); +// util.assertEqual, void>(true); +// util.assertEqual< +// z.infer<(typeof deepReadonlySchemas_0)[11]>, +// (args_0: string, args_1: number, ...args_2: unknown[]) => unknown +// >(true); +// util.assertEqual< +// z.infer<(typeof deepReadonlySchemas_0)[12]>, +// readonly string[] +// >(true); +// util.assertEqual< +// z.infer<(typeof deepReadonlySchemas_0)[13]>, +// readonly [string, number] +// >(true); +// util.assertEqual< +// z.infer<(typeof deepReadonlySchemas_0)[14]>, +// ReadonlyMap +// >(true); +// util.assertEqual< +// z.infer<(typeof deepReadonlySchemas_0)[15]>, +// ReadonlySet> +// >(true); +// util.assertEqual< +// z.infer<(typeof deepReadonlySchemas_0)[16]>, +// Readonly> +// >(true); +// util.assertEqual< +// z.infer<(typeof deepReadonlySchemas_0)[17]>, +// Readonly> +// >(true); +// util.assertEqual< +// z.infer<(typeof deepReadonlySchemas_0)[18]>, +// { readonly a: string; readonly 1: number } +// >(true); +// util.assertEqual< +// z.infer<(typeof deepReadonlySchemas_0)[19]>, +// Readonly +// >(true); +// util.assertEqual< +// z.infer<(typeof deepReadonlySchemas_0)[20]>, +// Promise +// >(true); + +// util.assertEqual< +// z.infer, +// ReadonlyMap< +// ReadonlySet, +// { +// readonly a: { +// readonly [x: string]: readonly any[]; +// }; +// readonly b: { +// readonly c: { +// readonly d: { +// readonly e: { +// readonly f: { +// readonly g?: {}; +// }; +// }; +// }; +// }; +// }; +// } +// > +// >(true); +// }); + +test("object freezing", () => { + expect(Object.isFrozen(z.array(z.string()).readonly().parse(["a"]))).toBe(true); + expect(Object.isFrozen(z.tuple([z.string(), z.number()]).readonly().parse(["a", 1]))).toBe(true); + expect( + Object.isFrozen( + z + .map(z.string(), z.date()) + .readonly() + .parse(new Map([["a", new Date()]])) + ) + ).toBe(true); + expect( + Object.isFrozen( + z + .set(z.promise(z.string())) + .readonly() + .parse(new Set([Promise.resolve("a")])) + ) + ).toBe(true); + expect(Object.isFrozen(z.record(z.string()).readonly().parse({ a: "b" }))).toBe(true); + expect(Object.isFrozen(z.record(z.string(), z.number()).readonly().parse({ a: 1 }))).toBe(true); + expect(Object.isFrozen(z.object({ a: z.string(), 1: z.number() }).readonly().parse({ a: "b", 1: 2 }))).toBe(true); + expect(Object.isFrozen(z.promise(z.string()).readonly().parse(Promise.resolve("a")))).toBe(true); +}); + +test("async object freezing", async () => { + expect(Object.isFrozen(await z.array(z.string()).readonly().parseAsync(["a"]))).toBe(true); + expect(Object.isFrozen(await z.tuple([z.string(), z.number()]).readonly().parseAsync(["a", 1]))).toBe(true); + expect( + Object.isFrozen( + await z + .map(z.string(), z.date()) + .readonly() + .parseAsync(new Map([["a", new Date()]])) + ) + ).toBe(true); + expect( + Object.isFrozen( + await z + .set(z.promise(z.string())) + .readonly() + .parseAsync(new Set([Promise.resolve("a")])) + ) + ).toBe(true); + expect(Object.isFrozen(await z.record(z.string()).readonly().parseAsync({ a: "b" }))).toBe(true); + expect(Object.isFrozen(await z.record(z.string(), z.number()).readonly().parseAsync({ a: 1 }))).toBe(true); + expect( + Object.isFrozen(await z.object({ a: z.string(), 1: z.number() }).readonly().parseAsync({ a: "b", 1: 2 })) + ).toBe(true); + expect(Object.isFrozen(await z.promise(z.string()).readonly().parseAsync(Promise.resolve("a")))).toBe(true); +}); diff --git a/node_modules/zod/src/v3/tests/record.test.ts b/node_modules/zod/src/v3/tests/record.test.ts new file mode 100644 index 00000000..83c363f3 --- /dev/null +++ b/node_modules/zod/src/v3/tests/record.test.ts @@ -0,0 +1,171 @@ +// @ts-ignore TS6133 +import { expect, test } from "vitest"; + +import * as z from "zod/v3"; +import { util } from "../helpers/util.js"; + +const booleanRecord = z.record(z.boolean()); +type booleanRecord = z.infer; + +const recordWithEnumKeys = z.record(z.enum(["Tuna", "Salmon"]), z.string()); +type recordWithEnumKeys = z.infer; + +const recordWithLiteralKeys = z.record(z.union([z.literal("Tuna"), z.literal("Salmon")]), z.string()); +type recordWithLiteralKeys = z.infer; + +test("type inference", () => { + util.assertEqual>(true); + + util.assertEqual>>(true); + + util.assertEqual>>(true); +}); + +test("methods", () => { + booleanRecord.optional(); + booleanRecord.nullable(); +}); + +test("string record parse - pass", () => { + booleanRecord.parse({ + k1: true, + k2: false, + 1234: false, + }); +}); + +test("string record parse - fail", () => { + const badCheck = () => + booleanRecord.parse({ + asdf: 1234, + } as any); + expect(badCheck).toThrow(); + + expect(() => booleanRecord.parse("asdf")).toThrow(); +}); + +test("string record parse - fail", () => { + const badCheck = () => + booleanRecord.parse({ + asdf: {}, + } as any); + expect(badCheck).toThrow(); +}); + +test("string record parse - fail", () => { + const badCheck = () => + booleanRecord.parse({ + asdf: [], + } as any); + expect(badCheck).toThrow(); +}); + +test("key schema", () => { + const result1 = recordWithEnumKeys.parse({ + Tuna: "asdf", + Salmon: "asdf", + }); + expect(result1).toEqual({ + Tuna: "asdf", + Salmon: "asdf", + }); + + const result2 = recordWithLiteralKeys.parse({ + Tuna: "asdf", + Salmon: "asdf", + }); + expect(result2).toEqual({ + Tuna: "asdf", + Salmon: "asdf", + }); + + // shouldn't require us to specify all props in record + const result3 = recordWithEnumKeys.parse({ + Tuna: "abcd", + }); + expect(result3).toEqual({ + Tuna: "abcd", + }); + + // shouldn't require us to specify all props in record + const result4 = recordWithLiteralKeys.parse({ + Salmon: "abcd", + }); + expect(result4).toEqual({ + Salmon: "abcd", + }); + + expect(() => + recordWithEnumKeys.parse({ + Tuna: "asdf", + Salmon: "asdf", + Trout: "asdf", + }) + ).toThrow(); + + expect(() => + recordWithLiteralKeys.parse({ + Tuna: "asdf", + Salmon: "asdf", + + Trout: "asdf", + }) + ).toThrow(); +}); + +// test("record element", () => { +// expect(booleanRecord.element).toBeInstanceOf(z.ZodBoolean); +// }); + +test("key and value getters", () => { + const rec = z.record(z.string(), z.number()); + + rec.keySchema.parse("asdf"); + rec.valueSchema.parse(1234); + rec.element.parse(1234); +}); + +test("is not vulnerable to prototype pollution", async () => { + const rec = z.record( + z.object({ + a: z.string(), + }) + ); + + const data = JSON.parse(` + { + "__proto__": { + "a": "evil" + }, + "b": { + "a": "good" + } + } + `); + + const obj1 = rec.parse(data); + expect(obj1.a).toBeUndefined(); + + const obj2 = rec.safeParse(data); + expect(obj2.success).toBe(true); + if (obj2.success) { + expect(obj2.data.a).toBeUndefined(); + } + + const obj3 = await rec.parseAsync(data); + expect(obj3.a).toBeUndefined(); + + const obj4 = await rec.safeParseAsync(data); + expect(obj4.success).toBe(true); + if (obj4.success) { + expect(obj4.data.a).toBeUndefined(); + } +}); + +test("dont parse undefined values", () => { + const result1 = z.record(z.any()).parse({ foo: undefined }); + + expect(result1).toEqual({ + foo: undefined, + }); +}); diff --git a/node_modules/zod/src/v3/tests/recursive.test.ts b/node_modules/zod/src/v3/tests/recursive.test.ts new file mode 100644 index 00000000..f5bb1088 --- /dev/null +++ b/node_modules/zod/src/v3/tests/recursive.test.ts @@ -0,0 +1,197 @@ +// @ts-ignore TS6133 +import { test } from "vitest"; + +import { z } from "zod/v3"; + +interface Category { + name: string; + subcategories: Category[]; +} + +const testCategory: Category = { + name: "I", + subcategories: [ + { + name: "A", + subcategories: [ + { + name: "1", + subcategories: [ + { + name: "a", + subcategories: [], + }, + ], + }, + ], + }, + ], +}; + +test("recursion with z.late.object", () => { + const Category: z.ZodType = z.late.object(() => ({ + name: z.string(), + subcategories: z.array(Category), + })); + Category.parse(testCategory); +}); + +test("recursion with z.lazy", () => { + const Category: z.ZodType = z.lazy(() => + z.object({ + name: z.string(), + subcategories: z.array(Category), + }) + ); + Category.parse(testCategory); +}); + +test("schema getter", () => { + z.lazy(() => z.string()).schema.parse("asdf"); +}); + +type LinkedList = null | { value: number; next: LinkedList }; + +const linkedListExample = { + value: 1, + next: { + value: 2, + next: { + value: 3, + next: { + value: 4, + next: null, + }, + }, + }, +}; + +test("recursion involving union type", () => { + const LinkedListSchema: z.ZodType = z.lazy(() => + z.union([ + z.null(), + z.object({ + value: z.number(), + next: LinkedListSchema, + }), + ]) + ); + LinkedListSchema.parse(linkedListExample); +}); + +// interface A { +// val: number; +// b: B; +// } + +// interface B { +// val: number; +// a: A; +// } + +// const A: z.ZodType = z.late.object(() => ({ +// val: z.number(), +// b: B, +// })); + +// const B: z.ZodType = z.late.object(() => ({ +// val: z.number(), +// a: A, +// })); + +// const Alazy: z.ZodType = z.lazy(() => z.object({ +// val: z.number(), +// b: B, +// })); + +// const Blazy: z.ZodType = z.lazy(() => z.object({ +// val: z.number(), +// a: A, +// })); + +// const a: any = { val: 1 }; +// const b: any = { val: 2 }; +// a.b = b; +// b.a = a; + +// test('valid check', () => { +// A.parse(a); +// B.parse(b); +// }); + +// test("valid check lazy", () => { +// A.parse({val:1, b:}); +// B.parse(b); +// }); + +// test('masking check', () => { +// const FragmentOnA = z +// .object({ +// val: z.number(), +// b: z +// .object({ +// val: z.number(), +// a: z +// .object({ +// val: z.number(), +// }) +// .nonstrict(), +// }) +// .nonstrict(), +// }) +// .nonstrict(); + +// const fragment = FragmentOnA.parse(a); +// fragment; +// }); + +// test('invalid check', () => { +// expect(() => A.parse({} as any)).toThrow(); +// }); + +// test('schema getter', () => { +// (A as z.ZodLazy).schema; +// }); + +// test("self recursion with cyclical data", () => { +// interface Category { +// name: string; +// subcategories: Category[]; +// } + +// const Category: z.ZodType = z.late.object(() => ({ +// name: z.string(), +// subcategories: z.array(Category), +// })); + +// const untypedCategory: any = { +// name: "Category A", +// }; +// // creating a cycle +// untypedCategory.subcategories = [untypedCategory]; +// Category.parse(untypedCategory); +// }); + +// test("self recursion with base type", () => { +// const BaseCategory = z.object({ +// name: z.string(), +// }); +// type BaseCategory = z.infer; + +// type Category = BaseCategory & { subcategories: Category[] }; + +// const Category: z.ZodType = z.late +// .object(() => ({ +// subcategories: z.array(Category), +// })) +// .extend({ +// name: z.string(), +// }); + +// const untypedCategory: any = { +// name: "Category A", +// }; +// // creating a cycle +// untypedCategory.subcategories = [untypedCategory]; +// Category.parse(untypedCategory); // parses successfully +// }); diff --git a/node_modules/zod/src/v3/tests/refine.test.ts b/node_modules/zod/src/v3/tests/refine.test.ts new file mode 100644 index 00000000..55c27fea --- /dev/null +++ b/node_modules/zod/src/v3/tests/refine.test.ts @@ -0,0 +1,313 @@ +// @ts-ignore TS6133 +import { expect, test } from "vitest"; + +import * as z from "zod/v3"; +import { ZodIssueCode } from "../ZodError.js"; +import { util } from "../helpers/util.js"; + +test("refinement", () => { + const obj1 = z.object({ + first: z.string(), + second: z.string(), + }); + const obj2 = obj1.partial().strict(); + + const obj3 = obj2.refine((data) => data.first || data.second, "Either first or second should be filled in."); + + expect(obj1 === (obj2 as any)).toEqual(false); + expect(obj2 === (obj3 as any)).toEqual(false); + + expect(() => obj1.parse({})).toThrow(); + expect(() => obj2.parse({ third: "adsf" })).toThrow(); + expect(() => obj3.parse({})).toThrow(); + obj3.parse({ first: "a" }); + obj3.parse({ second: "a" }); + obj3.parse({ first: "a", second: "a" }); +}); + +test("refinement 2", () => { + const validationSchema = z + .object({ + email: z.string().email(), + password: z.string(), + confirmPassword: z.string(), + }) + .refine((data) => data.password === data.confirmPassword, "Both password and confirmation must match"); + + expect(() => + validationSchema.parse({ + email: "aaaa@gmail.com", + password: "aaaaaaaa", + confirmPassword: "bbbbbbbb", + }) + ).toThrow(); +}); + +test("refinement type guard", () => { + const validationSchema = z.object({ + a: z.string().refine((s): s is "a" => s === "a"), + }); + type Input = z.input; + type Schema = z.infer; + + util.assertEqual<"a", Input["a"]>(false); + util.assertEqual(true); + + util.assertEqual<"a", Schema["a"]>(true); + util.assertEqual(false); +}); + +test("refinement Promise", async () => { + const validationSchema = z + .object({ + email: z.string().email(), + password: z.string(), + confirmPassword: z.string(), + }) + .refine( + (data) => Promise.resolve().then(() => data.password === data.confirmPassword), + "Both password and confirmation must match" + ); + + await validationSchema.parseAsync({ + email: "aaaa@gmail.com", + password: "password", + confirmPassword: "password", + }); +}); + +test("custom path", async () => { + const result = await z + .object({ + password: z.string(), + confirm: z.string(), + }) + .refine((data) => data.confirm === data.password, { path: ["confirm"] }) + .spa({ password: "asdf", confirm: "qewr" }); + expect(result.success).toEqual(false); + if (!result.success) { + expect(result.error.issues[0].path).toEqual(["confirm"]); + } +}); + +test("use path in refinement context", async () => { + const noNested = z.string()._refinement((_val, ctx) => { + if (ctx.path.length > 0) { + ctx.addIssue({ + code: ZodIssueCode.custom, + message: `schema cannot be nested. path: ${ctx.path.join(".")}`, + }); + return false; + } else { + return true; + } + }); + + const data = z.object({ + foo: noNested, + }); + + const t1 = await noNested.spa("asdf"); + const t2 = await data.spa({ foo: "asdf" }); + + expect(t1.success).toBe(true); + expect(t2.success).toBe(false); + if (t2.success === false) { + expect(t2.error.issues[0].message).toEqual("schema cannot be nested. path: foo"); + } +}); + +test("superRefine", () => { + const Strings = z.array(z.string()).superRefine((val, ctx) => { + if (val.length > 3) { + ctx.addIssue({ + code: z.ZodIssueCode.too_big, + maximum: 3, + type: "array", + inclusive: true, + exact: true, + message: "Too many items 😡", + }); + } + + if (val.length !== new Set(val).size) { + ctx.addIssue({ + code: z.ZodIssueCode.custom, + message: `No duplicates allowed.`, + }); + } + }); + + const result = Strings.safeParse(["asfd", "asfd", "asfd", "asfd"]); + + expect(result.success).toEqual(false); + if (!result.success) expect(result.error.issues.length).toEqual(2); + + Strings.parse(["asfd", "qwer"]); +}); + +test("superRefine async", async () => { + const Strings = z.array(z.string()).superRefine(async (val, ctx) => { + if (val.length > 3) { + ctx.addIssue({ + code: z.ZodIssueCode.too_big, + maximum: 3, + type: "array", + inclusive: true, + exact: true, + message: "Too many items 😡", + }); + } + + if (val.length !== new Set(val).size) { + ctx.addIssue({ + code: z.ZodIssueCode.custom, + message: `No duplicates allowed.`, + }); + } + }); + + const result = await Strings.safeParseAsync(["asfd", "asfd", "asfd", "asfd"]); + + expect(result.success).toEqual(false); + if (!result.success) expect(result.error.issues.length).toEqual(2); + + Strings.parseAsync(["asfd", "qwer"]); +}); + +test("superRefine - type narrowing", () => { + type NarrowType = { type: string; age: number }; + const schema = z + .object({ + type: z.string(), + age: z.number(), + }) + .nullable() + .superRefine((arg, ctx): arg is NarrowType => { + if (!arg) { + // still need to make a call to ctx.addIssue + ctx.addIssue({ + code: z.ZodIssueCode.custom, + message: "cannot be null", + fatal: true, + }); + return false; + } + return true; + }); + + util.assertEqual, NarrowType>(true); + + expect(schema.safeParse({ type: "test", age: 0 }).success).toEqual(true); + expect(schema.safeParse(null).success).toEqual(false); +}); + +test("chained mixed refining types", () => { + type firstRefinement = { first: string; second: number; third: true }; + type secondRefinement = { first: "bob"; second: number; third: true }; + type thirdRefinement = { first: "bob"; second: 33; third: true }; + const schema = z + .object({ + first: z.string(), + second: z.number(), + third: z.boolean(), + }) + .nullable() + .refine((arg): arg is firstRefinement => !!arg?.third) + .superRefine((arg, ctx): arg is secondRefinement => { + util.assertEqual(true); + if (arg.first !== "bob") { + ctx.addIssue({ + code: z.ZodIssueCode.custom, + message: "`first` property must be `bob`", + }); + return false; + } + return true; + }) + .refine((arg): arg is thirdRefinement => { + util.assertEqual(true); + return arg.second === 33; + }); + + util.assertEqual, thirdRefinement>(true); +}); + +test("get inner type", () => { + z.string() + .refine(() => true) + .innerType() + .parse("asdf"); +}); + +test("chained refinements", () => { + const objectSchema = z + .object({ + length: z.number(), + size: z.number(), + }) + .refine(({ length }) => length > 5, { + path: ["length"], + message: "length greater than 5", + }) + .refine(({ size }) => size > 7, { + path: ["size"], + message: "size greater than 7", + }); + const r1 = objectSchema.safeParse({ + length: 4, + size: 9, + }); + expect(r1.success).toEqual(false); + if (!r1.success) expect(r1.error.issues.length).toEqual(1); + + const r2 = objectSchema.safeParse({ + length: 4, + size: 3, + }); + expect(r2.success).toEqual(false); + if (!r2.success) expect(r2.error.issues.length).toEqual(2); +}); + +test("fatal superRefine", () => { + const Strings = z + .string() + .superRefine((val, ctx) => { + if (val === "") { + ctx.addIssue({ + code: z.ZodIssueCode.custom, + message: "foo", + fatal: true, + }); + } + }) + .superRefine((val, ctx) => { + if (val !== " ") { + ctx.addIssue({ + code: z.ZodIssueCode.custom, + message: "bar", + }); + } + }); + + const result = Strings.safeParse(""); + + expect(result.success).toEqual(false); + if (!result.success) expect(result.error.issues.length).toEqual(1); +}); + +test("superRefine after skipped transform", () => { + const schema = z + .string() + .regex(/^\d+$/) + .transform((val) => Number(val)) + .superRefine((val) => { + if (typeof val !== "number") { + throw new Error("Called without transform"); + } + }); + + const result = schema.safeParse(""); + + expect(result.success).toEqual(false); +}); diff --git a/node_modules/zod/src/v3/tests/safeparse.test.ts b/node_modules/zod/src/v3/tests/safeparse.test.ts new file mode 100644 index 00000000..950a2df5 --- /dev/null +++ b/node_modules/zod/src/v3/tests/safeparse.test.ts @@ -0,0 +1,27 @@ +// @ts-ignore TS6133 +import { expect, test } from "vitest"; + +import * as z from "zod/v3"; +const stringSchema = z.string(); + +test("safeparse fail", () => { + const safe = stringSchema.safeParse(12); + expect(safe.success).toEqual(false); + expect(safe.error).toBeInstanceOf(z.ZodError); +}); + +test("safeparse pass", () => { + const safe = stringSchema.safeParse("12"); + expect(safe.success).toEqual(true); + expect(safe.data).toEqual("12"); +}); + +test("safeparse unexpected error", () => { + expect(() => + stringSchema + .refine((data) => { + throw new Error(data); + }) + .safeParse("12") + ).toThrow(); +}); diff --git a/node_modules/zod/src/v3/tests/set.test.ts b/node_modules/zod/src/v3/tests/set.test.ts new file mode 100644 index 00000000..890cdd20 --- /dev/null +++ b/node_modules/zod/src/v3/tests/set.test.ts @@ -0,0 +1,142 @@ +// @ts-ignore TS6133 +import { expect, test } from "vitest"; + +import * as z from "zod/v3"; +import { ZodIssueCode } from "zod/v3"; +import { util } from "../helpers/util.js"; + +const stringSet = z.set(z.string()); +type stringSet = z.infer; + +const minTwo = z.set(z.string()).min(2); +const maxTwo = z.set(z.string()).max(2); +const justTwo = z.set(z.string()).size(2); +const nonEmpty = z.set(z.string()).nonempty(); +const nonEmptyMax = z.set(z.string()).nonempty().max(2); + +test("type inference", () => { + util.assertEqual>(true); +}); + +test("valid parse", () => { + const result = stringSet.safeParse(new Set(["first", "second"])); + expect(result.success).toEqual(true); + if (result.success) { + expect(result.data.has("first")).toEqual(true); + expect(result.data.has("second")).toEqual(true); + expect(result.data.has("third")).toEqual(false); + } + + expect(() => { + minTwo.parse(new Set(["a", "b"])); + minTwo.parse(new Set(["a", "b", "c"])); + maxTwo.parse(new Set(["a", "b"])); + maxTwo.parse(new Set(["a"])); + justTwo.parse(new Set(["a", "b"])); + nonEmpty.parse(new Set(["a"])); + nonEmptyMax.parse(new Set(["a"])); + }).not.toThrow(); +}); + +test("valid parse async", async () => { + const result = await stringSet.spa(new Set(["first", "second"])); + expect(result.success).toEqual(true); + if (result.success) { + expect(result.data.has("first")).toEqual(true); + expect(result.data.has("second")).toEqual(true); + expect(result.data.has("third")).toEqual(false); + } + + const asyncResult = await stringSet.safeParse(new Set(["first", "second"])); + expect(asyncResult.success).toEqual(true); + if (asyncResult.success) { + expect(asyncResult.data.has("first")).toEqual(true); + expect(asyncResult.data.has("second")).toEqual(true); + expect(asyncResult.data.has("third")).toEqual(false); + } +}); + +test("valid parse: size-related methods", () => { + expect(() => { + minTwo.parse(new Set(["a", "b"])); + minTwo.parse(new Set(["a", "b", "c"])); + maxTwo.parse(new Set(["a", "b"])); + maxTwo.parse(new Set(["a"])); + justTwo.parse(new Set(["a", "b"])); + nonEmpty.parse(new Set(["a"])); + nonEmptyMax.parse(new Set(["a"])); + }).not.toThrow(); + + const sizeZeroResult = stringSet.parse(new Set()); + expect(sizeZeroResult.size).toBe(0); + + const sizeTwoResult = minTwo.parse(new Set(["a", "b"])); + expect(sizeTwoResult.size).toBe(2); +}); + +test("failing when parsing empty set in nonempty ", () => { + const result = nonEmpty.safeParse(new Set()); + expect(result.success).toEqual(false); + + if (result.success === false) { + expect(result.error.issues.length).toEqual(1); + expect(result.error.issues[0].code).toEqual(ZodIssueCode.too_small); + } +}); + +test("failing when set is smaller than min() ", () => { + const result = minTwo.safeParse(new Set(["just_one"])); + expect(result.success).toEqual(false); + + if (result.success === false) { + expect(result.error.issues.length).toEqual(1); + expect(result.error.issues[0].code).toEqual(ZodIssueCode.too_small); + } +}); + +test("failing when set is bigger than max() ", () => { + const result = maxTwo.safeParse(new Set(["one", "two", "three"])); + expect(result.success).toEqual(false); + + if (result.success === false) { + expect(result.error.issues.length).toEqual(1); + expect(result.error.issues[0].code).toEqual(ZodIssueCode.too_big); + } +}); + +test("doesn’t throw when an empty set is given", () => { + const result = stringSet.safeParse(new Set([])); + expect(result.success).toEqual(true); +}); + +test("throws when a Map is given", () => { + const result = stringSet.safeParse(new Map([])); + expect(result.success).toEqual(false); + if (result.success === false) { + expect(result.error.issues.length).toEqual(1); + expect(result.error.issues[0].code).toEqual(ZodIssueCode.invalid_type); + } +}); + +test("throws when the given set has invalid input", () => { + const result = stringSet.safeParse(new Set([Symbol()])); + expect(result.success).toEqual(false); + if (result.success === false) { + expect(result.error.issues.length).toEqual(1); + expect(result.error.issues[0].code).toEqual(ZodIssueCode.invalid_type); + expect(result.error.issues[0].path).toEqual([0]); + } +}); + +test("throws when the given set has multiple invalid entries", () => { + const result = stringSet.safeParse(new Set([1, 2] as any[]) as Set); + + expect(result.success).toEqual(false); + if (result.success === false) { + expect(result.error.issues.length).toEqual(2); + expect(result.error.issues[0].code).toEqual(ZodIssueCode.invalid_type); + expect(result.error.issues[0].path).toEqual([0]); + expect(result.error.issues[1].code).toEqual(ZodIssueCode.invalid_type); + expect(result.error.issues[1].path).toEqual([1]); + } +}); diff --git a/node_modules/zod/src/v3/tests/standard-schema.test.ts b/node_modules/zod/src/v3/tests/standard-schema.test.ts new file mode 100644 index 00000000..74b3d2ba --- /dev/null +++ b/node_modules/zod/src/v3/tests/standard-schema.test.ts @@ -0,0 +1,83 @@ +// import type { StandardSchemaV1 } from "@standard-schema/spec"; +// @ts-ignore TS6133 +import { expect, test } from "vitest"; + +import * as z from "zod/v3"; +import { util } from "../helpers/util.js"; +import type { StandardSchemaV1 } from "../standard-schema.js"; + +test("assignability", () => { + const _s1: StandardSchemaV1 = z.string(); + const _s2: StandardSchemaV1 = z.string(); + const _s3: StandardSchemaV1 = z.string(); + const _s4: StandardSchemaV1 = z.string(); + [_s1, _s2, _s3, _s4]; +}); + +test("type inference", () => { + const stringToNumber = z.string().transform((x) => x.length); + type input = StandardSchemaV1.InferInput; + util.assertEqual(true); + type output = StandardSchemaV1.InferOutput; + util.assertEqual(true); +}); + +test("valid parse", () => { + const schema = z.string(); + const result = schema["~standard"].validate("hello"); + if (result instanceof Promise) { + throw new Error("Expected sync result"); + } + expect(result.issues).toEqual(undefined); + if (result.issues) { + throw new Error("Expected no issues"); + } else { + expect(result.value).toEqual("hello"); + } +}); + +test("invalid parse", () => { + const schema = z.string(); + const result = schema["~standard"].validate(1234); + if (result instanceof Promise) { + throw new Error("Expected sync result"); + } + expect(result.issues).toBeDefined(); + if (!result.issues) { + throw new Error("Expected issues"); + } + expect(result.issues.length).toEqual(1); + expect(result.issues[0].path).toEqual([]); +}); + +test("valid parse async", async () => { + const schema = z.string().refine(async () => true); + const _result = schema["~standard"].validate("hello"); + if (_result instanceof Promise) { + const result = await _result; + expect(result.issues).toEqual(undefined); + if (result.issues) { + throw new Error("Expected no issues"); + } else { + expect(result.value).toEqual("hello"); + } + } else { + throw new Error("Expected async result"); + } +}); + +test("invalid parse async", async () => { + const schema = z.string().refine(async () => false); + const _result = schema["~standard"].validate("hello"); + if (_result instanceof Promise) { + const result = await _result; + expect(result.issues).toBeDefined(); + if (!result.issues) { + throw new Error("Expected issues"); + } + expect(result.issues.length).toEqual(1); + expect(result.issues[0].path).toEqual([]); + } else { + throw new Error("Expected async result"); + } +}); diff --git a/node_modules/zod/src/v3/tests/string.test.ts b/node_modules/zod/src/v3/tests/string.test.ts new file mode 100644 index 00000000..2d712e10 --- /dev/null +++ b/node_modules/zod/src/v3/tests/string.test.ts @@ -0,0 +1,916 @@ +import { Buffer } from "node:buffer"; +// @ts-ignore TS6133 +import { expect, test } from "vitest"; + +import * as z from "zod/v3"; + +const minFive = z.string().min(5, "min5"); +const maxFive = z.string().max(5, "max5"); +const justFive = z.string().length(5); +const nonempty = z.string().nonempty("nonempty"); +const includes = z.string().includes("includes"); +const includesFromIndex2 = z.string().includes("includes", { position: 2 }); +const startsWith = z.string().startsWith("startsWith"); +const endsWith = z.string().endsWith("endsWith"); + +test("passing validations", () => { + minFive.parse("12345"); + minFive.parse("123456"); + maxFive.parse("12345"); + maxFive.parse("1234"); + nonempty.parse("1"); + justFive.parse("12345"); + includes.parse("XincludesXX"); + includesFromIndex2.parse("XXXincludesXX"); + startsWith.parse("startsWithX"); + endsWith.parse("XendsWith"); +}); + +test("failing validations", () => { + expect(() => minFive.parse("1234")).toThrow(); + expect(() => maxFive.parse("123456")).toThrow(); + expect(() => nonempty.parse("")).toThrow(); + expect(() => justFive.parse("1234")).toThrow(); + expect(() => justFive.parse("123456")).toThrow(); + expect(() => includes.parse("XincludeXX")).toThrow(); + expect(() => includesFromIndex2.parse("XincludesXX")).toThrow(); + expect(() => startsWith.parse("x")).toThrow(); + expect(() => endsWith.parse("x")).toThrow(); +}); + +test("email validations", () => { + const validEmails = [ + `email@domain.com`, + `firstname.lastname@domain.com`, + `email@subdomain.domain.com`, + `firstname+lastname@domain.com`, + `1234567890@domain.com`, + `email@domain-one.com`, + `_______@domain.com`, + `email@domain.name`, + `email@domain.co.jp`, + `firstname-lastname@domain.com`, + `very.common@example.com`, + `disposable.style.email.with+symbol@example.com`, + `other.email-with-hyphen@example.com`, + `fully-qualified-domain@example.com`, + `user.name+tag+sorting@example.com`, + `x@example.com`, + `mojojojo@asdf.example.com`, + `example-indeed@strange-example.com`, + `example@s.example`, + `user-@example.org`, + `user@my-example.com`, + `a@b.cd`, + `work+user@mail.com`, + `tom@test.te-st.com`, + `something@subdomain.domain-with-hyphens.tld`, + `common'name@domain.com`, + `francois@etu.inp-n7.fr`, + ]; + const invalidEmails = [ + // no "printable characters" + // `user%example.com@example.org`, + // `mailhost!username@example.org`, + // `test/test@test.com`, + + // double @ + `francois@@etu.inp-n7.fr`, + // do not support quotes + `"email"@domain.com`, + `"e asdf sadf ?<>ail"@domain.com`, + `" "@example.org`, + `"john..doe"@example.org`, + `"very.(),:;<>[]\".VERY.\"very@\\ \"very\".unusual"@strange.example.com`, + // do not support comma + `a,b@domain.com`, + + // do not support IPv4 + `email@123.123.123.123`, + `email@[123.123.123.123]`, + `postmaster@123.123.123.123`, + `user@[68.185.127.196]`, + `ipv4@[85.129.96.247]`, + `valid@[79.208.229.53]`, + `valid@[255.255.255.255]`, + `valid@[255.0.55.2]`, + `valid@[255.0.55.2]`, + + // do not support ipv6 + `hgrebert0@[IPv6:4dc8:ac7:ce79:8878:1290:6098:5c50:1f25]`, + `bshapiro4@[IPv6:3669:c709:e981:4884:59a3:75d1:166b:9ae]`, + `jsmith@[IPv6:2001:db8::1]`, + `postmaster@[IPv6:2001:0db8:85a3:0000:0000:8a2e:0370:7334]`, + `postmaster@[IPv6:2001:0db8:85a3:0000:0000:8a2e:0370:192.168.1.1]`, + + // microsoft test cases + `plainaddress`, + `#@%^%#$@#$@#.com`, + `@domain.com`, + `Joe Smith <email@domain.com>`, + `email.domain.com`, + `email@domain@domain.com`, + `.email@domain.com`, + `email.@domain.com`, + `email..email@domain.com`, + `あいうえお@domain.com`, + `email@domain.com (Joe Smith)`, + `email@domain`, + `email@-domain.com`, + `email@111.222.333.44444`, + `email@domain..com`, + `Abc.example.com`, + `A@b@c@example.com`, + `colin..hacks@domain.com`, + `a"b(c)d,e:f;gi[j\k]l@example.com`, + `just"not"right@example.com`, + `this is"not\allowed@example.com`, + `this\ still\"not\\allowed@example.com`, + + // random + `i_like_underscore@but_its_not_allowed_in_this_part.example.com`, + `QA[icon]CHOCOLATE[icon]@test.com`, + `invalid@-start.com`, + `invalid@end.com-`, + `a.b@c.d`, + `invalid@[1.1.1.-1]`, + `invalid@[68.185.127.196.55]`, + `temp@[192.168.1]`, + `temp@[9.18.122.]`, + `double..point@test.com`, + `asdad@test..com`, + `asdad@hghg...sd...au`, + `asdad@hghg........au`, + `invalid@[256.2.2.48]`, + `invalid@[256.2.2.48]`, + `invalid@[999.465.265.1]`, + `jkibbey4@[IPv6:82c4:19a8::70a9:2aac:557::ea69:d985:28d]`, + `mlivesay3@[9952:143f:b4df:2179:49a1:5e82:b92e:6b6]`, + `gbacher0@[IPv6:bc37:4d3f:5048:2e26:37cc:248e:df8e:2f7f:af]`, + `invalid@[IPv6:5348:4ed3:5d38:67fb:e9b:acd2:c13:192.168.256.1]`, + `test@.com`, + `aaaaaaaaaaaaaaalongemailthatcausesregexDoSvulnerability@test.c`, + ]; + const emailSchema = z.string().email(); + + expect( + validEmails.every((email) => { + return emailSchema.safeParse(email).success; + }) + ).toBe(true); + expect( + invalidEmails.every((email) => { + return emailSchema.safeParse(email).success === false; + }) + ).toBe(true); +}); + +const validBase64Strings = [ + "SGVsbG8gV29ybGQ=", // "Hello World" + "VGhpcyBpcyBhbiBlbmNvZGVkIHN0cmluZw==", // "This is an encoded string" + "TWFueSBoYW5kcyBtYWtlIGxpZ2h0IHdvcms=", // "Many hands make light work" + "UGF0aWVuY2UgaXMgdGhlIGtleSB0byBzdWNjZXNz", // "Patience is the key to success" + "QmFzZTY0IGVuY29kaW5nIGlzIGZ1bg==", // "Base64 encoding is fun" + "MTIzNDU2Nzg5MA==", // "1234567890" + "YWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXo=", // "abcdefghijklmnopqrstuvwxyz" + "QUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVo=", // "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + "ISIkJSMmJyonKCk=", // "!\"#$%&'()*" + "", // Empty string is technically valid base64 + "w7/Dv8O+w74K", // ÿÿþþ +]; + +for (const str of validBase64Strings) { + test(`base64 should accept ${str}`, () => { + expect(z.string().base64().safeParse(str).success).toBe(true); + }); +} + +const invalidBase64Strings = [ + "12345", // Not padded correctly, not a multiple of 4 characters + "12345===", // Not padded correctly + "SGVsbG8gV29ybGQ", // Missing padding + "VGhpcyBpcyBhbiBlbmNvZGVkIHN0cmluZw", // Missing padding + "!UGF0aWVuY2UgaXMgdGhlIGtleSB0byBzdWNjZXNz", // Invalid character '!' + "?QmFzZTY0IGVuY29kaW5nIGlzIGZ1bg==", // Invalid character '?' + ".MTIzND2Nzg5MC4=", // Invalid character '.' + "QUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVo", // Missing padding + "w7_Dv8O-w74K", // Has - and _ characters (is base64url) +]; + +for (const str of invalidBase64Strings) { + test(`base64 should reject ${str}`, () => { + expect(z.string().base64().safeParse(str).success).toBe(false); + }); +} + +const validBase64URLStrings = [ + "SGVsbG8gV29ybGQ", // "Hello World" + "SGVsbG8gV29ybGQ=", // "Hello World" with padding + "VGhpcyBpcyBhbiBlbmNvZGVkIHN0cmluZw", // "This is an encoded string" + "VGhpcyBpcyBhbiBlbmNvZGVkIHN0cmluZw==", // "This is an encoded string" with padding + "TWFueSBoYW5kcyBtYWtlIGxpZ2h0IHdvcms", // "Many hands make light work" + "TWFueSBoYW5kcyBtYWtlIGxpZ2h0IHdvcms=", // "Many hands make light work" with padding + "UGF0aWVuY2UgaXMgdGhlIGtleSB0byBzdWNjZXNz", // "Patience is the key to success" + "QmFzZTY0IGVuY29kaW5nIGlzIGZ1bg", // "Base64 encoding is fun" + "QmFzZTY0IGVuY29kaW5nIGlzIGZ1bg==", // "Base64 encoding is fun" with padding + "MTIzNDU2Nzg5MA", // "1234567890" + "MTIzNDU2Nzg5MA==", // "1234567890" with padding + "YWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXo", // "abcdefghijklmnopqrstuvwxyz" + "YWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXo=", // "abcdefghijklmnopqrstuvwxyz with padding" + "QUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVo", // "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + "QUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVo=", // "ABCDEFGHIJKLMNOPQRSTUVWXYZ" with padding + "ISIkJSMmJyonKCk", // "!\"#$%&'()*" + "ISIkJSMmJyonKCk=", // "!\"#$%&'()*" with padding + "", // Empty string is technically valid base64url + "w7_Dv8O-w74K", // ÿÿþþ + "123456", +]; + +for (const str of validBase64URLStrings) { + test(`base64url should accept ${str}`, () => { + expect(z.string().base64url().safeParse(str).success).toBe(true); + }); +} + +const invalidBase64URLStrings = [ + "w7/Dv8O+w74K", // Has + and / characters (is base64) + "12345", // Invalid length (not a multiple of 4 characters when adding allowed number of padding characters) + "12345===", // Not padded correctly + "!UGF0aWVuY2UgaXMgdGhlIGtleSB0byBzdWNjZXNz", // Invalid character '!' + "?QmFzZTY0IGVuY29kaW5nIGlzIGZ1bg==", // Invalid character '?' + ".MTIzND2Nzg5MC4=", // Invalid character '.' +]; + +for (const str of invalidBase64URLStrings) { + test(`base64url should reject ${str}`, () => { + expect(z.string().base64url().safeParse(str).success).toBe(false); + }); +} + +function makeJwt(header: object, payload: object) { + const headerBase64 = Buffer.from(JSON.stringify(header)).toString("base64url"); + const payloadBase64 = Buffer.from(JSON.stringify(payload)).toString("base64url"); + const signature = "signature"; // Placeholder for the signature + return `${headerBase64}.${payloadBase64}.${signature}`; +} + +test("jwt validations", () => { + const jwt = z.string().jwt(); + const jwtWithAlg = z.string().jwt({ alg: "HS256" }); + + expect(() => jwt.parse("invalid")).toThrow(); + expect(() => jwt.parse("invalid.invalid")).toThrow(); + expect(() => jwt.parse("invalid.invalid.invalid")).toThrow(); + + // Valid JWTs + const d1 = makeJwt({ typ: "JWT", alg: "HS256" }, {}); + expect(() => jwt.parse(d1)).not.toThrow(); + expect(() => jwtWithAlg.parse(d1)).not.toThrow(); + + // Invalid header + const d2 = makeJwt({}, {}); + expect(() => jwt.parse(d2)).toThrow(); + + // Wrong algorithm + const d3 = makeJwt({ typ: "JWT", alg: "RS256" }, {}); + expect(() => jwtWithAlg.parse(d3)).toThrow(); + + // missing typ is fine + const d4 = makeJwt({ alg: "HS256" }, {}); + jwt.parse(d4); + + // type isn't JWT + const d5 = makeJwt({ typ: "SUP", alg: "HS256" }, { foo: "bar" }); + expect(() => jwt.parse(d5)).toThrow(); + + // Custom error message + const customMsg = "Invalid JWT token"; + const jwtWithMsg = z.string().jwt({ message: customMsg }); + try { + jwtWithMsg.parse("invalid"); + } catch (error) { + expect((error as z.ZodError).issues[0].message).toBe(customMsg); + } +}); + +test("url validations", () => { + const url = z.string().url(); + url.parse("http://google.com"); + url.parse("https://google.com/asdf?asdf=ljk3lk4&asdf=234#asdf"); + expect(() => url.parse("asdf")).toThrow(); + expect(() => url.parse("https:/")).toThrow(); + expect(() => url.parse("asdfj@lkjsdf.com")).toThrow(); +}); + +test("url error overrides", () => { + try { + z.string().url().parse("https"); + } catch (err) { + expect((err as z.ZodError).issues[0].message).toEqual("Invalid url"); + } + try { + z.string().url("badurl").parse("https"); + } catch (err) { + expect((err as z.ZodError).issues[0].message).toEqual("badurl"); + } + try { + z.string().url({ message: "badurl" }).parse("https"); + } catch (err) { + expect((err as z.ZodError).issues[0].message).toEqual("badurl"); + } +}); + +test("emoji validations", () => { + const emoji = z.string().emoji(); + + emoji.parse("👋👋👋👋"); + emoji.parse("🍺👩‍🚀🫡"); + emoji.parse("💚💙💜💛❤️"); + emoji.parse("🐛🗝🐏🍡🎦🚢🏨💫🎌☘🗡😹🔒🎬➡️🍹🗂🚨⚜🕑〽️🚦🌊🍴💍🍌💰😳🌺🍃"); + emoji.parse("🇹🇷🤽🏿‍♂️"); + emoji.parse( + "😀😁😂🤣😃😄😅😆😉😊😋😎😍😘🥰😗😙😚☺️☺🙂🤗🤩🤔🤨😐😑😶🙄😏😣😥😮🤐😯😪😫😴😌😛😜😝🤤😒😓😔😕🙃🤑😲☹️☹🙁😖😞😟😤😢😭😦😧😨😩🤯😬😰😱🥵🥶😳🤪😵😡😠🤬😷🤒🤕🤢🤮🤧😇🤠🥳🥴🥺🤥🤫🤭🧐🤓😈👿🤡👹👺💀☠️☠👻👽👾🤖💩😺😸😹😻😼😽🙀😿😾🙈🙉🙊🏻🏼🏽🏾🏿👶👶🏻👶🏼👶🏽👶🏾👶🏿🧒🧒🏻🧒🏼🧒🏽🧒🏾🧒🏿👦👦🏻👦🏼👦🏽👦🏾👦🏿👧👧🏻👧🏼👧🏽👧🏾👧🏿🧑🧑🏻🧑🏼🧑🏽🧑🏾🧑🏿👨👨🏻👨🏼👨🏽👨🏾👨🏿👩👩🏻👩🏼👩🏽👩🏾👩🏿🧓🧓🏻🧓🏼🧓🏽🧓🏾🧓🏿👴👴🏻👴🏼👴🏽👴🏾👴🏿👵👵🏻👵🏼👵🏽👵🏾👵🏿👨‍⚕️👨‍⚕👨🏻‍⚕️👨🏻‍⚕👨🏼‍⚕️👨🏼‍⚕👨🏽‍⚕️👨🏽‍⚕👨🏾‍⚕️👨🏾‍⚕👨🏿‍⚕️👨🏿‍⚕👩‍⚕️👩‍⚕👩🏻‍⚕️👩🏻‍⚕👩🏼‍⚕️👩🏼‍⚕👩🏽‍⚕️👩🏽‍⚕👩🏾‍⚕️👩🏾‍⚕👩🏿‍⚕️👩🏿‍⚕👨‍🎓👨🏻‍🎓👨🏼‍🎓👨🏽‍🎓👨🏾‍🎓👨🏿‍🎓👩‍🎓👩🏻‍🎓👩🏼‍🎓👩🏽‍🎓👩🏾‍🎓👩🏿‍🎓👨‍🏫👨🏻‍🏫👨🏼‍🏫👨🏽‍🏫👨🏾‍🏫👨🏿‍🏫👩‍🏫👩🏻‍🏫👩🏼‍🏫👩🏽‍🏫👩🏾‍🏫👩🏿‍🏫👨‍⚖️👨‍⚖👨🏻‍⚖️👨🏻‍⚖👨🏼‍⚖️👨🏼‍⚖👨🏽‍⚖️👨🏽‍⚖👨🏾‍⚖️👨🏾‍⚖👨🏿‍⚖️👨🏿‍⚖👩‍⚖️👩‍⚖👩🏻‍⚖️👩🏻‍⚖👩🏼‍⚖️👩🏼‍⚖👩🏽‍⚖️👩🏽‍⚖👩🏾‍⚖️👩🏾‍⚖👩🏿‍⚖️👩🏿‍⚖👨‍🌾👨🏻‍🌾👨🏼‍🌾👨🏽‍🌾👨🏾‍🌾👨🏿‍🌾👩‍🌾👩🏻‍🌾👩🏼‍🌾👩🏽‍🌾👩🏾‍🌾👩🏿‍🌾👨‍🍳👨🏻‍🍳👨🏼‍🍳👨🏽‍🍳👨🏾‍🍳👨🏿‍🍳👩‍🍳👩🏻‍🍳👩🏼‍🍳👩🏽‍🍳👩🏾‍🍳👩🏿‍🍳👨‍🔧👨🏻‍🔧👨🏼‍🔧👨🏽‍🔧👨🏾‍🔧👨🏿‍🔧👩‍🔧👩🏻‍🔧👩🏼‍🔧👩🏽‍🔧👩🏾‍🔧👩🏿‍🔧👨‍🏭👨🏻‍🏭👨🏼‍🏭👨🏽‍🏭👨🏾‍🏭👨🏿‍🏭👩‍🏭👩🏻‍🏭👩🏼‍🏭👩🏽‍🏭👩🏾‍🏭👩🏿‍🏭👨‍💼👨🏻‍💼👨🏼‍💼👨🏽‍💼👨🏾‍💼👨🏿‍💼👩‍💼👩🏻‍💼👩🏼‍💼👩🏽‍💼👩🏾‍💼👩🏿‍💼👨‍🔬👨🏻‍🔬👨🏼‍🔬👨🏽‍🔬👨🏾‍🔬👨🏿‍🔬👩‍🔬👩🏻‍🔬👩🏼‍🔬👩🏽‍🔬👩🏾‍🔬👩🏿‍🔬👨‍💻👨🏻‍💻👨🏼‍💻👨🏽‍💻👨🏾‍💻👨🏿‍💻👩‍💻👩🏻‍💻👩🏼‍💻👩🏽‍💻👩🏾‍💻👩🏿‍💻👨‍🎤👨🏻‍🎤👨🏼‍🎤👨🏽‍🎤👨🏾‍🎤👨🏿‍🎤👩‍🎤👩🏻‍🎤👩🏼‍🎤👩🏽‍🎤👩🏾‍🎤👩🏿‍🎤👨‍🎨👨🏻‍🎨👨🏼‍🎨👨🏽‍🎨👨🏾‍🎨👨🏿‍🎨👩‍🎨👩🏻‍🎨👩🏼‍🎨👩🏽‍🎨👩🏾‍🎨👩🏿‍🎨👨‍✈️👨‍✈👨🏻‍✈️👨🏻‍✈👨🏼‍✈️👨🏼‍✈👨🏽‍✈️👨🏽‍✈👨🏾‍✈️👨🏾‍✈👨🏿‍✈️👨🏿‍✈👩‍✈️👩‍✈👩🏻‍✈️👩🏻‍✈👩🏼‍✈️👩🏼‍✈👩🏽‍✈️👩🏽‍✈👩🏾‍✈️👩🏾‍✈👩🏿‍✈️👩🏿‍✈👨‍🚀👨🏻‍🚀👨🏼‍🚀👨🏽‍🚀👨🏾‍🚀👨🏿‍🚀👩‍🚀👩🏻‍🚀👩🏼‍🚀👩🏽‍🚀👩🏾‍🚀👩🏿‍🚀👨‍🚒👨🏻‍🚒👨🏼‍🚒👨🏽‍🚒👨🏾‍🚒👨🏿‍🚒👩‍🚒👩🏻‍🚒👩🏼‍🚒👩🏽‍🚒👩🏾‍🚒👩🏿‍🚒👮👮🏻👮🏼👮🏽👮🏾👮🏿👮‍♂️👮‍♂👮🏻‍♂️👮🏻‍♂👮🏼‍♂️👮🏼‍♂👮🏽‍♂️👮🏽‍♂👮🏾‍♂️👮🏾‍♂👮🏿‍♂️👮🏿‍♂👮‍♀️👮‍♀👮🏻‍♀️👮🏻‍♀👮🏼‍♀️👮🏼‍♀👮🏽‍♀️👮🏽‍♀👮🏾‍♀️👮🏾‍♀👮🏿‍♀️👮🏿‍♀🕵️🕵🕵🏻🕵🏼🕵🏽🕵🏾🕵🏿🕵️‍♂️🕵‍♂️🕵️‍♂🕵‍♂🕵🏻‍♂️🕵🏻‍♂🕵🏼‍♂️🕵🏼‍♂🕵🏽‍♂️🕵🏽‍♂🕵🏾‍♂️🕵🏾‍♂🕵🏿‍♂️🕵🏿‍♂🕵️‍♀️🕵‍♀️🕵️‍♀🕵‍♀🕵🏻‍♀️🕵🏻‍♀🕵🏼‍♀️🕵🏼‍♀🕵🏽‍♀️🕵🏽‍♀🕵🏾‍♀️🕵🏾‍♀🕵🏿‍♀️🕵🏿‍♀💂💂🏻💂🏼💂🏽💂🏾💂🏿💂‍♂️💂‍♂💂🏻‍♂️💂🏻‍♂💂🏼‍♂️💂🏼‍♂💂🏽‍♂️💂🏽‍♂💂🏾‍♂️💂🏾‍♂💂🏿‍♂️💂🏿‍♂💂‍♀️💂‍♀💂🏻‍♀️💂🏻‍♀💂🏼‍♀️💂🏼‍♀💂🏽‍♀️💂🏽‍♀💂🏾‍♀️💂🏾‍♀💂🏿‍♀️💂🏿‍♀👷👷🏻👷🏼👷🏽👷🏾👷🏿👷‍♂️👷‍♂👷🏻‍♂️👷🏻‍♂👷🏼‍♂️👷🏼‍♂👷🏽‍♂️👷🏽‍♂👷🏾‍♂️👷🏾‍♂👷🏿‍♂️👷🏿‍♂👷‍♀️👷‍♀👷🏻‍♀️👷🏻‍♀👷🏼‍♀️👷🏼‍♀👷🏽‍♀️👷🏽‍♀👷🏾‍♀️👷🏾‍♀👷🏿‍♀️👷🏿‍♀🤴🤴🏻🤴🏼🤴🏽🤴🏾🤴🏿👸👸🏻👸🏼👸🏽👸🏾👸🏿👳👳🏻👳🏼👳🏽👳🏾👳🏿👳‍♂️👳‍♂👳🏻‍♂️👳🏻‍♂👳🏼‍♂️👳🏼‍♂👳🏽‍♂️👳🏽‍♂👳🏾‍♂️👳🏾‍♂👳🏿‍♂️👳🏿‍♂👳‍♀️👳‍♀👳🏻‍♀️👳🏻‍♀👳🏼‍♀️👳🏼‍♀👳🏽‍♀️👳🏽‍♀👳🏾‍♀️👳🏾‍♀👳🏿‍♀️👳🏿‍♀👲👲🏻👲🏼👲🏽👲🏾👲🏿🧕🧕🏻🧕🏼🧕🏽🧕🏾🧕🏿🧔🧔🏻🧔🏼🧔🏽🧔🏾🧔🏿👱👱🏻👱🏼👱🏽👱🏾👱🏿👱‍♂️👱‍♂👱🏻‍♂️👱🏻‍♂👱🏼‍♂️👱🏼‍♂👱🏽‍♂️👱🏽‍♂👱🏾‍♂️👱🏾‍♂👱🏿‍♂️👱🏿‍♂👱‍♀️👱‍♀👱🏻‍♀️👱🏻‍♀👱🏼‍♀️👱🏼‍♀👱🏽‍♀️👱🏽‍♀👱🏾‍♀️👱🏾‍♀👱🏿‍♀️👱🏿‍♀👨‍🦰👨🏻‍🦰👨🏼‍🦰👨🏽‍🦰👨🏾‍🦰👨🏿‍🦰👩‍🦰👩🏻‍🦰👩🏼‍🦰👩🏽‍🦰👩🏾‍🦰👩🏿‍🦰👨‍🦱👨🏻‍🦱👨🏼‍🦱👨🏽‍🦱👨🏾‍🦱👨🏿‍🦱👩‍🦱👩🏻‍🦱👩🏼‍🦱👩🏽‍🦱👩🏾‍🦱👩🏿‍🦱👨‍🦲👨🏻‍🦲👨🏼‍🦲👨🏽‍🦲👨🏾‍🦲👨🏿‍🦲👩‍🦲👩🏻‍🦲👩🏼‍🦲👩🏽‍🦲👩🏾‍🦲👩🏿‍🦲👨‍🦳👨🏻‍🦳👨🏼‍🦳👨🏽‍🦳👨🏾‍🦳👨🏿‍🦳👩‍🦳👩🏻‍🦳👩🏼‍🦳👩🏽‍🦳👩🏾‍🦳👩🏿‍🦳🤵🤵🏻🤵🏼🤵🏽🤵🏾🤵🏿👰👰🏻👰🏼👰🏽👰🏾👰🏿🤰🤰🏻🤰🏼🤰🏽🤰🏾🤰🏿🤱🤱🏻🤱🏼🤱🏽🤱🏾🤱🏿👼👼🏻👼🏼👼🏽👼🏾👼🏿🎅🎅🏻🎅🏼🎅🏽🎅🏾🎅🏿🤶🤶🏻🤶🏼🤶🏽🤶🏾🤶🏿🦸🦸🏻🦸🏼🦸🏽🦸🏾🦸🏿🦸‍♀️🦸‍♀🦸🏻‍♀️🦸🏻‍♀🦸🏼‍♀️🦸🏼‍♀🦸🏽‍♀️🦸🏽‍♀🦸🏾‍♀️🦸🏾‍♀🦸🏿‍♀️🦸🏿‍♀🦸‍♂️🦸‍♂🦸🏻‍♂️🦸🏻‍♂🦸🏼‍♂️🦸🏼‍♂🦸🏽‍♂️🦸🏽‍♂🦸🏾‍♂️🦸🏾‍♂🦸🏿‍♂️🦸🏿‍♂🦹🦹🏻🦹🏼🦹🏽🦹🏾🦹🏿🦹‍♀️🦹‍♀🦹🏻‍♀️🦹🏻‍♀🦹🏼‍♀️🦹🏼‍♀🦹🏽‍♀️🦹🏽‍♀🦹🏾‍♀️🦹🏾‍♀🦹🏿‍♀️🦹🏿‍♀🦹‍♂️🦹‍♂🦹🏻‍♂️🦹🏻‍♂🦹🏼‍♂️🦹🏼‍♂🦹🏽‍♂️🦹🏽‍♂🦹🏾‍♂️🦹🏾‍♂🦹🏿‍♂️🦹🏿‍♂🧙🧙🏻🧙🏼🧙🏽🧙🏾🧙🏿🧙‍♀️🧙‍♀🧙🏻‍♀️🧙🏻‍♀🧙🏼‍♀️🧙🏼‍♀🧙🏽‍♀️🧙🏽‍♀🧙🏾‍♀️🧙🏾‍♀🧙🏿‍♀️🧙🏿‍♀🧙‍♂️🧙‍♂🧙🏻‍♂️🧙🏻‍♂🧙🏼‍♂️🧙🏼‍♂🧙🏽‍♂️🧙🏽‍♂🧙🏾‍♂️🧙🏾‍♂🧙🏿‍♂️🧙🏿‍♂🧚🧚🏻🧚🏼🧚🏽🧚🏾🧚🏿🧚‍♀️🧚‍♀🧚🏻‍♀️🧚🏻‍♀🧚🏼‍♀️🧚🏼‍♀🧚🏽‍♀️🧚🏽‍♀🧚🏾‍♀️🧚🏾‍♀🧚🏿‍♀️🧚🏿‍♀🧚‍♂️🧚‍♂🧚🏻‍♂️🧚🏻‍♂🧚🏼‍♂️🧚🏼‍♂🧚🏽‍♂️🧚🏽‍♂🧚🏾‍♂️🧚🏾‍♂🧚🏿‍♂️🧚🏿‍♂🧛🧛🏻🧛🏼🧛🏽🧛🏾🧛🏿🧛‍♀️🧛‍♀🧛🏻‍♀️🧛🏻‍♀🧛🏼‍♀️🧛🏼‍♀🧛🏽‍♀️🧛🏽‍♀🧛🏾‍♀️🧛🏾‍♀🧛🏿‍♀️🧛🏿‍♀🧛‍♂️🧛‍♂🧛🏻‍♂️🧛🏻‍♂🧛🏼‍♂️🧛🏼‍♂🧛🏽‍♂️🧛🏽‍♂🧛🏾‍♂️🧛🏾‍♂🧛🏿‍♂️🧛🏿‍♂🧜🧜🏻🧜🏼🧜🏽🧜🏾🧜🏿🧜‍♀️🧜‍♀🧜🏻‍♀️🧜🏻‍♀🧜🏼‍♀️🧜🏼‍♀🧜🏽‍♀️🧜🏽‍♀🧜🏾‍♀️🧜🏾‍♀🧜🏿‍♀️🧜🏿‍♀🧜‍♂️🧜‍♂🧜🏻‍♂️🧜🏻‍♂🧜🏼‍♂️🧜🏼‍♂🧜🏽‍♂️🧜🏽‍♂🧜🏾‍♂️🧜🏾‍♂🧜🏿‍♂️🧜🏿‍♂🧝🧝🏻🧝🏼🧝🏽🧝🏾🧝🏿🧝‍♀️🧝‍♀🧝🏻‍♀️🧝🏻‍♀🧝🏼‍♀️🧝🏼‍♀🧝🏽‍♀️🧝🏽‍♀🧝🏾‍♀️🧝🏾‍♀🧝🏿‍♀️🧝🏿‍♀🧝‍♂️🧝‍♂🧝🏻‍♂️🧝🏻‍♂🧝🏼‍♂️🧝🏼‍♂🧝🏽‍♂️🧝🏽‍♂🧝🏾‍♂️🧝🏾‍♂🧝🏿‍♂️🧝🏿‍♂🧞🧞‍♀️🧞‍♀🧞‍♂️🧞‍♂🧟🧟‍♀️🧟‍♀🧟‍♂️🧟‍♂🙍🙍🏻🙍🏼🙍🏽🙍🏾🙍🏿🙍‍♂️🙍‍♂🙍🏻‍♂️🙍🏻‍♂🙍🏼‍♂️🙍🏼‍♂🙍🏽‍♂️🙍🏽‍♂🙍🏾‍♂️🙍🏾‍♂🙍🏿‍♂️🙍🏿‍♂🙍‍♀️🙍‍♀🙍🏻‍♀️🙍🏻‍♀🙍🏼‍♀️🙍🏼‍♀🙍🏽‍♀️🙍🏽‍♀🙍🏾‍♀️🙍🏾‍♀🙍🏿‍♀️🙍🏿‍♀🙎🙎🏻🙎🏼🙎🏽🙎🏾🙎🏿🙎‍♂️🙎‍♂🙎🏻‍♂️🙎🏻‍♂🙎🏼‍♂️🙎🏼‍♂🙎🏽‍♂️🙎🏽‍♂🙎🏾‍♂️🙎🏾‍♂🙎🏿‍♂️🙎🏿‍♂🙎‍♀️🙎‍♀🙎🏻‍♀️🙎🏻‍♀🙎🏼‍♀️🙎🏼‍♀🙎🏽‍♀️🙎🏽‍♀🙎🏾‍♀️🙎🏾‍♀🙎🏿‍♀️🙎🏿‍♀🙅🙅🏻🙅🏼🙅🏽🙅🏾🙅🏿🙅‍♂️🙅‍♂🙅🏻‍♂️🙅🏻‍♂🙅🏼‍♂️🙅🏼‍♂🙅🏽‍♂️🙅🏽‍♂🙅🏾‍♂️🙅🏾‍♂🙅🏿‍♂️🙅🏿‍♂🙅‍♀️🙅‍♀🙅🏻‍♀️🙅🏻‍♀🙅🏼‍♀️🙅🏼‍♀🙅🏽‍♀️🙅🏽‍♀🙅🏾‍♀️🙅🏾‍♀🙅🏿‍♀️🙅🏿‍♀🙆🙆🏻🙆🏼🙆🏽🙆🏾🙆🏿🙆‍♂️🙆‍♂🙆🏻‍♂️🙆🏻‍♂🙆🏼‍♂️🙆🏼‍♂🙆🏽‍♂️🙆🏽‍♂🙆🏾‍♂️🙆🏾‍♂🙆🏿‍♂️🙆🏿‍♂🙆‍♀️🙆‍♀🙆🏻‍♀️🙆🏻‍♀🙆🏼‍♀️🙆🏼‍♀🙆🏽‍♀️🙆🏽‍♀🙆🏾‍♀️🙆🏾‍♀🙆🏿‍♀️🙆🏿‍♀💁💁🏻💁🏼💁🏽💁🏾💁🏿💁‍♂️💁‍♂💁🏻‍♂️💁🏻‍♂💁🏼‍♂️💁🏼‍♂💁🏽‍♂️💁🏽‍♂💁🏾‍♂️💁🏾‍♂💁🏿‍♂️💁🏿‍♂💁‍♀️💁‍♀💁🏻‍♀️💁🏻‍♀💁🏼‍♀️💁🏼‍♀💁🏽‍♀️💁🏽‍♀💁🏾‍♀️💁🏾‍♀💁🏿‍♀️💁🏿‍♀🙋🙋🏻🙋🏼🙋🏽🙋🏾🙋🏿🙋‍♂️🙋‍♂🙋🏻‍♂️🙋🏻‍♂🙋🏼‍♂️🙋🏼‍♂🙋🏽‍♂️🙋🏽‍♂🙋🏾‍♂️🙋🏾‍♂🙋🏿‍♂️🙋🏿‍♂🙋‍♀️🙋‍♀🙋🏻‍♀️🙋🏻‍♀🙋🏼‍♀️🙋🏼‍♀🙋🏽‍♀️🙋🏽‍♀🙋🏾‍♀️🙋🏾‍♀🙋🏿‍♀️🙋🏿‍♀🙇🙇🏻🙇🏼🙇🏽🙇🏾🙇🏿🙇‍♂️🙇‍♂🙇🏻‍♂️🙇🏻‍♂🙇🏼‍♂️🙇🏼‍♂🙇🏽‍♂️🙇🏽‍♂🙇🏾‍♂️🙇🏾‍♂🙇🏿‍♂️🙇🏿‍♂🙇‍♀️🙇‍♀🙇🏻‍♀️🙇🏻‍♀🙇🏼‍♀️🙇🏼‍♀🙇🏽‍♀️🙇🏽‍♀🙇🏾‍♀️🙇🏾‍♀🙇🏿‍♀️🙇🏿‍♀🤦🤦🏻🤦🏼🤦🏽🤦🏾🤦🏿🤦‍♂️🤦‍♂🤦🏻‍♂️🤦🏻‍♂🤦🏼‍♂️🤦🏼‍♂🤦🏽‍♂️🤦🏽‍♂🤦🏾‍♂️🤦🏾‍♂🤦🏿‍♂️🤦🏿‍♂🤦‍♀️🤦‍♀🤦🏻‍♀️🤦🏻‍♀🤦🏼‍♀️🤦🏼‍♀🤦🏽‍♀️🤦🏽‍♀🤦🏾‍♀️🤦🏾‍♀🤦🏿‍♀️🤦🏿‍♀🤷🤷🏻🤷🏼🤷🏽🤷🏾🤷🏿🤷‍♂️🤷‍♂🤷🏻‍♂️🤷🏻‍♂🤷🏼‍♂️🤷🏼‍♂🤷🏽‍♂️🤷🏽‍♂🤷🏾‍♂️🤷🏾‍♂🤷🏿‍♂️🤷🏿‍♂🤷‍♀️🤷‍♀🤷🏻‍♀️🤷🏻‍♀🤷🏼‍♀️🤷🏼‍♀🤷🏽‍♀️🤷🏽‍♀🤷🏾‍♀️🤷🏾‍♀🤷🏿‍♀️🤷🏿‍♀💆💆🏻💆🏼💆🏽💆🏾💆🏿💆‍♂️💆‍♂💆🏻‍♂️💆🏻‍♂💆🏼‍♂️💆🏼‍♂💆🏽‍♂️💆🏽‍♂💆🏾‍♂️💆🏾‍♂💆🏿‍♂️💆🏿‍♂💆‍♀️💆‍♀💆🏻‍♀️💆🏻‍♀💆🏼‍♀️💆🏼‍♀💆🏽‍♀️💆🏽‍♀💆🏾‍♀️💆🏾‍♀💆🏿‍♀️💆🏿‍♀💇💇🏻💇🏼💇🏽💇🏾💇🏿💇‍♂️💇‍♂💇🏻‍♂️💇🏻‍♂💇🏼‍♂️💇🏼‍♂💇🏽‍♂️💇🏽‍♂💇🏾‍♂️💇🏾‍♂💇🏿‍♂️💇🏿‍♂💇‍♀️💇‍♀💇🏻‍♀️💇🏻‍♀💇🏼‍♀️💇🏼‍♀💇🏽‍♀️💇🏽‍♀💇🏾‍♀️💇🏾‍♀💇🏿‍♀️💇🏿‍♀🚶🚶🏻🚶🏼🚶🏽🚶🏾🚶🏿🚶‍♂️🚶‍♂🚶🏻‍♂️🚶🏻‍♂🚶🏼‍♂️🚶🏼‍♂🚶🏽‍♂️🚶🏽‍♂🚶🏾‍♂️🚶🏾‍♂🚶🏿‍♂️🚶🏿‍♂🚶‍♀️🚶‍♀🚶🏻‍♀️🚶🏻‍♀🚶🏼‍♀️🚶🏼‍♀🚶🏽‍♀️🚶🏽‍♀🚶🏾‍♀️🚶🏾‍♀🚶🏿‍♀️🚶🏿‍♀🏃🏃🏻🏃🏼🏃🏽🏃🏾🏃🏿🏃‍♂️🏃‍♂🏃🏻‍♂️🏃🏻‍♂🏃🏼‍♂️🏃🏼‍♂🏃🏽‍♂️🏃🏽‍♂🏃🏾‍♂️🏃🏾‍♂🏃🏿‍♂️🏃🏿‍♂🏃‍♀️🏃‍♀🏃🏻‍♀️🏃🏻‍♀🏃🏼‍♀️🏃🏼‍♀🏃🏽‍♀️🏃🏽‍♀🏃🏾‍♀️🏃🏾‍♀🏃🏿‍♀️🏃🏿‍♀💃💃🏻💃🏼💃🏽💃🏾💃🏿🕺🕺🏻🕺🏼🕺🏽🕺🏾🕺🏿👯👯‍♂️👯‍♂👯‍♀️👯‍♀🧖🧖🏻🧖🏼🧖🏽🧖🏾🧖🏿🧖‍♀️🧖‍♀🧖🏻‍♀️🧖🏻‍♀🧖🏼‍♀️🧖🏼‍♀🧖🏽‍♀️🧖🏽‍♀🧖🏾‍♀️🧖🏾‍♀🧖🏿‍♀️🧖🏿‍♀🧖‍♂️🧖‍♂🧖🏻‍♂️🧖🏻‍♂🧖🏼‍♂️🧖🏼‍♂🧖🏽‍♂️🧖🏽‍♂🧖🏾‍♂️🧖🏾‍♂🧖🏿‍♂️🧖🏿‍♂🧗🧗🏻🧗🏼🧗🏽🧗🏾🧗🏿🧗‍♀️🧗‍♀🧗🏻‍♀️🧗🏻‍♀🧗🏼‍♀️🧗🏼‍♀🧗🏽‍♀️🧗🏽‍♀🧗🏾‍♀️🧗🏾‍♀🧗🏿‍♀️🧗🏿‍♀🧗‍♂️🧗‍♂🧗🏻‍♂️🧗🏻‍♂🧗🏼‍♂️🧗🏼‍♂🧗🏽‍♂️🧗🏽‍♂🧗🏾‍♂️🧗🏾‍♂🧗🏿‍♂️🧗🏿‍♂🧘🧘🏻🧘🏼🧘🏽🧘🏾🧘🏿🧘‍♀️🧘‍♀🧘🏻‍♀️🧘🏻‍♀🧘🏼‍♀️🧘🏼‍♀🧘🏽‍♀️🧘🏽‍♀🧘🏾‍♀️🧘🏾‍♀🧘🏿‍♀️🧘🏿‍♀🧘‍♂️🧘‍♂🧘🏻‍♂️🧘🏻‍♂🧘🏼‍♂️🧘🏼‍♂🧘🏽‍♂️🧘🏽‍♂🧘🏾‍♂️🧘🏾‍♂🧘🏿‍♂️🧘🏿‍♂🛀🛀🏻🛀🏼🛀🏽🛀🏾🛀🏿🛌🛌🏻🛌🏼🛌🏽🛌🏾🛌🏿🕴️🕴🕴🏻🕴🏼🕴🏽🕴🏾🕴🏿🗣️🗣👤👥🤺🏇🏇🏻🏇🏼🏇🏽🏇🏾🏇🏿⛷️⛷🏂🏂🏻🏂🏼🏂🏽🏂🏾🏂🏿🏌️🏌🏌🏻🏌🏼🏌🏽🏌🏾🏌🏿🏌️‍♂️🏌‍♂️🏌️‍♂🏌‍♂🏌🏻‍♂️🏌🏻‍♂🏌🏼‍♂️🏌🏼‍♂🏌🏽‍♂️🏌🏽‍♂🏌🏾‍♂️🏌🏾‍♂🏌🏿‍♂️🏌🏿‍♂🏌️‍♀️🏌‍♀️🏌️‍♀🏌‍♀🏌🏻‍♀️🏌🏻‍♀🏌🏼‍♀️🏌🏼‍♀🏌🏽‍♀️🏌🏽‍♀🏌🏾‍♀️🏌🏾‍♀🏌🏿‍♀️🏌🏿‍♀🏄🏄🏻🏄🏼🏄🏽🏄🏾🏄🏿🏄‍♂️🏄‍♂🏄🏻‍♂️🏄🏻‍♂🏄🏼‍♂️🏄🏼‍♂🏄🏽‍♂️🏄🏽‍♂🏄🏾‍♂️🏄🏾‍♂🏄🏿‍♂️🏄🏿‍♂🏄‍♀️🏄‍♀🏄🏻‍♀️🏄🏻‍♀🏄🏼‍♀️🏄🏼‍♀🏄🏽‍♀️🏄🏽‍♀🏄🏾‍♀️🏄🏾‍♀🏄🏿‍♀️🏄🏿‍♀🚣🚣🏻🚣🏼🚣🏽🚣🏾🚣🏿🚣‍♂️🚣‍♂🚣🏻‍♂️🚣🏻‍♂🚣🏼‍♂️🚣🏼‍♂🚣🏽‍♂️🚣🏽‍♂🚣🏾‍♂️🚣🏾‍♂🚣🏿‍♂️🚣🏿‍♂🚣‍♀️🚣‍♀🚣🏻‍♀️🚣🏻‍♀🚣🏼‍♀️🚣🏼‍♀🚣🏽‍♀️🚣🏽‍♀🚣🏾‍♀️🚣🏾‍♀🚣🏿‍♀️🚣🏿‍♀🏊🏊🏻🏊🏼🏊🏽🏊🏾🏊🏿🏊‍♂️🏊‍♂🏊🏻‍♂️🏊🏻‍♂🏊🏼‍♂️🏊🏼‍♂🏊🏽‍♂️🏊🏽‍♂🏊🏾‍♂️🏊🏾‍♂🏊🏿‍♂️🏊🏿‍♂🏊‍♀️🏊‍♀🏊🏻‍♀️🏊🏻‍♀🏊🏼‍♀️🏊🏼‍♀🏊🏽‍♀️🏊🏽‍♀🏊🏾‍♀️🏊🏾‍♀🏊🏿‍♀️🏊🏿‍♀⛹️⛹⛹🏻⛹🏼⛹🏽⛹🏾⛹🏿⛹️‍♂️⛹‍♂️⛹️‍♂⛹‍♂⛹🏻‍♂️⛹🏻‍♂⛹🏼‍♂️⛹🏼‍♂⛹🏽‍♂️⛹🏽‍♂⛹🏾‍♂️⛹🏾‍♂⛹🏿‍♂️⛹🏿‍♂⛹️‍♀️⛹‍♀️⛹️‍♀⛹‍♀⛹🏻‍♀️⛹🏻‍♀⛹🏼‍♀️⛹🏼‍♀⛹🏽‍♀️⛹🏽‍♀⛹🏾‍♀️⛹🏾‍♀⛹🏿‍♀️⛹🏿‍♀🏋️🏋🏋🏻🏋🏼🏋🏽🏋🏾🏋🏿🏋️‍♂️🏋‍♂️🏋️‍♂🏋‍♂🏋🏻‍♂️🏋🏻‍♂🏋🏼‍♂️🏋🏼‍♂🏋🏽‍♂️🏋🏽‍♂🏋🏾‍♂️🏋🏾‍♂🏋🏿‍♂️🏋🏿‍♂🏋️‍♀️🏋‍♀️🏋️‍♀🏋‍♀🏋🏻‍♀️🏋🏻‍♀🏋🏼‍♀️🏋🏼‍♀🏋🏽‍♀️🏋🏽‍♀🏋🏾‍♀️🏋🏾‍♀🏋🏿‍♀️🏋🏿‍♀🚴🚴🏻🚴🏼🚴🏽🚴🏾🚴🏿🚴‍♂️🚴‍♂🚴🏻‍♂️🚴🏻‍♂🚴🏼‍♂️🚴🏼‍♂🚴🏽‍♂️🚴🏽‍♂🚴🏾‍♂️🚴🏾‍♂🚴🏿‍♂️🚴🏿‍♂🚴‍♀️🚴‍♀🚴🏻‍♀️🚴🏻‍♀🚴🏼‍♀️🚴🏼‍♀🚴🏽‍♀️🚴🏽‍♀🚴🏾‍♀️🚴🏾‍♀🚴🏿‍♀️🚴🏿‍♀🚵🚵🏻🚵🏼🚵🏽🚵🏾🚵🏿🚵‍♂️🚵‍♂🚵🏻‍♂️🚵🏻‍♂🚵🏼‍♂️🚵🏼‍♂🚵🏽‍♂️🚵🏽‍♂🚵🏾‍♂️🚵🏾‍♂🚵🏿‍♂️🚵🏿‍♂🚵‍♀️🚵‍♀🚵🏻‍♀️🚵🏻‍♀🚵🏼‍♀️🚵🏼‍♀🚵🏽‍♀️🚵🏽‍♀🚵🏾‍♀️🚵🏾‍♀🚵🏿‍♀️🚵🏿‍♀🏎️🏎🏍️🏍🤸🤸🏻🤸🏼🤸🏽🤸🏾🤸🏿🤸‍♂️🤸‍♂🤸🏻‍♂️🤸🏻‍♂🤸🏼‍♂️🤸🏼‍♂🤸🏽‍♂️🤸🏽‍♂🤸🏾‍♂️🤸🏾‍♂🤸🏿‍♂️🤸🏿‍♂🤸‍♀️🤸‍♀🤸🏻‍♀️🤸🏻‍♀🤸🏼‍♀️🤸🏼‍♀🤸🏽‍♀️🤸🏽‍♀🤸🏾‍♀️🤸🏾‍♀🤸🏿‍♀️🤸🏿‍♀🤼🤼‍♂️🤼‍♂🤼‍♀️🤼‍♀🤽🤽🏻🤽🏼🤽🏽🤽🏾🤽🏿🤽‍♂️🤽‍♂🤽🏻‍♂️🤽🏻‍♂🤽🏼‍♂️🤽🏼‍♂🤽🏽‍♂️🤽🏽‍♂🤽🏾‍♂️🤽🏾‍♂🤽🏿‍♂️🤽🏿‍♂🤽‍♀️🤽‍♀🤽🏻‍♀️🤽🏻‍♀🤽🏼‍♀️🤽🏼‍♀🤽🏽‍♀️🤽🏽‍♀🤽🏾‍♀️🤽🏾‍♀🤽🏿‍♀️🤽🏿‍♀🤾🤾🏻🤾🏼🤾🏽🤾🏾🤾🏿🤾‍♂️🤾‍♂🤾🏻‍♂️🤾🏻‍♂🤾🏼‍♂️🤾🏼‍♂🤾🏽‍♂️🤾🏽‍♂🤾🏾‍♂️🤾🏾‍♂🤾🏿‍♂️🤾🏿‍♂🤾‍♀️🤾‍♀🤾🏻‍♀️🤾🏻‍♀🤾🏼‍♀️🤾🏼‍♀🤾🏽‍♀️🤾🏽‍♀🤾🏾‍♀️🤾🏾‍♀🤾🏿‍♀️🤾🏿‍♀🤹🤹🏻🤹🏼🤹🏽🤹🏾🤹🏿🤹‍♂️🤹‍♂🤹🏻‍♂️🤹🏻‍♂🤹🏼‍♂️🤹🏼‍♂🤹🏽‍♂️🤹🏽‍♂🤹🏾‍♂️🤹🏾‍♂🤹🏿‍♂️🤹🏿‍♂🤹‍♀️🤹‍♀🤹🏻‍♀️🤹🏻‍♀🤹🏼‍♀️🤹🏼‍♀🤹🏽‍♀️🤹🏽‍♀🤹🏾‍♀️🤹🏾‍♀🤹🏿‍♀️🤹🏿‍♀👫👬👭💏👩‍❤️‍💋‍👨👩‍❤‍💋‍👨👨‍❤️‍💋‍👨👨‍❤‍💋‍👨👩‍❤️‍💋‍👩👩‍❤‍💋‍👩💑👩‍❤️‍👨👩‍❤‍👨👨‍❤️‍👨👨‍❤‍👨👩‍❤️‍👩👩‍❤‍👩👪👨‍👩‍👦👨‍👩‍👧👨‍👩‍👧‍👦👨‍👩‍👦‍👦👨‍👩‍👧‍👧👨‍👨‍👦👨‍👨‍👧👨‍👨‍👧‍👦👨‍👨‍👦‍👦👨‍👨‍👧‍👧👩‍👩‍👦👩‍👩‍👧👩‍👩‍👧‍👦👩‍👩‍👦‍👦👩‍👩‍👧‍👧👨‍👦👨‍👦‍👦👨‍👧👨‍👧‍👦👨‍👧‍👧👩‍👦👩‍👦‍👦👩‍👧👩‍👧‍👦👩‍👧‍👧🤳🤳🏻🤳🏼🤳🏽🤳🏾🤳🏿💪💪🏻💪🏼💪🏽💪🏾💪🏿🦵🦵🏻🦵🏼🦵🏽🦵🏾🦵🏿🦶🦶🏻🦶🏼🦶🏽🦶🏾🦶🏿👈👈🏻👈🏼👈🏽👈🏾👈🏿👉👉🏻👉🏼👉🏽👉🏾👉🏿☝️☝☝🏻☝🏼☝🏽☝🏾☝🏿👆👆🏻👆🏼👆🏽👆🏾👆🏿🖕🖕🏻🖕🏼🖕🏽🖕🏾🖕🏿👇👇🏻👇🏼👇🏽👇🏾👇🏿✌️✌✌🏻✌🏼✌🏽✌🏾✌🏿🤞🤞🏻🤞🏼🤞🏽🤞🏾🤞🏿🖖🖖🏻🖖🏼🖖🏽🖖🏾🖖🏿🤘🤘🏻🤘🏼🤘🏽🤘🏾🤘🏿🤙🤙🏻🤙🏼🤙🏽🤙🏾🤙🏿🖐️🖐🖐🏻🖐🏼🖐🏽🖐🏾🖐🏿✋✋🏻✋🏼✋🏽✋🏾✋🏿👌👌🏻👌🏼👌🏽👌🏾👌🏿👍👍🏻👍🏼👍🏽👍🏾👍🏿👎👎🏻👎🏼👎🏽👎🏾👎🏿✊✊🏻✊🏼✊🏽✊🏾✊🏿👊👊🏻👊🏼👊🏽👊🏾👊🏿🤛🤛🏻🤛🏼🤛🏽🤛🏾🤛🏿🤜🤜🏻🤜🏼🤜🏽🤜🏾🤜🏿🤚🤚🏻🤚🏼🤚🏽🤚🏾🤚🏿👋👋🏻👋🏼👋🏽👋🏾👋🏿🤟🤟🏻🤟🏼🤟🏽🤟🏾🤟🏿✍️✍✍🏻✍🏼✍🏽✍🏾✍🏿👏👏🏻👏🏼👏🏽👏🏾👏🏿👐👐🏻👐🏼👐🏽👐🏾👐🏿🙌🙌🏻🙌🏼🙌🏽🙌🏾🙌🏿🤲🤲🏻🤲🏼🤲🏽🤲🏾🤲🏿🙏🙏🏻🙏🏼🙏🏽🙏🏾🙏🏿🤝💅💅🏻💅🏼💅🏽💅🏾💅🏿👂👂🏻👂🏼👂🏽👂🏾👂🏿👃👃🏻👃🏼👃🏽👃🏾👃🏿🦰🦱🦲🦳👣👀👁️👁👁️‍🗨️👁‍🗨️👁️‍🗨👁‍🗨🧠🦴🦷👅👄💋💘❤️❤💓💔💕💖💗💙💚💛🧡💜🖤💝💞💟❣️❣💌💤💢💣💥💦💨💫💬🗨️🗨🗯️🗯💭🕳️🕳👓🕶️🕶🥽🥼👔👕👖🧣🧤🧥🧦👗👘👙👚👛👜👝🛍️🛍🎒👞👟🥾🥿👠👡👢👑👒🎩🎓🧢⛑️⛑📿💄💍💎🐵🐒🦍🐶🐕🐩🐺🦊🦝🐱🐈🦁🐯🐅🐆🐴🐎🦄🦓🦌🐮🐂🐃🐄🐷🐖🐗🐽🐏🐑🐐🐪🐫🦙🦒🐘🦏🦛🐭🐁🐀🐹🐰🐇🐿️🐿🦔🦇🐻🐨🐼🦘🦡🐾🦃🐔🐓🐣🐤🐥🐦🐧🕊️🕊🦅🦆🦢🦉🦚🦜🐸🐊🐢🦎🐍🐲🐉🦕🦖🐳🐋🐬🐟🐠🐡🦈🐙🐚🦀🦞🦐🦑🐌🦋🐛🐜🐝🐞🦗🕷️🕷🕸️🕸🦂🦟🦠💐🌸💮🏵️🏵🌹🥀🌺🌻🌼🌷🌱🌲🌳🌴🌵🌾🌿☘️☘🍀🍁🍂🍃🍇🍈🍉🍊🍋🍌🍍🥭🍎🍏🍐🍑🍒🍓🥝🍅🥥🥑🍆🥔🥕🌽🌶️🌶🥒🥬🥦🍄🥜🌰🍞🥐🥖🥨🥯🥞🧀🍖🍗🥩🥓🍔🍟🍕🌭🥪🌮🌯🥙🥚🍳🥘🍲🥣🥗🍿🧂🥫🍱🍘🍙🍚🍛🍜🍝🍠🍢🍣🍤🍥🥮🍡🥟🥠🥡🍦🍧🍨🍩🍪🎂🍰🧁🥧🍫🍬🍭🍮🍯🍼🥛☕🍵🍶🍾🍷🍸🍹🍺🍻🥂🥃🥤🥢🍽️🍽🍴🥄🔪🏺🌍🌎🌏🌐🗺️🗺🗾🧭🏔️🏔⛰️⛰🌋🗻🏕️🏕🏖️🏖🏜️🏜🏝️🏝🏞️🏞🏟️🏟🏛️🏛🏗️🏗🧱🏘️🏘🏚️🏚🏠🏡🏢🏣🏤🏥🏦🏨🏩🏪🏫🏬🏭🏯🏰💒🗼🗽⛪🕌🕍⛩️⛩🕋⛲⛺🌁🌃🏙️🏙🌄🌅🌆🌇🌉♨️♨🌌🎠🎡🎢💈🎪🚂🚃🚄🚅🚆🚇🚈🚉🚊🚝🚞🚋🚌🚍🚎🚐🚑🚒🚓🚔🚕🚖🚗🚘🚙🚚🚛🚜🚲🛴🛹🛵🚏🛣️🛣🛤️🛤🛢️🛢⛽🚨🚥🚦🛑🚧⚓⛵🛶🚤🛳️🛳⛴️⛴🛥️🛥🚢✈️✈🛩️🛩🛫🛬💺🚁🚟🚠🚡🛰️🛰🚀🛸🛎️🛎🧳⌛⏳⌚⏰⏱️⏱⏲️⏲🕰️🕰🕛🕧🕐🕜🕑🕝🕒🕞🕓🕟🕔🕠🕕🕡🕖🕢🕗🕣🕘🕤🕙🕥🕚🕦🌑🌒🌓🌔🌕🌖🌗🌘🌙🌚🌛🌜🌡️🌡☀️☀🌝🌞⭐🌟🌠☁️☁⛅⛈️⛈🌤️🌤🌥️🌥🌦️🌦🌧️🌧🌨️🌨🌩️🌩🌪️🌪🌫️🌫🌬️🌬🌀🌈🌂☂️☂☔⛱️⛱⚡❄️❄☃️☃⛄☄️☄🔥💧🌊🎃🎄🎆🎇🧨✨🎈🎉🎊🎋🎍🎎🎏🎐🎑🧧🎀🎁🎗️🎗🎟️🎟🎫🎖️🎖🏆🏅🥇🥈🥉⚽⚾🥎🏀🏐🏈🏉🎾🥏🎳🏏🏑🏒🥍🏓🏸🥊🥋🥅⛳⛸️⛸🎣🎽🎿🛷🥌🎯🎱🔮🧿🎮🕹️🕹🎰🎲🧩🧸♠️♠♥️♥♦️♦♣️♣♟️♟🃏🀄🎴🎭🖼️🖼🎨🧵🧶🔇🔈🔉🔊📢📣📯🔔🔕🎼🎵🎶🎙️🎙🎚️🎚🎛️🎛🎤🎧📻🎷🎸🎹🎺🎻🥁📱📲☎️☎📞📟📠🔋🔌💻🖥️🖥🖨️🖨⌨️⌨🖱️🖱🖲️🖲💽💾💿📀🧮🎥🎞️🎞📽️📽🎬📺📷📸📹📼🔍🔎🕯️🕯💡🔦🏮📔📕📖📗📘📙📚📓📒📃📜📄📰🗞️🗞📑🔖🏷️🏷💰💴💵💶💷💸💳🧾💹💱💲✉️✉📧📨📩📤📥📦📫📪📬📭📮🗳️🗳✏️✏✒️✒🖋️🖋🖊️🖊🖌️🖌🖍️🖍📝💼📁📂🗂️🗂📅📆🗒️🗒🗓️🗓📇📈📉📊📋📌📍📎🖇️🖇📏📐✂️✂🗃️🗃🗄️🗄🗑️🗑🔒🔓🔏🔐🔑🗝️🗝🔨⛏️⛏⚒️⚒🛠️🛠🗡️🗡⚔️⚔🔫🏹🛡️🛡🔧🔩⚙️⚙🗜️🗜⚖️⚖🔗⛓️⛓🧰🧲⚗️⚗🧪🧫🧬🔬🔭📡💉💊🚪🛏️🛏🛋️🛋🚽🚿🛁🧴🧷🧹🧺🧻🧼🧽🧯🛒🚬⚰️⚰⚱️⚱🗿🏧🚮🚰♿🚹🚺🚻🚼🚾🛂🛃🛄🛅⚠️⚠🚸⛔🚫🚳🚭🚯🚱🚷📵🔞☢️☢☣️☣⬆️⬆↗️↗➡️➡↘️↘⬇️⬇↙️↙⬅️⬅↖️↖↕️↕↔️↔↩️↩↪️↪⤴️⤴⤵️⤵🔃🔄🔙🔚🔛🔜🔝🛐⚛️⚛🕉️🕉✡️✡☸️☸☯️☯✝️✝☦️☦☪️☪☮️☮🕎🔯♈♉♊♋♌♍♎♏♐♑♒♓⛎🔀🔁🔂▶️▶⏩⏭️⏭⏯️⏯◀️◀⏪⏮️⏮🔼⏫🔽⏬⏸️⏸⏹️⏹⏺️⏺⏏️⏏🎦🔅🔆📶📳📴♀️♀♂️♂⚕️⚕♾️♾♻️♻⚜️⚜🔱📛🔰⭕✅☑️☑✔️✔✖️✖❌❎➕➖➗➰➿〽️〽✳️✳✴️✴❇️❇‼️‼⁉️⁉❓❔❕❗〰️〰©️©®️®™️™#️⃣#⃣*️⃣*⃣0️⃣0⃣1️⃣1⃣2️⃣2⃣3️⃣3⃣4️⃣4⃣5️⃣5⃣6️⃣6⃣7️⃣7⃣8️⃣8⃣9️⃣9⃣🔟💯🔠🔡🔢🔣🔤🅰️🅰🆎🅱️🅱🆑🆒🆓ℹ️ℹ🆔Ⓜ️Ⓜ🆕🆖🅾️🅾🆗🅿️🅿🆘🆙🆚🈁🈂️🈂🈷️🈷🈶🈯🉐🈹🈚🈲🉑🈸🈴🈳㊗️㊗㊙️㊙🈺🈵▪️▪▫️▫◻️◻◼️◼◽◾⬛⬜🔶🔷🔸🔹🔺🔻💠🔘🔲🔳⚪⚫🔴🔵🏁🚩🎌🏴🏳️🏳🏳️‍🌈🏳‍🌈🏴‍☠️🏴‍☠🇦🇨🇦🇩🇦🇪🇦🇫🇦🇬🇦🇮🇦🇱🇦🇲🇦🇴🇦🇶🇦🇷🇦🇸🇦🇹🇦🇺🇦🇼🇦🇽🇦🇿🇧🇦🇧🇧🇧🇩🇧🇪🇧🇫🇧🇬🇧🇭🇧🇮🇧🇯🇧🇱🇧🇲🇧🇳🇧🇴🇧🇶🇧🇷🇧🇸🇧🇹🇧🇻🇧🇼🇧🇾🇧🇿🇨🇦🇨🇨🇨🇩🇨🇫🇨🇬🇨🇭🇨🇮🇨🇰🇨🇱🇨🇲🇨🇳🇨🇴🇨🇵🇨🇷🇨🇺🇨🇻🇨🇼🇨🇽🇨🇾🇨🇿🇩🇪🇩🇬🇩🇯🇩🇰🇩🇲🇩🇴🇩🇿🇪🇦🇪🇨🇪🇪🇪🇬🇪🇭🇪🇷🇪🇸🇪🇹🇪🇺🇫🇮🇫🇯🇫🇰🇫🇲🇫🇴🇫🇷🇬🇦🇬🇧🇬🇩🇬🇪🇬🇫🇬🇬🇬🇭🇬🇮🇬🇱🇬🇲🇬🇳🇬🇵🇬🇶🇬🇷🇬🇸🇬🇹🇬🇺🇬🇼🇬🇾🇭🇰🇭🇲🇭🇳🇭🇷🇭🇹🇭🇺🇮🇨🇮🇩🇮🇪🇮🇱🇮🇲🇮🇳🇮🇴🇮🇶🇮🇷🇮🇸🇮🇹🇯🇪🇯🇲🇯🇴🇯🇵🇰🇪🇰🇬🇰🇭🇰🇮🇰🇲🇰🇳🇰🇵🇰🇷🇰🇼🇰🇾🇰🇿🇱🇦🇱🇧🇱🇨🇱🇮🇱🇰🇱🇷🇱🇸🇱🇹🇱🇺🇱🇻🇱🇾🇲🇦🇲🇨🇲🇩🇲🇪🇲🇫🇲🇬🇲🇭🇲🇰🇲🇱🇲🇲🇲🇳🇲🇴🇲🇵🇲🇶🇲🇷🇲🇸🇲🇹🇲🇺🇲🇻🇲🇼🇲🇽🇲🇾🇲🇿🇳🇦🇳🇨🇳🇪🇳🇫🇳🇬🇳🇮🇳🇱🇳🇴🇳🇵🇳🇷🇳🇺🇳🇿🇴🇲🇵🇦🇵🇪🇵🇫🇵🇬🇵🇭🇵🇰🇵🇱🇵🇲🇵🇳🇵🇷🇵🇸🇵🇹🇵🇼🇵🇾🇶🇦🇷🇪🇷🇴🇷🇸🇷🇺🇷🇼🇸🇦🇸🇧🇸🇨🇸🇩🇸🇪🇸🇬🇸🇭🇸🇮🇸🇯🇸🇰🇸🇱🇸🇲🇸🇳🇸🇴🇸🇷🇸🇸🇸🇹🇸🇻🇸🇽🇸🇾🇸🇿🇹🇦🇹🇨🇹🇩🇹🇫🇹🇬🇹🇭🇹🇯🇹🇰🇹🇱🇹🇲🇹🇳🇹🇴🇹🇷🇹🇹🇹🇻🇹🇼🇹🇿🇺🇦🇺🇬🇺🇲🇺🇳🇺🇸🇺🇾🇺🇿🇻🇦🇻🇨🇻🇪🇻🇬🇻🇮🇻🇳🇻🇺🇼🇫🇼🇸🇽🇰🇾🇪🇾🇹🇿🇦🇿🇲🇿🇼🏴󠁧󠁢󠁥󠁮󠁧󠁿🏴󠁧󠁢󠁳󠁣󠁴󠁿🏴󠁧󠁢󠁷󠁬󠁳󠁿" + ); + expect(() => emoji.parse(":-)")).toThrow(); + expect(() => emoji.parse("😀 is an emoji")).toThrow(); + expect(() => emoji.parse("😀stuff")).toThrow(); + expect(() => emoji.parse("stuff😀")).toThrow(); +}); + +test("uuid", () => { + const uuid = z.string().uuid("custom error"); + uuid.parse("9491d710-3185-4e06-bea0-6a2f275345e0"); + uuid.parse("d89e7b01-7598-ed11-9d7a-0022489382fd"); // new sequential id + uuid.parse("00000000-0000-0000-0000-000000000000"); + uuid.parse("b3ce60f8-e8b9-40f5-1150-172ede56ff74"); // Variant 0 - RFC 9562/4122: Reserved, NCS backward compatibility + uuid.parse("92e76bf9-28b3-4730-cd7f-cb6bc51f8c09"); // Variant 2 - RFC 9562/4122: Reserved, Microsoft Corporation backward compatibility + const result = uuid.safeParse("9491d710-3185-4e06-bea0-6a2f275345e0X"); + expect(result.success).toEqual(false); + if (!result.success) { + expect(result.error.issues[0].message).toEqual("custom error"); + } +}); + +test("bad uuid", () => { + const uuid = z.string().uuid("custom error"); + uuid.parse("9491d710-3185-4e06-bea0-6a2f275345e0"); + const result = uuid.safeParse("invalid uuid"); + expect(result.success).toEqual(false); + if (!result.success) { + expect(result.error.issues[0].message).toEqual("custom error"); + } +}); + +test("nanoid", () => { + const nanoid = z.string().nanoid("custom error"); + nanoid.parse("lfNZluvAxMkf7Q8C5H-QS"); + nanoid.parse("mIU_4PJWikaU8fMbmkouz"); + nanoid.parse("Hb9ZUtUa2JDm_dD-47EGv"); + nanoid.parse("5Noocgv_8vQ9oPijj4ioQ"); + const result = nanoid.safeParse("Xq90uDyhddC53KsoASYJGX"); + expect(result.success).toEqual(false); + if (!result.success) { + expect(result.error.issues[0].message).toEqual("custom error"); + } +}); + +test("bad nanoid", () => { + const nanoid = z.string().nanoid("custom error"); + nanoid.parse("ySh_984wpDUu7IQRrLXAp"); + const result = nanoid.safeParse("invalid nanoid"); + expect(result.success).toEqual(false); + if (!result.success) { + expect(result.error.issues[0].message).toEqual("custom error"); + } +}); + +test("cuid", () => { + const cuid = z.string().cuid(); + cuid.parse("ckopqwooh000001la8mbi2im9"); + const result = cuid.safeParse("cifjhdsfhsd-invalid-cuid"); + expect(result.success).toEqual(false); + if (!result.success) { + expect(result.error.issues[0].message).toEqual("Invalid cuid"); + } +}); + +test("cuid2", () => { + const cuid2 = z.string().cuid2(); + const validStrings = [ + "a", // short string + "tz4a98xxat96iws9zmbrgj3a", // normal string + "kf5vz6ssxe4zjcb409rjgo747tc5qjazgptvotk6", // longer than require("@paralleldrive/cuid2").bigLength + ]; + for (const s of validStrings) { + cuid2.parse(s); + } + + const invalidStrings = [ + "", // empty string + "tz4a98xxat96iws9zMbrgj3a", // include uppercase + "tz4a98xxat96iws-zmbrgj3a", // involve symbols + ]; + const results = invalidStrings.map((s) => cuid2.safeParse(s)); + expect(results.every((r) => !r.success)).toEqual(true); + if (!results[0].success) { + expect(results[0].error.issues[0].message).toEqual("Invalid cuid2"); + } +}); + +test("ulid", () => { + const ulid = z.string().ulid(); + ulid.parse("01ARZ3NDEKTSV4RRFFQ69G5FAV"); + const result = ulid.safeParse("invalidulid"); + expect(result.success).toEqual(false); + const tooLong = "01ARZ3NDEKTSV4RRFFQ69G5FAVA"; + expect(ulid.safeParse(tooLong).success).toEqual(false); + if (!result.success) { + expect(result.error.issues[0].message).toEqual("Invalid ulid"); + } + const caseInsensitive = ulid.safeParse("01arZ3nDeKTsV4RRffQ69G5FAV"); + expect(caseInsensitive.success).toEqual(true); +}); + +test("regex", () => { + z.string() + .regex(/^moo+$/) + .parse("mooooo"); + expect(() => z.string().uuid().parse("purr")).toThrow(); +}); + +test("regexp error message", () => { + const result = z + .string() + .regex(/^moo+$/) + .safeParse("boooo"); + if (!result.success) { + expect(result.error.issues[0].message).toEqual("Invalid"); + } else { + throw new Error("validation should have failed"); + } + + expect(() => z.string().uuid().parse("purr")).toThrow(); +}); + +test("regex lastIndex reset", () => { + const schema = z.string().regex(/^\d+$/g); + expect(schema.safeParse("123").success).toEqual(true); + expect(schema.safeParse("123").success).toEqual(true); + expect(schema.safeParse("123").success).toEqual(true); + expect(schema.safeParse("123").success).toEqual(true); + expect(schema.safeParse("123").success).toEqual(true); +}); + +test("checks getters", () => { + expect(z.string().email().isEmail).toEqual(true); + expect(z.string().email().isURL).toEqual(false); + expect(z.string().email().isCUID).toEqual(false); + expect(z.string().email().isCUID2).toEqual(false); + expect(z.string().email().isUUID).toEqual(false); + expect(z.string().email().isNANOID).toEqual(false); + expect(z.string().email().isIP).toEqual(false); + expect(z.string().email().isCIDR).toEqual(false); + expect(z.string().email().isULID).toEqual(false); + + expect(z.string().url().isEmail).toEqual(false); + expect(z.string().url().isURL).toEqual(true); + expect(z.string().url().isCUID).toEqual(false); + expect(z.string().url().isCUID2).toEqual(false); + expect(z.string().url().isUUID).toEqual(false); + expect(z.string().url().isNANOID).toEqual(false); + expect(z.string().url().isIP).toEqual(false); + expect(z.string().url().isCIDR).toEqual(false); + expect(z.string().url().isULID).toEqual(false); + + expect(z.string().cuid().isEmail).toEqual(false); + expect(z.string().cuid().isURL).toEqual(false); + expect(z.string().cuid().isCUID).toEqual(true); + expect(z.string().cuid().isCUID2).toEqual(false); + expect(z.string().cuid().isUUID).toEqual(false); + expect(z.string().cuid().isNANOID).toEqual(false); + expect(z.string().cuid().isIP).toEqual(false); + expect(z.string().cuid().isCIDR).toEqual(false); + expect(z.string().cuid().isULID).toEqual(false); + + expect(z.string().cuid2().isEmail).toEqual(false); + expect(z.string().cuid2().isURL).toEqual(false); + expect(z.string().cuid2().isCUID).toEqual(false); + expect(z.string().cuid2().isCUID2).toEqual(true); + expect(z.string().cuid2().isUUID).toEqual(false); + expect(z.string().cuid2().isNANOID).toEqual(false); + expect(z.string().cuid2().isIP).toEqual(false); + expect(z.string().cuid2().isCIDR).toEqual(false); + expect(z.string().cuid2().isULID).toEqual(false); + + expect(z.string().uuid().isEmail).toEqual(false); + expect(z.string().uuid().isURL).toEqual(false); + expect(z.string().uuid().isCUID).toEqual(false); + expect(z.string().uuid().isCUID2).toEqual(false); + expect(z.string().uuid().isUUID).toEqual(true); + expect(z.string().uuid().isNANOID).toEqual(false); + expect(z.string().uuid().isIP).toEqual(false); + expect(z.string().uuid().isCIDR).toEqual(false); + expect(z.string().uuid().isULID).toEqual(false); + + expect(z.string().nanoid().isEmail).toEqual(false); + expect(z.string().nanoid().isURL).toEqual(false); + expect(z.string().nanoid().isCUID).toEqual(false); + expect(z.string().nanoid().isCUID2).toEqual(false); + expect(z.string().nanoid().isUUID).toEqual(false); + expect(z.string().nanoid().isNANOID).toEqual(true); + expect(z.string().nanoid().isIP).toEqual(false); + expect(z.string().nanoid().isCIDR).toEqual(false); + expect(z.string().nanoid().isULID).toEqual(false); + + expect(z.string().ip().isEmail).toEqual(false); + expect(z.string().ip().isURL).toEqual(false); + expect(z.string().ip().isCUID).toEqual(false); + expect(z.string().ip().isCUID2).toEqual(false); + expect(z.string().ip().isUUID).toEqual(false); + expect(z.string().ip().isNANOID).toEqual(false); + expect(z.string().ip().isIP).toEqual(true); + expect(z.string().ip().isCIDR).toEqual(false); + expect(z.string().ip().isULID).toEqual(false); + + expect(z.string().cidr().isEmail).toEqual(false); + expect(z.string().cidr().isURL).toEqual(false); + expect(z.string().cidr().isCUID).toEqual(false); + expect(z.string().cidr().isCUID2).toEqual(false); + expect(z.string().cidr().isUUID).toEqual(false); + expect(z.string().cidr().isNANOID).toEqual(false); + expect(z.string().cidr().isIP).toEqual(false); + expect(z.string().cidr().isCIDR).toEqual(true); + expect(z.string().cidr().isULID).toEqual(false); + + expect(z.string().ulid().isEmail).toEqual(false); + expect(z.string().ulid().isURL).toEqual(false); + expect(z.string().ulid().isCUID).toEqual(false); + expect(z.string().ulid().isCUID2).toEqual(false); + expect(z.string().ulid().isUUID).toEqual(false); + expect(z.string().ulid().isNANOID).toEqual(false); + expect(z.string().ulid().isIP).toEqual(false); + expect(z.string().ulid().isCIDR).toEqual(false); + expect(z.string().ulid().isULID).toEqual(true); +}); + +test("min max getters", () => { + expect(z.string().min(5).minLength).toEqual(5); + expect(z.string().min(5).min(10).minLength).toEqual(10); + expect(z.string().minLength).toEqual(null); + + expect(z.string().max(5).maxLength).toEqual(5); + expect(z.string().max(5).max(1).maxLength).toEqual(1); + expect(z.string().maxLength).toEqual(null); +}); + +test("trim", () => { + expect(z.string().trim().min(2).parse(" 12 ")).toEqual("12"); + + // ordering of methods is respected + expect(z.string().min(2).trim().parse(" 1 ")).toEqual("1"); + expect(() => z.string().trim().min(2).parse(" 1 ")).toThrow(); +}); + +test("lowerCase", () => { + expect(z.string().toLowerCase().parse("ASDF")).toEqual("asdf"); + expect(z.string().toUpperCase().parse("asdf")).toEqual("ASDF"); +}); + +test("datetime", () => { + const a = z.string().datetime({}); + expect(a.isDatetime).toEqual(true); + + const b = z.string().datetime({ offset: true }); + expect(b.isDatetime).toEqual(true); + + const c = z.string().datetime({ precision: 3 }); + expect(c.isDatetime).toEqual(true); + + const d = z.string().datetime({ offset: true, precision: 0 }); + expect(d.isDatetime).toEqual(true); + + const { isDatetime } = z.string().datetime(); + expect(isDatetime).toEqual(true); +}); + +test("datetime parsing", () => { + const datetime = z.string().datetime(); + datetime.parse("1970-01-01T00:00:00.000Z"); + datetime.parse("2022-10-13T09:52:31.816Z"); + datetime.parse("2022-10-13T09:52:31.8162314Z"); + datetime.parse("1970-01-01T00:00:00Z"); + datetime.parse("2022-10-13T09:52:31Z"); + datetime.parse("2022-10-13T09:52Z"); + expect(() => datetime.parse("")).toThrow(); + expect(() => datetime.parse("foo")).toThrow(); + expect(() => datetime.parse("2020-10-14")).toThrow(); + expect(() => datetime.parse("T18:45:12.123")).toThrow(); + expect(() => datetime.parse("2020-10-14T17:42:29+00:00")).toThrow(); + expect(() => datetime.parse("2020-10-14T17:42.123+00:00")).toThrow(); + + const datetimeNoMs = z.string().datetime({ precision: 0 }); + datetimeNoMs.parse("1970-01-01T00:00:00Z"); + datetimeNoMs.parse("2022-10-13T09:52:31Z"); + datetimeNoMs.parse("2022-10-13T09:52Z"); + expect(() => datetimeNoMs.parse("tuna")).toThrow(); + expect(() => datetimeNoMs.parse("1970-01-01T00:00:00.000Z")).toThrow(); + expect(() => datetimeNoMs.parse("1970-01-01T00:00:00.Z")).toThrow(); + expect(() => datetimeNoMs.parse("2022-10-13T09:52:31.816Z")).toThrow(); + + const datetime3Ms = z.string().datetime({ precision: 3 }); + datetime3Ms.parse("1970-01-01T00:00:00.000Z"); + datetime3Ms.parse("2022-10-13T09:52:31.123Z"); + expect(() => datetime3Ms.parse("tuna")).toThrow(); + expect(() => datetime3Ms.parse("1970-01-01T00:00:00.1Z")).toThrow(); + expect(() => datetime3Ms.parse("1970-01-01T00:00:00.12Z")).toThrow(); + expect(() => datetime3Ms.parse("2022-10-13T09:52:31Z")).toThrow(); + expect(() => datetime3Ms.parse("2022-10-13T09:52Z")).toThrow(); + + const datetimeOffset = z.string().datetime({ offset: true }); + datetimeOffset.parse("1970-01-01T00:00:00.000Z"); + datetimeOffset.parse("2022-10-13T09:52:31.816234134Z"); + datetimeOffset.parse("1970-01-01T00:00:00Z"); + datetimeOffset.parse("2022-10-13T09:52:31.4Z"); + datetimeOffset.parse("2020-10-14T17:42:29+00:00"); + datetimeOffset.parse("2020-10-14T17:42:29+03:15"); + datetimeOffset.parse("2020-10-14T17:42:29+0315"); + datetimeOffset.parse("2020-10-14T17:42+0315"); + expect(() => datetimeOffset.parse("2020-10-14T17:42:29+03")); + expect(() => datetimeOffset.parse("tuna")).toThrow(); + expect(() => datetimeOffset.parse("2022-10-13T09:52:31.Z")).toThrow(); + + const datetimeOffsetNoMs = z.string().datetime({ offset: true, precision: 0 }); + datetimeOffsetNoMs.parse("1970-01-01T00:00:00Z"); + datetimeOffsetNoMs.parse("2022-10-13T09:52:31Z"); + datetimeOffsetNoMs.parse("2020-10-14T17:42:29+00:00"); + datetimeOffsetNoMs.parse("2020-10-14T17:42:29+0000"); + datetimeOffsetNoMs.parse("2020-10-14T17:42+0000"); + expect(() => datetimeOffsetNoMs.parse("2020-10-14T17:42:29+00")).toThrow(); + expect(() => datetimeOffsetNoMs.parse("tuna")).toThrow(); + expect(() => datetimeOffsetNoMs.parse("1970-01-01T00:00:00.000Z")).toThrow(); + expect(() => datetimeOffsetNoMs.parse("1970-01-01T00:00:00.Z")).toThrow(); + expect(() => datetimeOffsetNoMs.parse("2022-10-13T09:52:31.816Z")).toThrow(); + expect(() => datetimeOffsetNoMs.parse("2020-10-14T17:42:29.124+00:00")).toThrow(); + + const datetimeOffset4Ms = z.string().datetime({ offset: true, precision: 4 }); + datetimeOffset4Ms.parse("1970-01-01T00:00:00.1234Z"); + datetimeOffset4Ms.parse("2020-10-14T17:42:29.1234+00:00"); + datetimeOffset4Ms.parse("2020-10-14T17:42:29.1234+0000"); + expect(() => datetimeOffset4Ms.parse("2020-10-14T17:42:29.1234+00")).toThrow(); + expect(() => datetimeOffset4Ms.parse("tuna")).toThrow(); + expect(() => datetimeOffset4Ms.parse("1970-01-01T00:00:00.123Z")).toThrow(); + expect(() => datetimeOffset4Ms.parse("2020-10-14T17:42:29.124+00:00")).toThrow(); + expect(() => datetimeOffset4Ms.parse("2020-10-14T17:42+00:00")).toThrow(); +}); + +test("date", () => { + const a = z.string().date(); + expect(a.isDate).toEqual(true); +}); + +test("date parsing", () => { + const date = z.string().date(); + date.parse("1970-01-01"); + date.parse("2022-01-31"); + date.parse("2022-03-31"); + date.parse("2022-04-30"); + date.parse("2022-05-31"); + date.parse("2022-06-30"); + date.parse("2022-07-31"); + date.parse("2022-08-31"); + date.parse("2022-09-30"); + date.parse("2022-10-31"); + date.parse("2022-11-30"); + date.parse("2022-12-31"); + + date.parse("2000-02-29"); + date.parse("2400-02-29"); + expect(() => date.parse("2022-02-29")).toThrow(); + expect(() => date.parse("2100-02-29")).toThrow(); + expect(() => date.parse("2200-02-29")).toThrow(); + expect(() => date.parse("2300-02-29")).toThrow(); + expect(() => date.parse("2500-02-29")).toThrow(); + + expect(() => date.parse("")).toThrow(); + expect(() => date.parse("foo")).toThrow(); + expect(() => date.parse("200-01-01")).toThrow(); + expect(() => date.parse("20000-01-01")).toThrow(); + expect(() => date.parse("2000-0-01")).toThrow(); + expect(() => date.parse("2000-011-01")).toThrow(); + expect(() => date.parse("2000-01-0")).toThrow(); + expect(() => date.parse("2000-01-011")).toThrow(); + expect(() => date.parse("2000/01/01")).toThrow(); + expect(() => date.parse("01-01-2022")).toThrow(); + expect(() => date.parse("01/01/2022")).toThrow(); + expect(() => date.parse("2000-01-01 00:00:00Z")).toThrow(); + expect(() => date.parse("2020-10-14T17:42:29+00:00")).toThrow(); + expect(() => date.parse("2020-10-14T17:42:29Z")).toThrow(); + expect(() => date.parse("2020-10-14T17:42:29")).toThrow(); + expect(() => date.parse("2020-10-14T17:42:29.123Z")).toThrow(); + + expect(() => date.parse("2000-00-12")).toThrow(); + expect(() => date.parse("2000-12-00")).toThrow(); + expect(() => date.parse("2000-01-32")).toThrow(); + expect(() => date.parse("2000-13-01")).toThrow(); + expect(() => date.parse("2000-21-01")).toThrow(); + + expect(() => date.parse("2000-02-30")).toThrow(); + expect(() => date.parse("2000-02-31")).toThrow(); + expect(() => date.parse("2000-04-31")).toThrow(); + expect(() => date.parse("2000-06-31")).toThrow(); + expect(() => date.parse("2000-09-31")).toThrow(); + expect(() => date.parse("2000-11-31")).toThrow(); +}); + +test("time", () => { + const a = z.string().time(); + expect(a.isTime).toEqual(true); +}); + +test("time parsing", () => { + const time = z.string().time(); + time.parse("00:00:00"); + time.parse("23:00:00"); + time.parse("00:59:00"); + time.parse("00:00:59"); + time.parse("23:59:59"); + time.parse("09:52:31"); + time.parse("23:59:59.9999999"); + time.parse("23:59"); + expect(() => time.parse("")).toThrow(); + expect(() => time.parse("foo")).toThrow(); + expect(() => time.parse("00:00:00Z")).toThrow(); + expect(() => time.parse("0:00:00")).toThrow(); + expect(() => time.parse("00:0:00")).toThrow(); + expect(() => time.parse("00:00:0")).toThrow(); + expect(() => time.parse("00:00:00.000+00:00")).toThrow(); + + expect(() => time.parse("24:00:00")).toThrow(); + expect(() => time.parse("00:60:00")).toThrow(); + expect(() => time.parse("00:00:60")).toThrow(); + expect(() => time.parse("24:60:60")).toThrow(); + expect(() => time.parse("24:60")).toThrow(); + + const time2 = z.string().time({ precision: 2 }); + time2.parse("00:00:00.00"); + time2.parse("09:52:31.12"); + time2.parse("23:59:59.99"); + expect(() => time2.parse("")).toThrow(); + expect(() => time2.parse("foo")).toThrow(); + expect(() => time2.parse("00:00:00")).toThrow(); + expect(() => time2.parse("00:00:00.00Z")).toThrow(); + expect(() => time2.parse("00:00:00.0")).toThrow(); + expect(() => time2.parse("00:00:00.000")).toThrow(); + expect(() => time2.parse("00:00:00.00+00:00")).toThrow(); + expect(() => time2.parse("23:59")).toThrow(); + + // const time3 = z.string().time({ offset: true }); + // time3.parse("00:00:00Z"); + // time3.parse("09:52:31Z"); + // time3.parse("00:00:00+00:00"); + // time3.parse("00:00:00+0000"); + // time3.parse("00:00:00.000Z"); + // time3.parse("00:00:00.000+00:00"); + // time3.parse("00:00:00.000+0000"); + // expect(() => time3.parse("")).toThrow(); + // expect(() => time3.parse("foo")).toThrow(); + // expect(() => time3.parse("00:00:00")).toThrow(); + // expect(() => time3.parse("00:00:00.000")).toThrow(); + + // const time4 = z.string().time({ offset: true, precision: 0 }); + // time4.parse("00:00:00Z"); + // time4.parse("09:52:31Z"); + // time4.parse("00:00:00+00:00"); + // time4.parse("00:00:00+0000"); + // expect(() => time4.parse("")).toThrow(); + // expect(() => time4.parse("foo")).toThrow(); + // expect(() => time4.parse("00:00:00.0")).toThrow(); + // expect(() => time4.parse("00:00:00.000")).toThrow(); + // expect(() => time4.parse("00:00:00.000+00:00")).toThrow(); +}); + +test("duration", () => { + const duration = z.string().duration(); + expect(duration.isDuration).toEqual(true); + + const validDurations = [ + "P3Y6M4DT12H30M5S", + "P2Y9M3DT12H31M8.001S", + "+P3Y6M4DT12H30M5S", + "-PT0.001S", + "+PT0.001S", + "PT0,001S", + "PT12H30M5S", + "-P2M1D", + "P-2M-1D", + "-P5DT10H", + "P-5DT-10H", + "P1Y", + "P2MT30M", + "PT6H", + "P5W", + "P0.5Y", + "P0,5Y", + "P42YT7.004M", + ]; + + const invalidDurations = ["foo bar", "", " ", "P", "T1H", "P0.5Y1D", "P0,5Y6M", "P1YT"]; + + for (const val of validDurations) { + const result = duration.safeParse(val); + if (!result.success) { + throw Error(`Valid duration could not be parsed: ${val}`); + } + } + + for (const val of invalidDurations) { + const result = duration.safeParse(val); + + if (result.success) { + throw Error(`Invalid duration was successful parsed: ${val}`); + } + + expect(result.error.issues[0].message).toEqual("Invalid duration"); + } +}); + +test("IP validation", () => { + const ip = z.string().ip(); + expect(ip.safeParse("122.122.122.122").success).toBe(true); + + const ipv4 = z.string().ip({ version: "v4" }); + expect(() => ipv4.parse("6097:adfa:6f0b:220d:db08:5021:6191:7990")).toThrow(); + + const ipv6 = z.string().ip({ version: "v6" }); + expect(() => ipv6.parse("254.164.77.1")).toThrow(); + + const validIPs = [ + "1e5e:e6c8:daac:514b:114b:e360:d8c0:682c", + "9d4:c956:420f:5788:4339:9b3b:2418:75c3", + "474f:4c83::4e40:a47:ff95:0cda", + "d329:0:25b4:db47:a9d1:0:4926:0000", + "e48:10fb:1499:3e28:e4b6:dea5:4692:912c", + "114.71.82.94", + "0.0.0.0", + "37.85.236.115", + "2001:4888:50:ff00:500:d::", + "2001:4888:50:ff00:0500:000d:000:0000", + "2001:4888:50:ff00:0500:000d:0000:0000", + ]; + + const invalidIPs = [ + "d329:1be4:25b4:db47:a9d1:dc71:4926:992c:14af", + "d5e7:7214:2b78::3906:85e6:53cc:709:32ba", + "8f69::c757:395e:976e::3441", + "54cb::473f:d516:0.255.256.22", + "54cb::473f:d516:192.168.1", + "256.0.4.4", + "-1.0.555.4", + "0.0.0.0.0", + "1.1.1", + ]; + // no parameters check IPv4 or IPv6 + const ipSchema = z.string().ip(); + expect(validIPs.every((ip) => ipSchema.safeParse(ip).success)).toBe(true); + expect(invalidIPs.every((ip) => ipSchema.safeParse(ip).success === false)).toBe(true); +}); + +test("CIDR validation", () => { + const ipv4Cidr = z.string().cidr({ version: "v4" }); + expect(() => ipv4Cidr.parse("2001:0db8:85a3::8a2e:0370:7334/64")).toThrow(); + + const ipv6Cidr = z.string().cidr({ version: "v6" }); + expect(() => ipv6Cidr.parse("192.168.0.1/24")).toThrow(); + + const validCidrs = [ + "192.168.0.0/24", + "10.0.0.0/8", + "203.0.113.0/24", + "192.0.2.0/24", + "127.0.0.0/8", + "172.16.0.0/12", + "192.168.1.0/24", + "fc00::/7", + "fd00::/8", + "2001:db8::/32", + "2607:f0d0:1002:51::4/64", + "2001:0db8:85a3:0000:0000:8a2e:0370:7334/128", + "2001:0db8:1234:0000::/64", + ]; + + const invalidCidrs = [ + "192.168.1.1/33", + "10.0.0.1/-1", + "192.168.1.1/24/24", + "192.168.1.0/abc", + "2001:db8::1/129", + "2001:db8::1/-1", + "2001:db8::1/64/64", + "2001:db8::1/abc", + ]; + + // no parameters check IPv4 or IPv6 + const cidrSchema = z.string().cidr(); + expect(validCidrs.every((ip) => cidrSchema.safeParse(ip).success)).toBe(true); + expect(invalidCidrs.every((ip) => cidrSchema.safeParse(ip).success === false)).toBe(true); +}); diff --git a/node_modules/zod/src/v3/tests/transformer.test.ts b/node_modules/zod/src/v3/tests/transformer.test.ts new file mode 100644 index 00000000..ddd9e9a6 --- /dev/null +++ b/node_modules/zod/src/v3/tests/transformer.test.ts @@ -0,0 +1,233 @@ +// @ts-ignore TS6133 +import { expect, test } from "vitest"; + +import * as z from "zod/v3"; +import { util } from "../helpers/util.js"; + +const stringToNumber = z.string().transform((arg) => Number.parseFloat(arg)); +// const numberToString = z +// .transformer(z.number()) +// .transform((n) => String(n)); +const asyncNumberToString = z.number().transform(async (n) => String(n)); + +test("transform ctx.addIssue with parse", () => { + const strs = ["foo", "bar"]; + + expect(() => { + z.string() + .transform((data, ctx) => { + const i = strs.indexOf(data); + if (i === -1) { + ctx.addIssue({ + code: "custom", + message: `${data} is not one of our allowed strings`, + }); + } + return data.length; + }) + .parse("asdf"); + }).toThrow( + JSON.stringify( + [ + { + code: "custom", + message: "asdf is not one of our allowed strings", + path: [], + }, + ], + null, + 2 + ) + ); +}); + +test("transform ctx.addIssue with parseAsync", async () => { + const strs = ["foo", "bar"]; + + const result = await z + .string() + .transform(async (data, ctx) => { + const i = strs.indexOf(data); + if (i === -1) { + ctx.addIssue({ + code: "custom", + message: `${data} is not one of our allowed strings`, + }); + } + return data.length; + }) + .safeParseAsync("asdf"); + + expect(JSON.parse(JSON.stringify(result))).toEqual({ + success: false, + error: { + issues: [ + { + code: "custom", + message: "asdf is not one of our allowed strings", + path: [], + }, + ], + name: "ZodError", + }, + }); +}); + +test("z.NEVER in transform", () => { + const foo = z + .number() + .optional() + .transform((val, ctx) => { + if (!val) { + ctx.addIssue({ code: z.ZodIssueCode.custom, message: "bad" }); + return z.NEVER; + } + return val; + }); + type foo = z.infer; + util.assertEqual(true); + const arg = foo.safeParse(undefined); + if (!arg.success) { + expect(arg.error.issues[0].message).toEqual("bad"); + } +}); + +test("basic transformations", () => { + const r1 = z + .string() + .transform((data) => data.length) + .parse("asdf"); + expect(r1).toEqual(4); +}); + +test("coercion", () => { + const numToString = z.number().transform((n) => String(n)); + const data = z + .object({ + id: numToString, + }) + .parse({ id: 5 }); + + expect(data).toEqual({ id: "5" }); +}); + +test("async coercion", async () => { + const numToString = z.number().transform(async (n) => String(n)); + const data = await z + .object({ + id: numToString, + }) + .parseAsync({ id: 5 }); + + expect(data).toEqual({ id: "5" }); +}); + +test("sync coercion async error", async () => { + expect(() => + z + .object({ + id: asyncNumberToString, + }) + .parse({ id: 5 }) + ).toThrow(); + // expect(data).toEqual({ id: '5' }); +}); + +test("default", () => { + const data = z.string().default("asdf").parse(undefined); // => "asdf" + expect(data).toEqual("asdf"); +}); + +test("dynamic default", () => { + const data = z + .string() + .default(() => "string") + .parse(undefined); // => "asdf" + expect(data).toEqual("string"); +}); + +test("default when property is null or undefined", () => { + const data = z + .object({ + foo: z.boolean().nullable().default(true), + bar: z.boolean().default(true), + }) + .parse({ foo: null }); + + expect(data).toEqual({ foo: null, bar: true }); +}); + +test("default with falsy values", () => { + const schema = z.object({ + emptyStr: z.string().default("def"), + zero: z.number().default(5), + falseBoolean: z.boolean().default(true), + }); + const input = { emptyStr: "", zero: 0, falseBoolean: true }; + const output = schema.parse(input); + // defaults are not supposed to be used + expect(output).toEqual(input); +}); + +test("object typing", () => { + const t1 = z.object({ + stringToNumber, + }); + + type t1 = z.input; + type t2 = z.output; + + util.assertEqual(true); + util.assertEqual(true); +}); + +test("transform method overloads", () => { + const t1 = z.string().transform((val) => val.toUpperCase()); + expect(t1.parse("asdf")).toEqual("ASDF"); + + const t2 = z.string().transform((val) => val.length); + expect(t2.parse("asdf")).toEqual(4); +}); + +test("multiple transformers", () => { + const doubler = stringToNumber.transform((val) => { + return val * 2; + }); + expect(doubler.parse("5")).toEqual(10); +}); + +test("short circuit on dirty", () => { + const schema = z + .string() + .refine(() => false) + .transform((val) => val.toUpperCase()); + const result = schema.safeParse("asdf"); + expect(result.success).toEqual(false); + if (!result.success) { + expect(result.error.issues[0].code).toEqual(z.ZodIssueCode.custom); + } + + const result2 = schema.safeParse(1234); + expect(result2.success).toEqual(false); + if (!result2.success) { + expect(result2.error.issues[0].code).toEqual(z.ZodIssueCode.invalid_type); + } +}); + +test("async short circuit on dirty", async () => { + const schema = z + .string() + .refine(() => false) + .transform((val) => val.toUpperCase()); + const result = await schema.spa("asdf"); + expect(result.success).toEqual(false); + if (!result.success) { + expect(result.error.issues[0].code).toEqual(z.ZodIssueCode.custom); + } + + const result2 = await schema.spa(1234); + expect(result2.success).toEqual(false); + if (!result2.success) { + expect(result2.error.issues[0].code).toEqual(z.ZodIssueCode.invalid_type); + } +}); diff --git a/node_modules/zod/src/v3/tests/tuple.test.ts b/node_modules/zod/src/v3/tests/tuple.test.ts new file mode 100644 index 00000000..e525d3f4 --- /dev/null +++ b/node_modules/zod/src/v3/tests/tuple.test.ts @@ -0,0 +1,90 @@ +// @ts-ignore TS6133 +import { expect, test } from "vitest"; + +import * as z from "zod/v3"; +import { ZodError } from "../ZodError.js"; +import { util } from "../helpers/util.js"; + +const testTuple = z.tuple([z.string(), z.object({ name: z.literal("Rudy") }), z.array(z.literal("blue"))]); +const testData = ["asdf", { name: "Rudy" }, ["blue"]]; +const badData = [123, { name: "Rudy2" }, ["blue", "red"]]; + +test("tuple inference", () => { + const args1 = z.tuple([z.string()]); + const returns1 = z.number(); + const func1 = z.function(args1, returns1); + type func1 = z.TypeOf; + util.assertEqual number>(true); +}); + +test("successful validation", () => { + const val = testTuple.parse(testData); + expect(val).toEqual(["asdf", { name: "Rudy" }, ["blue"]]); +}); + +test("successful async validation", async () => { + const val = await testTuple.parseAsync(testData); + return expect(val).toEqual(testData); +}); + +test("failed validation", () => { + const checker = () => { + testTuple.parse([123, { name: "Rudy2" }, ["blue", "red"]] as any); + }; + try { + checker(); + } catch (err) { + if (err instanceof ZodError) { + expect(err.issues.length).toEqual(3); + } + } +}); + +test("failed async validation", async () => { + const res = await testTuple.safeParse(badData); + expect(res.success).toEqual(false); + if (!res.success) { + expect(res.error.issues.length).toEqual(3); + } + // try { + // checker(); + // } catch (err) { + // if (err instanceof ZodError) { + // expect(err.issues.length).toEqual(3); + // } + // } +}); + +test("tuple with transformers", () => { + const stringToNumber = z.string().transform((val) => val.length); + const val = z.tuple([stringToNumber]); + + type t1 = z.input; + util.assertEqual(true); + type t2 = z.output; + util.assertEqual(true); + expect(val.parse(["1234"])).toEqual([4]); +}); + +test("tuple with rest schema", () => { + const myTuple = z.tuple([z.string(), z.number()]).rest(z.boolean()); + expect(myTuple.parse(["asdf", 1234, true, false, true])).toEqual(["asdf", 1234, true, false, true]); + + expect(myTuple.parse(["asdf", 1234])).toEqual(["asdf", 1234]); + + expect(() => myTuple.parse(["asdf", 1234, "asdf"])).toThrow(); + type t1 = z.output; + + util.assertEqual(true); +}); + +test("parse should fail given sparse array as tuple", () => { + expect(() => testTuple.parse(new Array(3))).toThrow(); +}); + +// test('tuple with optional elements', () => { +// const result = z +// .tuple([z.string(), z.number().optional()]) +// .safeParse(['asdf']); +// expect(result).toEqual(['asdf']); +// }); diff --git a/node_modules/zod/src/v3/tests/unions.test.ts b/node_modules/zod/src/v3/tests/unions.test.ts new file mode 100644 index 00000000..2c3dc677 --- /dev/null +++ b/node_modules/zod/src/v3/tests/unions.test.ts @@ -0,0 +1,57 @@ +// @ts-ignore TS6133 +import { expect, test } from "vitest"; + +import * as z from "zod/v3"; + +test("function parsing", () => { + const schema = z.union([z.string().refine(() => false), z.number().refine(() => false)]); + const result = schema.safeParse("asdf"); + expect(result.success).toEqual(false); +}); + +test("union 2", () => { + const result = z.union([z.number(), z.string().refine(() => false)]).safeParse("a"); + expect(result.success).toEqual(false); +}); + +test("return valid over invalid", () => { + const schema = z.union([ + z.object({ + email: z.string().email(), + }), + z.string(), + ]); + expect(schema.parse("asdf")).toEqual("asdf"); + expect(schema.parse({ email: "asdlkjf@lkajsdf.com" })).toEqual({ + email: "asdlkjf@lkajsdf.com", + }); +}); + +test("return dirty result over aborted", () => { + const result = z.union([z.number(), z.string().refine(() => false)]).safeParse("a"); + expect(result.success).toEqual(false); + if (!result.success) { + expect(result.error.issues).toEqual([ + { + code: "custom", + message: "Invalid input", + path: [], + }, + ]); + } +}); + +test("options getter", async () => { + const union = z.union([z.string(), z.number()]); + union.options[0].parse("asdf"); + union.options[1].parse(1234); + await union.options[0].parseAsync("asdf"); + await union.options[1].parseAsync(1234); +}); + +test("readonly union", async () => { + const options = [z.string(), z.number()] as const; + const union = z.union(options); + union.parse("asdf"); + union.parse(12); +}); diff --git a/node_modules/zod/src/v3/tests/validations.test.ts b/node_modules/zod/src/v3/tests/validations.test.ts new file mode 100644 index 00000000..66f41dab --- /dev/null +++ b/node_modules/zod/src/v3/tests/validations.test.ts @@ -0,0 +1,133 @@ +// @ts-ignore TS6133 +import { expect, test } from "vitest"; + +import * as z from "zod/v3"; + +test("array min", async () => { + try { + await z.array(z.string()).min(4).parseAsync([]); + } catch (err) { + expect((err as z.ZodError).issues[0].message).toEqual("Array must contain at least 4 element(s)"); + } +}); + +test("array max", async () => { + try { + await z.array(z.string()).max(2).parseAsync(["asdf", "asdf", "asdf"]); + } catch (err) { + expect((err as z.ZodError).issues[0].message).toEqual("Array must contain at most 2 element(s)"); + } +}); + +test("array length", async () => { + try { + await z.array(z.string()).length(2).parseAsync(["asdf", "asdf", "asdf"]); + } catch (err) { + expect((err as z.ZodError).issues[0].message).toEqual("Array must contain exactly 2 element(s)"); + } + + try { + await z.array(z.string()).length(2).parseAsync(["asdf"]); + } catch (err) { + expect((err as z.ZodError).issues[0].message).toEqual("Array must contain exactly 2 element(s)"); + } +}); + +test("string length", async () => { + try { + await z.string().length(4).parseAsync("asd"); + } catch (err) { + expect((err as z.ZodError).issues[0].message).toEqual("String must contain exactly 4 character(s)"); + } + + try { + await z.string().length(4).parseAsync("asdaa"); + } catch (err) { + expect((err as z.ZodError).issues[0].message).toEqual("String must contain exactly 4 character(s)"); + } +}); + +test("string min", async () => { + try { + await z.string().min(4).parseAsync("asd"); + } catch (err) { + expect((err as z.ZodError).issues[0].message).toEqual("String must contain at least 4 character(s)"); + } +}); + +test("string max", async () => { + try { + await z.string().max(4).parseAsync("aasdfsdfsd"); + } catch (err) { + expect((err as z.ZodError).issues[0].message).toEqual("String must contain at most 4 character(s)"); + } +}); + +test("number min", async () => { + try { + await z.number().gte(3).parseAsync(2); + } catch (err) { + expect((err as z.ZodError).issues[0].message).toEqual("Number must be greater than or equal to 3"); + } +}); + +test("number max", async () => { + try { + await z.number().lte(3).parseAsync(4); + } catch (err) { + expect((err as z.ZodError).issues[0].message).toEqual("Number must be less than or equal to 3"); + } +}); + +test("number nonnegative", async () => { + try { + await z.number().nonnegative().parseAsync(-1); + } catch (err) { + expect((err as z.ZodError).issues[0].message).toEqual("Number must be greater than or equal to 0"); + } +}); + +test("number nonpositive", async () => { + try { + await z.number().nonpositive().parseAsync(1); + } catch (err) { + expect((err as z.ZodError).issues[0].message).toEqual("Number must be less than or equal to 0"); + } +}); + +test("number negative", async () => { + try { + await z.number().negative().parseAsync(1); + } catch (err) { + expect((err as z.ZodError).issues[0].message).toEqual("Number must be less than 0"); + } +}); + +test("number positive", async () => { + try { + await z.number().positive().parseAsync(-1); + } catch (err) { + expect((err as z.ZodError).issues[0].message).toEqual("Number must be greater than 0"); + } +}); + +test("instantiation", () => { + z.string().min(5); + z.string().max(5); + z.string().length(5); + z.string().email(); + z.string().url(); + z.string().uuid(); + z.string().min(5, { message: "Must be 5 or more characters long" }); + z.string().max(5, { message: "Must be 5 or fewer characters long" }); + z.string().length(5, { message: "Must be exactly 5 characters long" }); + z.string().email({ message: "Invalid email address." }); + z.string().url({ message: "Invalid url" }); + z.string().uuid({ message: "Invalid UUID" }); +}); + +test("int", async () => { + const int = z.number().int(); + int.parse(4); + expect(() => int.parse(3.5)).toThrow(); +}); diff --git a/node_modules/zod/src/v3/tests/void.test.ts b/node_modules/zod/src/v3/tests/void.test.ts new file mode 100644 index 00000000..b128f117 --- /dev/null +++ b/node_modules/zod/src/v3/tests/void.test.ts @@ -0,0 +1,15 @@ +// @ts-ignore TS6133 +import { expect, test } from "vitest"; + +import * as z from "zod/v3"; +import { util } from "../helpers/util.js"; +test("void", () => { + const v = z.void(); + v.parse(undefined); + + expect(() => v.parse(null)).toThrow(); + expect(() => v.parse("")).toThrow(); + + type v = z.infer; + util.assertEqual(true); +}); diff --git a/node_modules/zod/src/v3/types.ts b/node_modules/zod/src/v3/types.ts new file mode 100644 index 00000000..f4028549 --- /dev/null +++ b/node_modules/zod/src/v3/types.ts @@ -0,0 +1,5138 @@ +import { + type IssueData, + type StringValidation, + type ZodCustomIssue, + ZodError, + type ZodErrorMap, + type ZodIssue, + ZodIssueCode, +} from "./ZodError.js"; +import { defaultErrorMap, getErrorMap } from "./errors.js"; +import type { enumUtil } from "./helpers/enumUtil.js"; +import { errorUtil } from "./helpers/errorUtil.js"; +import { + type AsyncParseReturnType, + DIRTY, + INVALID, + OK, + type ParseContext, + type ParseInput, + type ParseParams, + type ParsePath, + type ParseReturnType, + ParseStatus, + type SyncParseReturnType, + addIssueToContext, + isAborted, + isAsync, + isDirty, + isValid, + makeIssue, +} from "./helpers/parseUtil.js"; +import type { partialUtil } from "./helpers/partialUtil.js"; +import type { Primitive } from "./helpers/typeAliases.js"; +import { util, ZodParsedType, getParsedType, type objectUtil } from "./helpers/util.js"; +import type { StandardSchemaV1 } from "./standard-schema.js"; + +/////////////////////////////////////// +/////////////////////////////////////// +////////// ////////// +////////// ZodType ////////// +////////// ////////// +/////////////////////////////////////// +/////////////////////////////////////// + +export interface RefinementCtx { + addIssue: (arg: IssueData) => void; + path: (string | number)[]; +} +export type ZodRawShape = { [k: string]: ZodTypeAny }; +export type ZodTypeAny = ZodType; +export type TypeOf> = T["_output"]; +export type input> = T["_input"]; +export type output> = T["_output"]; +export type { TypeOf as infer }; + +export type CustomErrorParams = Partial>; +export interface ZodTypeDef { + errorMap?: ZodErrorMap | undefined; + description?: string | undefined; +} + +class ParseInputLazyPath implements ParseInput { + parent: ParseContext; + data: any; + _path: ParsePath; + _key: string | number | (string | number)[]; + _cachedPath: ParsePath = []; + constructor(parent: ParseContext, value: any, path: ParsePath, key: string | number | (string | number)[]) { + this.parent = parent; + this.data = value; + this._path = path; + this._key = key; + } + get path() { + if (!this._cachedPath.length) { + if (Array.isArray(this._key)) { + this._cachedPath.push(...this._path, ...this._key); + } else { + this._cachedPath.push(...this._path, this._key); + } + } + + return this._cachedPath; + } +} + +const handleResult = ( + ctx: ParseContext, + result: SyncParseReturnType +): { success: true; data: Output } | { success: false; error: ZodError } => { + if (isValid(result)) { + return { success: true, data: result.value }; + } else { + if (!ctx.common.issues.length) { + throw new Error("Validation failed but no issues detected."); + } + + return { + success: false, + get error() { + if ((this as any)._error) return (this as any)._error as Error; + const error = new ZodError(ctx.common.issues); + (this as any)._error = error; + return (this as any)._error; + }, + }; + } +}; + +export type RawCreateParams = + | { + errorMap?: ZodErrorMap | undefined; + invalid_type_error?: string | undefined; + required_error?: string | undefined; + message?: string | undefined; + description?: string | undefined; + } + | undefined; +export type ProcessedCreateParams = { + errorMap?: ZodErrorMap | undefined; + description?: string | undefined; +}; +function processCreateParams(params: RawCreateParams): ProcessedCreateParams { + if (!params) return {}; + const { errorMap, invalid_type_error, required_error, description } = params; + if (errorMap && (invalid_type_error || required_error)) { + throw new Error(`Can't use "invalid_type_error" or "required_error" in conjunction with custom error map.`); + } + if (errorMap) return { errorMap: errorMap, description }; + const customMap: ZodErrorMap = (iss, ctx) => { + const { message } = params; + + if (iss.code === "invalid_enum_value") { + return { message: message ?? ctx.defaultError }; + } + if (typeof ctx.data === "undefined") { + return { message: message ?? required_error ?? ctx.defaultError }; + } + if (iss.code !== "invalid_type") return { message: ctx.defaultError }; + return { message: message ?? invalid_type_error ?? ctx.defaultError }; + }; + return { errorMap: customMap, description }; +} + +export type SafeParseSuccess = { + success: true; + data: Output; + error?: never; +}; +export type SafeParseError = { + success: false; + error: ZodError; + data?: never; +}; + +export type SafeParseReturnType = SafeParseSuccess | SafeParseError; + +export abstract class ZodType { + readonly _type!: Output; + readonly _output!: Output; + readonly _input!: Input; + readonly _def!: Def; + + get description(): string | undefined { + return this._def.description; + } + + "~standard": StandardSchemaV1.Props; + + abstract _parse(input: ParseInput): ParseReturnType; + + _getType(input: ParseInput): string { + return getParsedType(input.data); + } + + _getOrReturnCtx(input: ParseInput, ctx?: ParseContext | undefined): ParseContext { + return ( + ctx || { + common: input.parent.common, + data: input.data, + + parsedType: getParsedType(input.data), + + schemaErrorMap: this._def.errorMap, + path: input.path, + parent: input.parent, + } + ); + } + + _processInputParams(input: ParseInput): { + status: ParseStatus; + ctx: ParseContext; + } { + return { + status: new ParseStatus(), + ctx: { + common: input.parent.common, + data: input.data, + + parsedType: getParsedType(input.data), + + schemaErrorMap: this._def.errorMap, + path: input.path, + parent: input.parent, + }, + }; + } + + _parseSync(input: ParseInput): SyncParseReturnType { + const result = this._parse(input); + if (isAsync(result)) { + throw new Error("Synchronous parse encountered promise."); + } + return result; + } + + _parseAsync(input: ParseInput): AsyncParseReturnType { + const result = this._parse(input); + return Promise.resolve(result); + } + + parse(data: unknown, params?: util.InexactPartial): Output { + const result = this.safeParse(data, params); + if (result.success) return result.data; + throw result.error; + } + + safeParse(data: unknown, params?: util.InexactPartial): SafeParseReturnType { + const ctx: ParseContext = { + common: { + issues: [], + async: params?.async ?? false, + contextualErrorMap: params?.errorMap, + }, + path: params?.path || [], + schemaErrorMap: this._def.errorMap, + parent: null, + data, + parsedType: getParsedType(data), + }; + const result = this._parseSync({ data, path: ctx.path, parent: ctx }); + + return handleResult(ctx, result); + } + + "~validate"(data: unknown): StandardSchemaV1.Result | Promise> { + const ctx: ParseContext = { + common: { + issues: [], + async: !!(this["~standard"] as any).async, + }, + path: [], + schemaErrorMap: this._def.errorMap, + parent: null, + data, + parsedType: getParsedType(data), + }; + + if (!(this["~standard"] as any).async) { + try { + const result = this._parseSync({ data, path: [], parent: ctx }); + return isValid(result) + ? { + value: result.value, + } + : { + issues: ctx.common.issues, + }; + } catch (err: any) { + if ((err as Error)?.message?.toLowerCase()?.includes("encountered")) { + (this["~standard"] as any).async = true; + } + (ctx as any).common = { + issues: [], + async: true, + }; + } + } + + return this._parseAsync({ data, path: [], parent: ctx }).then((result) => + isValid(result) + ? { + value: result.value, + } + : { + issues: ctx.common.issues, + } + ); + } + + async parseAsync(data: unknown, params?: util.InexactPartial): Promise { + const result = await this.safeParseAsync(data, params); + if (result.success) return result.data; + throw result.error; + } + + async safeParseAsync( + data: unknown, + params?: util.InexactPartial + ): Promise> { + const ctx: ParseContext = { + common: { + issues: [], + contextualErrorMap: params?.errorMap, + async: true, + }, + path: params?.path || [], + schemaErrorMap: this._def.errorMap, + parent: null, + data, + parsedType: getParsedType(data), + }; + + const maybeAsyncResult = this._parse({ data, path: ctx.path, parent: ctx }); + const result = await (isAsync(maybeAsyncResult) ? maybeAsyncResult : Promise.resolve(maybeAsyncResult)); + return handleResult(ctx, result); + } + + /** Alias of safeParseAsync */ + spa = this.safeParseAsync; + + refine( + check: (arg: Output) => arg is RefinedOutput, + message?: string | CustomErrorParams | ((arg: Output) => CustomErrorParams) + ): ZodEffects; + refine( + check: (arg: Output) => unknown | Promise, + message?: string | CustomErrorParams | ((arg: Output) => CustomErrorParams) + ): ZodEffects; + refine( + check: (arg: Output) => unknown, + message?: string | CustomErrorParams | ((arg: Output) => CustomErrorParams) + ): ZodEffects { + const getIssueProperties = (val: Output) => { + if (typeof message === "string" || typeof message === "undefined") { + return { message }; + } else if (typeof message === "function") { + return message(val); + } else { + return message; + } + }; + return this._refinement((val, ctx) => { + const result = check(val); + const setError = () => + ctx.addIssue({ + code: ZodIssueCode.custom, + ...getIssueProperties(val), + }); + if (typeof Promise !== "undefined" && result instanceof Promise) { + return result.then((data) => { + if (!data) { + setError(); + return false; + } else { + return true; + } + }); + } + if (!result) { + setError(); + return false; + } else { + return true; + } + }); + } + + refinement( + check: (arg: Output) => arg is RefinedOutput, + refinementData: IssueData | ((arg: Output, ctx: RefinementCtx) => IssueData) + ): ZodEffects; + refinement( + check: (arg: Output) => boolean, + refinementData: IssueData | ((arg: Output, ctx: RefinementCtx) => IssueData) + ): ZodEffects; + refinement( + check: (arg: Output) => unknown, + refinementData: IssueData | ((arg: Output, ctx: RefinementCtx) => IssueData) + ): ZodEffects { + return this._refinement((val, ctx) => { + if (!check(val)) { + ctx.addIssue(typeof refinementData === "function" ? refinementData(val, ctx) : refinementData); + return false; + } else { + return true; + } + }); + } + + _refinement(refinement: RefinementEffect["refinement"]): ZodEffects { + return new ZodEffects({ + schema: this, + typeName: ZodFirstPartyTypeKind.ZodEffects, + effect: { type: "refinement", refinement }, + }); + } + + superRefine( + refinement: (arg: Output, ctx: RefinementCtx) => arg is RefinedOutput + ): ZodEffects; + superRefine(refinement: (arg: Output, ctx: RefinementCtx) => void): ZodEffects; + superRefine(refinement: (arg: Output, ctx: RefinementCtx) => Promise): ZodEffects; + superRefine( + refinement: (arg: Output, ctx: RefinementCtx) => unknown | Promise + ): ZodEffects { + return this._refinement(refinement); + } + + constructor(def: Def) { + this._def = def; + this.parse = this.parse.bind(this); + this.safeParse = this.safeParse.bind(this); + this.parseAsync = this.parseAsync.bind(this); + this.safeParseAsync = this.safeParseAsync.bind(this); + this.spa = this.spa.bind(this); + this.refine = this.refine.bind(this); + this.refinement = this.refinement.bind(this); + this.superRefine = this.superRefine.bind(this); + this.optional = this.optional.bind(this); + this.nullable = this.nullable.bind(this); + this.nullish = this.nullish.bind(this); + this.array = this.array.bind(this); + this.promise = this.promise.bind(this); + this.or = this.or.bind(this); + this.and = this.and.bind(this); + this.transform = this.transform.bind(this); + this.brand = this.brand.bind(this); + this.default = this.default.bind(this); + this.catch = this.catch.bind(this); + this.describe = this.describe.bind(this); + this.pipe = this.pipe.bind(this); + this.readonly = this.readonly.bind(this); + this.isNullable = this.isNullable.bind(this); + this.isOptional = this.isOptional.bind(this); + this["~standard"] = { + version: 1, + vendor: "zod", + validate: (data) => this["~validate"](data), + }; + } + + optional(): ZodOptional { + return ZodOptional.create(this, this._def) as any; + } + nullable(): ZodNullable { + return ZodNullable.create(this, this._def) as any; + } + nullish(): ZodOptional> { + return this.nullable().optional(); + } + array(): ZodArray { + return ZodArray.create(this); + } + promise(): ZodPromise { + return ZodPromise.create(this, this._def); + } + + or(option: T): ZodUnion<[this, T]> { + return ZodUnion.create([this, option], this._def) as any; + } + + and(incoming: T): ZodIntersection { + return ZodIntersection.create(this, incoming, this._def); + } + + transform( + transform: (arg: Output, ctx: RefinementCtx) => NewOut | Promise + ): ZodEffects { + return new ZodEffects({ + ...processCreateParams(this._def), + schema: this, + typeName: ZodFirstPartyTypeKind.ZodEffects, + effect: { type: "transform", transform }, + }) as any; + } + + default(def: util.noUndefined): ZodDefault; + default(def: () => util.noUndefined): ZodDefault; + default(def: any) { + const defaultValueFunc = typeof def === "function" ? def : () => def; + + return new ZodDefault({ + ...processCreateParams(this._def), + innerType: this, + defaultValue: defaultValueFunc, + typeName: ZodFirstPartyTypeKind.ZodDefault, + }) as any; + } + + brand(brand?: B): ZodBranded; + brand(): ZodBranded { + return new ZodBranded({ + typeName: ZodFirstPartyTypeKind.ZodBranded, + type: this, + ...processCreateParams(this._def), + }); + } + + catch(def: Output): ZodCatch; + catch(def: (ctx: { error: ZodError; input: Input }) => Output): ZodCatch; + catch(def: any) { + const catchValueFunc = typeof def === "function" ? def : () => def; + + return new ZodCatch({ + ...processCreateParams(this._def), + innerType: this, + catchValue: catchValueFunc, + typeName: ZodFirstPartyTypeKind.ZodCatch, + }) as any; + } + + describe(description: string): this { + const This = (this as any).constructor; + return new This({ + ...this._def, + description, + }); + } + + pipe(target: T): ZodPipeline { + return ZodPipeline.create(this, target); + } + readonly(): ZodReadonly { + return ZodReadonly.create(this); + } + + isOptional(): boolean { + return this.safeParse(undefined).success; + } + isNullable(): boolean { + return this.safeParse(null).success; + } +} + +///////////////////////////////////////// +///////////////////////////////////////// +////////// ////////// +////////// ZodString ////////// +////////// ////////// +///////////////////////////////////////// +///////////////////////////////////////// +export type IpVersion = "v4" | "v6"; +export type ZodStringCheck = + | { kind: "min"; value: number; message?: string | undefined } + | { kind: "max"; value: number; message?: string | undefined } + | { kind: "length"; value: number; message?: string | undefined } + | { kind: "email"; message?: string | undefined } + | { kind: "url"; message?: string | undefined } + | { kind: "emoji"; message?: string | undefined } + | { kind: "uuid"; message?: string | undefined } + | { kind: "nanoid"; message?: string | undefined } + | { kind: "cuid"; message?: string | undefined } + | { kind: "includes"; value: string; position?: number | undefined; message?: string | undefined } + | { kind: "cuid2"; message?: string | undefined } + | { kind: "ulid"; message?: string | undefined } + | { kind: "startsWith"; value: string; message?: string | undefined } + | { kind: "endsWith"; value: string; message?: string | undefined } + | { kind: "regex"; regex: RegExp; message?: string | undefined } + | { kind: "trim"; message?: string | undefined } + | { kind: "toLowerCase"; message?: string | undefined } + | { kind: "toUpperCase"; message?: string | undefined } + | { kind: "jwt"; alg?: string; message?: string | undefined } + | { + kind: "datetime"; + offset: boolean; + local: boolean; + precision: number | null; + message?: string | undefined; + } + | { + kind: "date"; + // withDate: true; + message?: string | undefined; + } + | { + kind: "time"; + precision: number | null; + message?: string | undefined; + } + | { kind: "duration"; message?: string | undefined } + | { kind: "ip"; version?: IpVersion | undefined; message?: string | undefined } + | { kind: "cidr"; version?: IpVersion | undefined; message?: string | undefined } + | { kind: "base64"; message?: string | undefined } + | { kind: "base64url"; message?: string | undefined }; + +export interface ZodStringDef extends ZodTypeDef { + checks: ZodStringCheck[]; + typeName: ZodFirstPartyTypeKind.ZodString; + coerce: boolean; +} + +const cuidRegex = /^c[^\s-]{8,}$/i; +const cuid2Regex = /^[0-9a-z]+$/; +const ulidRegex = /^[0-9A-HJKMNP-TV-Z]{26}$/i; +// const uuidRegex = +// /^([a-f0-9]{8}-[a-f0-9]{4}-[1-5][a-f0-9]{3}-[a-f0-9]{4}-[a-f0-9]{12}|00000000-0000-0000-0000-000000000000)$/i; +const uuidRegex = /^[0-9a-fA-F]{8}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{12}$/i; +const nanoidRegex = /^[a-z0-9_-]{21}$/i; +const jwtRegex = /^[A-Za-z0-9-_]+\.[A-Za-z0-9-_]+\.[A-Za-z0-9-_]*$/; +const durationRegex = + /^[-+]?P(?!$)(?:(?:[-+]?\d+Y)|(?:[-+]?\d+[.,]\d+Y$))?(?:(?:[-+]?\d+M)|(?:[-+]?\d+[.,]\d+M$))?(?:(?:[-+]?\d+W)|(?:[-+]?\d+[.,]\d+W$))?(?:(?:[-+]?\d+D)|(?:[-+]?\d+[.,]\d+D$))?(?:T(?=[\d+-])(?:(?:[-+]?\d+H)|(?:[-+]?\d+[.,]\d+H$))?(?:(?:[-+]?\d+M)|(?:[-+]?\d+[.,]\d+M$))?(?:[-+]?\d+(?:[.,]\d+)?S)?)??$/; + +// from https://stackoverflow.com/a/46181/1550155 +// old version: too slow, didn't support unicode +// const emailRegex = /^((([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+(\.([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+)*)|((\x22)((((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(([\x01-\x08\x0b\x0c\x0e-\x1f\x7f]|\x21|[\x23-\x5b]|[\x5d-\x7e]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(\\([\x01-\x09\x0b\x0c\x0d-\x7f]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]))))*(((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(\x22)))@((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))$/i; +//old email regex +// const emailRegex = /^(([^<>()[\].,;:\s@"]+(\.[^<>()[\].,;:\s@"]+)*)|(".+"))@((?!-)([^<>()[\].,;:\s@"]+\.)+[^<>()[\].,;:\s@"]{1,})[^-<>()[\].,;:\s@"]$/i; +// eslint-disable-next-line +// const emailRegex = +// /^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[(((25[0-5])|(2[0-4][0-9])|(1[0-9]{2})|([0-9]{1,2}))\.){3}((25[0-5])|(2[0-4][0-9])|(1[0-9]{2})|([0-9]{1,2}))\])|(\[IPv6:(([a-f0-9]{1,4}:){7}|::([a-f0-9]{1,4}:){0,6}|([a-f0-9]{1,4}:){1}:([a-f0-9]{1,4}:){0,5}|([a-f0-9]{1,4}:){2}:([a-f0-9]{1,4}:){0,4}|([a-f0-9]{1,4}:){3}:([a-f0-9]{1,4}:){0,3}|([a-f0-9]{1,4}:){4}:([a-f0-9]{1,4}:){0,2}|([a-f0-9]{1,4}:){5}:([a-f0-9]{1,4}:){0,1})([a-f0-9]{1,4}|(((25[0-5])|(2[0-4][0-9])|(1[0-9]{2})|([0-9]{1,2}))\.){3}((25[0-5])|(2[0-4][0-9])|(1[0-9]{2})|([0-9]{1,2})))\])|([A-Za-z0-9]([A-Za-z0-9-]*[A-Za-z0-9])*(\.[A-Za-z]{2,})+))$/; +// const emailRegex = +// /^[a-zA-Z0-9\.\!\#\$\%\&\'\*\+\/\=\?\^\_\`\{\|\}\~\-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/; +// const emailRegex = +// /^(?:[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*|"(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21\x23-\x5b\x5d-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])*")@(?:(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?|\[(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?|[a-z0-9-]*[a-z0-9]:(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21-\x5a\x53-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])+)\])$/i; +const emailRegex = /^(?!\.)(?!.*\.\.)([A-Z0-9_'+\-\.]*)[A-Z0-9_+-]@([A-Z0-9][A-Z0-9\-]*\.)+[A-Z]{2,}$/i; +// const emailRegex = +// /^[a-z0-9.!#$%&’*+/=?^_`{|}~-]+@[a-z0-9-]+(?:\.[a-z0-9\-]+)*$/i; + +// from https://thekevinscott.com/emojis-in-javascript/#writing-a-regular-expression +const _emojiRegex = `^(\\p{Extended_Pictographic}|\\p{Emoji_Component})+$`; +let emojiRegex: RegExp; + +// faster, simpler, safer +const ipv4Regex = + /^(?:(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\.){3}(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])$/; +const ipv4CidrRegex = + /^(?:(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\.){3}(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\/(3[0-2]|[12]?[0-9])$/; + +// const ipv6Regex = +// /^(([a-f0-9]{1,4}:){7}|::([a-f0-9]{1,4}:){0,6}|([a-f0-9]{1,4}:){1}:([a-f0-9]{1,4}:){0,5}|([a-f0-9]{1,4}:){2}:([a-f0-9]{1,4}:){0,4}|([a-f0-9]{1,4}:){3}:([a-f0-9]{1,4}:){0,3}|([a-f0-9]{1,4}:){4}:([a-f0-9]{1,4}:){0,2}|([a-f0-9]{1,4}:){5}:([a-f0-9]{1,4}:){0,1})([a-f0-9]{1,4}|(((25[0-5])|(2[0-4][0-9])|(1[0-9]{2})|([0-9]{1,2}))\.){3}((25[0-5])|(2[0-4][0-9])|(1[0-9]{2})|([0-9]{1,2})))$/; +const ipv6Regex = + /^(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))$/; +const ipv6CidrRegex = + /^(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))\/(12[0-8]|1[01][0-9]|[1-9]?[0-9])$/; + +// https://stackoverflow.com/questions/7860392/determine-if-string-is-in-base64-using-javascript +const base64Regex = /^([0-9a-zA-Z+/]{4})*(([0-9a-zA-Z+/]{2}==)|([0-9a-zA-Z+/]{3}=))?$/; + +// https://base64.guru/standards/base64url +const base64urlRegex = /^([0-9a-zA-Z-_]{4})*(([0-9a-zA-Z-_]{2}(==)?)|([0-9a-zA-Z-_]{3}(=)?))?$/; + +// simple +// const dateRegexSource = `\\d{4}-\\d{2}-\\d{2}`; +// no leap year validation +// const dateRegexSource = `\\d{4}-((0[13578]|10|12)-31|(0[13-9]|1[0-2])-30|(0[1-9]|1[0-2])-(0[1-9]|1\\d|2\\d))`; +// with leap year validation +const dateRegexSource = `((\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-((0[13578]|1[02])-(0[1-9]|[12]\\d|3[01])|(0[469]|11)-(0[1-9]|[12]\\d|30)|(02)-(0[1-9]|1\\d|2[0-8])))`; +const dateRegex = new RegExp(`^${dateRegexSource}$`); + +function timeRegexSource(args: { precision?: number | null }) { + let secondsRegexSource = `[0-5]\\d`; + if (args.precision) { + secondsRegexSource = `${secondsRegexSource}\\.\\d{${args.precision}}`; + } else if (args.precision == null) { + secondsRegexSource = `${secondsRegexSource}(\\.\\d+)?`; + } + + const secondsQuantifier = args.precision ? "+" : "?"; // require seconds if precision is nonzero + return `([01]\\d|2[0-3]):[0-5]\\d(:${secondsRegexSource})${secondsQuantifier}`; +} + +function timeRegex(args: { + offset?: boolean; + local?: boolean; + precision?: number | null; +}) { + return new RegExp(`^${timeRegexSource(args)}$`); +} + +// Adapted from https://stackoverflow.com/a/3143231 +export function datetimeRegex(args: { + precision?: number | null; + offset?: boolean; + local?: boolean; +}) { + let regex = `${dateRegexSource}T${timeRegexSource(args)}`; + + const opts: string[] = []; + opts.push(args.local ? `Z?` : `Z`); + if (args.offset) opts.push(`([+-]\\d{2}:?\\d{2})`); + regex = `${regex}(${opts.join("|")})`; + return new RegExp(`^${regex}$`); +} + +function isValidIP(ip: string, version?: IpVersion) { + if ((version === "v4" || !version) && ipv4Regex.test(ip)) { + return true; + } + if ((version === "v6" || !version) && ipv6Regex.test(ip)) { + return true; + } + + return false; +} + +function isValidJWT(jwt: string, alg?: string): boolean { + if (!jwtRegex.test(jwt)) return false; + try { + const [header] = jwt.split("."); + if (!header) return false; + // Convert base64url to base64 + const base64 = header + .replace(/-/g, "+") + .replace(/_/g, "/") + .padEnd(header.length + ((4 - (header.length % 4)) % 4), "="); + // @ts-ignore + const decoded = JSON.parse(atob(base64)); + if (typeof decoded !== "object" || decoded === null) return false; + if ("typ" in decoded && decoded?.typ !== "JWT") return false; + if (!decoded.alg) return false; + if (alg && decoded.alg !== alg) return false; + return true; + } catch { + return false; + } +} + +function isValidCidr(ip: string, version?: IpVersion) { + if ((version === "v4" || !version) && ipv4CidrRegex.test(ip)) { + return true; + } + if ((version === "v6" || !version) && ipv6CidrRegex.test(ip)) { + return true; + } + + return false; +} + +export class ZodString extends ZodType { + _parse(input: ParseInput): ParseReturnType { + if (this._def.coerce) { + input.data = String(input.data); + } + const parsedType = this._getType(input); + + if (parsedType !== ZodParsedType.string) { + const ctx = this._getOrReturnCtx(input); + addIssueToContext(ctx, { + code: ZodIssueCode.invalid_type, + expected: ZodParsedType.string, + received: ctx.parsedType, + }); + return INVALID; + } + + const status = new ParseStatus(); + let ctx: undefined | ParseContext = undefined; + + for (const check of this._def.checks) { + if (check.kind === "min") { + if (input.data.length < check.value) { + ctx = this._getOrReturnCtx(input, ctx); + addIssueToContext(ctx, { + code: ZodIssueCode.too_small, + minimum: check.value, + type: "string", + inclusive: true, + exact: false, + message: check.message, + }); + status.dirty(); + } + } else if (check.kind === "max") { + if (input.data.length > check.value) { + ctx = this._getOrReturnCtx(input, ctx); + addIssueToContext(ctx, { + code: ZodIssueCode.too_big, + maximum: check.value, + type: "string", + inclusive: true, + exact: false, + message: check.message, + }); + status.dirty(); + } + } else if (check.kind === "length") { + const tooBig = input.data.length > check.value; + const tooSmall = input.data.length < check.value; + if (tooBig || tooSmall) { + ctx = this._getOrReturnCtx(input, ctx); + if (tooBig) { + addIssueToContext(ctx, { + code: ZodIssueCode.too_big, + maximum: check.value, + type: "string", + inclusive: true, + exact: true, + message: check.message, + }); + } else if (tooSmall) { + addIssueToContext(ctx, { + code: ZodIssueCode.too_small, + minimum: check.value, + type: "string", + inclusive: true, + exact: true, + message: check.message, + }); + } + status.dirty(); + } + } else if (check.kind === "email") { + if (!emailRegex.test(input.data)) { + ctx = this._getOrReturnCtx(input, ctx); + addIssueToContext(ctx, { + validation: "email", + code: ZodIssueCode.invalid_string, + message: check.message, + }); + status.dirty(); + } + } else if (check.kind === "emoji") { + if (!emojiRegex) { + emojiRegex = new RegExp(_emojiRegex, "u"); + } + if (!emojiRegex.test(input.data)) { + ctx = this._getOrReturnCtx(input, ctx); + addIssueToContext(ctx, { + validation: "emoji", + code: ZodIssueCode.invalid_string, + message: check.message, + }); + status.dirty(); + } + } else if (check.kind === "uuid") { + if (!uuidRegex.test(input.data)) { + ctx = this._getOrReturnCtx(input, ctx); + addIssueToContext(ctx, { + validation: "uuid", + code: ZodIssueCode.invalid_string, + message: check.message, + }); + status.dirty(); + } + } else if (check.kind === "nanoid") { + if (!nanoidRegex.test(input.data)) { + ctx = this._getOrReturnCtx(input, ctx); + addIssueToContext(ctx, { + validation: "nanoid", + code: ZodIssueCode.invalid_string, + message: check.message, + }); + status.dirty(); + } + } else if (check.kind === "cuid") { + if (!cuidRegex.test(input.data)) { + ctx = this._getOrReturnCtx(input, ctx); + addIssueToContext(ctx, { + validation: "cuid", + code: ZodIssueCode.invalid_string, + message: check.message, + }); + status.dirty(); + } + } else if (check.kind === "cuid2") { + if (!cuid2Regex.test(input.data)) { + ctx = this._getOrReturnCtx(input, ctx); + addIssueToContext(ctx, { + validation: "cuid2", + code: ZodIssueCode.invalid_string, + message: check.message, + }); + status.dirty(); + } + } else if (check.kind === "ulid") { + if (!ulidRegex.test(input.data)) { + ctx = this._getOrReturnCtx(input, ctx); + addIssueToContext(ctx, { + validation: "ulid", + code: ZodIssueCode.invalid_string, + message: check.message, + }); + status.dirty(); + } + } else if (check.kind === "url") { + try { + // @ts-ignore + new URL(input.data); + } catch { + ctx = this._getOrReturnCtx(input, ctx); + addIssueToContext(ctx, { + validation: "url", + code: ZodIssueCode.invalid_string, + message: check.message, + }); + status.dirty(); + } + } else if (check.kind === "regex") { + check.regex.lastIndex = 0; + const testResult = check.regex.test(input.data); + if (!testResult) { + ctx = this._getOrReturnCtx(input, ctx); + addIssueToContext(ctx, { + validation: "regex", + code: ZodIssueCode.invalid_string, + message: check.message, + }); + status.dirty(); + } + } else if (check.kind === "trim") { + input.data = input.data.trim(); + } else if (check.kind === "includes") { + if (!(input.data as string).includes(check.value, check.position)) { + ctx = this._getOrReturnCtx(input, ctx); + addIssueToContext(ctx, { + code: ZodIssueCode.invalid_string, + validation: { includes: check.value, position: check.position }, + message: check.message, + }); + status.dirty(); + } + } else if (check.kind === "toLowerCase") { + input.data = input.data.toLowerCase(); + } else if (check.kind === "toUpperCase") { + input.data = input.data.toUpperCase(); + } else if (check.kind === "startsWith") { + if (!(input.data as string).startsWith(check.value)) { + ctx = this._getOrReturnCtx(input, ctx); + addIssueToContext(ctx, { + code: ZodIssueCode.invalid_string, + validation: { startsWith: check.value }, + message: check.message, + }); + status.dirty(); + } + } else if (check.kind === "endsWith") { + if (!(input.data as string).endsWith(check.value)) { + ctx = this._getOrReturnCtx(input, ctx); + addIssueToContext(ctx, { + code: ZodIssueCode.invalid_string, + validation: { endsWith: check.value }, + message: check.message, + }); + status.dirty(); + } + } else if (check.kind === "datetime") { + const regex = datetimeRegex(check); + + if (!regex.test(input.data)) { + ctx = this._getOrReturnCtx(input, ctx); + addIssueToContext(ctx, { + code: ZodIssueCode.invalid_string, + validation: "datetime", + message: check.message, + }); + status.dirty(); + } + } else if (check.kind === "date") { + const regex = dateRegex; + + if (!regex.test(input.data)) { + ctx = this._getOrReturnCtx(input, ctx); + addIssueToContext(ctx, { + code: ZodIssueCode.invalid_string, + validation: "date", + message: check.message, + }); + status.dirty(); + } + } else if (check.kind === "time") { + const regex = timeRegex(check); + + if (!regex.test(input.data)) { + ctx = this._getOrReturnCtx(input, ctx); + addIssueToContext(ctx, { + code: ZodIssueCode.invalid_string, + validation: "time", + message: check.message, + }); + status.dirty(); + } + } else if (check.kind === "duration") { + if (!durationRegex.test(input.data)) { + ctx = this._getOrReturnCtx(input, ctx); + addIssueToContext(ctx, { + validation: "duration", + code: ZodIssueCode.invalid_string, + message: check.message, + }); + status.dirty(); + } + } else if (check.kind === "ip") { + if (!isValidIP(input.data, check.version)) { + ctx = this._getOrReturnCtx(input, ctx); + addIssueToContext(ctx, { + validation: "ip", + code: ZodIssueCode.invalid_string, + message: check.message, + }); + status.dirty(); + } + } else if (check.kind === "jwt") { + if (!isValidJWT(input.data, check.alg)) { + ctx = this._getOrReturnCtx(input, ctx); + addIssueToContext(ctx, { + validation: "jwt", + code: ZodIssueCode.invalid_string, + message: check.message, + }); + status.dirty(); + } + } else if (check.kind === "cidr") { + if (!isValidCidr(input.data, check.version)) { + ctx = this._getOrReturnCtx(input, ctx); + addIssueToContext(ctx, { + validation: "cidr", + code: ZodIssueCode.invalid_string, + message: check.message, + }); + status.dirty(); + } + } else if (check.kind === "base64") { + if (!base64Regex.test(input.data)) { + ctx = this._getOrReturnCtx(input, ctx); + addIssueToContext(ctx, { + validation: "base64", + code: ZodIssueCode.invalid_string, + message: check.message, + }); + status.dirty(); + } + } else if (check.kind === "base64url") { + if (!base64urlRegex.test(input.data)) { + ctx = this._getOrReturnCtx(input, ctx); + addIssueToContext(ctx, { + validation: "base64url", + code: ZodIssueCode.invalid_string, + message: check.message, + }); + status.dirty(); + } + } else { + util.assertNever(check); + } + } + + return { status: status.value, value: input.data }; + } + + protected _regex(regex: RegExp, validation: StringValidation, message?: errorUtil.ErrMessage) { + return this.refinement((data) => regex.test(data), { + validation, + code: ZodIssueCode.invalid_string, + ...errorUtil.errToObj(message), + }); + } + + _addCheck(check: ZodStringCheck) { + return new ZodString({ + ...this._def, + checks: [...this._def.checks, check], + }); + } + + email(message?: errorUtil.ErrMessage) { + return this._addCheck({ kind: "email", ...errorUtil.errToObj(message) }); + } + + url(message?: errorUtil.ErrMessage) { + return this._addCheck({ kind: "url", ...errorUtil.errToObj(message) }); + } + + emoji(message?: errorUtil.ErrMessage) { + return this._addCheck({ kind: "emoji", ...errorUtil.errToObj(message) }); + } + + uuid(message?: errorUtil.ErrMessage) { + return this._addCheck({ kind: "uuid", ...errorUtil.errToObj(message) }); + } + nanoid(message?: errorUtil.ErrMessage) { + return this._addCheck({ kind: "nanoid", ...errorUtil.errToObj(message) }); + } + cuid(message?: errorUtil.ErrMessage) { + return this._addCheck({ kind: "cuid", ...errorUtil.errToObj(message) }); + } + + cuid2(message?: errorUtil.ErrMessage) { + return this._addCheck({ kind: "cuid2", ...errorUtil.errToObj(message) }); + } + ulid(message?: errorUtil.ErrMessage) { + return this._addCheck({ kind: "ulid", ...errorUtil.errToObj(message) }); + } + base64(message?: errorUtil.ErrMessage) { + return this._addCheck({ kind: "base64", ...errorUtil.errToObj(message) }); + } + base64url(message?: errorUtil.ErrMessage) { + // base64url encoding is a modification of base64 that can safely be used in URLs and filenames + return this._addCheck({ + kind: "base64url", + ...errorUtil.errToObj(message), + }); + } + + jwt(options?: { alg?: string; message?: string | undefined }) { + return this._addCheck({ kind: "jwt", ...errorUtil.errToObj(options) }); + } + + ip(options?: string | { version?: IpVersion; message?: string | undefined }) { + return this._addCheck({ kind: "ip", ...errorUtil.errToObj(options) }); + } + + cidr(options?: string | { version?: IpVersion; message?: string | undefined }) { + return this._addCheck({ kind: "cidr", ...errorUtil.errToObj(options) }); + } + + datetime( + options?: + | string + | { + message?: string | undefined; + precision?: number | null; + offset?: boolean; + local?: boolean; + } + ) { + if (typeof options === "string") { + return this._addCheck({ + kind: "datetime", + precision: null, + offset: false, + local: false, + message: options, + }); + } + return this._addCheck({ + kind: "datetime", + + precision: typeof options?.precision === "undefined" ? null : options?.precision, + offset: options?.offset ?? false, + local: options?.local ?? false, + ...errorUtil.errToObj(options?.message), + }); + } + + date(message?: string) { + return this._addCheck({ kind: "date", message }); + } + + time( + options?: + | string + | { + message?: string | undefined; + precision?: number | null; + } + ) { + if (typeof options === "string") { + return this._addCheck({ + kind: "time", + precision: null, + message: options, + }); + } + return this._addCheck({ + kind: "time", + precision: typeof options?.precision === "undefined" ? null : options?.precision, + ...errorUtil.errToObj(options?.message), + }); + } + + duration(message?: errorUtil.ErrMessage) { + return this._addCheck({ kind: "duration", ...errorUtil.errToObj(message) }); + } + + regex(regex: RegExp, message?: errorUtil.ErrMessage) { + return this._addCheck({ + kind: "regex", + regex: regex, + ...errorUtil.errToObj(message), + }); + } + + includes(value: string, options?: { message?: string; position?: number }) { + return this._addCheck({ + kind: "includes", + value: value, + position: options?.position, + ...errorUtil.errToObj(options?.message), + }); + } + + startsWith(value: string, message?: errorUtil.ErrMessage) { + return this._addCheck({ + kind: "startsWith", + value: value, + ...errorUtil.errToObj(message), + }); + } + + endsWith(value: string, message?: errorUtil.ErrMessage) { + return this._addCheck({ + kind: "endsWith", + value: value, + ...errorUtil.errToObj(message), + }); + } + + min(minLength: number, message?: errorUtil.ErrMessage) { + return this._addCheck({ + kind: "min", + value: minLength, + ...errorUtil.errToObj(message), + }); + } + + max(maxLength: number, message?: errorUtil.ErrMessage) { + return this._addCheck({ + kind: "max", + value: maxLength, + ...errorUtil.errToObj(message), + }); + } + + length(len: number, message?: errorUtil.ErrMessage) { + return this._addCheck({ + kind: "length", + value: len, + ...errorUtil.errToObj(message), + }); + } + + /** + * Equivalent to `.min(1)` + */ + nonempty(message?: errorUtil.ErrMessage) { + return this.min(1, errorUtil.errToObj(message)); + } + + trim() { + return new ZodString({ + ...this._def, + checks: [...this._def.checks, { kind: "trim" }], + }); + } + + toLowerCase() { + return new ZodString({ + ...this._def, + checks: [...this._def.checks, { kind: "toLowerCase" }], + }); + } + + toUpperCase() { + return new ZodString({ + ...this._def, + checks: [...this._def.checks, { kind: "toUpperCase" }], + }); + } + + get isDatetime() { + return !!this._def.checks.find((ch) => ch.kind === "datetime"); + } + + get isDate() { + return !!this._def.checks.find((ch) => ch.kind === "date"); + } + + get isTime() { + return !!this._def.checks.find((ch) => ch.kind === "time"); + } + get isDuration() { + return !!this._def.checks.find((ch) => ch.kind === "duration"); + } + + get isEmail() { + return !!this._def.checks.find((ch) => ch.kind === "email"); + } + + get isURL() { + return !!this._def.checks.find((ch) => ch.kind === "url"); + } + + get isEmoji() { + return !!this._def.checks.find((ch) => ch.kind === "emoji"); + } + + get isUUID() { + return !!this._def.checks.find((ch) => ch.kind === "uuid"); + } + get isNANOID() { + return !!this._def.checks.find((ch) => ch.kind === "nanoid"); + } + get isCUID() { + return !!this._def.checks.find((ch) => ch.kind === "cuid"); + } + + get isCUID2() { + return !!this._def.checks.find((ch) => ch.kind === "cuid2"); + } + get isULID() { + return !!this._def.checks.find((ch) => ch.kind === "ulid"); + } + get isIP() { + return !!this._def.checks.find((ch) => ch.kind === "ip"); + } + get isCIDR() { + return !!this._def.checks.find((ch) => ch.kind === "cidr"); + } + get isBase64() { + return !!this._def.checks.find((ch) => ch.kind === "base64"); + } + get isBase64url() { + // base64url encoding is a modification of base64 that can safely be used in URLs and filenames + return !!this._def.checks.find((ch) => ch.kind === "base64url"); + } + + get minLength() { + let min: number | null = null; + for (const ch of this._def.checks) { + if (ch.kind === "min") { + if (min === null || ch.value > min) min = ch.value; + } + } + return min; + } + + get maxLength() { + let max: number | null = null; + for (const ch of this._def.checks) { + if (ch.kind === "max") { + if (max === null || ch.value < max) max = ch.value; + } + } + return max; + } + + static create = (params?: RawCreateParams & { coerce?: true }): ZodString => { + return new ZodString({ + checks: [], + typeName: ZodFirstPartyTypeKind.ZodString, + coerce: params?.coerce ?? false, + ...processCreateParams(params), + }); + }; +} + +///////////////////////////////////////// +///////////////////////////////////////// +////////// ////////// +////////// ZodNumber ////////// +////////// ////////// +///////////////////////////////////////// +///////////////////////////////////////// +export type ZodNumberCheck = + | { kind: "min"; value: number; inclusive: boolean; message?: string | undefined } + | { kind: "max"; value: number; inclusive: boolean; message?: string | undefined } + | { kind: "int"; message?: string | undefined } + | { kind: "multipleOf"; value: number; message?: string | undefined } + | { kind: "finite"; message?: string | undefined }; + +// https://stackoverflow.com/questions/3966484/why-does-modulus-operator-return-fractional-number-in-javascript/31711034#31711034 +function floatSafeRemainder(val: number, step: number) { + const valDecCount = (val.toString().split(".")[1] || "").length; + const stepDecCount = (step.toString().split(".")[1] || "").length; + const decCount = valDecCount > stepDecCount ? valDecCount : stepDecCount; + const valInt = Number.parseInt(val.toFixed(decCount).replace(".", "")); + const stepInt = Number.parseInt(step.toFixed(decCount).replace(".", "")); + return (valInt % stepInt) / 10 ** decCount; +} + +export interface ZodNumberDef extends ZodTypeDef { + checks: ZodNumberCheck[]; + typeName: ZodFirstPartyTypeKind.ZodNumber; + coerce: boolean; +} + +export class ZodNumber extends ZodType { + _parse(input: ParseInput): ParseReturnType { + if (this._def.coerce) { + input.data = Number(input.data); + } + const parsedType = this._getType(input); + if (parsedType !== ZodParsedType.number) { + const ctx = this._getOrReturnCtx(input); + addIssueToContext(ctx, { + code: ZodIssueCode.invalid_type, + expected: ZodParsedType.number, + received: ctx.parsedType, + }); + return INVALID; + } + + let ctx: undefined | ParseContext = undefined; + const status = new ParseStatus(); + + for (const check of this._def.checks) { + if (check.kind === "int") { + if (!util.isInteger(input.data)) { + ctx = this._getOrReturnCtx(input, ctx); + addIssueToContext(ctx, { + code: ZodIssueCode.invalid_type, + expected: "integer", + received: "float", + message: check.message, + }); + status.dirty(); + } + } else if (check.kind === "min") { + const tooSmall = check.inclusive ? input.data < check.value : input.data <= check.value; + if (tooSmall) { + ctx = this._getOrReturnCtx(input, ctx); + addIssueToContext(ctx, { + code: ZodIssueCode.too_small, + minimum: check.value, + type: "number", + inclusive: check.inclusive, + exact: false, + message: check.message, + }); + status.dirty(); + } + } else if (check.kind === "max") { + const tooBig = check.inclusive ? input.data > check.value : input.data >= check.value; + if (tooBig) { + ctx = this._getOrReturnCtx(input, ctx); + addIssueToContext(ctx, { + code: ZodIssueCode.too_big, + maximum: check.value, + type: "number", + inclusive: check.inclusive, + exact: false, + message: check.message, + }); + status.dirty(); + } + } else if (check.kind === "multipleOf") { + if (floatSafeRemainder(input.data, check.value) !== 0) { + ctx = this._getOrReturnCtx(input, ctx); + addIssueToContext(ctx, { + code: ZodIssueCode.not_multiple_of, + multipleOf: check.value, + message: check.message, + }); + status.dirty(); + } + } else if (check.kind === "finite") { + if (!Number.isFinite(input.data)) { + ctx = this._getOrReturnCtx(input, ctx); + addIssueToContext(ctx, { + code: ZodIssueCode.not_finite, + message: check.message, + }); + status.dirty(); + } + } else { + util.assertNever(check); + } + } + + return { status: status.value, value: input.data }; + } + + static create = (params?: RawCreateParams & { coerce?: boolean }): ZodNumber => { + return new ZodNumber({ + checks: [], + typeName: ZodFirstPartyTypeKind.ZodNumber, + coerce: params?.coerce || false, + ...processCreateParams(params), + }); + }; + + gte(value: number, message?: errorUtil.ErrMessage) { + return this.setLimit("min", value, true, errorUtil.toString(message)); + } + min = this.gte; + + gt(value: number, message?: errorUtil.ErrMessage) { + return this.setLimit("min", value, false, errorUtil.toString(message)); + } + + lte(value: number, message?: errorUtil.ErrMessage) { + return this.setLimit("max", value, true, errorUtil.toString(message)); + } + max = this.lte; + + lt(value: number, message?: errorUtil.ErrMessage) { + return this.setLimit("max", value, false, errorUtil.toString(message)); + } + + protected setLimit(kind: "min" | "max", value: number, inclusive: boolean, message?: string) { + return new ZodNumber({ + ...this._def, + checks: [ + ...this._def.checks, + { + kind, + value, + inclusive, + message: errorUtil.toString(message), + }, + ], + }); + } + + _addCheck(check: ZodNumberCheck) { + return new ZodNumber({ + ...this._def, + checks: [...this._def.checks, check], + }); + } + + int(message?: errorUtil.ErrMessage) { + return this._addCheck({ + kind: "int", + message: errorUtil.toString(message), + }); + } + + positive(message?: errorUtil.ErrMessage) { + return this._addCheck({ + kind: "min", + value: 0, + inclusive: false, + message: errorUtil.toString(message), + }); + } + + negative(message?: errorUtil.ErrMessage) { + return this._addCheck({ + kind: "max", + value: 0, + inclusive: false, + message: errorUtil.toString(message), + }); + } + + nonpositive(message?: errorUtil.ErrMessage) { + return this._addCheck({ + kind: "max", + value: 0, + inclusive: true, + message: errorUtil.toString(message), + }); + } + + nonnegative(message?: errorUtil.ErrMessage) { + return this._addCheck({ + kind: "min", + value: 0, + inclusive: true, + message: errorUtil.toString(message), + }); + } + + multipleOf(value: number, message?: errorUtil.ErrMessage) { + return this._addCheck({ + kind: "multipleOf", + value: value, + message: errorUtil.toString(message), + }); + } + step = this.multipleOf; + + finite(message?: errorUtil.ErrMessage) { + return this._addCheck({ + kind: "finite", + message: errorUtil.toString(message), + }); + } + + safe(message?: errorUtil.ErrMessage) { + return this._addCheck({ + kind: "min", + inclusive: true, + value: Number.MIN_SAFE_INTEGER, + message: errorUtil.toString(message), + })._addCheck({ + kind: "max", + inclusive: true, + value: Number.MAX_SAFE_INTEGER, + message: errorUtil.toString(message), + }); + } + + get minValue() { + let min: number | null = null; + for (const ch of this._def.checks) { + if (ch.kind === "min") { + if (min === null || ch.value > min) min = ch.value; + } + } + return min; + } + + get maxValue() { + let max: number | null = null; + for (const ch of this._def.checks) { + if (ch.kind === "max") { + if (max === null || ch.value < max) max = ch.value; + } + } + return max; + } + + get isInt() { + return !!this._def.checks.find((ch) => ch.kind === "int" || (ch.kind === "multipleOf" && util.isInteger(ch.value))); + } + + get isFinite() { + let max: number | null = null; + let min: number | null = null; + for (const ch of this._def.checks) { + if (ch.kind === "finite" || ch.kind === "int" || ch.kind === "multipleOf") { + return true; + } else if (ch.kind === "min") { + if (min === null || ch.value > min) min = ch.value; + } else if (ch.kind === "max") { + if (max === null || ch.value < max) max = ch.value; + } + } + return Number.isFinite(min) && Number.isFinite(max); + } +} + +///////////////////////////////////////// +///////////////////////////////////////// +////////// ////////// +////////// ZodBigInt ////////// +////////// ////////// +///////////////////////////////////////// +///////////////////////////////////////// +export type ZodBigIntCheck = + | { kind: "min"; value: bigint; inclusive: boolean; message?: string | undefined } + | { kind: "max"; value: bigint; inclusive: boolean; message?: string | undefined } + | { kind: "multipleOf"; value: bigint; message?: string | undefined }; + +export interface ZodBigIntDef extends ZodTypeDef { + checks: ZodBigIntCheck[]; + typeName: ZodFirstPartyTypeKind.ZodBigInt; + coerce: boolean; +} + +export class ZodBigInt extends ZodType { + _parse(input: ParseInput): ParseReturnType { + if (this._def.coerce) { + try { + input.data = BigInt(input.data); + } catch { + return this._getInvalidInput(input); + } + } + const parsedType = this._getType(input); + if (parsedType !== ZodParsedType.bigint) { + return this._getInvalidInput(input); + } + + let ctx: undefined | ParseContext = undefined; + const status = new ParseStatus(); + + for (const check of this._def.checks) { + if (check.kind === "min") { + const tooSmall = check.inclusive ? input.data < check.value : input.data <= check.value; + if (tooSmall) { + ctx = this._getOrReturnCtx(input, ctx); + addIssueToContext(ctx, { + code: ZodIssueCode.too_small, + type: "bigint", + minimum: check.value, + inclusive: check.inclusive, + message: check.message, + }); + status.dirty(); + } + } else if (check.kind === "max") { + const tooBig = check.inclusive ? input.data > check.value : input.data >= check.value; + if (tooBig) { + ctx = this._getOrReturnCtx(input, ctx); + addIssueToContext(ctx, { + code: ZodIssueCode.too_big, + type: "bigint", + maximum: check.value, + inclusive: check.inclusive, + message: check.message, + }); + status.dirty(); + } + } else if (check.kind === "multipleOf") { + if (input.data % check.value !== BigInt(0)) { + ctx = this._getOrReturnCtx(input, ctx); + addIssueToContext(ctx, { + code: ZodIssueCode.not_multiple_of, + multipleOf: check.value, + message: check.message, + }); + status.dirty(); + } + } else { + util.assertNever(check); + } + } + + return { status: status.value, value: input.data }; + } + + _getInvalidInput(input: ParseInput) { + const ctx = this._getOrReturnCtx(input); + addIssueToContext(ctx, { + code: ZodIssueCode.invalid_type, + expected: ZodParsedType.bigint, + received: ctx.parsedType, + }); + return INVALID; + } + + static create = (params?: RawCreateParams & { coerce?: boolean }): ZodBigInt => { + return new ZodBigInt({ + checks: [], + typeName: ZodFirstPartyTypeKind.ZodBigInt, + coerce: params?.coerce ?? false, + ...processCreateParams(params), + }); + }; + + gte(value: bigint, message?: errorUtil.ErrMessage) { + return this.setLimit("min", value, true, errorUtil.toString(message)); + } + min = this.gte; + + gt(value: bigint, message?: errorUtil.ErrMessage) { + return this.setLimit("min", value, false, errorUtil.toString(message)); + } + + lte(value: bigint, message?: errorUtil.ErrMessage) { + return this.setLimit("max", value, true, errorUtil.toString(message)); + } + max = this.lte; + + lt(value: bigint, message?: errorUtil.ErrMessage) { + return this.setLimit("max", value, false, errorUtil.toString(message)); + } + + protected setLimit(kind: "min" | "max", value: bigint, inclusive: boolean, message?: string) { + return new ZodBigInt({ + ...this._def, + checks: [ + ...this._def.checks, + { + kind, + value, + inclusive, + message: errorUtil.toString(message), + }, + ], + }); + } + + _addCheck(check: ZodBigIntCheck) { + return new ZodBigInt({ + ...this._def, + checks: [...this._def.checks, check], + }); + } + + positive(message?: errorUtil.ErrMessage) { + return this._addCheck({ + kind: "min", + value: BigInt(0), + inclusive: false, + message: errorUtil.toString(message), + }); + } + + negative(message?: errorUtil.ErrMessage) { + return this._addCheck({ + kind: "max", + value: BigInt(0), + inclusive: false, + message: errorUtil.toString(message), + }); + } + + nonpositive(message?: errorUtil.ErrMessage) { + return this._addCheck({ + kind: "max", + value: BigInt(0), + inclusive: true, + message: errorUtil.toString(message), + }); + } + + nonnegative(message?: errorUtil.ErrMessage) { + return this._addCheck({ + kind: "min", + value: BigInt(0), + inclusive: true, + message: errorUtil.toString(message), + }); + } + + multipleOf(value: bigint, message?: errorUtil.ErrMessage) { + return this._addCheck({ + kind: "multipleOf", + value, + message: errorUtil.toString(message), + }); + } + + get minValue() { + let min: bigint | null = null; + for (const ch of this._def.checks) { + if (ch.kind === "min") { + if (min === null || ch.value > min) min = ch.value; + } + } + return min; + } + + get maxValue() { + let max: bigint | null = null; + for (const ch of this._def.checks) { + if (ch.kind === "max") { + if (max === null || ch.value < max) max = ch.value; + } + } + return max; + } +} + +////////////////////////////////////////// +////////////////////////////////////////// +////////// /////////// +////////// ZodBoolean ////////// +////////// /////////// +////////////////////////////////////////// +////////////////////////////////////////// +export interface ZodBooleanDef extends ZodTypeDef { + typeName: ZodFirstPartyTypeKind.ZodBoolean; + coerce: boolean; +} + +export class ZodBoolean extends ZodType { + _parse(input: ParseInput): ParseReturnType { + if (this._def.coerce) { + input.data = Boolean(input.data); + } + const parsedType = this._getType(input); + + if (parsedType !== ZodParsedType.boolean) { + const ctx = this._getOrReturnCtx(input); + addIssueToContext(ctx, { + code: ZodIssueCode.invalid_type, + expected: ZodParsedType.boolean, + received: ctx.parsedType, + }); + return INVALID; + } + return OK(input.data); + } + + static create = (params?: RawCreateParams & { coerce?: boolean }): ZodBoolean => { + return new ZodBoolean({ + typeName: ZodFirstPartyTypeKind.ZodBoolean, + coerce: params?.coerce || false, + ...processCreateParams(params), + }); + }; +} + +/////////////////////////////////////// +/////////////////////////////////////// +////////// //////// +////////// ZodDate //////// +////////// //////// +/////////////////////////////////////// +/////////////////////////////////////// +export type ZodDateCheck = + | { kind: "min"; value: number; message?: string | undefined } + | { kind: "max"; value: number; message?: string | undefined }; +export interface ZodDateDef extends ZodTypeDef { + checks: ZodDateCheck[]; + coerce: boolean; + typeName: ZodFirstPartyTypeKind.ZodDate; +} + +export class ZodDate extends ZodType { + _parse(input: ParseInput): ParseReturnType { + if (this._def.coerce) { + input.data = new Date(input.data); + } + const parsedType = this._getType(input); + + if (parsedType !== ZodParsedType.date) { + const ctx = this._getOrReturnCtx(input); + addIssueToContext(ctx, { + code: ZodIssueCode.invalid_type, + expected: ZodParsedType.date, + received: ctx.parsedType, + }); + return INVALID; + } + + if (Number.isNaN(input.data.getTime())) { + const ctx = this._getOrReturnCtx(input); + addIssueToContext(ctx, { + code: ZodIssueCode.invalid_date, + }); + return INVALID; + } + + const status = new ParseStatus(); + let ctx: undefined | ParseContext = undefined; + + for (const check of this._def.checks) { + if (check.kind === "min") { + if (input.data.getTime() < check.value) { + ctx = this._getOrReturnCtx(input, ctx); + addIssueToContext(ctx, { + code: ZodIssueCode.too_small, + message: check.message, + inclusive: true, + exact: false, + minimum: check.value, + type: "date", + }); + status.dirty(); + } + } else if (check.kind === "max") { + if (input.data.getTime() > check.value) { + ctx = this._getOrReturnCtx(input, ctx); + addIssueToContext(ctx, { + code: ZodIssueCode.too_big, + message: check.message, + inclusive: true, + exact: false, + maximum: check.value, + type: "date", + }); + status.dirty(); + } + } else { + util.assertNever(check); + } + } + + return { + status: status.value, + value: new Date((input.data as Date).getTime()), + }; + } + + _addCheck(check: ZodDateCheck) { + return new ZodDate({ + ...this._def, + checks: [...this._def.checks, check], + }); + } + + min(minDate: Date, message?: errorUtil.ErrMessage) { + return this._addCheck({ + kind: "min", + value: minDate.getTime(), + message: errorUtil.toString(message), + }); + } + + max(maxDate: Date, message?: errorUtil.ErrMessage) { + return this._addCheck({ + kind: "max", + value: maxDate.getTime(), + message: errorUtil.toString(message), + }); + } + + get minDate() { + let min: number | null = null; + for (const ch of this._def.checks) { + if (ch.kind === "min") { + if (min === null || ch.value > min) min = ch.value; + } + } + + return min != null ? new Date(min) : null; + } + + get maxDate() { + let max: number | null = null; + for (const ch of this._def.checks) { + if (ch.kind === "max") { + if (max === null || ch.value < max) max = ch.value; + } + } + + return max != null ? new Date(max) : null; + } + + static create = (params?: RawCreateParams & { coerce?: boolean }): ZodDate => { + return new ZodDate({ + checks: [], + coerce: params?.coerce || false, + typeName: ZodFirstPartyTypeKind.ZodDate, + ...processCreateParams(params), + }); + }; +} + +//////////////////////////////////////////// +//////////////////////////////////////////// +////////// ////////// +////////// ZodSymbol ////////// +////////// ////////// +//////////////////////////////////////////// +//////////////////////////////////////////// +export interface ZodSymbolDef extends ZodTypeDef { + typeName: ZodFirstPartyTypeKind.ZodSymbol; +} + +export class ZodSymbol extends ZodType { + _parse(input: ParseInput): ParseReturnType { + const parsedType = this._getType(input); + if (parsedType !== ZodParsedType.symbol) { + const ctx = this._getOrReturnCtx(input); + addIssueToContext(ctx, { + code: ZodIssueCode.invalid_type, + expected: ZodParsedType.symbol, + received: ctx.parsedType, + }); + return INVALID; + } + + return OK(input.data); + } + + static create = (params?: RawCreateParams): ZodSymbol => { + return new ZodSymbol({ + typeName: ZodFirstPartyTypeKind.ZodSymbol, + ...processCreateParams(params), + }); + }; +} + +//////////////////////////////////////////// +//////////////////////////////////////////// +////////// ////////// +////////// ZodUndefined ////////// +////////// ////////// +//////////////////////////////////////////// +//////////////////////////////////////////// +export interface ZodUndefinedDef extends ZodTypeDef { + typeName: ZodFirstPartyTypeKind.ZodUndefined; +} + +export class ZodUndefined extends ZodType { + _parse(input: ParseInput): ParseReturnType { + const parsedType = this._getType(input); + if (parsedType !== ZodParsedType.undefined) { + const ctx = this._getOrReturnCtx(input); + addIssueToContext(ctx, { + code: ZodIssueCode.invalid_type, + expected: ZodParsedType.undefined, + received: ctx.parsedType, + }); + return INVALID; + } + return OK(input.data); + } + params?: RawCreateParams; + + static create = (params?: RawCreateParams): ZodUndefined => { + return new ZodUndefined({ + typeName: ZodFirstPartyTypeKind.ZodUndefined, + ...processCreateParams(params), + }); + }; +} + +/////////////////////////////////////// +/////////////////////////////////////// +////////// ////////// +////////// ZodNull ////////// +////////// ////////// +/////////////////////////////////////// +/////////////////////////////////////// +export interface ZodNullDef extends ZodTypeDef { + typeName: ZodFirstPartyTypeKind.ZodNull; +} + +export class ZodNull extends ZodType { + _parse(input: ParseInput): ParseReturnType { + const parsedType = this._getType(input); + if (parsedType !== ZodParsedType.null) { + const ctx = this._getOrReturnCtx(input); + addIssueToContext(ctx, { + code: ZodIssueCode.invalid_type, + expected: ZodParsedType.null, + received: ctx.parsedType, + }); + return INVALID; + } + return OK(input.data); + } + static create = (params?: RawCreateParams): ZodNull => { + return new ZodNull({ + typeName: ZodFirstPartyTypeKind.ZodNull, + ...processCreateParams(params), + }); + }; +} + +////////////////////////////////////// +////////////////////////////////////// +////////// ////////// +////////// ZodAny ////////// +////////// ////////// +////////////////////////////////////// +////////////////////////////////////// +export interface ZodAnyDef extends ZodTypeDef { + typeName: ZodFirstPartyTypeKind.ZodAny; +} + +export class ZodAny extends ZodType { + // to prevent instances of other classes from extending ZodAny. this causes issues with catchall in ZodObject. + _any = true as const; + _parse(input: ParseInput): ParseReturnType { + return OK(input.data); + } + static create = (params?: RawCreateParams): ZodAny => { + return new ZodAny({ + typeName: ZodFirstPartyTypeKind.ZodAny, + ...processCreateParams(params), + }); + }; +} + +////////////////////////////////////////// +////////////////////////////////////////// +////////// ////////// +////////// ZodUnknown ////////// +////////// ////////// +////////////////////////////////////////// +////////////////////////////////////////// +export interface ZodUnknownDef extends ZodTypeDef { + typeName: ZodFirstPartyTypeKind.ZodUnknown; +} + +export class ZodUnknown extends ZodType { + // required + _unknown = true as const; + _parse(input: ParseInput): ParseReturnType { + return OK(input.data); + } + + static create = (params?: RawCreateParams): ZodUnknown => { + return new ZodUnknown({ + typeName: ZodFirstPartyTypeKind.ZodUnknown, + ...processCreateParams(params), + }); + }; +} + +//////////////////////////////////////// +//////////////////////////////////////// +////////// ////////// +////////// ZodNever ////////// +////////// ////////// +//////////////////////////////////////// +//////////////////////////////////////// +export interface ZodNeverDef extends ZodTypeDef { + typeName: ZodFirstPartyTypeKind.ZodNever; +} + +export class ZodNever extends ZodType { + _parse(input: ParseInput): ParseReturnType { + const ctx = this._getOrReturnCtx(input); + addIssueToContext(ctx, { + code: ZodIssueCode.invalid_type, + expected: ZodParsedType.never, + received: ctx.parsedType, + }); + return INVALID; + } + static create = (params?: RawCreateParams): ZodNever => { + return new ZodNever({ + typeName: ZodFirstPartyTypeKind.ZodNever, + ...processCreateParams(params), + }); + }; +} + +/////////////////////////////////////// +/////////////////////////////////////// +////////// ////////// +////////// ZodVoid ////////// +////////// ////////// +/////////////////////////////////////// +/////////////////////////////////////// +export interface ZodVoidDef extends ZodTypeDef { + typeName: ZodFirstPartyTypeKind.ZodVoid; +} + +export class ZodVoid extends ZodType { + _parse(input: ParseInput): ParseReturnType { + const parsedType = this._getType(input); + if (parsedType !== ZodParsedType.undefined) { + const ctx = this._getOrReturnCtx(input); + addIssueToContext(ctx, { + code: ZodIssueCode.invalid_type, + expected: ZodParsedType.void, + received: ctx.parsedType, + }); + return INVALID; + } + return OK(input.data); + } + + static create = (params?: RawCreateParams): ZodVoid => { + return new ZodVoid({ + typeName: ZodFirstPartyTypeKind.ZodVoid, + ...processCreateParams(params), + }); + }; +} + +//////////////////////////////////////// +//////////////////////////////////////// +////////// ////////// +////////// ZodArray ////////// +////////// ////////// +//////////////////////////////////////// +//////////////////////////////////////// +export interface ZodArrayDef extends ZodTypeDef { + type: T; + typeName: ZodFirstPartyTypeKind.ZodArray; + exactLength: { value: number; message?: string | undefined } | null; + minLength: { value: number; message?: string | undefined } | null; + maxLength: { value: number; message?: string | undefined } | null; +} + +export type ArrayCardinality = "many" | "atleastone"; +export type arrayOutputType< + T extends ZodTypeAny, + Cardinality extends ArrayCardinality = "many", +> = Cardinality extends "atleastone" ? [T["_output"], ...T["_output"][]] : T["_output"][]; + +export class ZodArray extends ZodType< + arrayOutputType, + ZodArrayDef, + Cardinality extends "atleastone" ? [T["_input"], ...T["_input"][]] : T["_input"][] +> { + _parse(input: ParseInput): ParseReturnType { + const { ctx, status } = this._processInputParams(input); + + const def = this._def; + + if (ctx.parsedType !== ZodParsedType.array) { + addIssueToContext(ctx, { + code: ZodIssueCode.invalid_type, + expected: ZodParsedType.array, + received: ctx.parsedType, + }); + return INVALID; + } + + if (def.exactLength !== null) { + const tooBig = ctx.data.length > def.exactLength.value; + const tooSmall = ctx.data.length < def.exactLength.value; + if (tooBig || tooSmall) { + addIssueToContext(ctx, { + code: tooBig ? ZodIssueCode.too_big : ZodIssueCode.too_small, + minimum: (tooSmall ? def.exactLength.value : undefined) as number, + maximum: (tooBig ? def.exactLength.value : undefined) as number, + type: "array", + inclusive: true, + exact: true, + message: def.exactLength.message, + }); + status.dirty(); + } + } + + if (def.minLength !== null) { + if (ctx.data.length < def.minLength.value) { + addIssueToContext(ctx, { + code: ZodIssueCode.too_small, + minimum: def.minLength.value, + type: "array", + inclusive: true, + exact: false, + message: def.minLength.message, + }); + status.dirty(); + } + } + + if (def.maxLength !== null) { + if (ctx.data.length > def.maxLength.value) { + addIssueToContext(ctx, { + code: ZodIssueCode.too_big, + maximum: def.maxLength.value, + type: "array", + inclusive: true, + exact: false, + message: def.maxLength.message, + }); + status.dirty(); + } + } + + if (ctx.common.async) { + return Promise.all( + ([...ctx.data] as any[]).map((item, i) => { + return def.type._parseAsync(new ParseInputLazyPath(ctx, item, ctx.path, i)); + }) + ).then((result) => { + return ParseStatus.mergeArray(status, result); + }); + } + + const result = ([...ctx.data] as any[]).map((item, i) => { + return def.type._parseSync(new ParseInputLazyPath(ctx, item, ctx.path, i)); + }); + + return ParseStatus.mergeArray(status, result); + } + + get element() { + return this._def.type; + } + + min(minLength: number, message?: errorUtil.ErrMessage): this { + return new ZodArray({ + ...this._def, + minLength: { value: minLength, message: errorUtil.toString(message) }, + }) as any; + } + + max(maxLength: number, message?: errorUtil.ErrMessage): this { + return new ZodArray({ + ...this._def, + maxLength: { value: maxLength, message: errorUtil.toString(message) }, + }) as any; + } + + length(len: number, message?: errorUtil.ErrMessage): this { + return new ZodArray({ + ...this._def, + exactLength: { value: len, message: errorUtil.toString(message) }, + }) as any; + } + + nonempty(message?: errorUtil.ErrMessage): ZodArray { + return this.min(1, message) as any; + } + + static create = (schema: El, params?: RawCreateParams): ZodArray => { + return new ZodArray({ + type: schema, + minLength: null, + maxLength: null, + exactLength: null, + typeName: ZodFirstPartyTypeKind.ZodArray, + ...processCreateParams(params), + }); + }; +} + +export type ZodNonEmptyArray = ZodArray; + +///////////////////////////////////////// +///////////////////////////////////////// +////////// ////////// +////////// ZodObject ////////// +////////// ////////// +///////////////////////////////////////// +///////////////////////////////////////// + +export type UnknownKeysParam = "passthrough" | "strict" | "strip"; + +export interface ZodObjectDef< + T extends ZodRawShape = ZodRawShape, + UnknownKeys extends UnknownKeysParam = UnknownKeysParam, + Catchall extends ZodTypeAny = ZodTypeAny, +> extends ZodTypeDef { + typeName: ZodFirstPartyTypeKind.ZodObject; + shape: () => T; + catchall: Catchall; + unknownKeys: UnknownKeys; +} + +export type mergeTypes = { + [k in keyof A | keyof B]: k extends keyof B ? B[k] : k extends keyof A ? A[k] : never; +}; + +export type objectOutputType< + Shape extends ZodRawShape, + Catchall extends ZodTypeAny, + UnknownKeys extends UnknownKeysParam = UnknownKeysParam, +> = objectUtil.flatten>> & + CatchallOutput & + PassthroughType; + +export type baseObjectOutputType = { + [k in keyof Shape]: Shape[k]["_output"]; +}; + +export type objectInputType< + Shape extends ZodRawShape, + Catchall extends ZodTypeAny, + UnknownKeys extends UnknownKeysParam = UnknownKeysParam, +> = objectUtil.flatten> & CatchallInput & PassthroughType; +export type baseObjectInputType = objectUtil.addQuestionMarks<{ + [k in keyof Shape]: Shape[k]["_input"]; +}>; + +export type CatchallOutput = ZodType extends T ? unknown : { [k: string]: T["_output"] }; + +export type CatchallInput = ZodType extends T ? unknown : { [k: string]: T["_input"] }; + +export type PassthroughType = T extends "passthrough" ? { [k: string]: unknown } : unknown; + +export type deoptional = T extends ZodOptional + ? deoptional + : T extends ZodNullable + ? ZodNullable> + : T; + +export type SomeZodObject = ZodObject; + +export type noUnrecognized = { + [k in keyof Obj]: k extends keyof Shape ? Obj[k] : never; +}; + +function deepPartialify(schema: ZodTypeAny): any { + if (schema instanceof ZodObject) { + const newShape: any = {}; + + for (const key in schema.shape) { + const fieldSchema = schema.shape[key]; + newShape[key] = ZodOptional.create(deepPartialify(fieldSchema)); + } + return new ZodObject({ + ...schema._def, + shape: () => newShape, + }) as any; + } else if (schema instanceof ZodArray) { + return new ZodArray({ + ...schema._def, + type: deepPartialify(schema.element), + }); + } else if (schema instanceof ZodOptional) { + return ZodOptional.create(deepPartialify(schema.unwrap())); + } else if (schema instanceof ZodNullable) { + return ZodNullable.create(deepPartialify(schema.unwrap())); + } else if (schema instanceof ZodTuple) { + return ZodTuple.create(schema.items.map((item: any) => deepPartialify(item))); + } else { + return schema; + } +} + +export class ZodObject< + T extends ZodRawShape, + UnknownKeys extends UnknownKeysParam = UnknownKeysParam, + Catchall extends ZodTypeAny = ZodTypeAny, + Output = objectOutputType, + Input = objectInputType, +> extends ZodType, Input> { + _cached: { shape: T; keys: string[] } | null = null; + + _getCached(): { shape: T; keys: string[] } { + if (this._cached !== null) return this._cached; + const shape = this._def.shape(); + const keys = util.objectKeys(shape); + this._cached = { shape, keys }; + return this._cached; + } + + _parse(input: ParseInput): ParseReturnType { + const parsedType = this._getType(input); + if (parsedType !== ZodParsedType.object) { + const ctx = this._getOrReturnCtx(input); + addIssueToContext(ctx, { + code: ZodIssueCode.invalid_type, + expected: ZodParsedType.object, + received: ctx.parsedType, + }); + return INVALID; + } + + const { status, ctx } = this._processInputParams(input); + + const { shape, keys: shapeKeys } = this._getCached(); + const extraKeys: string[] = []; + + if (!(this._def.catchall instanceof ZodNever && this._def.unknownKeys === "strip")) { + for (const key in ctx.data) { + if (!shapeKeys.includes(key)) { + extraKeys.push(key); + } + } + } + + const pairs: { + key: ParseReturnType; + value: ParseReturnType; + alwaysSet?: boolean; + }[] = []; + for (const key of shapeKeys) { + const keyValidator = shape[key]!; + const value = ctx.data[key]; + pairs.push({ + key: { status: "valid", value: key }, + value: keyValidator._parse(new ParseInputLazyPath(ctx, value, ctx.path, key)), + alwaysSet: key in ctx.data, + }); + } + + if (this._def.catchall instanceof ZodNever) { + const unknownKeys = this._def.unknownKeys; + + if (unknownKeys === "passthrough") { + for (const key of extraKeys) { + pairs.push({ + key: { status: "valid", value: key }, + value: { status: "valid", value: ctx.data[key] }, + }); + } + } else if (unknownKeys === "strict") { + if (extraKeys.length > 0) { + addIssueToContext(ctx, { + code: ZodIssueCode.unrecognized_keys, + keys: extraKeys, + }); + status.dirty(); + } + } else if (unknownKeys === "strip") { + } else { + throw new Error(`Internal ZodObject error: invalid unknownKeys value.`); + } + } else { + // run catchall validation + const catchall = this._def.catchall; + + for (const key of extraKeys) { + const value = ctx.data[key]; + pairs.push({ + key: { status: "valid", value: key }, + value: catchall._parse( + new ParseInputLazyPath(ctx, value, ctx.path, key) //, ctx.child(key), value, getParsedType(value) + ), + alwaysSet: key in ctx.data, + }); + } + } + + if (ctx.common.async) { + return Promise.resolve() + .then(async () => { + const syncPairs: any[] = []; + for (const pair of pairs) { + const key = await pair.key; + const value = await pair.value; + syncPairs.push({ + key, + value, + alwaysSet: pair.alwaysSet, + }); + } + return syncPairs; + }) + .then((syncPairs) => { + return ParseStatus.mergeObjectSync(status, syncPairs); + }); + } else { + return ParseStatus.mergeObjectSync(status, pairs as any); + } + } + + get shape() { + return this._def.shape(); + } + + strict(message?: errorUtil.ErrMessage): ZodObject { + errorUtil.errToObj; + return new ZodObject({ + ...this._def, + unknownKeys: "strict", + ...(message !== undefined + ? { + errorMap: (issue, ctx) => { + const defaultError = this._def.errorMap?.(issue, ctx).message ?? ctx.defaultError; + if (issue.code === "unrecognized_keys") + return { + message: errorUtil.errToObj(message).message ?? defaultError, + }; + return { + message: defaultError, + }; + }, + } + : {}), + }) as any; + } + + strip(): ZodObject { + return new ZodObject({ + ...this._def, + unknownKeys: "strip", + }) as any; + } + + passthrough(): ZodObject { + return new ZodObject({ + ...this._def, + unknownKeys: "passthrough", + }) as any; + } + + /** + * @deprecated In most cases, this is no longer needed - unknown properties are now silently stripped. + * If you want to pass through unknown properties, use `.passthrough()` instead. + */ + nonstrict = this.passthrough; + + // const AugmentFactory = + // (def: Def) => + // ( + // augmentation: Augmentation + // ): ZodObject< + // extendShape, Augmentation>, + // Def["unknownKeys"], + // Def["catchall"] + // > => { + // return new ZodObject({ + // ...def, + // shape: () => ({ + // ...def.shape(), + // ...augmentation, + // }), + // }) as any; + // }; + extend( + augmentation: Augmentation + ): ZodObject, UnknownKeys, Catchall> { + return new ZodObject({ + ...this._def, + shape: () => ({ + ...this._def.shape(), + ...augmentation, + }), + }) as any; + } + // extend< + // Augmentation extends ZodRawShape, + // NewOutput extends util.flatten<{ + // [k in keyof Augmentation | keyof Output]: k extends keyof Augmentation + // ? Augmentation[k]["_output"] + // : k extends keyof Output + // ? Output[k] + // : never; + // }>, + // NewInput extends util.flatten<{ + // [k in keyof Augmentation | keyof Input]: k extends keyof Augmentation + // ? Augmentation[k]["_input"] + // : k extends keyof Input + // ? Input[k] + // : never; + // }> + // >( + // augmentation: Augmentation + // ): ZodObject< + // extendShape, + // UnknownKeys, + // Catchall, + // NewOutput, + // NewInput + // > { + // return new ZodObject({ + // ...this._def, + // shape: () => ({ + // ...this._def.shape(), + // ...augmentation, + // }), + // }) as any; + // } + /** + * @deprecated Use `.extend` instead + * */ + augment = this.extend; + + /** + * Prior to zod@1.0.12 there was a bug in the + * inferred type of merged objects. Please + * upgrade if you are experiencing issues. + */ + merge( + merging: Incoming + ): ZodObject, Incoming["_def"]["unknownKeys"], Incoming["_def"]["catchall"]> { + const merged: any = new ZodObject({ + unknownKeys: merging._def.unknownKeys, + catchall: merging._def.catchall, + shape: () => ({ + ...this._def.shape(), + ...merging._def.shape(), + }), + typeName: ZodFirstPartyTypeKind.ZodObject, + }) as any; + return merged; + } + // merge< + // Incoming extends AnyZodObject, + // Augmentation extends Incoming["shape"], + // NewOutput extends { + // [k in keyof Augmentation | keyof Output]: k extends keyof Augmentation + // ? Augmentation[k]["_output"] + // : k extends keyof Output + // ? Output[k] + // : never; + // }, + // NewInput extends { + // [k in keyof Augmentation | keyof Input]: k extends keyof Augmentation + // ? Augmentation[k]["_input"] + // : k extends keyof Input + // ? Input[k] + // : never; + // } + // >( + // merging: Incoming + // ): ZodObject< + // extendShape>, + // Incoming["_def"]["unknownKeys"], + // Incoming["_def"]["catchall"], + // NewOutput, + // NewInput + // > { + // const merged: any = new ZodObject({ + // unknownKeys: merging._def.unknownKeys, + // catchall: merging._def.catchall, + // shape: () => + // objectUtil.mergeShapes(this._def.shape(), merging._def.shape()), + // typeName: ZodFirstPartyTypeKind.ZodObject, + // }) as any; + // return merged; + // } + + setKey( + key: Key, + schema: Schema + ): ZodObject { + return this.augment({ [key]: schema }) as any; + } + // merge( + // merging: Incoming + // ): //ZodObject = (merging) => { + // ZodObject< + // extendShape>, + // Incoming["_def"]["unknownKeys"], + // Incoming["_def"]["catchall"] + // > { + // // const mergedShape = objectUtil.mergeShapes( + // // this._def.shape(), + // // merging._def.shape() + // // ); + // const merged: any = new ZodObject({ + // unknownKeys: merging._def.unknownKeys, + // catchall: merging._def.catchall, + // shape: () => + // objectUtil.mergeShapes(this._def.shape(), merging._def.shape()), + // typeName: ZodFirstPartyTypeKind.ZodObject, + // }) as any; + // return merged; + // } + + catchall(index: Index): ZodObject { + return new ZodObject({ + ...this._def, + catchall: index, + }) as any; + } + + pick>( + mask: Mask + ): ZodObject>, UnknownKeys, Catchall> { + const shape: any = {}; + + for (const key of util.objectKeys(mask)) { + if (mask[key] && this.shape[key]) { + shape[key] = this.shape[key]; + } + } + + return new ZodObject({ + ...this._def, + shape: () => shape, + }) as any; + } + + omit>( + mask: Mask + ): ZodObject, UnknownKeys, Catchall> { + const shape: any = {}; + + for (const key of util.objectKeys(this.shape)) { + if (!mask[key]) { + shape[key] = this.shape[key]; + } + } + + return new ZodObject({ + ...this._def, + shape: () => shape, + }) as any; + } + + /** + * @deprecated + */ + deepPartial(): partialUtil.DeepPartial { + return deepPartialify(this); + } + + partial(): ZodObject<{ [k in keyof T]: ZodOptional }, UnknownKeys, Catchall>; + partial>( + mask: Mask + ): ZodObject< + objectUtil.noNever<{ + [k in keyof T]: k extends keyof Mask ? ZodOptional : T[k]; + }>, + UnknownKeys, + Catchall + >; + partial(mask?: any) { + const newShape: any = {}; + + for (const key of util.objectKeys(this.shape)) { + const fieldSchema = this.shape[key]!; + + if (mask && !mask[key]) { + newShape[key] = fieldSchema; + } else { + newShape[key] = fieldSchema.optional(); + } + } + + return new ZodObject({ + ...this._def, + shape: () => newShape, + }) as any; + } + + required(): ZodObject<{ [k in keyof T]: deoptional }, UnknownKeys, Catchall>; + required>( + mask: Mask + ): ZodObject< + objectUtil.noNever<{ + [k in keyof T]: k extends keyof Mask ? deoptional : T[k]; + }>, + UnknownKeys, + Catchall + >; + required(mask?: any) { + const newShape: any = {}; + + for (const key of util.objectKeys(this.shape)) { + if (mask && !mask[key]) { + newShape[key] = this.shape[key]; + } else { + const fieldSchema = this.shape[key]; + let newField = fieldSchema; + + while (newField instanceof ZodOptional) { + newField = (newField as ZodOptional)._def.innerType; + } + + newShape[key] = newField; + } + } + + return new ZodObject({ + ...this._def, + shape: () => newShape, + }) as any; + } + + keyof(): ZodEnum> { + return createZodEnum(util.objectKeys(this.shape) as [string, ...string[]]) as any; + } + + static create = ( + shape: Shape, + params?: RawCreateParams + ): ZodObject< + Shape, + "strip", + ZodTypeAny, + objectOutputType, + objectInputType + > => { + return new ZodObject({ + shape: () => shape, + unknownKeys: "strip", + catchall: ZodNever.create(), + typeName: ZodFirstPartyTypeKind.ZodObject, + ...processCreateParams(params), + }) as any; + }; + + static strictCreate = ( + shape: Shape, + params?: RawCreateParams + ): ZodObject => { + return new ZodObject({ + shape: () => shape, + unknownKeys: "strict", + catchall: ZodNever.create(), + typeName: ZodFirstPartyTypeKind.ZodObject, + ...processCreateParams(params), + }) as any; + }; + + static lazycreate = ( + shape: () => Shape, + params?: RawCreateParams + ): ZodObject => { + return new ZodObject({ + shape, + unknownKeys: "strip", + catchall: ZodNever.create(), + typeName: ZodFirstPartyTypeKind.ZodObject, + ...processCreateParams(params), + }) as any; + }; +} + +export type AnyZodObject = ZodObject; + +//////////////////////////////////////// +//////////////////////////////////////// +////////// ////////// +////////// ZodUnion ////////// +////////// ////////// +//////////////////////////////////////// +//////////////////////////////////////// +export type ZodUnionOptions = Readonly<[ZodTypeAny, ...ZodTypeAny[]]>; +export interface ZodUnionDef> + extends ZodTypeDef { + options: T; + typeName: ZodFirstPartyTypeKind.ZodUnion; +} + +export class ZodUnion extends ZodType< + T[number]["_output"], + ZodUnionDef, + T[number]["_input"] +> { + _parse(input: ParseInput): ParseReturnType { + const { ctx } = this._processInputParams(input); + const options = this._def.options; + + function handleResults(results: { ctx: ParseContext; result: SyncParseReturnType }[]) { + // return first issue-free validation if it exists + for (const result of results) { + if (result.result.status === "valid") { + return result.result; + } + } + + for (const result of results) { + if (result.result.status === "dirty") { + // add issues from dirty option + + ctx.common.issues.push(...result.ctx.common.issues); + return result.result; + } + } + + // return invalid + const unionErrors = results.map((result) => new ZodError(result.ctx.common.issues)); + + addIssueToContext(ctx, { + code: ZodIssueCode.invalid_union, + unionErrors, + }); + return INVALID; + } + + if (ctx.common.async) { + return Promise.all( + options.map(async (option) => { + const childCtx: ParseContext = { + ...ctx, + common: { + ...ctx.common, + issues: [], + }, + parent: null, + }; + return { + result: await option._parseAsync({ + data: ctx.data, + path: ctx.path, + parent: childCtx, + }), + ctx: childCtx, + }; + }) + ).then(handleResults); + } else { + let dirty: undefined | { result: DIRTY; ctx: ParseContext } = undefined; + const issues: ZodIssue[][] = []; + for (const option of options) { + const childCtx: ParseContext = { + ...ctx, + common: { + ...ctx.common, + issues: [], + }, + parent: null, + }; + const result = option._parseSync({ + data: ctx.data, + path: ctx.path, + parent: childCtx, + }); + + if (result.status === "valid") { + return result; + } else if (result.status === "dirty" && !dirty) { + dirty = { result, ctx: childCtx }; + } + + if (childCtx.common.issues.length) { + issues.push(childCtx.common.issues); + } + } + + if (dirty) { + ctx.common.issues.push(...dirty.ctx.common.issues); + return dirty.result; + } + + const unionErrors = issues.map((issues) => new ZodError(issues)); + addIssueToContext(ctx, { + code: ZodIssueCode.invalid_union, + unionErrors, + }); + + return INVALID; + } + } + + get options() { + return this._def.options; + } + + static create = >( + types: Options, + params?: RawCreateParams + ): ZodUnion => { + return new ZodUnion({ + options: types, + typeName: ZodFirstPartyTypeKind.ZodUnion, + ...processCreateParams(params), + }); + }; +} + +///////////////////////////////////////////////////// +///////////////////////////////////////////////////// +////////// ////////// +////////// ZodDiscriminatedUnion ////////// +////////// ////////// +///////////////////////////////////////////////////// +///////////////////////////////////////////////////// + +const getDiscriminator = (type: T): Primitive[] => { + if (type instanceof ZodLazy) { + return getDiscriminator(type.schema); + } else if (type instanceof ZodEffects) { + return getDiscriminator(type.innerType()); + } else if (type instanceof ZodLiteral) { + return [type.value]; + } else if (type instanceof ZodEnum) { + return type.options; + } else if (type instanceof ZodNativeEnum) { + // eslint-disable-next-line ban/ban + return util.objectValues(type.enum); + } else if (type instanceof ZodDefault) { + return getDiscriminator(type._def.innerType); + } else if (type instanceof ZodUndefined) { + return [undefined]; + } else if (type instanceof ZodNull) { + return [null]; + } else if (type instanceof ZodOptional) { + return [undefined, ...getDiscriminator(type.unwrap())]; + } else if (type instanceof ZodNullable) { + return [null, ...getDiscriminator(type.unwrap())]; + } else if (type instanceof ZodBranded) { + return getDiscriminator(type.unwrap()); + } else if (type instanceof ZodReadonly) { + return getDiscriminator(type.unwrap()); + } else if (type instanceof ZodCatch) { + return getDiscriminator(type._def.innerType); + } else { + return []; + } +}; + +export type ZodDiscriminatedUnionOption = ZodObject< + { [key in Discriminator]: ZodTypeAny } & ZodRawShape, + UnknownKeysParam, + ZodTypeAny +>; + +export interface ZodDiscriminatedUnionDef< + Discriminator extends string, + Options extends readonly ZodDiscriminatedUnionOption[] = ZodDiscriminatedUnionOption[], +> extends ZodTypeDef { + discriminator: Discriminator; + options: Options; + optionsMap: Map>; + typeName: ZodFirstPartyTypeKind.ZodDiscriminatedUnion; +} + +export class ZodDiscriminatedUnion< + Discriminator extends string, + Options extends readonly ZodDiscriminatedUnionOption[], +> extends ZodType, ZodDiscriminatedUnionDef, input> { + _parse(input: ParseInput): ParseReturnType { + const { ctx } = this._processInputParams(input); + + if (ctx.parsedType !== ZodParsedType.object) { + addIssueToContext(ctx, { + code: ZodIssueCode.invalid_type, + expected: ZodParsedType.object, + received: ctx.parsedType, + }); + return INVALID; + } + + const discriminator = this.discriminator; + + const discriminatorValue: string = ctx.data[discriminator]; + + const option = this.optionsMap.get(discriminatorValue); + + if (!option) { + addIssueToContext(ctx, { + code: ZodIssueCode.invalid_union_discriminator, + options: Array.from(this.optionsMap.keys()), + path: [discriminator], + }); + return INVALID; + } + + if (ctx.common.async) { + return option._parseAsync({ + data: ctx.data, + path: ctx.path, + parent: ctx, + }) as any; + } else { + return option._parseSync({ + data: ctx.data, + path: ctx.path, + parent: ctx, + }) as any; + } + } + + get discriminator() { + return this._def.discriminator; + } + + get options() { + return this._def.options; + } + + get optionsMap() { + return this._def.optionsMap; + } + + /** + * The constructor of the discriminated union schema. Its behaviour is very similar to that of the normal z.union() constructor. + * However, it only allows a union of objects, all of which need to share a discriminator property. This property must + * have a different value for each object in the union. + * @param discriminator the name of the discriminator property + * @param types an array of object schemas + * @param params + */ + static create< + Discriminator extends string, + Types extends readonly [ + ZodDiscriminatedUnionOption, + ...ZodDiscriminatedUnionOption[], + ], + >( + discriminator: Discriminator, + options: Types, + params?: RawCreateParams + ): ZodDiscriminatedUnion { + // Get all the valid discriminator values + const optionsMap: Map = new Map(); + + // try { + for (const type of options) { + const discriminatorValues = getDiscriminator(type.shape[discriminator]); + if (!discriminatorValues.length) { + throw new Error( + `A discriminator value for key \`${discriminator}\` could not be extracted from all schema options` + ); + } + for (const value of discriminatorValues) { + if (optionsMap.has(value)) { + throw new Error(`Discriminator property ${String(discriminator)} has duplicate value ${String(value)}`); + } + + optionsMap.set(value, type); + } + } + + return new ZodDiscriminatedUnion< + Discriminator, + // DiscriminatorValue, + Types + >({ + typeName: ZodFirstPartyTypeKind.ZodDiscriminatedUnion, + discriminator, + options, + optionsMap, + ...processCreateParams(params), + }); + } +} + +/////////////////////////////////////////////// +/////////////////////////////////////////////// +////////// ////////// +////////// ZodIntersection ////////// +////////// ////////// +/////////////////////////////////////////////// +/////////////////////////////////////////////// +export interface ZodIntersectionDef + extends ZodTypeDef { + left: T; + right: U; + typeName: ZodFirstPartyTypeKind.ZodIntersection; +} + +function mergeValues(a: any, b: any): { valid: true; data: any } | { valid: false } { + const aType = getParsedType(a); + const bType = getParsedType(b); + + if (a === b) { + return { valid: true, data: a }; + } else if (aType === ZodParsedType.object && bType === ZodParsedType.object) { + const bKeys = util.objectKeys(b); + const sharedKeys = util.objectKeys(a).filter((key) => bKeys.indexOf(key) !== -1); + + const newObj: any = { ...a, ...b }; + for (const key of sharedKeys) { + const sharedValue = mergeValues(a[key], b[key]); + if (!sharedValue.valid) { + return { valid: false }; + } + newObj[key] = sharedValue.data; + } + + return { valid: true, data: newObj }; + } else if (aType === ZodParsedType.array && bType === ZodParsedType.array) { + if (a.length !== b.length) { + return { valid: false }; + } + + const newArray: unknown[] = []; + for (let index = 0; index < a.length; index++) { + const itemA = a[index]; + const itemB = b[index]; + const sharedValue = mergeValues(itemA, itemB); + + if (!sharedValue.valid) { + return { valid: false }; + } + + newArray.push(sharedValue.data); + } + + return { valid: true, data: newArray }; + } else if (aType === ZodParsedType.date && bType === ZodParsedType.date && +a === +b) { + return { valid: true, data: a }; + } else { + return { valid: false }; + } +} + +export class ZodIntersection extends ZodType< + T["_output"] & U["_output"], + ZodIntersectionDef, + T["_input"] & U["_input"] +> { + _parse(input: ParseInput): ParseReturnType { + const { status, ctx } = this._processInputParams(input); + const handleParsed = ( + parsedLeft: SyncParseReturnType, + parsedRight: SyncParseReturnType + ): SyncParseReturnType => { + if (isAborted(parsedLeft) || isAborted(parsedRight)) { + return INVALID; + } + + const merged = mergeValues(parsedLeft.value, parsedRight.value); + + if (!merged.valid) { + addIssueToContext(ctx, { + code: ZodIssueCode.invalid_intersection_types, + }); + return INVALID; + } + + if (isDirty(parsedLeft) || isDirty(parsedRight)) { + status.dirty(); + } + + return { status: status.value, value: merged.data }; + }; + + if (ctx.common.async) { + return Promise.all([ + this._def.left._parseAsync({ + data: ctx.data, + path: ctx.path, + parent: ctx, + }), + this._def.right._parseAsync({ + data: ctx.data, + path: ctx.path, + parent: ctx, + }), + ]).then(([left, right]: any) => handleParsed(left, right)); + } else { + return handleParsed( + this._def.left._parseSync({ + data: ctx.data, + path: ctx.path, + parent: ctx, + }), + this._def.right._parseSync({ + data: ctx.data, + path: ctx.path, + parent: ctx, + }) + ); + } + } + + static create = ( + left: TSchema, + right: USchema, + params?: RawCreateParams + ): ZodIntersection => { + return new ZodIntersection({ + left: left, + right: right, + typeName: ZodFirstPartyTypeKind.ZodIntersection, + ...processCreateParams(params), + }); + }; +} + +//////////////////////////////////////// +//////////////////////////////////////// +////////// ////////// +////////// ZodTuple ////////// +////////// ////////// +//////////////////////////////////////// +//////////////////////////////////////// +export type ZodTupleItems = [ZodTypeAny, ...ZodTypeAny[]]; +export type AssertArray = T extends any[] ? T : never; +export type OutputTypeOfTuple = AssertArray<{ + [k in keyof T]: T[k] extends ZodType ? T[k]["_output"] : never; +}>; +export type OutputTypeOfTupleWithRest< + T extends ZodTupleItems | [], + Rest extends ZodTypeAny | null = null, +> = Rest extends ZodTypeAny ? [...OutputTypeOfTuple, ...Rest["_output"][]] : OutputTypeOfTuple; + +export type InputTypeOfTuple = AssertArray<{ + [k in keyof T]: T[k] extends ZodType ? T[k]["_input"] : never; +}>; +export type InputTypeOfTupleWithRest< + T extends ZodTupleItems | [], + Rest extends ZodTypeAny | null = null, +> = Rest extends ZodTypeAny ? [...InputTypeOfTuple, ...Rest["_input"][]] : InputTypeOfTuple; + +export interface ZodTupleDef + extends ZodTypeDef { + items: T; + rest: Rest; + typeName: ZodFirstPartyTypeKind.ZodTuple; +} + +export type AnyZodTuple = ZodTuple<[ZodTypeAny, ...ZodTypeAny[]] | [], ZodTypeAny | null>; +// type ZodTupleItems = [ZodTypeAny, ...ZodTypeAny[]]; +export class ZodTuple< + T extends ZodTupleItems | [] = ZodTupleItems, + Rest extends ZodTypeAny | null = null, +> extends ZodType, ZodTupleDef, InputTypeOfTupleWithRest> { + _parse(input: ParseInput): ParseReturnType { + const { status, ctx } = this._processInputParams(input); + if (ctx.parsedType !== ZodParsedType.array) { + addIssueToContext(ctx, { + code: ZodIssueCode.invalid_type, + expected: ZodParsedType.array, + received: ctx.parsedType, + }); + return INVALID; + } + + if (ctx.data.length < this._def.items.length) { + addIssueToContext(ctx, { + code: ZodIssueCode.too_small, + minimum: this._def.items.length, + inclusive: true, + exact: false, + type: "array", + }); + + return INVALID; + } + + const rest = this._def.rest; + + if (!rest && ctx.data.length > this._def.items.length) { + addIssueToContext(ctx, { + code: ZodIssueCode.too_big, + maximum: this._def.items.length, + inclusive: true, + exact: false, + type: "array", + }); + status.dirty(); + } + + const items = ([...ctx.data] as any[]) + .map((item, itemIndex) => { + const schema = this._def.items[itemIndex] || this._def.rest; + if (!schema) return null as any as SyncParseReturnType; + return schema._parse(new ParseInputLazyPath(ctx, item, ctx.path, itemIndex)); + }) + .filter((x) => !!x); // filter nulls + + if (ctx.common.async) { + return Promise.all(items).then((results) => { + return ParseStatus.mergeArray(status, results); + }); + } else { + return ParseStatus.mergeArray(status, items as SyncParseReturnType[]); + } + } + + get items() { + return this._def.items; + } + + rest(rest: RestSchema): ZodTuple { + return new ZodTuple({ + ...this._def, + rest, + }); + } + + static create = ( + schemas: Items, + params?: RawCreateParams + ): ZodTuple => { + if (!Array.isArray(schemas)) { + throw new Error("You must pass an array of schemas to z.tuple([ ... ])"); + } + return new ZodTuple({ + items: schemas, + typeName: ZodFirstPartyTypeKind.ZodTuple, + rest: null, + ...processCreateParams(params), + }); + }; +} + +///////////////////////////////////////// +///////////////////////////////////////// +////////// ////////// +////////// ZodRecord ////////// +////////// ////////// +///////////////////////////////////////// +///////////////////////////////////////// +export interface ZodRecordDef + extends ZodTypeDef { + valueType: Value; + keyType: Key; + typeName: ZodFirstPartyTypeKind.ZodRecord; +} + +export type KeySchema = ZodType; +export type RecordType = [string] extends [K] + ? Record + : [number] extends [K] + ? Record + : [symbol] extends [K] + ? Record + : [BRAND] extends [K] + ? Record + : Partial>; +export class ZodRecord extends ZodType< + RecordType, + ZodRecordDef, + RecordType +> { + get keySchema() { + return this._def.keyType; + } + get valueSchema() { + return this._def.valueType; + } + _parse(input: ParseInput): ParseReturnType { + const { status, ctx } = this._processInputParams(input); + if (ctx.parsedType !== ZodParsedType.object) { + addIssueToContext(ctx, { + code: ZodIssueCode.invalid_type, + expected: ZodParsedType.object, + received: ctx.parsedType, + }); + return INVALID; + } + + const pairs: { + key: ParseReturnType; + value: ParseReturnType; + alwaysSet: boolean; + }[] = []; + + const keyType = this._def.keyType; + const valueType = this._def.valueType; + + for (const key in ctx.data) { + pairs.push({ + key: keyType._parse(new ParseInputLazyPath(ctx, key, ctx.path, key)), + value: valueType._parse(new ParseInputLazyPath(ctx, ctx.data[key], ctx.path, key)), + alwaysSet: key in ctx.data, + }); + } + + if (ctx.common.async) { + return ParseStatus.mergeObjectAsync(status, pairs); + } else { + return ParseStatus.mergeObjectSync(status, pairs as any); + } + } + + get element() { + return this._def.valueType; + } + + static create(valueType: Value, params?: RawCreateParams): ZodRecord; + static create( + keySchema: Keys, + valueType: Value, + params?: RawCreateParams + ): ZodRecord; + static create(first: any, second?: any, third?: any): ZodRecord { + if (second instanceof ZodType) { + return new ZodRecord({ + keyType: first, + valueType: second, + typeName: ZodFirstPartyTypeKind.ZodRecord, + ...processCreateParams(third), + }); + } + + return new ZodRecord({ + keyType: ZodString.create(), + valueType: first, + typeName: ZodFirstPartyTypeKind.ZodRecord, + ...processCreateParams(second), + }); + } +} + +////////////////////////////////////// +////////////////////////////////////// +////////// ////////// +////////// ZodMap ////////// +////////// ////////// +////////////////////////////////////// +////////////////////////////////////// +export interface ZodMapDef + extends ZodTypeDef { + valueType: Value; + keyType: Key; + typeName: ZodFirstPartyTypeKind.ZodMap; +} + +export class ZodMap extends ZodType< + Map, + ZodMapDef, + Map +> { + get keySchema() { + return this._def.keyType; + } + get valueSchema() { + return this._def.valueType; + } + _parse(input: ParseInput): ParseReturnType { + const { status, ctx } = this._processInputParams(input); + if (ctx.parsedType !== ZodParsedType.map) { + addIssueToContext(ctx, { + code: ZodIssueCode.invalid_type, + expected: ZodParsedType.map, + received: ctx.parsedType, + }); + return INVALID; + } + + const keyType = this._def.keyType; + const valueType = this._def.valueType; + + const pairs = [...(ctx.data as Map).entries()].map(([key, value], index) => { + return { + key: keyType._parse(new ParseInputLazyPath(ctx, key, ctx.path, [index, "key"])), + value: valueType._parse(new ParseInputLazyPath(ctx, value, ctx.path, [index, "value"])), + }; + }); + + if (ctx.common.async) { + const finalMap = new Map(); + return Promise.resolve().then(async () => { + for (const pair of pairs) { + const key = await pair.key; + const value = await pair.value; + if (key.status === "aborted" || value.status === "aborted") { + return INVALID; + } + if (key.status === "dirty" || value.status === "dirty") { + status.dirty(); + } + + finalMap.set(key.value, value.value); + } + return { status: status.value, value: finalMap }; + }); + } else { + const finalMap = new Map(); + for (const pair of pairs) { + const key = pair.key as SyncParseReturnType; + const value = pair.value as SyncParseReturnType; + if (key.status === "aborted" || value.status === "aborted") { + return INVALID; + } + if (key.status === "dirty" || value.status === "dirty") { + status.dirty(); + } + + finalMap.set(key.value, value.value); + } + return { status: status.value, value: finalMap }; + } + } + static create = ( + keyType: KeySchema, + valueType: ValueSchema, + params?: RawCreateParams + ): ZodMap => { + return new ZodMap({ + valueType, + keyType, + typeName: ZodFirstPartyTypeKind.ZodMap, + ...processCreateParams(params), + }); + }; +} + +////////////////////////////////////// +////////////////////////////////////// +////////// ////////// +////////// ZodSet ////////// +////////// ////////// +////////////////////////////////////// +////////////////////////////////////// +export interface ZodSetDef extends ZodTypeDef { + valueType: Value; + typeName: ZodFirstPartyTypeKind.ZodSet; + minSize: { value: number; message?: string | undefined } | null; + maxSize: { value: number; message?: string | undefined } | null; +} + +export class ZodSet extends ZodType< + Set, + ZodSetDef, + Set +> { + _parse(input: ParseInput): ParseReturnType { + const { status, ctx } = this._processInputParams(input); + if (ctx.parsedType !== ZodParsedType.set) { + addIssueToContext(ctx, { + code: ZodIssueCode.invalid_type, + expected: ZodParsedType.set, + received: ctx.parsedType, + }); + return INVALID; + } + + const def = this._def; + + if (def.minSize !== null) { + if (ctx.data.size < def.minSize.value) { + addIssueToContext(ctx, { + code: ZodIssueCode.too_small, + minimum: def.minSize.value, + type: "set", + inclusive: true, + exact: false, + message: def.minSize.message, + }); + status.dirty(); + } + } + + if (def.maxSize !== null) { + if (ctx.data.size > def.maxSize.value) { + addIssueToContext(ctx, { + code: ZodIssueCode.too_big, + maximum: def.maxSize.value, + type: "set", + inclusive: true, + exact: false, + message: def.maxSize.message, + }); + status.dirty(); + } + } + + const valueType = this._def.valueType; + + function finalizeSet(elements: SyncParseReturnType[]) { + const parsedSet = new Set(); + for (const element of elements) { + if (element.status === "aborted") return INVALID; + if (element.status === "dirty") status.dirty(); + parsedSet.add(element.value); + } + return { status: status.value, value: parsedSet }; + } + + const elements = [...(ctx.data as Set).values()].map((item, i) => + valueType._parse(new ParseInputLazyPath(ctx, item, ctx.path, i)) + ); + + if (ctx.common.async) { + return Promise.all(elements).then((elements) => finalizeSet(elements)); + } else { + return finalizeSet(elements as SyncParseReturnType[]); + } + } + + min(minSize: number, message?: errorUtil.ErrMessage): this { + return new ZodSet({ + ...this._def, + minSize: { value: minSize, message: errorUtil.toString(message) }, + }) as any; + } + + max(maxSize: number, message?: errorUtil.ErrMessage): this { + return new ZodSet({ + ...this._def, + maxSize: { value: maxSize, message: errorUtil.toString(message) }, + }) as any; + } + + size(size: number, message?: errorUtil.ErrMessage): this { + return this.min(size, message).max(size, message) as any; + } + + nonempty(message?: errorUtil.ErrMessage): ZodSet { + return this.min(1, message) as any; + } + + static create = ( + valueType: ValueSchema, + params?: RawCreateParams + ): ZodSet => { + return new ZodSet({ + valueType, + minSize: null, + maxSize: null, + typeName: ZodFirstPartyTypeKind.ZodSet, + ...processCreateParams(params), + }); + }; +} + +/////////////////////////////////////////// +/////////////////////////////////////////// +////////// ////////// +////////// ZodFunction ////////// +////////// ////////// +/////////////////////////////////////////// +/////////////////////////////////////////// +export interface ZodFunctionDef< + Args extends ZodTuple = ZodTuple, + Returns extends ZodTypeAny = ZodTypeAny, +> extends ZodTypeDef { + args: Args; + returns: Returns; + typeName: ZodFirstPartyTypeKind.ZodFunction; +} + +export type OuterTypeOfFunction< + Args extends ZodTuple, + Returns extends ZodTypeAny, +> = Args["_input"] extends Array ? (...args: Args["_input"]) => Returns["_output"] : never; + +export type InnerTypeOfFunction< + Args extends ZodTuple, + Returns extends ZodTypeAny, +> = Args["_output"] extends Array ? (...args: Args["_output"]) => Returns["_input"] : never; + +export class ZodFunction, Returns extends ZodTypeAny> extends ZodType< + OuterTypeOfFunction, + ZodFunctionDef, + InnerTypeOfFunction +> { + _parse(input: ParseInput): ParseReturnType { + const { ctx } = this._processInputParams(input); + if (ctx.parsedType !== ZodParsedType.function) { + addIssueToContext(ctx, { + code: ZodIssueCode.invalid_type, + expected: ZodParsedType.function, + received: ctx.parsedType, + }); + return INVALID; + } + + function makeArgsIssue(args: any, error: ZodError): ZodIssue { + return makeIssue({ + data: args, + path: ctx.path, + errorMaps: [ctx.common.contextualErrorMap, ctx.schemaErrorMap, getErrorMap(), defaultErrorMap].filter( + (x) => !!x + ), + issueData: { + code: ZodIssueCode.invalid_arguments, + argumentsError: error, + }, + }); + } + + function makeReturnsIssue(returns: any, error: ZodError): ZodIssue { + return makeIssue({ + data: returns, + path: ctx.path, + errorMaps: [ctx.common.contextualErrorMap, ctx.schemaErrorMap, getErrorMap(), defaultErrorMap].filter( + (x) => !!x + ), + issueData: { + code: ZodIssueCode.invalid_return_type, + returnTypeError: error, + }, + }); + } + + const params = { errorMap: ctx.common.contextualErrorMap }; + const fn = ctx.data; + + if (this._def.returns instanceof ZodPromise) { + // Would love a way to avoid disabling this rule, but we need + // an alias (using an arrow function was what caused 2651). + // eslint-disable-next-line @typescript-eslint/no-this-alias + const me = this; + return OK(async function (this: any, ...args: any[]) { + const error = new ZodError([]); + const parsedArgs = await me._def.args.parseAsync(args, params).catch((e) => { + error.addIssue(makeArgsIssue(args, e)); + throw error; + }); + const result = await Reflect.apply(fn, this, parsedArgs as any); + const parsedReturns = await (me._def.returns as unknown as ZodPromise)._def.type + .parseAsync(result, params) + .catch((e) => { + error.addIssue(makeReturnsIssue(result, e)); + throw error; + }); + return parsedReturns; + }); + } else { + // Would love a way to avoid disabling this rule, but we need + // an alias (using an arrow function was what caused 2651). + // eslint-disable-next-line @typescript-eslint/no-this-alias + const me = this; + return OK(function (this: any, ...args: any[]) { + const parsedArgs = me._def.args.safeParse(args, params); + if (!parsedArgs.success) { + throw new ZodError([makeArgsIssue(args, parsedArgs.error)]); + } + const result = Reflect.apply(fn, this, parsedArgs.data); + const parsedReturns = me._def.returns.safeParse(result, params); + if (!parsedReturns.success) { + throw new ZodError([makeReturnsIssue(result, parsedReturns.error)]); + } + return parsedReturns.data; + }) as any; + } + } + + parameters() { + return this._def.args; + } + + returnType() { + return this._def.returns; + } + + args[0]>( + ...items: Items + ): ZodFunction, Returns> { + return new ZodFunction({ + ...this._def, + args: ZodTuple.create(items).rest(ZodUnknown.create()) as any, + }); + } + + returns>(returnType: NewReturnType): ZodFunction { + return new ZodFunction({ + ...this._def, + returns: returnType, + }); + } + + implement>( + func: F + ): ReturnType extends Returns["_output"] + ? (...args: Args["_input"]) => ReturnType + : OuterTypeOfFunction { + const validatedFunc = this.parse(func); + return validatedFunc as any; + } + + strictImplement(func: InnerTypeOfFunction): InnerTypeOfFunction { + const validatedFunc = this.parse(func); + return validatedFunc as any; + } + + validate = this.implement; + + static create(): ZodFunction, ZodUnknown>; + static create>(args: T): ZodFunction; + static create(args: T, returns: U): ZodFunction; + static create, U extends ZodTypeAny = ZodUnknown>( + args: T, + returns: U, + params?: RawCreateParams + ): ZodFunction; + static create(args?: AnyZodTuple, returns?: ZodTypeAny, params?: RawCreateParams) { + return new ZodFunction({ + args: (args ? args : ZodTuple.create([]).rest(ZodUnknown.create())) as any, + returns: returns || ZodUnknown.create(), + typeName: ZodFirstPartyTypeKind.ZodFunction, + ...processCreateParams(params), + }) as any; + } +} + +/////////////////////////////////////// +/////////////////////////////////////// +////////// ////////// +////////// ZodLazy ////////// +////////// ////////// +/////////////////////////////////////// +/////////////////////////////////////// +export interface ZodLazyDef extends ZodTypeDef { + getter: () => T; + typeName: ZodFirstPartyTypeKind.ZodLazy; +} + +export class ZodLazy extends ZodType, ZodLazyDef, input> { + get schema(): T { + return this._def.getter(); + } + + _parse(input: ParseInput): ParseReturnType { + const { ctx } = this._processInputParams(input); + const lazySchema = this._def.getter(); + return lazySchema._parse({ data: ctx.data, path: ctx.path, parent: ctx }); + } + + static create = (getter: () => Inner, params?: RawCreateParams): ZodLazy => { + return new ZodLazy({ + getter: getter, + typeName: ZodFirstPartyTypeKind.ZodLazy, + ...processCreateParams(params), + }); + }; +} + +////////////////////////////////////////// +////////////////////////////////////////// +////////// ////////// +////////// ZodLiteral ////////// +////////// ////////// +////////////////////////////////////////// +////////////////////////////////////////// +export interface ZodLiteralDef extends ZodTypeDef { + value: T; + typeName: ZodFirstPartyTypeKind.ZodLiteral; +} + +export class ZodLiteral extends ZodType, T> { + _parse(input: ParseInput): ParseReturnType { + if (input.data !== this._def.value) { + const ctx = this._getOrReturnCtx(input); + addIssueToContext(ctx, { + received: ctx.data, + code: ZodIssueCode.invalid_literal, + expected: this._def.value, + }); + return INVALID; + } + return { status: "valid", value: input.data }; + } + + get value() { + return this._def.value; + } + + static create = (value: Value, params?: RawCreateParams): ZodLiteral => { + return new ZodLiteral({ + value: value, + typeName: ZodFirstPartyTypeKind.ZodLiteral, + ...processCreateParams(params), + }); + }; +} + +/////////////////////////////////////// +/////////////////////////////////////// +////////// ////////// +////////// ZodEnum ////////// +////////// ////////// +/////////////////////////////////////// +/////////////////////////////////////// +export type ArrayKeys = keyof any[]; +export type Indices = Exclude; + +export type EnumValues = readonly [T, ...T[]]; + +export type Values = { + [k in T[number]]: k; +}; + +export interface ZodEnumDef extends ZodTypeDef { + values: T; + typeName: ZodFirstPartyTypeKind.ZodEnum; +} + +export type Writeable = { -readonly [P in keyof T]: T[P] }; + +export type FilterEnum = Values extends [] + ? [] + : Values extends [infer Head, ...infer Rest] + ? Head extends ToExclude + ? FilterEnum + : [Head, ...FilterEnum] + : never; + +export type typecast = A extends T ? A : never; + +function createZodEnum>( + values: T, + params?: RawCreateParams +): ZodEnum>; +function createZodEnum(values: T, params?: RawCreateParams): ZodEnum; +function createZodEnum(values: [string, ...string[]], params?: RawCreateParams) { + return new ZodEnum({ + values, + typeName: ZodFirstPartyTypeKind.ZodEnum, + ...processCreateParams(params), + }); +} + +export class ZodEnum extends ZodType, T[number]> { + _cache: Set | undefined; + + _parse(input: ParseInput): ParseReturnType { + if (typeof input.data !== "string") { + const ctx = this._getOrReturnCtx(input); + const expectedValues = this._def.values; + addIssueToContext(ctx, { + expected: util.joinValues(expectedValues) as "string", + received: ctx.parsedType, + code: ZodIssueCode.invalid_type, + }); + return INVALID; + } + + if (!this._cache) { + this._cache = new Set(this._def.values); + } + + if (!this._cache.has(input.data)) { + const ctx = this._getOrReturnCtx(input); + const expectedValues = this._def.values; + + addIssueToContext(ctx, { + received: ctx.data, + code: ZodIssueCode.invalid_enum_value, + options: expectedValues, + }); + return INVALID; + } + return OK(input.data); + } + + get options() { + return this._def.values; + } + + get enum(): Values { + const enumValues: any = {}; + for (const val of this._def.values) { + enumValues[val] = val; + } + return enumValues; + } + + get Values(): Values { + const enumValues: any = {}; + for (const val of this._def.values) { + enumValues[val] = val; + } + return enumValues; + } + + get Enum(): Values { + const enumValues: any = {}; + for (const val of this._def.values) { + enumValues[val] = val; + } + return enumValues; + } + + extract( + values: ToExtract, + newDef: RawCreateParams = this._def + ): ZodEnum> { + return ZodEnum.create(values, { + ...this._def, + ...newDef, + }) as any; + } + + exclude( + values: ToExclude, + newDef: RawCreateParams = this._def + ): ZodEnum>, [string, ...string[]]>> { + return ZodEnum.create(this.options.filter((opt) => !values.includes(opt)) as FilterEnum, { + ...this._def, + ...newDef, + }) as any; + } + + static create = createZodEnum; +} + +///////////////////////////////////////////// +///////////////////////////////////////////// +////////// ////////// +////////// ZodNativeEnum ////////// +////////// ////////// +///////////////////////////////////////////// +///////////////////////////////////////////// +export interface ZodNativeEnumDef extends ZodTypeDef { + values: T; + typeName: ZodFirstPartyTypeKind.ZodNativeEnum; +} + +export type EnumLike = { [k: string]: string | number; [nu: number]: string }; + +export class ZodNativeEnum extends ZodType, T[keyof T]> { + _cache: Set | undefined; + _parse(input: ParseInput): ParseReturnType { + const nativeEnumValues = util.getValidEnumValues(this._def.values); + + const ctx = this._getOrReturnCtx(input); + if (ctx.parsedType !== ZodParsedType.string && ctx.parsedType !== ZodParsedType.number) { + const expectedValues = util.objectValues(nativeEnumValues); + addIssueToContext(ctx, { + expected: util.joinValues(expectedValues) as "string", + received: ctx.parsedType, + code: ZodIssueCode.invalid_type, + }); + return INVALID; + } + + if (!this._cache) { + this._cache = new Set(util.getValidEnumValues(this._def.values)); + } + + if (!this._cache.has(input.data)) { + const expectedValues = util.objectValues(nativeEnumValues); + + addIssueToContext(ctx, { + received: ctx.data, + code: ZodIssueCode.invalid_enum_value, + options: expectedValues, + }); + return INVALID; + } + return OK(input.data); + } + + get enum() { + return this._def.values; + } + + static create = (values: Elements, params?: RawCreateParams): ZodNativeEnum => { + return new ZodNativeEnum({ + values: values, + typeName: ZodFirstPartyTypeKind.ZodNativeEnum, + ...processCreateParams(params), + }); + }; +} + +////////////////////////////////////////// +////////////////////////////////////////// +////////// ////////// +////////// ZodPromise ////////// +////////// ////////// +////////////////////////////////////////// +////////////////////////////////////////// +export interface ZodPromiseDef extends ZodTypeDef { + type: T; + typeName: ZodFirstPartyTypeKind.ZodPromise; +} + +export class ZodPromise extends ZodType< + Promise, + ZodPromiseDef, + Promise +> { + unwrap() { + return this._def.type; + } + + _parse(input: ParseInput): ParseReturnType { + const { ctx } = this._processInputParams(input); + if (ctx.parsedType !== ZodParsedType.promise && ctx.common.async === false) { + addIssueToContext(ctx, { + code: ZodIssueCode.invalid_type, + expected: ZodParsedType.promise, + received: ctx.parsedType, + }); + return INVALID; + } + + const promisified = ctx.parsedType === ZodParsedType.promise ? ctx.data : Promise.resolve(ctx.data); + + return OK( + promisified.then((data: any) => { + return this._def.type.parseAsync(data, { + path: ctx.path, + errorMap: ctx.common.contextualErrorMap, + }); + }) + ); + } + + static create = (schema: Inner, params?: RawCreateParams): ZodPromise => { + return new ZodPromise({ + type: schema, + typeName: ZodFirstPartyTypeKind.ZodPromise, + ...processCreateParams(params), + }); + }; +} + +////////////////////////////////////////////// +////////////////////////////////////////////// +////////// ////////// +////////// ZodEffects ////////// +////////// ////////// +////////////////////////////////////////////// +////////////////////////////////////////////// + +export type Refinement = (arg: T, ctx: RefinementCtx) => any; +export type SuperRefinement = (arg: T, ctx: RefinementCtx) => void | Promise; + +export type RefinementEffect = { + type: "refinement"; + refinement: (arg: T, ctx: RefinementCtx) => any; +}; +export type TransformEffect = { + type: "transform"; + transform: (arg: T, ctx: RefinementCtx) => any; +}; +export type PreprocessEffect = { + type: "preprocess"; + transform: (arg: T, ctx: RefinementCtx) => any; +}; +export type Effect = RefinementEffect | TransformEffect | PreprocessEffect; + +export interface ZodEffectsDef extends ZodTypeDef { + schema: T; + typeName: ZodFirstPartyTypeKind.ZodEffects; + effect: Effect; +} + +export class ZodEffects, Input = input> extends ZodType< + Output, + ZodEffectsDef, + Input +> { + innerType() { + return this._def.schema; + } + + sourceType(): T { + return this._def.schema._def.typeName === ZodFirstPartyTypeKind.ZodEffects + ? (this._def.schema as unknown as ZodEffects).sourceType() + : (this._def.schema as T); + } + + _parse(input: ParseInput): ParseReturnType { + const { status, ctx } = this._processInputParams(input); + + const effect = this._def.effect || null; + + const checkCtx: RefinementCtx = { + addIssue: (arg: IssueData) => { + addIssueToContext(ctx, arg); + if (arg.fatal) { + status.abort(); + } else { + status.dirty(); + } + }, + get path() { + return ctx.path; + }, + }; + + checkCtx.addIssue = checkCtx.addIssue.bind(checkCtx); + + if (effect.type === "preprocess") { + const processed = effect.transform(ctx.data, checkCtx); + + if (ctx.common.async) { + return Promise.resolve(processed).then(async (processed) => { + if (status.value === "aborted") return INVALID; + + const result = await this._def.schema._parseAsync({ + data: processed, + path: ctx.path, + parent: ctx, + }); + if (result.status === "aborted") return INVALID; + if (result.status === "dirty") return DIRTY(result.value); + if (status.value === "dirty") return DIRTY(result.value); + return result; + }); + } else { + if (status.value === "aborted") return INVALID; + const result = this._def.schema._parseSync({ + data: processed, + path: ctx.path, + parent: ctx, + }); + if (result.status === "aborted") return INVALID; + if (result.status === "dirty") return DIRTY(result.value); + if (status.value === "dirty") return DIRTY(result.value); + return result; + } + } + if (effect.type === "refinement") { + const executeRefinement = (acc: unknown): any => { + const result = effect.refinement(acc, checkCtx); + if (ctx.common.async) { + return Promise.resolve(result); + } + if (result instanceof Promise) { + throw new Error("Async refinement encountered during synchronous parse operation. Use .parseAsync instead."); + } + return acc; + }; + + if (ctx.common.async === false) { + const inner = this._def.schema._parseSync({ + data: ctx.data, + path: ctx.path, + parent: ctx, + }); + if (inner.status === "aborted") return INVALID; + if (inner.status === "dirty") status.dirty(); + + // return value is ignored + executeRefinement(inner.value); + return { status: status.value, value: inner.value }; + } else { + return this._def.schema._parseAsync({ data: ctx.data, path: ctx.path, parent: ctx }).then((inner) => { + if (inner.status === "aborted") return INVALID; + if (inner.status === "dirty") status.dirty(); + + return executeRefinement(inner.value).then(() => { + return { status: status.value, value: inner.value }; + }); + }); + } + } + + if (effect.type === "transform") { + if (ctx.common.async === false) { + const base = this._def.schema._parseSync({ + data: ctx.data, + path: ctx.path, + parent: ctx, + }); + + if (!isValid(base)) return INVALID; + + const result = effect.transform(base.value, checkCtx); + if (result instanceof Promise) { + throw new Error( + `Asynchronous transform encountered during synchronous parse operation. Use .parseAsync instead.` + ); + } + + return { status: status.value, value: result }; + } else { + return this._def.schema._parseAsync({ data: ctx.data, path: ctx.path, parent: ctx }).then((base) => { + if (!isValid(base)) return INVALID; + + return Promise.resolve(effect.transform(base.value, checkCtx)).then((result) => ({ + status: status.value, + value: result, + })); + }); + } + } + + util.assertNever(effect); + } + + static create = ( + schema: I, + effect: Effect, + params?: RawCreateParams + ): ZodEffects => { + return new ZodEffects({ + schema, + typeName: ZodFirstPartyTypeKind.ZodEffects, + effect, + ...processCreateParams(params), + }); + }; + + static createWithPreprocess = ( + preprocess: (arg: unknown, ctx: RefinementCtx) => unknown, + schema: I, + params?: RawCreateParams + ): ZodEffects => { + return new ZodEffects({ + schema, + effect: { type: "preprocess", transform: preprocess }, + typeName: ZodFirstPartyTypeKind.ZodEffects, + ...processCreateParams(params), + }); + }; +} + +export { ZodEffects as ZodTransformer }; + +/////////////////////////////////////////// +/////////////////////////////////////////// +////////// ////////// +////////// ZodOptional ////////// +////////// ////////// +/////////////////////////////////////////// +/////////////////////////////////////////// +export interface ZodOptionalDef extends ZodTypeDef { + innerType: T; + typeName: ZodFirstPartyTypeKind.ZodOptional; +} + +export type ZodOptionalType = ZodOptional; + +export class ZodOptional extends ZodType< + T["_output"] | undefined, + ZodOptionalDef, + T["_input"] | undefined +> { + _parse(input: ParseInput): ParseReturnType { + const parsedType = this._getType(input); + if (parsedType === ZodParsedType.undefined) { + return OK(undefined); + } + return this._def.innerType._parse(input); + } + + unwrap() { + return this._def.innerType; + } + + static create = (type: Inner, params?: RawCreateParams): ZodOptional => { + return new ZodOptional({ + innerType: type, + typeName: ZodFirstPartyTypeKind.ZodOptional, + ...processCreateParams(params), + }) as any; + }; +} + +/////////////////////////////////////////// +/////////////////////////////////////////// +////////// ////////// +////////// ZodNullable ////////// +////////// ////////// +/////////////////////////////////////////// +/////////////////////////////////////////// +export interface ZodNullableDef extends ZodTypeDef { + innerType: T; + typeName: ZodFirstPartyTypeKind.ZodNullable; +} + +export type ZodNullableType = ZodNullable; + +export class ZodNullable extends ZodType< + T["_output"] | null, + ZodNullableDef, + T["_input"] | null +> { + _parse(input: ParseInput): ParseReturnType { + const parsedType = this._getType(input); + if (parsedType === ZodParsedType.null) { + return OK(null); + } + return this._def.innerType._parse(input); + } + + unwrap() { + return this._def.innerType; + } + + static create = (type: Inner, params?: RawCreateParams): ZodNullable => { + return new ZodNullable({ + innerType: type, + typeName: ZodFirstPartyTypeKind.ZodNullable, + ...processCreateParams(params), + }) as any; + }; +} + +//////////////////////////////////////////// +//////////////////////////////////////////// +////////// ////////// +////////// ZodDefault ////////// +////////// ////////// +//////////////////////////////////////////// +//////////////////////////////////////////// +export interface ZodDefaultDef extends ZodTypeDef { + innerType: T; + defaultValue: () => util.noUndefined; + typeName: ZodFirstPartyTypeKind.ZodDefault; +} + +export class ZodDefault extends ZodType< + util.noUndefined, + ZodDefaultDef, + T["_input"] | undefined +> { + _parse(input: ParseInput): ParseReturnType { + const { ctx } = this._processInputParams(input); + let data = ctx.data; + if (ctx.parsedType === ZodParsedType.undefined) { + data = this._def.defaultValue(); + } + return this._def.innerType._parse({ + data, + path: ctx.path, + parent: ctx, + }); + } + + removeDefault() { + return this._def.innerType; + } + + static create = ( + type: Inner, + params: RawCreateParams & { + default: Inner["_input"] | (() => util.noUndefined); + } + ): ZodDefault => { + return new ZodDefault({ + innerType: type, + typeName: ZodFirstPartyTypeKind.ZodDefault, + defaultValue: typeof params.default === "function" ? params.default : () => params.default as any, + ...processCreateParams(params), + }) as any; + }; +} + +////////////////////////////////////////// +////////////////////////////////////////// +////////// ////////// +////////// ZodCatch ////////// +////////// ////////// +////////////////////////////////////////// +////////////////////////////////////////// +export interface ZodCatchDef extends ZodTypeDef { + innerType: T; + catchValue: (ctx: { error: ZodError; input: unknown }) => T["_input"]; + typeName: ZodFirstPartyTypeKind.ZodCatch; +} + +export class ZodCatch extends ZodType< + T["_output"], + ZodCatchDef, + unknown // any input will pass validation // T["_input"] +> { + _parse(input: ParseInput): ParseReturnType { + const { ctx } = this._processInputParams(input); + + // newCtx is used to not collect issues from inner types in ctx + const newCtx: ParseContext = { + ...ctx, + common: { + ...ctx.common, + issues: [], + }, + }; + + const result = this._def.innerType._parse({ + data: newCtx.data, + path: newCtx.path, + parent: { + ...newCtx, + }, + }); + + if (isAsync(result)) { + return result.then((result) => { + return { + status: "valid", + value: + result.status === "valid" + ? result.value + : this._def.catchValue({ + get error() { + return new ZodError(newCtx.common.issues); + }, + input: newCtx.data, + }), + }; + }); + } else { + return { + status: "valid", + value: + result.status === "valid" + ? result.value + : this._def.catchValue({ + get error() { + return new ZodError(newCtx.common.issues); + }, + input: newCtx.data, + }), + }; + } + } + + removeCatch() { + return this._def.innerType; + } + + static create = ( + type: Inner, + params: RawCreateParams & { + catch: Inner["_output"] | (() => Inner["_output"]); + } + ): ZodCatch => { + return new ZodCatch({ + innerType: type, + typeName: ZodFirstPartyTypeKind.ZodCatch, + catchValue: typeof params.catch === "function" ? params.catch : () => params.catch, + ...processCreateParams(params), + }); + }; +} + +///////////////////////////////////////// +///////////////////////////////////////// +////////// ////////// +////////// ZodNaN ////////// +////////// ////////// +///////////////////////////////////////// +///////////////////////////////////////// + +export interface ZodNaNDef extends ZodTypeDef { + typeName: ZodFirstPartyTypeKind.ZodNaN; +} + +export class ZodNaN extends ZodType { + _parse(input: ParseInput): ParseReturnType { + const parsedType = this._getType(input); + if (parsedType !== ZodParsedType.nan) { + const ctx = this._getOrReturnCtx(input); + addIssueToContext(ctx, { + code: ZodIssueCode.invalid_type, + expected: ZodParsedType.nan, + received: ctx.parsedType, + }); + return INVALID; + } + + return { status: "valid", value: input.data }; + } + + static create = (params?: RawCreateParams): ZodNaN => { + return new ZodNaN({ + typeName: ZodFirstPartyTypeKind.ZodNaN, + ...processCreateParams(params), + }); + }; +} + +////////////////////////////////////////// +////////////////////////////////////////// +////////// ////////// +////////// ZodBranded ////////// +////////// ////////// +////////////////////////////////////////// +////////////////////////////////////////// + +export interface ZodBrandedDef extends ZodTypeDef { + type: T; + typeName: ZodFirstPartyTypeKind.ZodBranded; +} + +export const BRAND: unique symbol = Symbol("zod_brand"); +export type BRAND = { + [BRAND]: { [k in T]: true }; +}; + +export class ZodBranded extends ZodType< + T["_output"] & BRAND, + ZodBrandedDef, + T["_input"] +> { + _parse(input: ParseInput): ParseReturnType { + const { ctx } = this._processInputParams(input); + const data = ctx.data; + return this._def.type._parse({ + data, + path: ctx.path, + parent: ctx, + }); + } + + unwrap() { + return this._def.type; + } +} + +//////////////////////////////////////////// +//////////////////////////////////////////// +////////// ////////// +////////// ZodPipeline ////////// +////////// ////////// +//////////////////////////////////////////// +//////////////////////////////////////////// + +export interface ZodPipelineDef extends ZodTypeDef { + in: A; + out: B; + typeName: ZodFirstPartyTypeKind.ZodPipeline; +} + +export class ZodPipeline extends ZodType< + B["_output"], + ZodPipelineDef, + A["_input"] +> { + _parse(input: ParseInput): ParseReturnType { + const { status, ctx } = this._processInputParams(input); + if (ctx.common.async) { + const handleAsync = async () => { + const inResult = await this._def.in._parseAsync({ + data: ctx.data, + path: ctx.path, + parent: ctx, + }); + if (inResult.status === "aborted") return INVALID; + if (inResult.status === "dirty") { + status.dirty(); + return DIRTY(inResult.value); + } else { + return this._def.out._parseAsync({ + data: inResult.value, + path: ctx.path, + parent: ctx, + }); + } + }; + return handleAsync(); + } else { + const inResult = this._def.in._parseSync({ + data: ctx.data, + path: ctx.path, + parent: ctx, + }); + if (inResult.status === "aborted") return INVALID; + if (inResult.status === "dirty") { + status.dirty(); + return { + status: "dirty", + value: inResult.value, + }; + } else { + return this._def.out._parseSync({ + data: inResult.value, + path: ctx.path, + parent: ctx, + }); + } + } + } + + static create( + a: ASchema, + b: BSchema + ): ZodPipeline { + return new ZodPipeline({ + in: a, + out: b, + typeName: ZodFirstPartyTypeKind.ZodPipeline, + }); + } +} + +/////////////////////////////////////////// +/////////////////////////////////////////// +////////// ////////// +////////// ZodReadonly ////////// +////////// ////////// +/////////////////////////////////////////// +/////////////////////////////////////////// +type BuiltIn = + | (((...args: any[]) => any) | (new (...args: any[]) => any)) + | { readonly [Symbol.toStringTag]: string } + | Date + | Error + | Generator + | Promise + | RegExp; + +type MakeReadonly = T extends Map + ? ReadonlyMap + : T extends Set + ? ReadonlySet + : T extends [infer Head, ...infer Tail] + ? readonly [Head, ...Tail] + : T extends Array + ? ReadonlyArray + : T extends BuiltIn + ? T + : Readonly; + +export interface ZodReadonlyDef extends ZodTypeDef { + innerType: T; + typeName: ZodFirstPartyTypeKind.ZodReadonly; +} + +export class ZodReadonly extends ZodType< + MakeReadonly, + ZodReadonlyDef, + MakeReadonly +> { + _parse(input: ParseInput): ParseReturnType { + const result = this._def.innerType._parse(input); + const freeze = (data: ParseReturnType) => { + if (isValid(data)) { + data.value = Object.freeze(data.value); + } + return data; + }; + return isAsync(result) ? result.then((data) => freeze(data)) : freeze(result); + } + + static create = (type: Inner, params?: RawCreateParams): ZodReadonly => { + return new ZodReadonly({ + innerType: type, + typeName: ZodFirstPartyTypeKind.ZodReadonly, + ...processCreateParams(params), + }) as any; + }; + + unwrap() { + return this._def.innerType; + } +} + +//////////////////////////////////////// +//////////////////////////////////////// +////////// ////////// +////////// z.custom ////////// +////////// ////////// +//////////////////////////////////////// +//////////////////////////////////////// +function cleanParams(params: unknown, data: unknown) { + const p = typeof params === "function" ? params(data) : typeof params === "string" ? { message: params } : params; + + const p2 = typeof p === "string" ? { message: p } : p; + return p2; +} +type CustomParams = CustomErrorParams & { fatal?: boolean }; +export function custom( + check?: (data: any) => any, + _params: string | CustomParams | ((input: any) => CustomParams) = {}, + /** + * @deprecated + * + * Pass `fatal` into the params object instead: + * + * ```ts + * z.string().custom((val) => val.length > 5, { fatal: false }) + * ``` + * + */ + fatal?: boolean +): ZodType { + if (check) + return ZodAny.create().superRefine((data, ctx) => { + const r = check(data); + if (r instanceof Promise) { + return r.then((r) => { + if (!r) { + const params = cleanParams(_params, data); + const _fatal = params.fatal ?? fatal ?? true; + ctx.addIssue({ code: "custom", ...params, fatal: _fatal }); + } + }); + } + if (!r) { + const params = cleanParams(_params, data); + const _fatal = params.fatal ?? fatal ?? true; + ctx.addIssue({ code: "custom", ...params, fatal: _fatal }); + } + return; + }); + return ZodAny.create(); +} + +export { ZodType as Schema, ZodType as ZodSchema }; + +export const late = { + object: ZodObject.lazycreate, +}; + +export enum ZodFirstPartyTypeKind { + ZodString = "ZodString", + ZodNumber = "ZodNumber", + ZodNaN = "ZodNaN", + ZodBigInt = "ZodBigInt", + ZodBoolean = "ZodBoolean", + ZodDate = "ZodDate", + ZodSymbol = "ZodSymbol", + ZodUndefined = "ZodUndefined", + ZodNull = "ZodNull", + ZodAny = "ZodAny", + ZodUnknown = "ZodUnknown", + ZodNever = "ZodNever", + ZodVoid = "ZodVoid", + ZodArray = "ZodArray", + ZodObject = "ZodObject", + ZodUnion = "ZodUnion", + ZodDiscriminatedUnion = "ZodDiscriminatedUnion", + ZodIntersection = "ZodIntersection", + ZodTuple = "ZodTuple", + ZodRecord = "ZodRecord", + ZodMap = "ZodMap", + ZodSet = "ZodSet", + ZodFunction = "ZodFunction", + ZodLazy = "ZodLazy", + ZodLiteral = "ZodLiteral", + ZodEnum = "ZodEnum", + ZodEffects = "ZodEffects", + ZodNativeEnum = "ZodNativeEnum", + ZodOptional = "ZodOptional", + ZodNullable = "ZodNullable", + ZodDefault = "ZodDefault", + ZodCatch = "ZodCatch", + ZodPromise = "ZodPromise", + ZodBranded = "ZodBranded", + ZodPipeline = "ZodPipeline", + ZodReadonly = "ZodReadonly", +} +export type ZodFirstPartySchemaTypes = + | ZodString + | ZodNumber + | ZodNaN + | ZodBigInt + | ZodBoolean + | ZodDate + | ZodUndefined + | ZodNull + | ZodAny + | ZodUnknown + | ZodNever + | ZodVoid + | ZodArray + | ZodObject + | ZodUnion + | ZodDiscriminatedUnion + | ZodIntersection + | ZodTuple + | ZodRecord + | ZodMap + | ZodSet + | ZodFunction + | ZodLazy + | ZodLiteral + | ZodEnum + | ZodEffects + | ZodNativeEnum + | ZodOptional + | ZodNullable + | ZodDefault + | ZodCatch + | ZodPromise + | ZodBranded + | ZodPipeline + | ZodReadonly + | ZodSymbol; + +// requires TS 4.4+ +abstract class Class { + constructor(..._: any[]) {} +} +const instanceOfType = ( + // const instanceOfType = any>( + cls: T, + params: CustomParams = { + message: `Input not instance of ${cls.name}`, + } +) => custom>((data) => data instanceof cls, params); + +const stringType = ZodString.create; +const numberType = ZodNumber.create; +const nanType = ZodNaN.create; +const bigIntType = ZodBigInt.create; +const booleanType = ZodBoolean.create; +const dateType = ZodDate.create; +const symbolType = ZodSymbol.create; +const undefinedType = ZodUndefined.create; +const nullType = ZodNull.create; +const anyType = ZodAny.create; +const unknownType = ZodUnknown.create; +const neverType = ZodNever.create; +const voidType = ZodVoid.create; +const arrayType = ZodArray.create; +const objectType = ZodObject.create; +const strictObjectType = ZodObject.strictCreate; +const unionType = ZodUnion.create; +const discriminatedUnionType = ZodDiscriminatedUnion.create; +const intersectionType = ZodIntersection.create; +const tupleType = ZodTuple.create; +const recordType = ZodRecord.create; +const mapType = ZodMap.create; +const setType = ZodSet.create; +const functionType = ZodFunction.create; +const lazyType = ZodLazy.create; +const literalType = ZodLiteral.create; +const enumType = ZodEnum.create; +const nativeEnumType = ZodNativeEnum.create; +const promiseType = ZodPromise.create; +const effectsType = ZodEffects.create; +const optionalType = ZodOptional.create; +const nullableType = ZodNullable.create; +const preprocessType = ZodEffects.createWithPreprocess; +const pipelineType = ZodPipeline.create; +const ostring = () => stringType().optional(); +const onumber = () => numberType().optional(); +const oboolean = () => booleanType().optional(); + +export const coerce = { + string: ((arg) => ZodString.create({ ...arg, coerce: true })) as (typeof ZodString)["create"], + number: ((arg) => ZodNumber.create({ ...arg, coerce: true })) as (typeof ZodNumber)["create"], + boolean: ((arg) => + ZodBoolean.create({ + ...arg, + coerce: true, + })) as (typeof ZodBoolean)["create"], + bigint: ((arg) => ZodBigInt.create({ ...arg, coerce: true })) as (typeof ZodBigInt)["create"], + date: ((arg) => ZodDate.create({ ...arg, coerce: true })) as (typeof ZodDate)["create"], +}; + +export { + anyType as any, + arrayType as array, + bigIntType as bigint, + booleanType as boolean, + dateType as date, + discriminatedUnionType as discriminatedUnion, + effectsType as effect, + enumType as enum, + functionType as function, + instanceOfType as instanceof, + intersectionType as intersection, + lazyType as lazy, + literalType as literal, + mapType as map, + nanType as nan, + nativeEnumType as nativeEnum, + neverType as never, + nullType as null, + nullableType as nullable, + numberType as number, + objectType as object, + oboolean, + onumber, + optionalType as optional, + ostring, + pipelineType as pipeline, + preprocessType as preprocess, + promiseType as promise, + recordType as record, + setType as set, + strictObjectType as strictObject, + stringType as string, + symbolType as symbol, + effectsType as transformer, + tupleType as tuple, + undefinedType as undefined, + unionType as union, + unknownType as unknown, + voidType as void, +}; + +export const NEVER = INVALID as never; diff --git a/node_modules/zod/src/v4-mini/index.ts b/node_modules/zod/src/v4-mini/index.ts new file mode 100644 index 00000000..bb95da0a --- /dev/null +++ b/node_modules/zod/src/v4-mini/index.ts @@ -0,0 +1,3 @@ +import * as z from "../v4/mini/external.js"; +export * from "../v4/mini/external.js"; +export { z }; diff --git a/node_modules/zod/src/v4/classic/checks.ts b/node_modules/zod/src/v4/classic/checks.ts new file mode 100644 index 00000000..cd78c0e4 --- /dev/null +++ b/node_modules/zod/src/v4/classic/checks.ts @@ -0,0 +1,32 @@ +export { + _lt as lt, + _lte as lte, + _gt as gt, + _gte as gte, + _positive as positive, + _negative as negative, + _nonpositive as nonpositive, + _nonnegative as nonnegative, + _multipleOf as multipleOf, + _maxSize as maxSize, + _minSize as minSize, + _size as size, + _maxLength as maxLength, + _minLength as minLength, + _length as length, + _regex as regex, + _lowercase as lowercase, + _uppercase as uppercase, + _includes as includes, + _startsWith as startsWith, + _endsWith as endsWith, + _property as property, + _mime as mime, + _overwrite as overwrite, + _normalize as normalize, + _trim as trim, + _toLowerCase as toLowerCase, + _toUpperCase as toUpperCase, + _slugify as slugify, + type $RefinementCtx as RefinementCtx, +} from "../core/index.js"; diff --git a/node_modules/zod/src/v4/classic/coerce.ts b/node_modules/zod/src/v4/classic/coerce.ts new file mode 100644 index 00000000..cc400e0d --- /dev/null +++ b/node_modules/zod/src/v4/classic/coerce.ts @@ -0,0 +1,27 @@ +import * as core from "../core/index.js"; +import * as schemas from "./schemas.js"; + +export interface ZodCoercedString extends schemas._ZodString> {} +export function string(params?: string | core.$ZodStringParams): ZodCoercedString { + return core._coercedString(schemas.ZodString, params) as any; +} + +export interface ZodCoercedNumber extends schemas._ZodNumber> {} +export function number(params?: string | core.$ZodNumberParams): ZodCoercedNumber { + return core._coercedNumber(schemas.ZodNumber, params) as ZodCoercedNumber; +} + +export interface ZodCoercedBoolean extends schemas._ZodBoolean> {} +export function boolean(params?: string | core.$ZodBooleanParams): ZodCoercedBoolean { + return core._coercedBoolean(schemas.ZodBoolean, params) as ZodCoercedBoolean; +} + +export interface ZodCoercedBigInt extends schemas._ZodBigInt> {} +export function bigint(params?: string | core.$ZodBigIntParams): ZodCoercedBigInt { + return core._coercedBigint(schemas.ZodBigInt, params) as ZodCoercedBigInt; +} + +export interface ZodCoercedDate extends schemas._ZodDate> {} +export function date(params?: string | core.$ZodDateParams): ZodCoercedDate { + return core._coercedDate(schemas.ZodDate, params) as ZodCoercedDate; +} diff --git a/node_modules/zod/src/v4/classic/compat.ts b/node_modules/zod/src/v4/classic/compat.ts new file mode 100644 index 00000000..86a5813a --- /dev/null +++ b/node_modules/zod/src/v4/classic/compat.ts @@ -0,0 +1,70 @@ +// Zod 3 compat layer + +import * as core from "../core/index.js"; +import type { ZodType } from "./schemas.js"; + +export type { + /** @deprecated Use `z.output` instead. */ + output as TypeOf, + /** @deprecated Use `z.output` instead. */ + output as Infer, + /** @deprecated Use `z.core.$$ZodFirstPartyTypes` instead */ + $ZodTypes as ZodFirstPartySchemaTypes, +} from "../core/index.js"; + +/** @deprecated Use the raw string literal codes instead, e.g. "invalid_type". */ +export const ZodIssueCode = { + invalid_type: "invalid_type", + too_big: "too_big", + too_small: "too_small", + invalid_format: "invalid_format", + not_multiple_of: "not_multiple_of", + unrecognized_keys: "unrecognized_keys", + invalid_union: "invalid_union", + invalid_key: "invalid_key", + invalid_element: "invalid_element", + invalid_value: "invalid_value", + custom: "custom", +} as const; + +/** @deprecated Use `z.$ZodFlattenedError` */ +export type inferFlattenedErrors = core.$ZodFlattenedError, U>; + +/** @deprecated Use `z.$ZodFormattedError` */ +export type inferFormattedError, U = string> = core.$ZodFormattedError< + core.output, + U +>; + +/** Use `z.$brand` instead */ +export type BRAND = { + [core.$brand]: { [k in T]: true }; +}; +export { $brand, config } from "../core/index.js"; + +/** @deprecated Use `z.config(params)` instead. */ +export function setErrorMap(map: core.$ZodErrorMap): void { + core.config({ + customError: map, + }); +} + +/** @deprecated Use `z.config()` instead. */ +export function getErrorMap(): core.$ZodErrorMap | undefined { + return core.config().customError; +} + +export type { + /** @deprecated Use z.ZodType (without generics) instead. */ + ZodType as ZodTypeAny, + /** @deprecated Use `z.ZodType` */ + ZodType as ZodSchema, + /** @deprecated Use `z.ZodType` */ + ZodType as Schema, +}; + +/** Included for Zod 3 compatibility */ +export type ZodRawShape = core.$ZodShape; + +/** @deprecated Do not use. Stub definition, only included for zod-to-json-schema compatibility. */ +export enum ZodFirstPartyTypeKind {} diff --git a/node_modules/zod/src/v4/classic/errors.ts b/node_modules/zod/src/v4/classic/errors.ts new file mode 100644 index 00000000..695a5343 --- /dev/null +++ b/node_modules/zod/src/v4/classic/errors.ts @@ -0,0 +1,82 @@ +import * as core from "../core/index.js"; +import { $ZodError } from "../core/index.js"; +import * as util from "../core/util.js"; + +/** @deprecated Use `z.core.$ZodIssue` from `@zod/core` instead, especially if you are building a library on top of Zod. */ +export type ZodIssue = core.$ZodIssue; + +/** An Error-like class used to store Zod validation issues. */ +export interface ZodError extends $ZodError { + /** @deprecated Use the `z.treeifyError(err)` function instead. */ + format(): core.$ZodFormattedError; + format(mapper: (issue: core.$ZodIssue) => U): core.$ZodFormattedError; + /** @deprecated Use the `z.treeifyError(err)` function instead. */ + flatten(): core.$ZodFlattenedError; + flatten(mapper: (issue: core.$ZodIssue) => U): core.$ZodFlattenedError; + /** @deprecated Push directly to `.issues` instead. */ + addIssue(issue: core.$ZodIssue): void; + /** @deprecated Push directly to `.issues` instead. */ + addIssues(issues: core.$ZodIssue[]): void; + + /** @deprecated Check `err.issues.length === 0` instead. */ + isEmpty: boolean; +} + +const initializer = (inst: ZodError, issues: core.$ZodIssue[]) => { + $ZodError.init(inst, issues); + inst.name = "ZodError"; + Object.defineProperties(inst, { + format: { + value: (mapper: any) => core.formatError(inst, mapper), + // enumerable: false, + }, + flatten: { + value: (mapper: any) => core.flattenError(inst, mapper), + // enumerable: false, + }, + addIssue: { + value: (issue: any) => { + inst.issues.push(issue); + inst.message = JSON.stringify(inst.issues, util.jsonStringifyReplacer, 2); + }, + // enumerable: false, + }, + addIssues: { + value: (issues: any) => { + inst.issues.push(...issues); + inst.message = JSON.stringify(inst.issues, util.jsonStringifyReplacer, 2); + }, + // enumerable: false, + }, + isEmpty: { + get() { + return inst.issues.length === 0; + }, + // enumerable: false, + }, + }); + // Object.defineProperty(inst, "isEmpty", { + // get() { + // return inst.issues.length === 0; + // }, + // }); +}; +export const ZodError: core.$constructor = core.$constructor("ZodError", initializer); +export const ZodRealError: core.$constructor = core.$constructor("ZodError", initializer, { + Parent: Error, +}); + +export type { + /** @deprecated Use `z.core.$ZodFlattenedError` instead. */ + $ZodFlattenedError as ZodFlattenedError, + /** @deprecated Use `z.core.$ZodFormattedError` instead. */ + $ZodFormattedError as ZodFormattedError, + /** @deprecated Use `z.core.$ZodErrorMap` instead. */ + $ZodErrorMap as ZodErrorMap, +} from "../core/index.js"; + +/** @deprecated Use `z.core.$ZodRawIssue` instead. */ +export type IssueData = core.$ZodRawIssue; + +// /** @deprecated Use `z.core.$ZodErrorMapCtx` instead. */ +// export type ErrorMapCtx = core.$ZodErrorMapCtx; diff --git a/node_modules/zod/src/v4/classic/external.ts b/node_modules/zod/src/v4/classic/external.ts new file mode 100644 index 00000000..084deaa5 --- /dev/null +++ b/node_modules/zod/src/v4/classic/external.ts @@ -0,0 +1,51 @@ +export * as core from "../core/index.js"; +export * from "./schemas.js"; +export * from "./checks.js"; +export * from "./errors.js"; +export * from "./parse.js"; +export * from "./compat.js"; + +// zod-specified +import { config } from "../core/index.js"; +import en from "../locales/en.js"; +config(en()); + +export type { infer, output, input } from "../core/index.js"; +export { + globalRegistry, + type GlobalMeta, + registry, + config, + $output, + $input, + $brand, + clone, + regexes, + treeifyError, + prettifyError, + formatError, + flattenError, + TimePrecision, + util, + NEVER, +} from "../core/index.js"; +export { toJSONSchema } from "../core/json-schema-processors.js"; +export { fromJSONSchema } from "./from-json-schema.js"; + +export * as locales from "../locales/index.js"; + +// iso +// must be exported from top-level +// https://github.com/colinhacks/zod/issues/4491 +export { ZodISODateTime, ZodISODate, ZodISOTime, ZodISODuration } from "./iso.js"; +export * as iso from "./iso.js"; + +// coerce +export type { + ZodCoercedString, + ZodCoercedNumber, + ZodCoercedBigInt, + ZodCoercedBoolean, + ZodCoercedDate, +} from "./coerce.js"; +export * as coerce from "./coerce.js"; diff --git a/node_modules/zod/src/v4/classic/from-json-schema.ts b/node_modules/zod/src/v4/classic/from-json-schema.ts new file mode 100644 index 00000000..b2c806ec --- /dev/null +++ b/node_modules/zod/src/v4/classic/from-json-schema.ts @@ -0,0 +1,643 @@ +import type * as JSONSchema from "../core/json-schema.js"; +import { type $ZodRegistry, globalRegistry } from "../core/registries.js"; +import * as _checks from "./checks.js"; +import * as _iso from "./iso.js"; +import * as _schemas from "./schemas.js"; +import type { ZodNumber, ZodString, ZodType } from "./schemas.js"; + +// Local z object to avoid circular dependency with ../index.js +const z = { + ..._schemas, + ..._checks, + iso: _iso, +}; + +type JSONSchemaVersion = "draft-2020-12" | "draft-7" | "draft-4" | "openapi-3.0"; + +interface FromJSONSchemaParams { + defaultTarget?: JSONSchemaVersion; + registry?: $ZodRegistry; +} + +interface ConversionContext { + version: JSONSchemaVersion; + defs: Record; + refs: Map; + processing: Set; + rootSchema: JSONSchema.JSONSchema; + registry: $ZodRegistry; +} + +// Keys that are recognized and handled by the conversion logic +const RECOGNIZED_KEYS = new Set([ + // Schema identification + "$schema", + "$ref", + "$defs", + "definitions", + // Core schema keywords + "$id", + "id", + "$comment", + "$anchor", + "$vocabulary", + "$dynamicRef", + "$dynamicAnchor", + // Type + "type", + "enum", + "const", + // Composition + "anyOf", + "oneOf", + "allOf", + "not", + // Object + "properties", + "required", + "additionalProperties", + "patternProperties", + "propertyNames", + "minProperties", + "maxProperties", + // Array + "items", + "prefixItems", + "additionalItems", + "minItems", + "maxItems", + "uniqueItems", + "contains", + "minContains", + "maxContains", + // String + "minLength", + "maxLength", + "pattern", + "format", + // Number + "minimum", + "maximum", + "exclusiveMinimum", + "exclusiveMaximum", + "multipleOf", + // Already handled metadata + "description", + "default", + // Content + "contentEncoding", + "contentMediaType", + "contentSchema", + // Unsupported (error-throwing) + "unevaluatedItems", + "unevaluatedProperties", + "if", + "then", + "else", + "dependentSchemas", + "dependentRequired", + // OpenAPI + "nullable", + "readOnly", +]); + +function detectVersion(schema: JSONSchema.JSONSchema, defaultTarget?: JSONSchemaVersion): JSONSchemaVersion { + const $schema = schema.$schema; + + if ($schema === "https://json-schema.org/draft/2020-12/schema") { + return "draft-2020-12"; + } + if ($schema === "http://json-schema.org/draft-07/schema#") { + return "draft-7"; + } + if ($schema === "http://json-schema.org/draft-04/schema#") { + return "draft-4"; + } + + // Use defaultTarget if provided, otherwise default to draft-2020-12 + return defaultTarget ?? "draft-2020-12"; +} + +function resolveRef(ref: string, ctx: ConversionContext): JSONSchema.JSONSchema { + if (!ref.startsWith("#")) { + throw new Error("External $ref is not supported, only local refs (#/...) are allowed"); + } + + const path = ref.slice(1).split("/").filter(Boolean); + + // Handle root reference "#" + if (path.length === 0) { + return ctx.rootSchema; + } + + const defsKey = ctx.version === "draft-2020-12" ? "$defs" : "definitions"; + + if (path[0] === defsKey) { + const key = path[1]; + if (!key || !ctx.defs[key]) { + throw new Error(`Reference not found: ${ref}`); + } + return ctx.defs[key]!; + } + + throw new Error(`Reference not found: ${ref}`); +} + +function convertBaseSchema(schema: JSONSchema.JSONSchema, ctx: ConversionContext): ZodType { + // Handle unsupported features + if (schema.not !== undefined) { + // Special case: { not: {} } represents never + if (typeof schema.not === "object" && Object.keys(schema.not).length === 0) { + return z.never(); + } + throw new Error("not is not supported in Zod (except { not: {} } for never)"); + } + if (schema.unevaluatedItems !== undefined) { + throw new Error("unevaluatedItems is not supported"); + } + if (schema.unevaluatedProperties !== undefined) { + throw new Error("unevaluatedProperties is not supported"); + } + if (schema.if !== undefined || schema.then !== undefined || schema.else !== undefined) { + throw new Error("Conditional schemas (if/then/else) are not supported"); + } + if (schema.dependentSchemas !== undefined || schema.dependentRequired !== undefined) { + throw new Error("dependentSchemas and dependentRequired are not supported"); + } + + // Handle $ref + if (schema.$ref) { + const refPath = schema.$ref; + if (ctx.refs.has(refPath)) { + return ctx.refs.get(refPath)!; + } + + if (ctx.processing.has(refPath)) { + // Circular reference - use lazy + return z.lazy(() => { + if (!ctx.refs.has(refPath)) { + throw new Error(`Circular reference not resolved: ${refPath}`); + } + return ctx.refs.get(refPath)!; + }); + } + + ctx.processing.add(refPath); + const resolved = resolveRef(refPath, ctx); + const zodSchema = convertSchema(resolved, ctx); + ctx.refs.set(refPath, zodSchema); + ctx.processing.delete(refPath); + return zodSchema; + } + + // Handle enum + if (schema.enum !== undefined) { + const enumValues = schema.enum; + + // Special case: OpenAPI 3.0 null representation { type: "string", nullable: true, enum: [null] } + if ( + ctx.version === "openapi-3.0" && + schema.nullable === true && + enumValues.length === 1 && + enumValues[0] === null + ) { + return z.null(); + } + + if (enumValues.length === 0) { + return z.never(); + } + if (enumValues.length === 1) { + return z.literal(enumValues[0]!); + } + // Check if all values are strings + if (enumValues.every((v) => typeof v === "string")) { + return z.enum(enumValues as [string, ...string[]]); + } + // Mixed types - use union of literals + const literalSchemas = enumValues.map((v) => z.literal(v)); + if (literalSchemas.length < 2) { + return literalSchemas[0]!; + } + return z.union([literalSchemas[0]!, literalSchemas[1]!, ...literalSchemas.slice(2)] as [ + ZodType, + ZodType, + ...ZodType[], + ]); + } + + // Handle const + if (schema.const !== undefined) { + return z.literal(schema.const); + } + + // Handle type + const type = schema.type; + + if (Array.isArray(type)) { + // Expand type array into anyOf union + const typeSchemas = type.map((t) => { + const typeSchema: JSONSchema.JSONSchema = { ...schema, type: t }; + return convertBaseSchema(typeSchema, ctx); + }); + if (typeSchemas.length === 0) { + return z.never(); + } + if (typeSchemas.length === 1) { + return typeSchemas[0]!; + } + return z.union(typeSchemas as [ZodType, ZodType, ...ZodType[]]); + } + + if (!type) { + // No type specified - empty schema (any) + return z.any(); + } + + let zodSchema: ZodType; + + switch (type) { + case "string": { + let stringSchema: ZodString = z.string(); + + // Apply format using .check() with Zod format functions + if (schema.format) { + const format = schema.format; + // Map common formats to Zod check functions + if (format === "email") { + stringSchema = stringSchema.check(z.email()); + } else if (format === "uri" || format === "uri-reference") { + stringSchema = stringSchema.check(z.url()); + } else if (format === "uuid" || format === "guid") { + stringSchema = stringSchema.check(z.uuid()); + } else if (format === "date-time") { + stringSchema = stringSchema.check(z.iso.datetime()); + } else if (format === "date") { + stringSchema = stringSchema.check(z.iso.date()); + } else if (format === "time") { + stringSchema = stringSchema.check(z.iso.time()); + } else if (format === "duration") { + stringSchema = stringSchema.check(z.iso.duration()); + } else if (format === "ipv4") { + stringSchema = stringSchema.check(z.ipv4()); + } else if (format === "ipv6") { + stringSchema = stringSchema.check(z.ipv6()); + } else if (format === "mac") { + stringSchema = stringSchema.check(z.mac()); + } else if (format === "cidr") { + stringSchema = stringSchema.check(z.cidrv4()); + } else if (format === "cidr-v6") { + stringSchema = stringSchema.check(z.cidrv6()); + } else if (format === "base64") { + stringSchema = stringSchema.check(z.base64()); + } else if (format === "base64url") { + stringSchema = stringSchema.check(z.base64url()); + } else if (format === "e164") { + stringSchema = stringSchema.check(z.e164()); + } else if (format === "jwt") { + stringSchema = stringSchema.check(z.jwt()); + } else if (format === "emoji") { + stringSchema = stringSchema.check(z.emoji()); + } else if (format === "nanoid") { + stringSchema = stringSchema.check(z.nanoid()); + } else if (format === "cuid") { + stringSchema = stringSchema.check(z.cuid()); + } else if (format === "cuid2") { + stringSchema = stringSchema.check(z.cuid2()); + } else if (format === "ulid") { + stringSchema = stringSchema.check(z.ulid()); + } else if (format === "xid") { + stringSchema = stringSchema.check(z.xid()); + } else if (format === "ksuid") { + stringSchema = stringSchema.check(z.ksuid()); + } + // Note: json-string format is not currently supported by Zod + // Custom formats are ignored - keep as plain string + } + + // Apply constraints + if (typeof schema.minLength === "number") { + stringSchema = stringSchema.min(schema.minLength); + } + if (typeof schema.maxLength === "number") { + stringSchema = stringSchema.max(schema.maxLength); + } + if (schema.pattern) { + // JSON Schema patterns are not implicitly anchored (match anywhere in string) + stringSchema = stringSchema.regex(new RegExp(schema.pattern)); + } + + zodSchema = stringSchema; + break; + } + + case "number": + case "integer": { + let numberSchema: ZodNumber = type === "integer" ? z.number().int() : z.number(); + + // Apply constraints + if (typeof schema.minimum === "number") { + numberSchema = numberSchema.min(schema.minimum); + } + if (typeof schema.maximum === "number") { + numberSchema = numberSchema.max(schema.maximum); + } + if (typeof schema.exclusiveMinimum === "number") { + numberSchema = numberSchema.gt(schema.exclusiveMinimum); + } else if (schema.exclusiveMinimum === true && typeof schema.minimum === "number") { + numberSchema = numberSchema.gt(schema.minimum); + } + if (typeof schema.exclusiveMaximum === "number") { + numberSchema = numberSchema.lt(schema.exclusiveMaximum); + } else if (schema.exclusiveMaximum === true && typeof schema.maximum === "number") { + numberSchema = numberSchema.lt(schema.maximum); + } + if (typeof schema.multipleOf === "number") { + numberSchema = numberSchema.multipleOf(schema.multipleOf); + } + + zodSchema = numberSchema; + break; + } + + case "boolean": { + zodSchema = z.boolean(); + break; + } + + case "null": { + zodSchema = z.null(); + break; + } + + case "object": { + const shape: Record = {}; + const properties = schema.properties || {}; + const requiredSet = new Set(schema.required || []); + + // Convert properties - mark optional ones + for (const [key, propSchema] of Object.entries(properties)) { + const propZodSchema = convertSchema(propSchema as JSONSchema.JSONSchema, ctx); + // If not in required array, make it optional + shape[key] = requiredSet.has(key) ? propZodSchema : propZodSchema.optional(); + } + + // Handle propertyNames + if (schema.propertyNames) { + const keySchema = convertSchema(schema.propertyNames, ctx) as ZodString; + const valueSchema = + schema.additionalProperties && typeof schema.additionalProperties === "object" + ? convertSchema(schema.additionalProperties as JSONSchema.JSONSchema, ctx) + : z.any(); + + // Case A: No properties (pure record) + if (Object.keys(shape).length === 0) { + zodSchema = z.record(keySchema, valueSchema); + break; + } + + // Case B: With properties (intersection of object and looseRecord) + const objectSchema = z.object(shape).passthrough(); + const recordSchema = z.looseRecord(keySchema, valueSchema); + zodSchema = z.intersection(objectSchema, recordSchema); + break; + } + + // Handle patternProperties + if (schema.patternProperties) { + // patternProperties: keys matching pattern must satisfy corresponding schema + // Use loose records so non-matching keys pass through + const patternProps = schema.patternProperties; + const patternKeys = Object.keys(patternProps); + const looseRecords: ZodType[] = []; + + for (const pattern of patternKeys) { + const patternValue = convertSchema(patternProps[pattern] as JSONSchema.JSONSchema, ctx); + const keySchema = z.string().regex(new RegExp(pattern)); + looseRecords.push(z.looseRecord(keySchema, patternValue)); + } + + // Build intersection: object schema + all pattern property records + const schemasToIntersect: ZodType[] = []; + if (Object.keys(shape).length > 0) { + // Use passthrough so patternProperties can validate additional keys + schemasToIntersect.push(z.object(shape).passthrough()); + } + schemasToIntersect.push(...looseRecords); + + if (schemasToIntersect.length === 0) { + zodSchema = z.object({}).passthrough(); + } else if (schemasToIntersect.length === 1) { + zodSchema = schemasToIntersect[0]!; + } else { + // Chain intersections: (A & B) & C & D ... + let result = z.intersection(schemasToIntersect[0]!, schemasToIntersect[1]!); + for (let i = 2; i < schemasToIntersect.length; i++) { + result = z.intersection(result, schemasToIntersect[i]!); + } + zodSchema = result; + } + break; + } + + // Handle additionalProperties + // In JSON Schema, additionalProperties defaults to true (allow any extra properties) + // In Zod, objects strip unknown keys by default, so we need to handle this explicitly + const objectSchema = z.object(shape); + if (schema.additionalProperties === false) { + // Strict mode - no extra properties allowed + zodSchema = objectSchema.strict(); + } else if (typeof schema.additionalProperties === "object") { + // Extra properties must match the specified schema + zodSchema = objectSchema.catchall(convertSchema(schema.additionalProperties as JSONSchema.JSONSchema, ctx)); + } else { + // additionalProperties is true or undefined - allow any extra properties (passthrough) + zodSchema = objectSchema.passthrough(); + } + break; + } + + case "array": { + // TODO: uniqueItems is not supported + // TODO: contains/minContains/maxContains are not supported + // Check if this is a tuple (prefixItems or items as array) + const prefixItems = schema.prefixItems; + const items = schema.items; + + if (prefixItems && Array.isArray(prefixItems)) { + // Tuple with prefixItems (draft-2020-12) + const tupleItems = prefixItems.map((item) => convertSchema(item as JSONSchema.JSONSchema, ctx)); + const rest = + items && typeof items === "object" && !Array.isArray(items) + ? convertSchema(items as JSONSchema.JSONSchema, ctx) + : undefined; + if (rest) { + zodSchema = z.tuple(tupleItems as [ZodType, ...ZodType[]]).rest(rest); + } else { + zodSchema = z.tuple(tupleItems as [ZodType, ...ZodType[]]); + } + // Apply minItems/maxItems constraints to tuples + if (typeof schema.minItems === "number") { + zodSchema = (zodSchema as any).check(z.minLength(schema.minItems)); + } + if (typeof schema.maxItems === "number") { + zodSchema = (zodSchema as any).check(z.maxLength(schema.maxItems)); + } + } else if (Array.isArray(items)) { + // Tuple with items array (draft-7) + const tupleItems = items.map((item) => convertSchema(item as JSONSchema.JSONSchema, ctx)); + const rest = + schema.additionalItems && typeof schema.additionalItems === "object" + ? convertSchema(schema.additionalItems as JSONSchema.JSONSchema, ctx) + : undefined; // additionalItems: false means no rest, handled by default tuple behavior + if (rest) { + zodSchema = z.tuple(tupleItems as [ZodType, ...ZodType[]]).rest(rest); + } else { + zodSchema = z.tuple(tupleItems as [ZodType, ...ZodType[]]); + } + // Apply minItems/maxItems constraints to tuples + if (typeof schema.minItems === "number") { + zodSchema = (zodSchema as any).check(z.minLength(schema.minItems)); + } + if (typeof schema.maxItems === "number") { + zodSchema = (zodSchema as any).check(z.maxLength(schema.maxItems)); + } + } else if (items !== undefined) { + // Regular array + const element = convertSchema(items as JSONSchema.JSONSchema, ctx); + let arraySchema = z.array(element); + + // Apply constraints + if (typeof schema.minItems === "number") { + arraySchema = (arraySchema as any).min(schema.minItems); + } + if (typeof schema.maxItems === "number") { + arraySchema = (arraySchema as any).max(schema.maxItems); + } + + zodSchema = arraySchema; + } else { + // No items specified - array of any + zodSchema = z.array(z.any()); + } + break; + } + + default: + throw new Error(`Unsupported type: ${type}`); + } + + // Apply metadata + if (schema.description) { + zodSchema = zodSchema.describe(schema.description); + } + if (schema.default !== undefined) { + zodSchema = (zodSchema as any).default(schema.default); + } + + return zodSchema; +} + +function convertSchema(schema: JSONSchema.JSONSchema | boolean, ctx: ConversionContext): ZodType { + if (typeof schema === "boolean") { + return schema ? z.any() : z.never(); + } + + // Convert base schema first (ignoring composition keywords) + let baseSchema = convertBaseSchema(schema, ctx); + const hasExplicitType = schema.type || schema.enum !== undefined || schema.const !== undefined; + + // Process composition keywords LAST (they can appear together) + // Handle anyOf - wrap base schema with union + if (schema.anyOf && Array.isArray(schema.anyOf)) { + const options = schema.anyOf.map((s) => convertSchema(s, ctx)); + const anyOfUnion = z.union(options as [ZodType, ZodType, ...ZodType[]]); + baseSchema = hasExplicitType ? z.intersection(baseSchema, anyOfUnion) : anyOfUnion; + } + + // Handle oneOf - exclusive union (exactly one must match) + if (schema.oneOf && Array.isArray(schema.oneOf)) { + const options = schema.oneOf.map((s) => convertSchema(s, ctx)); + const oneOfUnion = z.xor(options as [ZodType, ZodType, ...ZodType[]]); + baseSchema = hasExplicitType ? z.intersection(baseSchema, oneOfUnion) : oneOfUnion; + } + + // Handle allOf - wrap base schema with intersection + if (schema.allOf && Array.isArray(schema.allOf)) { + if (schema.allOf.length === 0) { + baseSchema = hasExplicitType ? baseSchema : z.any(); + } else { + let result = hasExplicitType ? baseSchema : convertSchema(schema.allOf[0]!, ctx); + const startIdx = hasExplicitType ? 0 : 1; + for (let i = startIdx; i < schema.allOf.length; i++) { + result = z.intersection(result, convertSchema(schema.allOf[i]!, ctx)); + } + baseSchema = result; + } + } + + // Handle nullable (OpenAPI 3.0) + if (schema.nullable === true && ctx.version === "openapi-3.0") { + baseSchema = z.nullable(baseSchema); + } + + // Handle readOnly + if (schema.readOnly === true) { + baseSchema = z.readonly(baseSchema); + } + + // Collect metadata: core schema keywords and unrecognized keys + const extraMeta: Record = {}; + + // Core schema keywords that should be captured as metadata + const coreMetadataKeys = ["$id", "id", "$comment", "$anchor", "$vocabulary", "$dynamicRef", "$dynamicAnchor"]; + for (const key of coreMetadataKeys) { + if (key in schema) { + extraMeta[key] = schema[key]; + } + } + + // Content keywords - store as metadata + const contentMetadataKeys = ["contentEncoding", "contentMediaType", "contentSchema"]; + for (const key of contentMetadataKeys) { + if (key in schema) { + extraMeta[key] = schema[key]; + } + } + + // Unrecognized keys (custom metadata) + for (const key of Object.keys(schema)) { + if (!RECOGNIZED_KEYS.has(key)) { + extraMeta[key] = schema[key]; + } + } + + if (Object.keys(extraMeta).length > 0) { + ctx.registry.add(baseSchema, extraMeta); + } + + return baseSchema; +} + +/** + * Converts a JSON Schema to a Zod schema. This function should be considered semi-experimental. It's behavior is liable to change. */ +export function fromJSONSchema(schema: JSONSchema.JSONSchema | boolean, params?: FromJSONSchemaParams): ZodType { + // Handle boolean schemas + if (typeof schema === "boolean") { + return schema ? z.any() : z.never(); + } + + const version = detectVersion(schema, params?.defaultTarget); + const defs = (schema.$defs || schema.definitions || {}) as Record; + + const ctx: ConversionContext = { + version, + defs, + refs: new Map(), + processing: new Set(), + rootSchema: schema, + registry: params?.registry ?? globalRegistry, + }; + + return convertSchema(schema, ctx); +} diff --git a/node_modules/zod/src/v4/classic/index.ts b/node_modules/zod/src/v4/classic/index.ts new file mode 100644 index 00000000..f0f7547f --- /dev/null +++ b/node_modules/zod/src/v4/classic/index.ts @@ -0,0 +1,5 @@ +import * as z from "./external.js"; + +export { z }; +export * from "./external.js"; +export default z; diff --git a/node_modules/zod/src/v4/classic/iso.ts b/node_modules/zod/src/v4/classic/iso.ts new file mode 100644 index 00000000..b08696d6 --- /dev/null +++ b/node_modules/zod/src/v4/classic/iso.ts @@ -0,0 +1,90 @@ +import * as core from "../core/index.js"; +import * as schemas from "./schemas.js"; + +////////////////////////////////////////////// +////////////////////////////////////////////// +////////// ////////// +////////// ZodISODateTime ////////// +////////// ////////// +////////////////////////////////////////////// +////////////////////////////////////////////// + +export interface ZodISODateTime extends schemas.ZodStringFormat { + _zod: core.$ZodISODateTimeInternals; +} +export const ZodISODateTime: core.$constructor = /*@__PURE__*/ core.$constructor( + "ZodISODateTime", + (inst, def) => { + core.$ZodISODateTime.init(inst, def); + schemas.ZodStringFormat.init(inst, def); + } +); + +export function datetime(params?: string | core.$ZodISODateTimeParams): ZodISODateTime { + return core._isoDateTime(ZodISODateTime, params); +} + +////////////////////////////////////////// +////////////////////////////////////////// +////////// ////////// +////////// ZodISODate ////////// +////////// ////////// +////////////////////////////////////////// +////////////////////////////////////////// + +export interface ZodISODate extends schemas.ZodStringFormat { + _zod: core.$ZodISODateInternals; +} +export const ZodISODate: core.$constructor = /*@__PURE__*/ core.$constructor("ZodISODate", (inst, def) => { + core.$ZodISODate.init(inst, def); + schemas.ZodStringFormat.init(inst, def); +}); + +export function date(params?: string | core.$ZodISODateParams): ZodISODate { + return core._isoDate(ZodISODate, params); +} + +// ZodISOTime + +////////////////////////////////////////// +////////////////////////////////////////// +////////// ////////// +////////// ZodISOTime ////////// +////////// ////////// +////////////////////////////////////////// +////////////////////////////////////////// + +export interface ZodISOTime extends schemas.ZodStringFormat { + _zod: core.$ZodISOTimeInternals; +} +export const ZodISOTime: core.$constructor = /*@__PURE__*/ core.$constructor("ZodISOTime", (inst, def) => { + core.$ZodISOTime.init(inst, def); + schemas.ZodStringFormat.init(inst, def); +}); + +export function time(params?: string | core.$ZodISOTimeParams): ZodISOTime { + return core._isoTime(ZodISOTime, params); +} + +////////////////////////////////////////////// +////////////////////////////////////////////// +////////// ////////// +////////// ZodISODuration ////////// +////////// ////////// +////////////////////////////////////////////// +////////////////////////////////////////////// + +export interface ZodISODuration extends schemas.ZodStringFormat { + _zod: core.$ZodISODurationInternals; +} +export const ZodISODuration: core.$constructor = /*@__PURE__*/ core.$constructor( + "ZodISODuration", + (inst, def) => { + core.$ZodISODuration.init(inst, def); + schemas.ZodStringFormat.init(inst, def); + } +); + +export function duration(params?: string | core.$ZodISODurationParams): ZodISODuration { + return core._isoDuration(ZodISODuration, params); +} diff --git a/node_modules/zod/src/v4/classic/parse.ts b/node_modules/zod/src/v4/classic/parse.ts new file mode 100644 index 00000000..e9b88c07 --- /dev/null +++ b/node_modules/zod/src/v4/classic/parse.ts @@ -0,0 +1,82 @@ +import * as core from "../core/index.js"; +import { type ZodError, ZodRealError } from "./errors.js"; + +export type ZodSafeParseResult = ZodSafeParseSuccess | ZodSafeParseError; +export type ZodSafeParseSuccess = { success: true; data: T; error?: never }; +export type ZodSafeParseError = { success: false; data?: never; error: ZodError }; + +export const parse: ( + schema: T, + value: unknown, + _ctx?: core.ParseContext, + _params?: { callee?: core.util.AnyFunc; Err?: core.$ZodErrorClass } +) => core.output = /* @__PURE__ */ core._parse(ZodRealError) as any; + +export const parseAsync: ( + schema: T, + value: unknown, + _ctx?: core.ParseContext, + _params?: { callee?: core.util.AnyFunc; Err?: core.$ZodErrorClass } +) => Promise> = /* @__PURE__ */ core._parseAsync(ZodRealError) as any; + +export const safeParse: ( + schema: T, + value: unknown, + _ctx?: core.ParseContext + // _params?: { callee?: core.util.AnyFunc; Err?: core.$ZodErrorClass } +) => ZodSafeParseResult> = /* @__PURE__ */ core._safeParse(ZodRealError) as any; + +export const safeParseAsync: ( + schema: T, + value: unknown, + _ctx?: core.ParseContext +) => Promise>> = /* @__PURE__ */ core._safeParseAsync(ZodRealError) as any; + +// Codec functions +export const encode: ( + schema: T, + value: core.output, + _ctx?: core.ParseContext +) => core.input = /* @__PURE__ */ core._encode(ZodRealError) as any; + +export const decode: ( + schema: T, + value: core.input, + _ctx?: core.ParseContext +) => core.output = /* @__PURE__ */ core._decode(ZodRealError) as any; + +export const encodeAsync: ( + schema: T, + value: core.output, + _ctx?: core.ParseContext +) => Promise> = /* @__PURE__ */ core._encodeAsync(ZodRealError) as any; + +export const decodeAsync: ( + schema: T, + value: core.input, + _ctx?: core.ParseContext +) => Promise> = /* @__PURE__ */ core._decodeAsync(ZodRealError) as any; + +export const safeEncode: ( + schema: T, + value: core.output, + _ctx?: core.ParseContext +) => ZodSafeParseResult> = /* @__PURE__ */ core._safeEncode(ZodRealError) as any; + +export const safeDecode: ( + schema: T, + value: core.input, + _ctx?: core.ParseContext +) => ZodSafeParseResult> = /* @__PURE__ */ core._safeDecode(ZodRealError) as any; + +export const safeEncodeAsync: ( + schema: T, + value: core.output, + _ctx?: core.ParseContext +) => Promise>> = /* @__PURE__ */ core._safeEncodeAsync(ZodRealError) as any; + +export const safeDecodeAsync: ( + schema: T, + value: core.input, + _ctx?: core.ParseContext +) => Promise>> = /* @__PURE__ */ core._safeDecodeAsync(ZodRealError) as any; diff --git a/node_modules/zod/src/v4/classic/schemas.ts b/node_modules/zod/src/v4/classic/schemas.ts new file mode 100644 index 00000000..481d25a1 --- /dev/null +++ b/node_modules/zod/src/v4/classic/schemas.ts @@ -0,0 +1,2409 @@ +import * as core from "../core/index.js"; +import { util } from "../core/index.js"; +import * as processors from "../core/json-schema-processors.js"; +import type { StandardSchemaWithJSONProps } from "../core/standard-schema.js"; +import { createStandardJSONSchemaMethod, createToJSONSchemaMethod } from "../core/to-json-schema.js"; + +import * as checks from "./checks.js"; +import * as iso from "./iso.js"; +import * as parse from "./parse.js"; + +/////////////////////////////////////////// +/////////////////////////////////////////// +//////////// //////////// +//////////// ZodType //////////// +//////////// //////////// +/////////////////////////////////////////// +/////////////////////////////////////////// + +export type ZodStandardSchemaWithJSON = StandardSchemaWithJSONProps, core.output>; +export interface ZodType< + out Output = unknown, + out Input = unknown, + out Internals extends core.$ZodTypeInternals = core.$ZodTypeInternals, +> extends core.$ZodType { + def: Internals["def"]; + type: Internals["def"]["type"]; + + /** @deprecated Use `.def` instead. */ + _def: Internals["def"]; + /** @deprecated Use `z.output` instead. */ + _output: Internals["output"]; + /** @deprecated Use `z.input` instead. */ + _input: Internals["input"]; + + "~standard": ZodStandardSchemaWithJSON; + /** Converts this schema to a JSON Schema representation. */ + toJSONSchema(params?: core.ToJSONSchemaParams): core.ZodStandardJSONSchemaPayload; + + // base methods + check(...checks: (core.CheckFn> | core.$ZodCheck>)[]): this; + with(...checks: (core.CheckFn> | core.$ZodCheck>)[]): this; + clone(def?: Internals["def"], params?: { parent: boolean }): this; + register( + registry: R, + ...meta: this extends R["_schema"] + ? undefined extends R["_meta"] + ? [core.$replace?] + : [core.$replace] + : ["Incompatible schema"] + ): this; + + brand( + value?: T + ): PropertyKey extends T ? this : core.$ZodBranded; + + // parsing + parse(data: unknown, params?: core.ParseContext): core.output; + safeParse(data: unknown, params?: core.ParseContext): parse.ZodSafeParseResult>; + parseAsync(data: unknown, params?: core.ParseContext): Promise>; + safeParseAsync( + data: unknown, + params?: core.ParseContext + ): Promise>>; + spa: ( + data: unknown, + params?: core.ParseContext + ) => Promise>>; + + // encoding/decoding + encode(data: core.output, params?: core.ParseContext): core.input; + decode(data: core.input, params?: core.ParseContext): core.output; + encodeAsync(data: core.output, params?: core.ParseContext): Promise>; + decodeAsync(data: core.input, params?: core.ParseContext): Promise>; + safeEncode( + data: core.output, + params?: core.ParseContext + ): parse.ZodSafeParseResult>; + safeDecode( + data: core.input, + params?: core.ParseContext + ): parse.ZodSafeParseResult>; + safeEncodeAsync( + data: core.output, + params?: core.ParseContext + ): Promise>>; + safeDecodeAsync( + data: core.input, + params?: core.ParseContext + ): Promise>>; + + // refinements + refine) => unknown | Promise>( + check: Ch, + params?: string | core.$ZodCustomParams + ): Ch extends (arg: any) => arg is infer R ? this & ZodType> : this; + superRefine( + refinement: (arg: core.output, ctx: core.$RefinementCtx>) => void | Promise + ): this; + overwrite(fn: (x: core.output) => core.output): this; + + // wrappers + optional(): ZodOptional; + exactOptional(): ZodExactOptional; + nonoptional(params?: string | core.$ZodNonOptionalParams): ZodNonOptional; + nullable(): ZodNullable; + nullish(): ZodOptional>; + default(def: util.NoUndefined>): ZodDefault; + default(def: () => util.NoUndefined>): ZodDefault; + prefault(def: () => core.input): ZodPrefault; + prefault(def: core.input): ZodPrefault; + array(): ZodArray; + or(option: T): ZodUnion<[this, T]>; + and(incoming: T): ZodIntersection; + transform( + transform: (arg: core.output, ctx: core.$RefinementCtx>) => NewOut | Promise + ): ZodPipe, core.output>>; + catch(def: core.output): ZodCatch; + catch(def: (ctx: core.$ZodCatchCtx) => core.output): ZodCatch; + pipe>>( + target: T | core.$ZodType> + ): ZodPipe; + readonly(): ZodReadonly; + + /** Returns a new instance that has been registered in `z.globalRegistry` with the specified description */ + describe(description: string): this; + description?: string; + /** Returns the metadata associated with this instance in `z.globalRegistry` */ + meta(): core.$replace | undefined; + /** Returns a new instance that has been registered in `z.globalRegistry` with the specified metadata */ + meta(data: core.$replace): this; + + // helpers + /** @deprecated Try safe-parsing `undefined` (this is what `isOptional` does internally): + * + * ```ts + * const schema = z.string().optional(); + * const isOptional = schema.safeParse(undefined).success; // true + * ``` + */ + isOptional(): boolean; + /** + * @deprecated Try safe-parsing `null` (this is what `isNullable` does internally): + * + * ```ts + * const schema = z.string().nullable(); + * const isNullable = schema.safeParse(null).success; // true + * ``` + */ + isNullable(): boolean; + apply(fn: (schema: this) => T): T; +} + +export interface _ZodType + extends ZodType {} + +export const ZodType: core.$constructor = /*@__PURE__*/ core.$constructor("ZodType", (inst, def) => { + core.$ZodType.init(inst, def); + Object.assign(inst["~standard"], { + jsonSchema: { + input: createStandardJSONSchemaMethod(inst, "input"), + output: createStandardJSONSchemaMethod(inst, "output"), + }, + }); + inst.toJSONSchema = createToJSONSchemaMethod(inst, {}); + + inst.def = def; + inst.type = def.type; + Object.defineProperty(inst, "_def", { value: def }); + + // base methods + inst.check = (...checks) => { + return inst.clone( + util.mergeDefs(def, { + checks: [ + ...(def.checks ?? []), + ...checks.map((ch) => + typeof ch === "function" ? { _zod: { check: ch, def: { check: "custom" }, onattach: [] } } : ch + ), + ], + }), + { + parent: true, + } + ); + }; + inst.with = inst.check; + inst.clone = (def, params) => core.clone(inst, def, params); + inst.brand = () => inst as any; + inst.register = ((reg: any, meta: any) => { + reg.add(inst, meta); + return inst; + }) as any; + + // parsing + inst.parse = (data, params) => parse.parse(inst, data, params, { callee: inst.parse }); + inst.safeParse = (data, params) => parse.safeParse(inst, data, params); + inst.parseAsync = async (data, params) => parse.parseAsync(inst, data, params, { callee: inst.parseAsync }); + inst.safeParseAsync = async (data, params) => parse.safeParseAsync(inst, data, params); + inst.spa = inst.safeParseAsync; + + // encoding/decoding + inst.encode = (data, params) => parse.encode(inst, data, params); + inst.decode = (data, params) => parse.decode(inst, data, params); + inst.encodeAsync = async (data, params) => parse.encodeAsync(inst, data, params); + inst.decodeAsync = async (data, params) => parse.decodeAsync(inst, data, params); + inst.safeEncode = (data, params) => parse.safeEncode(inst, data, params); + inst.safeDecode = (data, params) => parse.safeDecode(inst, data, params); + inst.safeEncodeAsync = async (data, params) => parse.safeEncodeAsync(inst, data, params); + inst.safeDecodeAsync = async (data, params) => parse.safeDecodeAsync(inst, data, params); + + // refinements + inst.refine = (check, params) => inst.check(refine(check, params)) as never; + inst.superRefine = (refinement) => inst.check(superRefine(refinement)); + inst.overwrite = (fn) => inst.check(checks.overwrite(fn)); + + // wrappers + inst.optional = () => optional(inst); + inst.exactOptional = () => exactOptional(inst); + inst.nullable = () => nullable(inst); + inst.nullish = () => optional(nullable(inst)); + inst.nonoptional = (params) => nonoptional(inst, params); + inst.array = () => array(inst); + inst.or = (arg) => union([inst, arg]); + inst.and = (arg) => intersection(inst, arg); + inst.transform = (tx) => pipe(inst, transform(tx as any)) as never; + inst.default = (def) => _default(inst, def); + inst.prefault = (def) => prefault(inst, def); + // inst.coalesce = (def, params) => coalesce(inst, def, params); + inst.catch = (params) => _catch(inst, params); + inst.pipe = (target) => pipe(inst, target); + inst.readonly = () => readonly(inst); + + // meta + inst.describe = (description) => { + const cl = inst.clone(); + core.globalRegistry.add(cl, { description }); + return cl; + }; + Object.defineProperty(inst, "description", { + get() { + return core.globalRegistry.get(inst)?.description; + }, + configurable: true, + }); + inst.meta = (...args: any) => { + if (args.length === 0) { + return core.globalRegistry.get(inst); + } + const cl = inst.clone(); + core.globalRegistry.add(cl, args[0]); + return cl as any; + }; + + // helpers + inst.isOptional = () => inst.safeParse(undefined).success; + inst.isNullable = () => inst.safeParse(null).success; + inst.apply = (fn) => fn(inst); + return inst; +}); + +// ZodString +export interface _ZodString = core.$ZodStringInternals> + extends _ZodType { + format: string | null; + minLength: number | null; + maxLength: number | null; + + // miscellaneous checks + regex(regex: RegExp, params?: string | core.$ZodCheckRegexParams): this; + includes(value: string, params?: string | core.$ZodCheckIncludesParams): this; + startsWith(value: string, params?: string | core.$ZodCheckStartsWithParams): this; + endsWith(value: string, params?: string | core.$ZodCheckEndsWithParams): this; + min(minLength: number, params?: string | core.$ZodCheckMinLengthParams): this; + max(maxLength: number, params?: string | core.$ZodCheckMaxLengthParams): this; + length(len: number, params?: string | core.$ZodCheckLengthEqualsParams): this; + nonempty(params?: string | core.$ZodCheckMinLengthParams): this; + lowercase(params?: string | core.$ZodCheckLowerCaseParams): this; + uppercase(params?: string | core.$ZodCheckUpperCaseParams): this; + + // transforms + trim(): this; + normalize(form?: "NFC" | "NFD" | "NFKC" | "NFKD" | (string & {})): this; + toLowerCase(): this; + toUpperCase(): this; + slugify(): this; +} + +/** @internal */ +export const _ZodString: core.$constructor<_ZodString> = /*@__PURE__*/ core.$constructor("_ZodString", (inst, def) => { + core.$ZodString.init(inst, def); + ZodType.init(inst, def); + + inst._zod.processJSONSchema = (ctx, json, params) => processors.stringProcessor(inst, ctx, json, params); + + const bag = inst._zod.bag; + inst.format = bag.format ?? null; + inst.minLength = bag.minimum ?? null; + inst.maxLength = bag.maximum ?? null; + + // validations + inst.regex = (...args) => inst.check(checks.regex(...args)); + inst.includes = (...args) => inst.check(checks.includes(...args)); + inst.startsWith = (...args) => inst.check(checks.startsWith(...args)); + inst.endsWith = (...args) => inst.check(checks.endsWith(...args)); + inst.min = (...args) => inst.check(checks.minLength(...args)); + inst.max = (...args) => inst.check(checks.maxLength(...args)); + inst.length = (...args) => inst.check(checks.length(...args)); + inst.nonempty = (...args) => inst.check(checks.minLength(1, ...args)); + inst.lowercase = (params) => inst.check(checks.lowercase(params)); + inst.uppercase = (params) => inst.check(checks.uppercase(params)); + + // transforms + inst.trim = () => inst.check(checks.trim()); + inst.normalize = (...args) => inst.check(checks.normalize(...args)); + inst.toLowerCase = () => inst.check(checks.toLowerCase()); + inst.toUpperCase = () => inst.check(checks.toUpperCase()); + inst.slugify = () => inst.check(checks.slugify()); +}); + +export interface ZodString extends _ZodString> { + // string format checks + + /** @deprecated Use `z.email()` instead. */ + email(params?: string | core.$ZodCheckEmailParams): this; + /** @deprecated Use `z.url()` instead. */ + url(params?: string | core.$ZodCheckURLParams): this; + /** @deprecated Use `z.jwt()` instead. */ + jwt(params?: string | core.$ZodCheckJWTParams): this; + /** @deprecated Use `z.emoji()` instead. */ + emoji(params?: string | core.$ZodCheckEmojiParams): this; + /** @deprecated Use `z.guid()` instead. */ + guid(params?: string | core.$ZodCheckGUIDParams): this; + /** @deprecated Use `z.uuid()` instead. */ + uuid(params?: string | core.$ZodCheckUUIDParams): this; + /** @deprecated Use `z.uuid()` instead. */ + uuidv4(params?: string | core.$ZodCheckUUIDParams): this; + /** @deprecated Use `z.uuid()` instead. */ + uuidv6(params?: string | core.$ZodCheckUUIDParams): this; + /** @deprecated Use `z.uuid()` instead. */ + uuidv7(params?: string | core.$ZodCheckUUIDParams): this; + /** @deprecated Use `z.nanoid()` instead. */ + nanoid(params?: string | core.$ZodCheckNanoIDParams): this; + /** @deprecated Use `z.guid()` instead. */ + guid(params?: string | core.$ZodCheckGUIDParams): this; + /** @deprecated Use `z.cuid()` instead. */ + cuid(params?: string | core.$ZodCheckCUIDParams): this; + /** @deprecated Use `z.cuid2()` instead. */ + cuid2(params?: string | core.$ZodCheckCUID2Params): this; + /** @deprecated Use `z.ulid()` instead. */ + ulid(params?: string | core.$ZodCheckULIDParams): this; + /** @deprecated Use `z.base64()` instead. */ + base64(params?: string | core.$ZodCheckBase64Params): this; + /** @deprecated Use `z.base64url()` instead. */ + base64url(params?: string | core.$ZodCheckBase64URLParams): this; + // /** @deprecated Use `z.jsonString()` instead. */ + // jsonString(params?: string | core.$ZodCheckJSONStringParams): this; + /** @deprecated Use `z.xid()` instead. */ + xid(params?: string | core.$ZodCheckXIDParams): this; + /** @deprecated Use `z.ksuid()` instead. */ + ksuid(params?: string | core.$ZodCheckKSUIDParams): this; + // /** @deprecated Use `z.ipv4()` or `z.ipv6()` instead. */ + // ip(params?: string | (core.$ZodCheckIPv4Params & { version?: "v4" | "v6" })): ZodUnion<[this, this]>; + /** @deprecated Use `z.ipv4()` instead. */ + ipv4(params?: string | core.$ZodCheckIPv4Params): this; + /** @deprecated Use `z.ipv6()` instead. */ + ipv6(params?: string | core.$ZodCheckIPv6Params): this; + /** @deprecated Use `z.cidrv4()` instead. */ + cidrv4(params?: string | core.$ZodCheckCIDRv4Params): this; + /** @deprecated Use `z.cidrv6()` instead. */ + cidrv6(params?: string | core.$ZodCheckCIDRv6Params): this; + /** @deprecated Use `z.e164()` instead. */ + e164(params?: string | core.$ZodCheckE164Params): this; + + // ISO 8601 checks + /** @deprecated Use `z.iso.datetime()` instead. */ + datetime(params?: string | core.$ZodCheckISODateTimeParams): this; + /** @deprecated Use `z.iso.date()` instead. */ + date(params?: string | core.$ZodCheckISODateParams): this; + /** @deprecated Use `z.iso.time()` instead. */ + time( + params?: + | string + // | { + // message?: string | undefined; + // precision?: number | null; + // } + | core.$ZodCheckISOTimeParams + ): this; + /** @deprecated Use `z.iso.duration()` instead. */ + duration(params?: string | core.$ZodCheckISODurationParams): this; +} + +export const ZodString: core.$constructor = /*@__PURE__*/ core.$constructor("ZodString", (inst, def) => { + core.$ZodString.init(inst, def); + _ZodString.init(inst, def); + + inst.email = (params) => inst.check(core._email(ZodEmail, params)); + inst.url = (params) => inst.check(core._url(ZodURL, params)); + inst.jwt = (params) => inst.check(core._jwt(ZodJWT, params)); + inst.emoji = (params) => inst.check(core._emoji(ZodEmoji, params)); + inst.guid = (params) => inst.check(core._guid(ZodGUID, params)); + inst.uuid = (params) => inst.check(core._uuid(ZodUUID, params)); + inst.uuidv4 = (params) => inst.check(core._uuidv4(ZodUUID, params)); + inst.uuidv6 = (params) => inst.check(core._uuidv6(ZodUUID, params)); + inst.uuidv7 = (params) => inst.check(core._uuidv7(ZodUUID, params)); + inst.nanoid = (params) => inst.check(core._nanoid(ZodNanoID, params)); + inst.guid = (params) => inst.check(core._guid(ZodGUID, params)); + inst.cuid = (params) => inst.check(core._cuid(ZodCUID, params)); + inst.cuid2 = (params) => inst.check(core._cuid2(ZodCUID2, params)); + inst.ulid = (params) => inst.check(core._ulid(ZodULID, params)); + inst.base64 = (params) => inst.check(core._base64(ZodBase64, params)); + inst.base64url = (params) => inst.check(core._base64url(ZodBase64URL, params)); + inst.xid = (params) => inst.check(core._xid(ZodXID, params)); + inst.ksuid = (params) => inst.check(core._ksuid(ZodKSUID, params)); + inst.ipv4 = (params) => inst.check(core._ipv4(ZodIPv4, params)); + inst.ipv6 = (params) => inst.check(core._ipv6(ZodIPv6, params)); + inst.cidrv4 = (params) => inst.check(core._cidrv4(ZodCIDRv4, params)); + inst.cidrv6 = (params) => inst.check(core._cidrv6(ZodCIDRv6, params)); + inst.e164 = (params) => inst.check(core._e164(ZodE164, params)); + + // iso + inst.datetime = (params) => inst.check(iso.datetime(params as any)); + inst.date = (params) => inst.check(iso.date(params as any)); + inst.time = (params) => inst.check(iso.time(params as any)); + inst.duration = (params) => inst.check(iso.duration(params as any)); +}); + +export function string(params?: string | core.$ZodStringParams): ZodString; +export function string(params?: string | core.$ZodStringParams): core.$ZodType; +export function string(params?: string | core.$ZodStringParams): ZodString { + return core._string(ZodString, params) as any; +} + +// ZodStringFormat +export interface ZodStringFormat + extends _ZodString> {} +export const ZodStringFormat: core.$constructor = /*@__PURE__*/ core.$constructor( + "ZodStringFormat", + (inst, def) => { + core.$ZodStringFormat.init(inst, def); + _ZodString.init(inst, def); + } +); + +// ZodEmail +export interface ZodEmail extends ZodStringFormat<"email"> { + _zod: core.$ZodEmailInternals; +} +export const ZodEmail: core.$constructor = /*@__PURE__*/ core.$constructor("ZodEmail", (inst, def) => { + // ZodStringFormat.init(inst, def); + core.$ZodEmail.init(inst, def); + ZodStringFormat.init(inst, def); +}); + +export function email(params?: string | core.$ZodEmailParams): ZodEmail { + return core._email(ZodEmail, params); +} + +// ZodGUID +export interface ZodGUID extends ZodStringFormat<"guid"> { + _zod: core.$ZodGUIDInternals; +} +export const ZodGUID: core.$constructor = /*@__PURE__*/ core.$constructor("ZodGUID", (inst, def) => { + // ZodStringFormat.init(inst, def); + core.$ZodGUID.init(inst, def); + ZodStringFormat.init(inst, def); +}); + +export function guid(params?: string | core.$ZodGUIDParams): ZodGUID { + return core._guid(ZodGUID, params); +} + +// ZodUUID +export interface ZodUUID extends ZodStringFormat<"uuid"> { + _zod: core.$ZodUUIDInternals; +} +export const ZodUUID: core.$constructor = /*@__PURE__*/ core.$constructor("ZodUUID", (inst, def) => { + // ZodStringFormat.init(inst, def); + core.$ZodUUID.init(inst, def); + ZodStringFormat.init(inst, def); +}); + +export function uuid(params?: string | core.$ZodUUIDParams): ZodUUID { + return core._uuid(ZodUUID, params); +} + +export function uuidv4(params?: string | core.$ZodUUIDv4Params): ZodUUID { + return core._uuidv4(ZodUUID, params); +} + +// ZodUUIDv6 + +export function uuidv6(params?: string | core.$ZodUUIDv6Params): ZodUUID { + return core._uuidv6(ZodUUID, params); +} + +// ZodUUIDv7 + +export function uuidv7(params?: string | core.$ZodUUIDv7Params): ZodUUID { + return core._uuidv7(ZodUUID, params); +} + +// ZodURL +export interface ZodURL extends ZodStringFormat<"url"> { + _zod: core.$ZodURLInternals; +} +export const ZodURL: core.$constructor = /*@__PURE__*/ core.$constructor("ZodURL", (inst, def) => { + // ZodStringFormat.init(inst, def); + core.$ZodURL.init(inst, def); + ZodStringFormat.init(inst, def); +}); + +export function url(params?: string | core.$ZodURLParams): ZodURL { + return core._url(ZodURL, params); +} + +export function httpUrl(params?: string | Omit): ZodURL { + return core._url(ZodURL, { + protocol: /^https?$/, + hostname: core.regexes.domain, + ...util.normalizeParams(params), + }); +} + +// ZodEmoji +export interface ZodEmoji extends ZodStringFormat<"emoji"> { + _zod: core.$ZodEmojiInternals; +} +export const ZodEmoji: core.$constructor = /*@__PURE__*/ core.$constructor("ZodEmoji", (inst, def) => { + // ZodStringFormat.init(inst, def); + core.$ZodEmoji.init(inst, def); + ZodStringFormat.init(inst, def); +}); + +export function emoji(params?: string | core.$ZodEmojiParams): ZodEmoji { + return core._emoji(ZodEmoji, params); +} + +// ZodNanoID +export interface ZodNanoID extends ZodStringFormat<"nanoid"> { + _zod: core.$ZodNanoIDInternals; +} +export const ZodNanoID: core.$constructor = /*@__PURE__*/ core.$constructor("ZodNanoID", (inst, def) => { + // ZodStringFormat.init(inst, def); + core.$ZodNanoID.init(inst, def); + ZodStringFormat.init(inst, def); +}); + +export function nanoid(params?: string | core.$ZodNanoIDParams): ZodNanoID { + return core._nanoid(ZodNanoID, params); +} + +// ZodCUID +export interface ZodCUID extends ZodStringFormat<"cuid"> { + _zod: core.$ZodCUIDInternals; +} +export const ZodCUID: core.$constructor = /*@__PURE__*/ core.$constructor("ZodCUID", (inst, def) => { + // ZodStringFormat.init(inst, def); + core.$ZodCUID.init(inst, def); + ZodStringFormat.init(inst, def); +}); + +export function cuid(params?: string | core.$ZodCUIDParams): ZodCUID { + return core._cuid(ZodCUID, params); +} + +// ZodCUID2 +export interface ZodCUID2 extends ZodStringFormat<"cuid2"> { + _zod: core.$ZodCUID2Internals; +} +export const ZodCUID2: core.$constructor = /*@__PURE__*/ core.$constructor("ZodCUID2", (inst, def) => { + // ZodStringFormat.init(inst, def); + core.$ZodCUID2.init(inst, def); + ZodStringFormat.init(inst, def); +}); + +export function cuid2(params?: string | core.$ZodCUID2Params): ZodCUID2 { + return core._cuid2(ZodCUID2, params); +} + +// ZodULID +export interface ZodULID extends ZodStringFormat<"ulid"> { + _zod: core.$ZodULIDInternals; +} +export const ZodULID: core.$constructor = /*@__PURE__*/ core.$constructor("ZodULID", (inst, def) => { + // ZodStringFormat.init(inst, def); + core.$ZodULID.init(inst, def); + ZodStringFormat.init(inst, def); +}); + +export function ulid(params?: string | core.$ZodULIDParams): ZodULID { + return core._ulid(ZodULID, params); +} + +// ZodXID +export interface ZodXID extends ZodStringFormat<"xid"> { + _zod: core.$ZodXIDInternals; +} +export const ZodXID: core.$constructor = /*@__PURE__*/ core.$constructor("ZodXID", (inst, def) => { + // ZodStringFormat.init(inst, def); + core.$ZodXID.init(inst, def); + ZodStringFormat.init(inst, def); +}); + +export function xid(params?: string | core.$ZodXIDParams): ZodXID { + return core._xid(ZodXID, params); +} + +// ZodKSUID +export interface ZodKSUID extends ZodStringFormat<"ksuid"> { + _zod: core.$ZodKSUIDInternals; +} +export const ZodKSUID: core.$constructor = /*@__PURE__*/ core.$constructor("ZodKSUID", (inst, def) => { + // ZodStringFormat.init(inst, def); + core.$ZodKSUID.init(inst, def); + ZodStringFormat.init(inst, def); +}); + +export function ksuid(params?: string | core.$ZodKSUIDParams): ZodKSUID { + return core._ksuid(ZodKSUID, params); +} + +// ZodIP +// export interface ZodIP extends ZodStringFormat<"ip"> { +// _zod: core.$ZodIPInternals; +// } +// export const ZodIP: core.$constructor = /*@__PURE__*/ core.$constructor("ZodIP", (inst, def) => { +// // ZodStringFormat.init(inst, def); +// core.$ZodIP.init(inst, def); +// ZodStringFormat.init(inst, def); +// }); + +// export function ip(params?: string | core.$ZodIPParams): ZodIP { +// return core._ip(ZodIP, params); +// } + +// ZodIPv4 +export interface ZodIPv4 extends ZodStringFormat<"ipv4"> { + _zod: core.$ZodIPv4Internals; +} +export const ZodIPv4: core.$constructor = /*@__PURE__*/ core.$constructor("ZodIPv4", (inst, def) => { + // ZodStringFormat.init(inst, def); + core.$ZodIPv4.init(inst, def); + ZodStringFormat.init(inst, def); +}); + +export function ipv4(params?: string | core.$ZodIPv4Params): ZodIPv4 { + return core._ipv4(ZodIPv4, params); +} + +// ZodMAC +export interface ZodMAC extends ZodStringFormat<"mac"> { + _zod: core.$ZodMACInternals; +} +export const ZodMAC: core.$constructor = /*@__PURE__*/ core.$constructor("ZodMAC", (inst, def) => { + // ZodStringFormat.init(inst, def); + core.$ZodMAC.init(inst, def); + ZodStringFormat.init(inst, def); +}); +export function mac(params?: string | core.$ZodMACParams): ZodMAC { + return core._mac(ZodMAC, params); +} + +// ZodIPv6 +export interface ZodIPv6 extends ZodStringFormat<"ipv6"> { + _zod: core.$ZodIPv6Internals; +} +export const ZodIPv6: core.$constructor = /*@__PURE__*/ core.$constructor("ZodIPv6", (inst, def) => { + // ZodStringFormat.init(inst, def); + core.$ZodIPv6.init(inst, def); + ZodStringFormat.init(inst, def); +}); +export function ipv6(params?: string | core.$ZodIPv6Params): ZodIPv6 { + return core._ipv6(ZodIPv6, params); +} + +// ZodCIDRv4 +export interface ZodCIDRv4 extends ZodStringFormat<"cidrv4"> { + _zod: core.$ZodCIDRv4Internals; +} +export const ZodCIDRv4: core.$constructor = /*@__PURE__*/ core.$constructor("ZodCIDRv4", (inst, def) => { + core.$ZodCIDRv4.init(inst, def); + ZodStringFormat.init(inst, def); +}); + +export function cidrv4(params?: string | core.$ZodCIDRv4Params): ZodCIDRv4 { + return core._cidrv4(ZodCIDRv4, params); +} + +// ZodCIDRv6 +export interface ZodCIDRv6 extends ZodStringFormat<"cidrv6"> { + _zod: core.$ZodCIDRv6Internals; +} +export const ZodCIDRv6: core.$constructor = /*@__PURE__*/ core.$constructor("ZodCIDRv6", (inst, def) => { + core.$ZodCIDRv6.init(inst, def); + ZodStringFormat.init(inst, def); +}); + +export function cidrv6(params?: string | core.$ZodCIDRv6Params): ZodCIDRv6 { + return core._cidrv6(ZodCIDRv6, params); +} + +// ZodBase64 +export interface ZodBase64 extends ZodStringFormat<"base64"> { + _zod: core.$ZodBase64Internals; +} +export const ZodBase64: core.$constructor = /*@__PURE__*/ core.$constructor("ZodBase64", (inst, def) => { + // ZodStringFormat.init(inst, def); + core.$ZodBase64.init(inst, def); + ZodStringFormat.init(inst, def); +}); +export function base64(params?: string | core.$ZodBase64Params): ZodBase64 { + return core._base64(ZodBase64, params); +} + +// ZodBase64URL +export interface ZodBase64URL extends ZodStringFormat<"base64url"> { + _zod: core.$ZodBase64URLInternals; +} +export const ZodBase64URL: core.$constructor = /*@__PURE__*/ core.$constructor( + "ZodBase64URL", + (inst, def) => { + // ZodStringFormat.init(inst, def); + core.$ZodBase64URL.init(inst, def); + ZodStringFormat.init(inst, def); + } +); +export function base64url(params?: string | core.$ZodBase64URLParams): ZodBase64URL { + return core._base64url(ZodBase64URL, params); +} + +// ZodE164 +export interface ZodE164 extends ZodStringFormat<"e164"> { + _zod: core.$ZodE164Internals; +} +export const ZodE164: core.$constructor = /*@__PURE__*/ core.$constructor("ZodE164", (inst, def) => { + // ZodStringFormat.init(inst, def); + core.$ZodE164.init(inst, def); + ZodStringFormat.init(inst, def); +}); + +export function e164(params?: string | core.$ZodE164Params): ZodE164 { + return core._e164(ZodE164, params); +} + +// ZodJWT +export interface ZodJWT extends ZodStringFormat<"jwt"> { + _zod: core.$ZodJWTInternals; +} +export const ZodJWT: core.$constructor = /*@__PURE__*/ core.$constructor("ZodJWT", (inst, def) => { + // ZodStringFormat.init(inst, def); + core.$ZodJWT.init(inst, def); + ZodStringFormat.init(inst, def); +}); + +export function jwt(params?: string | core.$ZodJWTParams): ZodJWT { + return core._jwt(ZodJWT, params); +} + +// ZodCustomStringFormat +export interface ZodCustomStringFormat + extends ZodStringFormat, + core.$ZodCustomStringFormat { + _zod: core.$ZodCustomStringFormatInternals; + "~standard": ZodStandardSchemaWithJSON; +} +export const ZodCustomStringFormat: core.$constructor = /*@__PURE__*/ core.$constructor( + "ZodCustomStringFormat", + (inst, def) => { + // ZodStringFormat.init(inst, def); + core.$ZodCustomStringFormat.init(inst, def); + ZodStringFormat.init(inst, def); + } +); +export function stringFormat( + format: Format, + fnOrRegex: ((arg: string) => util.MaybeAsync) | RegExp, + _params: string | core.$ZodStringFormatParams = {} +): ZodCustomStringFormat { + return core._stringFormat(ZodCustomStringFormat, format, fnOrRegex, _params) as any; +} + +export function hostname(_params?: string | core.$ZodStringFormatParams): ZodCustomStringFormat<"hostname"> { + return core._stringFormat(ZodCustomStringFormat, "hostname", core.regexes.hostname, _params) as any; +} + +export function hex(_params?: string | core.$ZodStringFormatParams): ZodCustomStringFormat<"hex"> { + return core._stringFormat(ZodCustomStringFormat, "hex", core.regexes.hex, _params) as any; +} + +export function hash( + alg: Alg, + params?: { + enc?: Enc; + } & core.$ZodStringFormatParams +): ZodCustomStringFormat<`${Alg}_${Enc}`> { + const enc = params?.enc ?? "hex"; + const format = `${alg}_${enc}` as const; + const regex = core.regexes[format as keyof typeof core.regexes] as RegExp; + if (!regex) throw new Error(`Unrecognized hash format: ${format}`); + return core._stringFormat(ZodCustomStringFormat, format, regex, params) as any; +} + +// ZodNumber +export interface _ZodNumber + extends _ZodType { + gt(value: number, params?: string | core.$ZodCheckGreaterThanParams): this; + /** Identical to .min() */ + gte(value: number, params?: string | core.$ZodCheckGreaterThanParams): this; + min(value: number, params?: string | core.$ZodCheckGreaterThanParams): this; + lt(value: number, params?: string | core.$ZodCheckLessThanParams): this; + /** Identical to .max() */ + lte(value: number, params?: string | core.$ZodCheckLessThanParams): this; + max(value: number, params?: string | core.$ZodCheckLessThanParams): this; + /** Consider `z.int()` instead. This API is considered *legacy*; it will never be removed but a better alternative exists. */ + int(params?: string | core.$ZodCheckNumberFormatParams): this; + /** @deprecated This is now identical to `.int()`. Only numbers in the safe integer range are accepted. */ + safe(params?: string | core.$ZodCheckNumberFormatParams): this; + positive(params?: string | core.$ZodCheckGreaterThanParams): this; + nonnegative(params?: string | core.$ZodCheckGreaterThanParams): this; + negative(params?: string | core.$ZodCheckLessThanParams): this; + nonpositive(params?: string | core.$ZodCheckLessThanParams): this; + multipleOf(value: number, params?: string | core.$ZodCheckMultipleOfParams): this; + /** @deprecated Use `.multipleOf()` instead. */ + step(value: number, params?: string | core.$ZodCheckMultipleOfParams): this; + + /** @deprecated In v4 and later, z.number() does not allow infinite values by default. This is a no-op. */ + finite(params?: unknown): this; + + minValue: number | null; + maxValue: number | null; + /** @deprecated Check the `format` property instead. */ + isInt: boolean; + /** @deprecated Number schemas no longer accept infinite values, so this always returns `true`. */ + isFinite: boolean; + format: string | null; +} + +export interface ZodNumber extends _ZodNumber> {} + +export const ZodNumber: core.$constructor = /*@__PURE__*/ core.$constructor("ZodNumber", (inst, def) => { + core.$ZodNumber.init(inst, def); + + ZodType.init(inst, def); + + inst._zod.processJSONSchema = (ctx, json, params) => processors.numberProcessor(inst, ctx, json, params); + + inst.gt = (value, params) => inst.check(checks.gt(value, params)); + inst.gte = (value, params) => inst.check(checks.gte(value, params)); + inst.min = (value, params) => inst.check(checks.gte(value, params)); + inst.lt = (value, params) => inst.check(checks.lt(value, params)); + inst.lte = (value, params) => inst.check(checks.lte(value, params)); + inst.max = (value, params) => inst.check(checks.lte(value, params)); + inst.int = (params) => inst.check(int(params)); + inst.safe = (params) => inst.check(int(params)); + inst.positive = (params) => inst.check(checks.gt(0, params)); + inst.nonnegative = (params) => inst.check(checks.gte(0, params)); + inst.negative = (params) => inst.check(checks.lt(0, params)); + inst.nonpositive = (params) => inst.check(checks.lte(0, params)); + inst.multipleOf = (value, params) => inst.check(checks.multipleOf(value, params)); + inst.step = (value, params) => inst.check(checks.multipleOf(value, params)); + + // inst.finite = (params) => inst.check(core.finite(params)); + inst.finite = () => inst; + + const bag = inst._zod.bag; + inst.minValue = + Math.max(bag.minimum ?? Number.NEGATIVE_INFINITY, bag.exclusiveMinimum ?? Number.NEGATIVE_INFINITY) ?? null; + inst.maxValue = + Math.min(bag.maximum ?? Number.POSITIVE_INFINITY, bag.exclusiveMaximum ?? Number.POSITIVE_INFINITY) ?? null; + inst.isInt = (bag.format ?? "").includes("int") || Number.isSafeInteger(bag.multipleOf ?? 0.5); + inst.isFinite = true; + inst.format = bag.format ?? null; +}); + +export function number(params?: string | core.$ZodNumberParams): ZodNumber { + return core._number(ZodNumber, params) as any; +} + +// ZodNumberFormat +export interface ZodNumberFormat extends ZodNumber { + _zod: core.$ZodNumberFormatInternals; +} +export const ZodNumberFormat: core.$constructor = /*@__PURE__*/ core.$constructor( + "ZodNumberFormat", + (inst, def) => { + core.$ZodNumberFormat.init(inst, def); + ZodNumber.init(inst, def); + } +); + +// int +export interface ZodInt extends ZodNumberFormat {} +export function int(params?: string | core.$ZodCheckNumberFormatParams): ZodInt { + return core._int(ZodNumberFormat, params); +} + +// float32 +export interface ZodFloat32 extends ZodNumberFormat {} +export function float32(params?: string | core.$ZodCheckNumberFormatParams): ZodFloat32 { + return core._float32(ZodNumberFormat, params); +} + +// float64 +export interface ZodFloat64 extends ZodNumberFormat {} +export function float64(params?: string | core.$ZodCheckNumberFormatParams): ZodFloat64 { + return core._float64(ZodNumberFormat, params); +} + +// int32 +export interface ZodInt32 extends ZodNumberFormat {} +export function int32(params?: string | core.$ZodCheckNumberFormatParams): ZodInt32 { + return core._int32(ZodNumberFormat, params); +} + +// uint32 +export interface ZodUInt32 extends ZodNumberFormat {} +export function uint32(params?: string | core.$ZodCheckNumberFormatParams): ZodUInt32 { + return core._uint32(ZodNumberFormat, params); +} + +// boolean +export interface _ZodBoolean extends _ZodType {} +export interface ZodBoolean extends _ZodBoolean> {} +export const ZodBoolean: core.$constructor = /*@__PURE__*/ core.$constructor("ZodBoolean", (inst, def) => { + core.$ZodBoolean.init(inst, def); + ZodType.init(inst, def); + inst._zod.processJSONSchema = (ctx, json, params) => processors.booleanProcessor(inst, ctx, json, params); +}); + +export function boolean(params?: string | core.$ZodBooleanParams): ZodBoolean { + return core._boolean(ZodBoolean, params) as any; +} + +// bigint +export interface _ZodBigInt extends _ZodType { + gte(value: bigint, params?: string | core.$ZodCheckGreaterThanParams): this; + /** Alias of `.gte()` */ + min(value: bigint, params?: string | core.$ZodCheckGreaterThanParams): this; + gt(value: bigint, params?: string | core.$ZodCheckGreaterThanParams): this; + /** Alias of `.lte()` */ + lte(value: bigint, params?: string | core.$ZodCheckLessThanParams): this; + max(value: bigint, params?: string | core.$ZodCheckLessThanParams): this; + lt(value: bigint, params?: string | core.$ZodCheckLessThanParams): this; + positive(params?: string | core.$ZodCheckGreaterThanParams): this; + negative(params?: string | core.$ZodCheckLessThanParams): this; + nonpositive(params?: string | core.$ZodCheckLessThanParams): this; + nonnegative(params?: string | core.$ZodCheckGreaterThanParams): this; + multipleOf(value: bigint, params?: string | core.$ZodCheckMultipleOfParams): this; + + minValue: bigint | null; + maxValue: bigint | null; + format: string | null; +} + +export interface ZodBigInt extends _ZodBigInt> {} +export const ZodBigInt: core.$constructor = /*@__PURE__*/ core.$constructor("ZodBigInt", (inst, def) => { + core.$ZodBigInt.init(inst, def); + ZodType.init(inst, def); + inst._zod.processJSONSchema = (ctx, json, params) => processors.bigintProcessor(inst, ctx, json, params); + + inst.gte = (value, params) => inst.check(checks.gte(value, params)); + inst.min = (value, params) => inst.check(checks.gte(value, params)); + inst.gt = (value, params) => inst.check(checks.gt(value, params)); + inst.gte = (value, params) => inst.check(checks.gte(value, params)); + inst.min = (value, params) => inst.check(checks.gte(value, params)); + inst.lt = (value, params) => inst.check(checks.lt(value, params)); + inst.lte = (value, params) => inst.check(checks.lte(value, params)); + inst.max = (value, params) => inst.check(checks.lte(value, params)); + inst.positive = (params) => inst.check(checks.gt(BigInt(0), params)); + inst.negative = (params) => inst.check(checks.lt(BigInt(0), params)); + inst.nonpositive = (params) => inst.check(checks.lte(BigInt(0), params)); + inst.nonnegative = (params) => inst.check(checks.gte(BigInt(0), params)); + inst.multipleOf = (value, params) => inst.check(checks.multipleOf(value, params)); + + const bag = inst._zod.bag; + inst.minValue = bag.minimum ?? null; + inst.maxValue = bag.maximum ?? null; + inst.format = bag.format ?? null; +}); + +export function bigint(params?: string | core.$ZodBigIntParams): ZodBigInt { + return core._bigint(ZodBigInt, params) as any; +} +// bigint formats + +// ZodBigIntFormat +export interface ZodBigIntFormat extends ZodBigInt { + _zod: core.$ZodBigIntFormatInternals; +} +export const ZodBigIntFormat: core.$constructor = /*@__PURE__*/ core.$constructor( + "ZodBigIntFormat", + (inst, def) => { + core.$ZodBigIntFormat.init(inst, def); + ZodBigInt.init(inst, def); + } +); + +// int64 +export function int64(params?: string | core.$ZodBigIntFormatParams): ZodBigIntFormat { + return core._int64(ZodBigIntFormat, params); +} + +// uint64 +export function uint64(params?: string | core.$ZodBigIntFormatParams): ZodBigIntFormat { + return core._uint64(ZodBigIntFormat, params); +} + +// symbol +export interface ZodSymbol extends _ZodType {} +export const ZodSymbol: core.$constructor = /*@__PURE__*/ core.$constructor("ZodSymbol", (inst, def) => { + core.$ZodSymbol.init(inst, def); + ZodType.init(inst, def); + inst._zod.processJSONSchema = (ctx, json, params) => processors.symbolProcessor(inst, ctx, json, params); +}); + +export function symbol(params?: string | core.$ZodSymbolParams): ZodSymbol { + return core._symbol(ZodSymbol, params); +} + +// ZodUndefined +export interface ZodUndefined extends _ZodType {} +export const ZodUndefined: core.$constructor = /*@__PURE__*/ core.$constructor( + "ZodUndefined", + (inst, def) => { + core.$ZodUndefined.init(inst, def); + ZodType.init(inst, def); + inst._zod.processJSONSchema = (ctx, json, params) => processors.undefinedProcessor(inst, ctx, json, params); + } +); + +function _undefined(params?: string | core.$ZodUndefinedParams): ZodUndefined { + return core._undefined(ZodUndefined, params); +} +export { _undefined as undefined }; + +// ZodNull +export interface ZodNull extends _ZodType {} +export const ZodNull: core.$constructor = /*@__PURE__*/ core.$constructor("ZodNull", (inst, def) => { + core.$ZodNull.init(inst, def); + ZodType.init(inst, def); + inst._zod.processJSONSchema = (ctx, json, params) => processors.nullProcessor(inst, ctx, json, params); +}); + +function _null(params?: string | core.$ZodNullParams): ZodNull { + return core._null(ZodNull, params); +} +export { _null as null }; + +// ZodAny +export interface ZodAny extends _ZodType {} +export const ZodAny: core.$constructor = /*@__PURE__*/ core.$constructor("ZodAny", (inst, def) => { + core.$ZodAny.init(inst, def); + ZodType.init(inst, def); + inst._zod.processJSONSchema = (ctx, json, params) => processors.anyProcessor(inst, ctx, json, params); +}); + +export function any(): ZodAny { + return core._any(ZodAny); +} + +// ZodUnknown +export interface ZodUnknown extends _ZodType {} +export const ZodUnknown: core.$constructor = /*@__PURE__*/ core.$constructor("ZodUnknown", (inst, def) => { + core.$ZodUnknown.init(inst, def); + ZodType.init(inst, def); + inst._zod.processJSONSchema = (ctx, json, params) => processors.unknownProcessor(inst, ctx, json, params); +}); + +export function unknown(): ZodUnknown { + return core._unknown(ZodUnknown); +} + +// ZodNever +export interface ZodNever extends _ZodType {} +export const ZodNever: core.$constructor = /*@__PURE__*/ core.$constructor("ZodNever", (inst, def) => { + core.$ZodNever.init(inst, def); + ZodType.init(inst, def); + inst._zod.processJSONSchema = (ctx, json, params) => processors.neverProcessor(inst, ctx, json, params); +}); + +export function never(params?: string | core.$ZodNeverParams): ZodNever { + return core._never(ZodNever, params); +} + +// ZodVoid +export interface ZodVoid extends _ZodType {} +export const ZodVoid: core.$constructor = /*@__PURE__*/ core.$constructor("ZodVoid", (inst, def) => { + core.$ZodVoid.init(inst, def); + ZodType.init(inst, def); + inst._zod.processJSONSchema = (ctx, json, params) => processors.voidProcessor(inst, ctx, json, params); +}); + +function _void(params?: string | core.$ZodVoidParams): ZodVoid { + return core._void(ZodVoid, params); +} +export { _void as void }; + +// ZodDate +export interface _ZodDate extends _ZodType { + min(value: number | Date, params?: string | core.$ZodCheckGreaterThanParams): this; + max(value: number | Date, params?: string | core.$ZodCheckLessThanParams): this; + + /** @deprecated Not recommended. */ + minDate: Date | null; + /** @deprecated Not recommended. */ + maxDate: Date | null; +} + +export interface ZodDate extends _ZodDate> {} +export const ZodDate: core.$constructor = /*@__PURE__*/ core.$constructor("ZodDate", (inst, def) => { + core.$ZodDate.init(inst, def); + ZodType.init(inst, def); + inst._zod.processJSONSchema = (ctx, json, params) => processors.dateProcessor(inst, ctx, json, params); + + inst.min = (value, params) => inst.check(checks.gte(value, params)); + inst.max = (value, params) => inst.check(checks.lte(value, params)); + + const c = inst._zod.bag; + inst.minDate = c.minimum ? new Date(c.minimum) : null; + inst.maxDate = c.maximum ? new Date(c.maximum) : null; +}); + +export function date(params?: string | core.$ZodDateParams): ZodDate { + return core._date(ZodDate, params); +} + +// ZodArray +export interface ZodArray + extends _ZodType>, + core.$ZodArray { + element: T; + min(minLength: number, params?: string | core.$ZodCheckMinLengthParams): this; + nonempty(params?: string | core.$ZodCheckMinLengthParams): this; + max(maxLength: number, params?: string | core.$ZodCheckMaxLengthParams): this; + length(len: number, params?: string | core.$ZodCheckLengthEqualsParams): this; + + unwrap(): T; + "~standard": ZodStandardSchemaWithJSON; +} +export const ZodArray: core.$constructor = /*@__PURE__*/ core.$constructor("ZodArray", (inst, def) => { + core.$ZodArray.init(inst, def); + ZodType.init(inst, def); + inst._zod.processJSONSchema = (ctx, json, params) => processors.arrayProcessor(inst, ctx, json, params); + + inst.element = def.element as any; + inst.min = (minLength, params) => inst.check(checks.minLength(minLength, params)); + inst.nonempty = (params) => inst.check(checks.minLength(1, params)); + inst.max = (maxLength, params) => inst.check(checks.maxLength(maxLength, params)); + inst.length = (len, params) => inst.check(checks.length(len, params)); + + inst.unwrap = () => inst.element; +}); + +export function array(element: T, params?: string | core.$ZodArrayParams): ZodArray { + return core._array(ZodArray, element as any, params) as any; +} + +// .keyof +export function keyof(schema: T): ZodEnum> { + const shape = schema._zod.def.shape; + return _enum(Object.keys(shape)) as any; +} + +// ZodObject + +export type SafeExtendShape = { + [K in keyof Ext]: K extends keyof Base + ? core.output extends core.output + ? core.input extends core.input + ? Ext[K] + : never + : never + : Ext[K]; +}; + +export interface ZodObject< + /** @ts-ignore Cast variance */ + out Shape extends core.$ZodShape = core.$ZodLooseShape, + out Config extends core.$ZodObjectConfig = core.$strip, +> extends _ZodType>, + core.$ZodObject { + "~standard": ZodStandardSchemaWithJSON; + shape: Shape; + + keyof(): ZodEnum>; + /** Define a schema to validate all unrecognized keys. This overrides the existing strict/loose behavior. */ + catchall(schema: T): ZodObject>; + + /** @deprecated Use `z.looseObject()` or `.loose()` instead. */ + passthrough(): ZodObject; + /** Consider `z.looseObject(A.shape)` instead */ + loose(): ZodObject; + + /** Consider `z.strictObject(A.shape)` instead */ + strict(): ZodObject; + + /** This is the default behavior. This method call is likely unnecessary. */ + strip(): ZodObject; + + extend(shape: U): ZodObject, Config>; + + safeExtend( + shape: SafeExtendShape & Partial> + ): ZodObject, Config>; + + /** + * @deprecated Use [`A.extend(B.shape)`](https://zod.dev/api?id=extend) instead. + */ + merge(other: U): ZodObject, U["_zod"]["config"]>; + + pick>( + mask: M & Record, never> + ): ZodObject>>, Config>; + + omit>( + mask: M & Record, never> + ): ZodObject>>, Config>; + + partial(): ZodObject< + { + [k in keyof Shape]: ZodOptional; + }, + Config + >; + partial>( + mask: M & Record, never> + ): ZodObject< + { + [k in keyof Shape]: k extends keyof M + ? // Shape[k] extends OptionalInSchema + // ? Shape[k] + // : + ZodOptional + : Shape[k]; + }, + Config + >; + + // required + required(): ZodObject< + { + [k in keyof Shape]: ZodNonOptional; + }, + Config + >; + required>( + mask: M & Record, never> + ): ZodObject< + { + [k in keyof Shape]: k extends keyof M ? ZodNonOptional : Shape[k]; + }, + Config + >; +} + +export const ZodObject: core.$constructor = /*@__PURE__*/ core.$constructor("ZodObject", (inst, def) => { + core.$ZodObjectJIT.init(inst, def); + ZodType.init(inst, def); + inst._zod.processJSONSchema = (ctx, json, params) => processors.objectProcessor(inst, ctx, json, params); + + util.defineLazy(inst, "shape", () => { + return def.shape; + }); + + inst.keyof = () => _enum(Object.keys(inst._zod.def.shape)) as any; + inst.catchall = (catchall) => inst.clone({ ...inst._zod.def, catchall: catchall as any as core.$ZodType }) as any; + inst.passthrough = () => inst.clone({ ...inst._zod.def, catchall: unknown() }); + inst.loose = () => inst.clone({ ...inst._zod.def, catchall: unknown() }); + inst.strict = () => inst.clone({ ...inst._zod.def, catchall: never() }); + inst.strip = () => inst.clone({ ...inst._zod.def, catchall: undefined }); + + inst.extend = (incoming: any) => { + return util.extend(inst, incoming); + }; + inst.safeExtend = (incoming: any) => { + return util.safeExtend(inst, incoming); + }; + inst.merge = (other) => util.merge(inst, other); + inst.pick = (mask) => util.pick(inst, mask); + inst.omit = (mask) => util.omit(inst, mask); + inst.partial = (...args: any[]) => util.partial(ZodOptional, inst, args[0] as object); + inst.required = (...args: any[]) => util.required(ZodNonOptional, inst, args[0] as object); +}); + +export function object>>( + shape?: T, + params?: string | core.$ZodObjectParams +): ZodObject, core.$strip> { + const def: core.$ZodObjectDef = { + type: "object", + shape: shape ?? {}, + ...util.normalizeParams(params), + }; + return new ZodObject(def) as any; +} + +// strictObject + +export function strictObject( + shape: T, + params?: string | core.$ZodObjectParams +): ZodObject { + return new ZodObject({ + type: "object", + shape, + catchall: never(), + ...util.normalizeParams(params), + }) as any; +} + +// looseObject + +export function looseObject( + shape: T, + params?: string | core.$ZodObjectParams +): ZodObject { + return new ZodObject({ + type: "object", + shape, + catchall: unknown(), + ...util.normalizeParams(params), + }) as any; +} + +// ZodUnion +export interface ZodUnion + extends _ZodType>, + core.$ZodUnion { + "~standard": ZodStandardSchemaWithJSON; + options: T; +} +export const ZodUnion: core.$constructor = /*@__PURE__*/ core.$constructor("ZodUnion", (inst, def) => { + core.$ZodUnion.init(inst, def); + ZodType.init(inst, def); + inst._zod.processJSONSchema = (ctx, json, params) => processors.unionProcessor(inst, ctx, json, params); + inst.options = def.options; +}); + +export function union( + options: T, + params?: string | core.$ZodUnionParams +): ZodUnion { + return new ZodUnion({ + type: "union", + options: options as any as core.$ZodType[], + ...util.normalizeParams(params), + }) as any; +} + +// ZodXor +export interface ZodXor + extends _ZodType>, + core.$ZodXor { + "~standard": ZodStandardSchemaWithJSON; + options: T; +} +export const ZodXor: core.$constructor = /*@__PURE__*/ core.$constructor("ZodXor", (inst, def) => { + ZodUnion.init(inst, def); + core.$ZodXor.init(inst, def); + inst._zod.processJSONSchema = (ctx, json, params) => processors.unionProcessor(inst, ctx, json, params); + inst.options = def.options; +}); + +/** Creates an exclusive union (XOR) where exactly one option must match. + * Unlike regular unions that succeed when any option matches, xor fails if + * zero or more than one option matches the input. */ +export function xor( + options: T, + params?: string | core.$ZodXorParams +): ZodXor { + return new ZodXor({ + type: "union", + options: options as any as core.$ZodType[], + inclusive: false, + ...util.normalizeParams(params), + }) as any; +} + +// ZodDiscriminatedUnion +export interface ZodDiscriminatedUnion< + Options extends readonly core.SomeType[] = readonly core.$ZodType[], + Disc extends string = string, +> extends ZodUnion, + core.$ZodDiscriminatedUnion { + "~standard": ZodStandardSchemaWithJSON; + _zod: core.$ZodDiscriminatedUnionInternals; + def: core.$ZodDiscriminatedUnionDef; +} +export const ZodDiscriminatedUnion: core.$constructor = /*@__PURE__*/ core.$constructor( + "ZodDiscriminatedUnion", + (inst, def) => { + ZodUnion.init(inst, def); + core.$ZodDiscriminatedUnion.init(inst, def); + } +); + +export function discriminatedUnion< + Types extends readonly [core.$ZodTypeDiscriminable, ...core.$ZodTypeDiscriminable[]], + Disc extends string, +>( + discriminator: Disc, + options: Types, + params?: string | core.$ZodDiscriminatedUnionParams +): ZodDiscriminatedUnion { + // const [options, params] = args; + return new ZodDiscriminatedUnion({ + type: "union", + options, + discriminator, + ...util.normalizeParams(params), + }) as any; +} + +// ZodIntersection +export interface ZodIntersection + extends _ZodType>, + core.$ZodIntersection { + "~standard": ZodStandardSchemaWithJSON; +} +export const ZodIntersection: core.$constructor = /*@__PURE__*/ core.$constructor( + "ZodIntersection", + (inst, def) => { + core.$ZodIntersection.init(inst, def); + ZodType.init(inst, def); + inst._zod.processJSONSchema = (ctx, json, params) => processors.intersectionProcessor(inst, ctx, json, params); + } +); + +export function intersection( + left: T, + right: U +): ZodIntersection { + return new ZodIntersection({ + type: "intersection", + left: left as any as core.$ZodType, + right: right as any as core.$ZodType, + }) as any; +} + +// ZodTuple +export interface ZodTuple< + T extends util.TupleItems = readonly core.$ZodType[], + Rest extends core.SomeType | null = core.$ZodType | null, +> extends _ZodType>, + core.$ZodTuple { + "~standard": ZodStandardSchemaWithJSON; + rest(rest: Rest): ZodTuple; +} +export const ZodTuple: core.$constructor = /*@__PURE__*/ core.$constructor("ZodTuple", (inst, def) => { + core.$ZodTuple.init(inst, def); + ZodType.init(inst, def); + inst._zod.processJSONSchema = (ctx, json, params) => processors.tupleProcessor(inst, ctx, json, params); + inst.rest = (rest) => + inst.clone({ + ...inst._zod.def, + rest: rest as any as core.$ZodType, + }) as any; +}); + +export function tuple( + items: T, + params?: string | core.$ZodTupleParams +): ZodTuple; +export function tuple( + items: T, + rest: Rest, + params?: string | core.$ZodTupleParams +): ZodTuple; +export function tuple(items: [], params?: string | core.$ZodTupleParams): ZodTuple<[], null>; +export function tuple( + items: core.SomeType[], + _paramsOrRest?: string | core.$ZodTupleParams | core.SomeType, + _params?: string | core.$ZodTupleParams +) { + const hasRest = _paramsOrRest instanceof core.$ZodType; + const params = hasRest ? _params : _paramsOrRest; + const rest = hasRest ? _paramsOrRest : null; + return new ZodTuple({ + type: "tuple", + items: items as any as core.$ZodType[], + rest, + ...util.normalizeParams(params), + }); +} + +// ZodRecord +export interface ZodRecord< + Key extends core.$ZodRecordKey = core.$ZodRecordKey, + Value extends core.SomeType = core.$ZodType, +> extends _ZodType>, + core.$ZodRecord { + "~standard": ZodStandardSchemaWithJSON; + keyType: Key; + valueType: Value; +} +export const ZodRecord: core.$constructor = /*@__PURE__*/ core.$constructor("ZodRecord", (inst, def) => { + core.$ZodRecord.init(inst, def); + ZodType.init(inst, def); + inst._zod.processJSONSchema = (ctx, json, params) => processors.recordProcessor(inst, ctx, json, params); + + inst.keyType = def.keyType; + inst.valueType = def.valueType; +}); + +export function record( + keyType: Key, + valueType: Value, + params?: string | core.$ZodRecordParams +): ZodRecord { + return new ZodRecord({ + type: "record", + keyType, + valueType: valueType as any as core.$ZodType, + ...util.normalizeParams(params), + }) as any; +} +// type alksjf = core.output; +export function partialRecord( + keyType: Key, + valueType: Value, + params?: string | core.$ZodRecordParams +): ZodRecord { + const k = core.clone(keyType); + k._zod.values = undefined; + return new ZodRecord({ + type: "record", + keyType: k, + valueType: valueType as any, + ...util.normalizeParams(params), + }) as any; +} + +export function looseRecord( + keyType: Key, + valueType: Value, + params?: string | core.$ZodRecordParams +): ZodRecord { + return new ZodRecord({ + type: "record", + keyType, + valueType: valueType as any as core.$ZodType, + mode: "loose", + ...util.normalizeParams(params), + }) as any; +} + +// ZodMap +export interface ZodMap + extends _ZodType>, + core.$ZodMap { + "~standard": ZodStandardSchemaWithJSON; + keyType: Key; + valueType: Value; + min(minSize: number, params?: string | core.$ZodCheckMinSizeParams): this; + nonempty(params?: string | core.$ZodCheckMinSizeParams): this; + max(maxSize: number, params?: string | core.$ZodCheckMaxSizeParams): this; + size(size: number, params?: string | core.$ZodCheckSizeEqualsParams): this; +} +export const ZodMap: core.$constructor = /*@__PURE__*/ core.$constructor("ZodMap", (inst, def) => { + core.$ZodMap.init(inst, def); + ZodType.init(inst, def); + inst._zod.processJSONSchema = (ctx, json, params) => processors.mapProcessor(inst, ctx, json, params); + inst.keyType = def.keyType; + inst.valueType = def.valueType; + inst.min = (...args) => inst.check(core._minSize(...args)); + inst.nonempty = (params) => inst.check(core._minSize(1, params)); + inst.max = (...args) => inst.check(core._maxSize(...args)); + inst.size = (...args) => inst.check(core._size(...args)); +}); + +export function map( + keyType: Key, + valueType: Value, + params?: string | core.$ZodMapParams +): ZodMap { + return new ZodMap({ + type: "map", + keyType: keyType as any as core.$ZodType, + valueType: valueType as any as core.$ZodType, + ...util.normalizeParams(params), + }) as any; +} + +// ZodSet +export interface ZodSet + extends _ZodType>, + core.$ZodSet { + "~standard": ZodStandardSchemaWithJSON; + min(minSize: number, params?: string | core.$ZodCheckMinSizeParams): this; + nonempty(params?: string | core.$ZodCheckMinSizeParams): this; + max(maxSize: number, params?: string | core.$ZodCheckMaxSizeParams): this; + size(size: number, params?: string | core.$ZodCheckSizeEqualsParams): this; +} +export const ZodSet: core.$constructor = /*@__PURE__*/ core.$constructor("ZodSet", (inst, def) => { + core.$ZodSet.init(inst, def); + ZodType.init(inst, def); + inst._zod.processJSONSchema = (ctx, json, params) => processors.setProcessor(inst, ctx, json, params); + + inst.min = (...args) => inst.check(core._minSize(...args)); + inst.nonempty = (params) => inst.check(core._minSize(1, params)); + inst.max = (...args) => inst.check(core._maxSize(...args)); + inst.size = (...args) => inst.check(core._size(...args)); +}); + +export function set( + valueType: Value, + params?: string | core.$ZodSetParams +): ZodSet { + return new ZodSet({ + type: "set", + valueType: valueType as any as core.$ZodType, + ...util.normalizeParams(params), + }) as any; +} + +// ZodEnum +export interface ZodEnum< + /** @ts-ignore Cast variance */ + out T extends util.EnumLike = util.EnumLike, +> extends _ZodType>, + core.$ZodEnum { + "~standard": ZodStandardSchemaWithJSON; + enum: T; + options: Array; + + extract( + values: U, + params?: string | core.$ZodEnumParams + ): ZodEnum>>; + exclude( + values: U, + params?: string | core.$ZodEnumParams + ): ZodEnum>>; +} +export const ZodEnum: core.$constructor = /*@__PURE__*/ core.$constructor("ZodEnum", (inst, def) => { + core.$ZodEnum.init(inst, def); + ZodType.init(inst, def); + inst._zod.processJSONSchema = (ctx, json, params) => processors.enumProcessor(inst, ctx, json, params); + + inst.enum = def.entries; + inst.options = Object.values(def.entries); + + const keys = new Set(Object.keys(def.entries)); + + inst.extract = (values, params) => { + const newEntries: Record = {}; + for (const value of values) { + if (keys.has(value)) { + newEntries[value] = def.entries[value]; + } else throw new Error(`Key ${value} not found in enum`); + } + return new ZodEnum({ + ...def, + checks: [], + ...util.normalizeParams(params), + entries: newEntries, + }) as any; + }; + + inst.exclude = (values, params) => { + const newEntries: Record = { ...def.entries }; + for (const value of values) { + if (keys.has(value)) { + delete newEntries[value]; + } else throw new Error(`Key ${value} not found in enum`); + } + return new ZodEnum({ + ...def, + checks: [], + ...util.normalizeParams(params), + entries: newEntries, + }) as any; + }; +}); + +function _enum( + values: T, + params?: string | core.$ZodEnumParams +): ZodEnum>; +function _enum(entries: T, params?: string | core.$ZodEnumParams): ZodEnum; +function _enum(values: any, params?: string | core.$ZodEnumParams) { + const entries: any = Array.isArray(values) ? Object.fromEntries(values.map((v) => [v, v])) : values; + + return new ZodEnum({ + type: "enum", + entries, + ...util.normalizeParams(params), + }) as any; +} +export { _enum as enum }; + +/** @deprecated This API has been merged into `z.enum()`. Use `z.enum()` instead. + * + * ```ts + * enum Colors { red, green, blue } + * z.enum(Colors); + * ``` + */ +export function nativeEnum(entries: T, params?: string | core.$ZodEnumParams): ZodEnum { + return new ZodEnum({ + type: "enum", + entries, + ...util.normalizeParams(params), + }) as any as ZodEnum; +} + +// ZodLiteral +export interface ZodLiteral + extends _ZodType>, + core.$ZodLiteral { + "~standard": ZodStandardSchemaWithJSON; + values: Set; + /** @legacy Use `.values` instead. Accessing this property will throw an error if the literal accepts multiple values. */ + value: T; +} +export const ZodLiteral: core.$constructor = /*@__PURE__*/ core.$constructor("ZodLiteral", (inst, def) => { + core.$ZodLiteral.init(inst, def); + ZodType.init(inst, def); + inst._zod.processJSONSchema = (ctx, json, params) => processors.literalProcessor(inst, ctx, json, params); + inst.values = new Set(def.values); + Object.defineProperty(inst, "value", { + get() { + if (def.values.length > 1) { + throw new Error("This schema contains multiple valid literal values. Use `.values` instead."); + } + return def.values[0]; + }, + }); +}); + +export function literal>( + value: T, + params?: string | core.$ZodLiteralParams +): ZodLiteral; +export function literal( + value: T, + params?: string | core.$ZodLiteralParams +): ZodLiteral; +export function literal(value: any, params: any) { + return new ZodLiteral({ + type: "literal", + values: Array.isArray(value) ? value : [value], + ...util.normalizeParams(params), + }); +} + +// ZodFile +export interface ZodFile extends _ZodType, core.$ZodFile { + "~standard": ZodStandardSchemaWithJSON; + min(size: number, params?: string | core.$ZodCheckMinSizeParams): this; + max(size: number, params?: string | core.$ZodCheckMaxSizeParams): this; + mime(types: util.MimeTypes | Array, params?: string | core.$ZodCheckMimeTypeParams): this; +} +export const ZodFile: core.$constructor = /*@__PURE__*/ core.$constructor("ZodFile", (inst, def) => { + core.$ZodFile.init(inst, def); + ZodType.init(inst, def); + inst._zod.processJSONSchema = (ctx, json, params) => processors.fileProcessor(inst, ctx, json, params); + + inst.min = (size, params) => inst.check(core._minSize(size, params)); + inst.max = (size, params) => inst.check(core._maxSize(size, params)); + inst.mime = (types, params) => inst.check(core._mime(Array.isArray(types) ? types : [types], params)); +}); + +export function file(params?: string | core.$ZodFileParams): ZodFile { + return core._file(ZodFile, params) as any; +} + +// ZodTransform +export interface ZodTransform + extends _ZodType>, + core.$ZodTransform { + "~standard": ZodStandardSchemaWithJSON; +} +export const ZodTransform: core.$constructor = /*@__PURE__*/ core.$constructor( + "ZodTransform", + (inst, def) => { + core.$ZodTransform.init(inst, def); + ZodType.init(inst, def); + inst._zod.processJSONSchema = (ctx, json, params) => processors.transformProcessor(inst, ctx, json, params); + + inst._zod.parse = (payload, _ctx) => { + if (_ctx.direction === "backward") { + throw new core.$ZodEncodeError(inst.constructor.name); + } + + (payload as core.$RefinementCtx).addIssue = (issue) => { + if (typeof issue === "string") { + payload.issues.push(util.issue(issue, payload.value, def)); + } else { + // for Zod 3 backwards compatibility + const _issue = issue as any; + + if (_issue.fatal) _issue.continue = false; + _issue.code ??= "custom"; + _issue.input ??= payload.value; + _issue.inst ??= inst; + // _issue.continue ??= true; + payload.issues.push(util.issue(_issue)); + } + }; + + const output = def.transform(payload.value, payload); + if (output instanceof Promise) { + return output.then((output) => { + payload.value = output; + return payload; + }); + } + payload.value = output; + return payload; + }; + } +); + +export function transform( + fn: (input: I, ctx: core.ParsePayload) => O +): ZodTransform, I> { + return new ZodTransform({ + type: "transform", + transform: fn as any, + }) as any; +} + +// ZodOptional +export interface ZodOptional + extends _ZodType>, + core.$ZodOptional { + "~standard": ZodStandardSchemaWithJSON; + unwrap(): T; +} +export const ZodOptional: core.$constructor = /*@__PURE__*/ core.$constructor( + "ZodOptional", + (inst, def) => { + core.$ZodOptional.init(inst, def); + ZodType.init(inst, def); + inst._zod.processJSONSchema = (ctx, json, params) => processors.optionalProcessor(inst, ctx, json, params); + + inst.unwrap = () => inst._zod.def.innerType; + } +); + +export function optional(innerType: T): ZodOptional { + return new ZodOptional({ + type: "optional", + innerType: innerType as any as core.$ZodType, + }) as any; +} + +// ZodExactOptional +export interface ZodExactOptional + extends _ZodType>, + core.$ZodExactOptional { + "~standard": ZodStandardSchemaWithJSON; + unwrap(): T; +} +export const ZodExactOptional: core.$constructor = /*@__PURE__*/ core.$constructor( + "ZodExactOptional", + (inst, def) => { + core.$ZodExactOptional.init(inst, def); + ZodType.init(inst, def); + inst._zod.processJSONSchema = (ctx, json, params) => processors.optionalProcessor(inst, ctx, json, params); + + inst.unwrap = () => inst._zod.def.innerType; + } +); + +export function exactOptional(innerType: T): ZodExactOptional { + return new ZodExactOptional({ + type: "optional", + innerType: innerType as any as core.$ZodType, + }) as any; +} + +// ZodNullable +export interface ZodNullable + extends _ZodType>, + core.$ZodNullable { + "~standard": ZodStandardSchemaWithJSON; + unwrap(): T; +} +export const ZodNullable: core.$constructor = /*@__PURE__*/ core.$constructor( + "ZodNullable", + (inst, def) => { + core.$ZodNullable.init(inst, def); + ZodType.init(inst, def); + inst._zod.processJSONSchema = (ctx, json, params) => processors.nullableProcessor(inst, ctx, json, params); + + inst.unwrap = () => inst._zod.def.innerType; + } +); + +export function nullable(innerType: T): ZodNullable { + return new ZodNullable({ + type: "nullable", + innerType: innerType as any as core.$ZodType, + }) as any; +} + +// nullish +export function nullish(innerType: T): ZodOptional> { + return optional(nullable(innerType)); +} + +// ZodDefault +export interface ZodDefault + extends _ZodType>, + core.$ZodDefault { + "~standard": ZodStandardSchemaWithJSON; + unwrap(): T; + /** @deprecated Use `.unwrap()` instead. */ + removeDefault(): T; +} +export const ZodDefault: core.$constructor = /*@__PURE__*/ core.$constructor("ZodDefault", (inst, def) => { + core.$ZodDefault.init(inst, def); + ZodType.init(inst, def); + inst._zod.processJSONSchema = (ctx, json, params) => processors.defaultProcessor(inst, ctx, json, params); + + inst.unwrap = () => inst._zod.def.innerType; + inst.removeDefault = inst.unwrap; +}); + +export function _default( + innerType: T, + defaultValue: util.NoUndefined> | (() => util.NoUndefined>) +): ZodDefault { + return new ZodDefault({ + type: "default", + innerType: innerType as any as core.$ZodType, + get defaultValue() { + return typeof defaultValue === "function" ? (defaultValue as Function)() : util.shallowClone(defaultValue); + }, + }) as any; +} + +// ZodPrefault +export interface ZodPrefault + extends _ZodType>, + core.$ZodPrefault { + "~standard": ZodStandardSchemaWithJSON; + unwrap(): T; +} +export const ZodPrefault: core.$constructor = /*@__PURE__*/ core.$constructor( + "ZodPrefault", + (inst, def) => { + core.$ZodPrefault.init(inst, def); + ZodType.init(inst, def); + inst._zod.processJSONSchema = (ctx, json, params) => processors.prefaultProcessor(inst, ctx, json, params); + inst.unwrap = () => inst._zod.def.innerType; + } +); + +export function prefault( + innerType: T, + defaultValue: core.input | (() => core.input) +): ZodPrefault { + return new ZodPrefault({ + type: "prefault", + innerType: innerType as any as core.$ZodType, + get defaultValue() { + return typeof defaultValue === "function" ? (defaultValue as Function)() : util.shallowClone(defaultValue); + }, + }) as any; +} + +// ZodNonOptional +export interface ZodNonOptional + extends _ZodType>, + core.$ZodNonOptional { + "~standard": ZodStandardSchemaWithJSON; + unwrap(): T; +} +export const ZodNonOptional: core.$constructor = /*@__PURE__*/ core.$constructor( + "ZodNonOptional", + (inst, def) => { + core.$ZodNonOptional.init(inst, def); + ZodType.init(inst, def); + inst._zod.processJSONSchema = (ctx, json, params) => processors.nonoptionalProcessor(inst, ctx, json, params); + + inst.unwrap = () => inst._zod.def.innerType; + } +); + +export function nonoptional( + innerType: T, + params?: string | core.$ZodNonOptionalParams +): ZodNonOptional { + return new ZodNonOptional({ + type: "nonoptional", + innerType: innerType as any as core.$ZodType, + ...util.normalizeParams(params), + }) as any; +} + +// ZodSuccess +export interface ZodSuccess + extends _ZodType>, + core.$ZodSuccess { + "~standard": ZodStandardSchemaWithJSON; + unwrap(): T; +} +export const ZodSuccess: core.$constructor = /*@__PURE__*/ core.$constructor("ZodSuccess", (inst, def) => { + core.$ZodSuccess.init(inst, def); + ZodType.init(inst, def); + inst._zod.processJSONSchema = (ctx, json, params) => processors.successProcessor(inst, ctx, json, params); + + inst.unwrap = () => inst._zod.def.innerType; +}); + +export function success(innerType: T): ZodSuccess { + return new ZodSuccess({ + type: "success", + innerType: innerType as any as core.$ZodType, + }) as any; +} + +// ZodCatch +export interface ZodCatch + extends _ZodType>, + core.$ZodCatch { + "~standard": ZodStandardSchemaWithJSON; + unwrap(): T; + /** @deprecated Use `.unwrap()` instead. */ + removeCatch(): T; +} +export const ZodCatch: core.$constructor = /*@__PURE__*/ core.$constructor("ZodCatch", (inst, def) => { + core.$ZodCatch.init(inst, def); + ZodType.init(inst, def); + inst._zod.processJSONSchema = (ctx, json, params) => processors.catchProcessor(inst, ctx, json, params); + + inst.unwrap = () => inst._zod.def.innerType; + inst.removeCatch = inst.unwrap; +}); + +function _catch( + innerType: T, + catchValue: core.output | ((ctx: core.$ZodCatchCtx) => core.output) +): ZodCatch { + return new ZodCatch({ + type: "catch", + innerType: innerType as any as core.$ZodType, + catchValue: (typeof catchValue === "function" ? catchValue : () => catchValue) as ( + ctx: core.$ZodCatchCtx + ) => core.output, + }) as any; +} +export { _catch as catch }; + +// ZodNaN +export interface ZodNaN extends _ZodType, core.$ZodNaN { + "~standard": ZodStandardSchemaWithJSON; +} +export const ZodNaN: core.$constructor = /*@__PURE__*/ core.$constructor("ZodNaN", (inst, def) => { + core.$ZodNaN.init(inst, def); + ZodType.init(inst, def); + inst._zod.processJSONSchema = (ctx, json, params) => processors.nanProcessor(inst, ctx, json, params); +}); + +export function nan(params?: string | core.$ZodNaNParams): ZodNaN { + return core._nan(ZodNaN, params); +} + +// ZodPipe +export interface ZodPipe + extends _ZodType>, + core.$ZodPipe { + "~standard": ZodStandardSchemaWithJSON; + in: A; + out: B; +} +export const ZodPipe: core.$constructor = /*@__PURE__*/ core.$constructor("ZodPipe", (inst, def) => { + core.$ZodPipe.init(inst, def); + ZodType.init(inst, def); + inst._zod.processJSONSchema = (ctx, json, params) => processors.pipeProcessor(inst, ctx, json, params); + + inst.in = def.in; + inst.out = def.out; +}); + +export function pipe< + const A extends core.SomeType, + B extends core.$ZodType> = core.$ZodType>, +>(in_: A, out: B | core.$ZodType>): ZodPipe; +export function pipe(in_: core.SomeType, out: core.SomeType) { + return new ZodPipe({ + type: "pipe", + in: in_ as unknown as core.$ZodType, + out: out as unknown as core.$ZodType, + // ...util.normalizeParams(params), + }); +} + +// ZodCodec +export interface ZodCodec + extends ZodPipe, + core.$ZodCodec { + "~standard": ZodStandardSchemaWithJSON; + _zod: core.$ZodCodecInternals; + def: core.$ZodCodecDef; +} +export const ZodCodec: core.$constructor = /*@__PURE__*/ core.$constructor("ZodCodec", (inst, def) => { + ZodPipe.init(inst, def); + core.$ZodCodec.init(inst, def); +}); + +export function codec( + in_: A, + out: B, + params: { + decode: (value: core.output, payload: core.ParsePayload>) => core.util.MaybeAsync>; + encode: (value: core.input, payload: core.ParsePayload>) => core.util.MaybeAsync>; + } +): ZodCodec { + return new ZodCodec({ + type: "pipe", + in: in_ as any as core.$ZodType, + out: out as any as core.$ZodType, + transform: params.decode as any, + reverseTransform: params.encode as any, + }) as any; +} + +// ZodReadonly +export interface ZodReadonly + extends _ZodType>, + core.$ZodReadonly { + "~standard": ZodStandardSchemaWithJSON; + unwrap(): T; +} +export const ZodReadonly: core.$constructor = /*@__PURE__*/ core.$constructor( + "ZodReadonly", + (inst, def) => { + core.$ZodReadonly.init(inst, def); + ZodType.init(inst, def); + inst._zod.processJSONSchema = (ctx, json, params) => processors.readonlyProcessor(inst, ctx, json, params); + + inst.unwrap = () => inst._zod.def.innerType; + } +); + +export function readonly(innerType: T): ZodReadonly { + return new ZodReadonly({ + type: "readonly", + innerType: innerType as any as core.$ZodType, + }) as any; +} + +// ZodTemplateLiteral +export interface ZodTemplateLiteral